Release Notes for P4Python, Perforce's derived API for Python Version 2010.2 Introduction This document lists all user-visible changes to P4Python starting from release 2007.3, the first supported P4Python release. Perforce numbers releases YYYY.R/CCCCC, for example, 2007.3/30547. YYYY is the year; R is the release of that year; CCCCC is the bug fix change level. Each bug fix in these release notes is marked by its change number. Any build includes all bug fixes of all previous releases and all bug fixes of the current release up to the bug fix change level. To display the version of P4Python you have installed, start Python and issue the following commands: >>> import P4 >>> print(P4.P4.identify()) -------------------------------------------------------------------------- Installing P4Python Windows users can download an installer containing pre-built packages for P4Python from the Perforce FTP site. Users on other platforms must build from source, as detailed below. -------------------------------------------------------------------------- Upgrading P4Python Before installing P4Python 2010.2, uninstall any older versions of P4Python. Some earlier versions of P4Python consisted of the following files, which must be deleted before installing a later version: p4.py p4.pyc p4.pyo P4Client.pyd -------------------------------------------------------------------------- Building P4Python from Source 1. Download a suitable Perforce C++ API build from the Perforce FTP site at "ftp://ftp.perforce.com/perforce". The 32-bit Perforce C++ API build requires Python 32-bit and the 64-bit one requires Python 64-bit. Mac OS X users can get the Perforce C++ API build in the univeral bin.darwin80u directory. Windows users must get "p4api_vs2008_static.zip" from the "bin.ntx86" directory (for Python 32-bit) or "bin.ntx64" directory (for Python 64-bit). Then, unzip the archive into an empty directory. 2. Extract the P4Python API archive into a new, empty directory. 3. To build P4Python, run the following command: python setup.py build --apidir Note: in order to reinstall cleanly P4Python, remove the directory named "build". 4. To test your P4Python build, run the following command: python p4test.py Note: the test harness requires the Perforce server executable p4d to be installed and in the PATH. 5. To install P4Python, run the following command: python setup.py install --apidir Note: on Unix/Mac platforms, the installation must be performed as the root user. Also ensure that the umask is set correctly (typically 0022) before running the install. With a umask of 027, for example, the resulting installed files are accessible only by users of group root. -------------------------------------------------------------------------- Compatibility Statements Server Compatibility You can use any release of P4Python with any release of the Perforce server later than 2001.1 API Compatibility The 2010.2 release of P4Python requires the 2010.2 Perforce API. Older releases (down to 2008.2) might work but are not supported. Python Compatibility The 2010.2 release of P4Python, when built from source, is compatible only with Python 2.6 and Python 3.1. Using a prior version of Python will result in a compile error. For detailed compatibilty, please check the following table: Python Release | P4Python Release ====================================== 2.3 or earlier | not supported 2.4 | 2008.2 (unsupported) 2.5 | 2007.3 up to 2009.2 2.6 | 2009.1 or later 2.7 | 2010.1 or later (unsupported) 3.0 | 2010.1 (unsupported) 3.1 | 2010.2 The P4Python Windows installer requires Python 2.6. Platform Compatibility This release is certified on the following platforms: Linux 2.6 Intel (x86, x86_64) Solaris 10 Intel (x86) Windows XP, 2003, Vista, 7, 2008 Intel (x86, x86_64) FreeBSD 6.0, 7.0 Intel (x86, x86_64) Mac OS X 10.5, 10.6 (PPC/x86/x86_64) Compiler Compatibility To build P4Python from source, you must use a version of P4Python that has been compiled with the same compiler used to build the Perforce C++ API. For most platforms, use gcc/g++. Attempting to use a different compiler or a different version of the compiler causes linker errors due to differences in name handling. On Windows platforms, Python 2.6 and the P4Python installer are built with Visual Studio 2008. You can download the static version of the Perforce API for this compiler from the Perforce FTP site and build P4Python yourself. On Mac OS X, building P4Python with Python 3.1 may failed due to a Python bug. A workaround can be found in this Python bug report: http://bugs.python.org/issue7580 Compatibility with Previous Releases of P4Python P4Python 2010.2 is compatible with previous releases of P4Python from Perforce Software, unless otherwise specified. Known Limitations The Perforce client-server protocol is not designed to support multiple concurrent queries over the same connection. For this reason, multi-threaded applications using the C++ API or the derived APIs (P4Perl, P4Ruby, etc.) should ensure that a separate connection is used for each thread or that only one thread may use a shared connection at a time. Compatibility with the P4Python from the Public Depot Perforce P4Python is significantly different from the version of P4Python in the Perforce Public Depot. Perforce P4Python contains several improvements and interface changes intended to make P4Python consistent with the other scripting interfaces and with Python in general. If you are migrating from Public Depot version of P4Python, edit your scripts to ensure that the scripts comply with the new interface. The differences are detailed below. New module name --------------- The P4Python module has been renamed from p4 to P4. For example: Old: >>> import p4 >>> p4c = p4.P4() New: >>> import P4 >>> p4 = P4.P4() By convention, Public Depot P4Python used "p4c" as an instance variable because "p4" was used as a module name. Because the module has been renamed "P4", you can use "p4" for your instance variables. All demos and tests use the new convention. Deleted methods --------------- The following methods have been deleted from the P4 class and are no longer available. dropped Use connected() parse_forms Form parsing is now always on tagged See tagged attribute below New methods ----------- The following methods are new to Perforce P4Python. connected Returns True if the client is connected format_xxx Converts a dict-based specification into a string (replace xxx with spec type, for example: format_client) identify Returns information about P4Python parse_xxx Converts a string into a P4.Spec object (replace xxx with spec type) run_filelog Runs 'p4 filelog' and returns an array of P4.DepotFile objects run_login Runs "p4 login" using current password run_password Runs "p4 passwd" with old and new password run_submit Runs "p4 submit" Attributes ---------- Perforce P4Python provides the following attributes. Attributes can be set in the P4() constructor or by using their setters and getters. For example: >>> import P4 >>> p4 = P4.P4(client="myclient", port="1666") >>> p4.user = 'me' Most attributes can be set and read. Attributes are strings unless noted otherwise. api_level API compatibility level, INTEGER charset The character set to use. String, not a constant as in previous versions client Client to use (P4CLIENT) cwd Current Working Directory debug Debug level (for debugging P4Python), INTEGER errors Array of errors returned by the server (Read-Only), LIST exception_level Determines whether exceptions are thrown, INTEGER host Client Host input Input for next command, can be STRING, LIST or DICTIONARY maxlocktime MaxLockTime for commands, INTEGER maxresults MaxResults for commands, INTEGER maxscanrows MaxScanRows for commands, INTEGER p4config_file Returns the config file path (Read-Only) password Value of P4PASSWD port Value of P4PORT prog Name of the script, shown in the server log server_level Returns the server level (Read-Only) tagged Boolean value, determines whether to use tagged mode, INTEGER ticket_file Returns the name of the ticket file user Value of P4USER warnings Array of warnings returned by the server (Read-Only), LIST Tagged mode and form parsing ---------------------------- In Perforce P4Python 2007.3, form parsing and tagged output are enabled by default. (In Public Depot P4Python, tagged output and form parsing mode were disabled by default, but most scripts enabled them immediately.) Form parsing cannot be disabled explicitly, but tagged output can be enabled or disabled by setting p4.tagged as follows: p4.tagged = False # Disabled p4.tagged = True # Enabled This method can be used to disable form parsing, because form parsing does not work when tagged output is disabled. -------------------------------------------------------------------------- Key to symbols used in change notes below. * -- requires new p4python ** -- requires new p4d server program *** -- requires new P4API -------------------------------------------------------------------------- New functionality in 2010.2 #257896 (Bug #38952) * P4Python now comes in a Perfore standardized directory structure: p4python-..[-BETA]. Source and binary distributions created via 'python setup.py' will follow this naming scheme. #257259 (Bug #37856) * Python 3.1 is now fully supported. It also has full support for Unicode-enabled Perforce Servers. This also means that P4.charset can be set to multibyte charsets such as UTF16. #257096 (Bug #38766) * *** Errors and warnings are now instances of P4Message. This object has the additional methods generic(), severity() and (unique) msgid(), which makes parsing of error messages easier. P4.warnings and P4.errors still return the errors and warnings as strings for backwards compatibility. #239278 (Bug #38210) * Added new SetTrack() and GetTrack() methods. For more details about server performance tracking see: http://kb.perforce.com/article/883 Bugs fixed in 2010.2 #285237 (Bug #43213) * The connect() context would silently swallow exceptions thrown within the block. This means problems within the following code would get missed unless explicitly caught within the block: with p4.connect(): # do something with p4 # automatically disconnected This is now fixed. #287032 (Bug #43415) * Running 'print' on a file that started with '---' would crash Python. This is now fixed. There is still an oddity when p4.track = 1 and a user runs p4.run_print() on a file that only has lines starting with '--- '. In that case, the output of the print is lost. Disable tracking by setting p4.track = 0 (the default) will solve this problem. -------------------------------------------------------------------------- -------------------------------------------------------------------------- New functionality in 2010.1 #235589 (Bug #35946) * Compatibility with Python 3. This change makes P4Python incompatible with Python 2.5 and prior, but retains compatibility with Python 2.6 (Python 2.7 also works but is unsupported). Python 3.1 is currently only experimental because of Unicode and 8-bit ASCII support. P4Python 2010.1 with Python 3.1 at the moment only supports 7-bit ASCII on non-Unicode servers and UTF8 on Unicode servers. #231765 * Added new P4.server_unicode attribute that allows script writers to test whether or not a Perforce Server is in internationalized (unicode) mode. P4.server_case_insensitive() has been changed from a method to an attribute (that is, no brackets) P4.server_level, P4.server_unicode and P4.server_case_insensitive all will send a "info" command to the server upon invocation if no previous command was sent before. Previously, these commands would throw an exception instead. #230480 * New read-only string attributes PATCHLEVEL and OS so that script writers can test the installation of P4Python without having to parse the output of P4.identify() Bugs fixed in 2010.1 #242158 (Bug #38677) * P4.identify() now correctly report 'NTX64' for 64-bit builds on Windows. #230649 (Bug #37434) * All keyword arguments passed in the constructor are now evaluated correctly. #235706 * Support for P4.run_print() for more than one file. Previously, P4.run_print() would throw an exception when trying to print more than one file. #235718 (Bug #37841) * P4.RAISE_ERROR has been renamed to P4.RAISE_ERRORS for consistency with P4Ruby. P4.RAISE_ERROR is still available for backwards compatibility. #235730 (Bug #37186) * Under rare circumstances P4.run_filelog() would throw an "Index out of range" error for "fileSize" fields. This is now prevented. -------------------------------------------------------------------------- -------------------------------------------------------------------------- New functionality in 2009.2 #214490 (Bug #35417 ) * New P4.server_case_sensitive() method enables scripts to detect whether the server is case-sensitive. Can be called only after a command has been issued to the server. #214611 (Bug #032917) * Throw a P4Exception if user attempts to change the port after a connection is established. #215413 (Bug #31789) * Throw an exception if a user tries to set a charset wider than one byte. Previously, all commands subsequent to setting a multi-byte charset returned empty strings. Bugs fixed in 2009.2 #227423 (Bug #37143) * The build script removed the release notes when invoked. Fixed. #214614 (Bug #34866) * The P4.connected() method now correctly resets the flag when detecting a dropped connection. #215406 * P4.__enter__() now correctly returns self, which permits the following idiom to work correctly: with p4.connect() as p: # use p here as an alias #209643 (Bug #36223) * P4Python now builds with the latest API on Windows using Visual Studio 2008. Previously, the build failed because of a link error. #222723 (Bug #36558) * The Map class removed '-' and '+' from the path if the form Map.insert(lhs, rhs) was used, even if these characters did not appear at the beginning of the path. Now dashes and pluses are preserved within the path. -------------------------------------------------------------------------- -------------------------------------------------------------------------- New functionality in 2009.1 #191476 (Bug #26731) * Support for the Python "with" statement. P4.connect() now returns a Contect Management object that can be used in a "with" statement with a block. When the block is finished, the connection is automatically disconnected: import P4 p4 = P4.P4() with p4.connect(): # execute statements here # p4 is now disconnected Also, there are two new methods, P4.while_tagged() and P4.at_exception_level() that, when used in a "with" statement, set the tagged mode and exception_level for the block and then reset it back to the original state. For example: with p4.at_exception_level(P4.RAISE_ERROR): # no exceptions # for warnings p4.run_sync("//depot/main/...") Bugs fixed in 2009.1 #192108 (Bug #32920) * P4Python now correctly parsse jobs when the jobspec contains fields with names ending in numbers. #191458 (Bug #32834) * Charset can now be reset to the empty string ''. -------------------------------------------------------------------------- -------------------------------------------------------------------------- New functionality in 2008.2 #164805 (Bug #30704) * P4Python now builds under CYGWIN. #163103 (Bug #30363) * #166832 * A new class P4.Map has been defined in P4Python that allows users to create, and work with, Perforce mappings without requiring a connection to a server. Methods in the P4.Map class are: P4.Map() Constructor. P4.Map.join() Class method. Joins two maps to create a third. P4.Map.clear() Empties the map P4.Map.count() Returns the number of entries in the map P4.Map.is_empty() Returns True if the map is empty P4.Map.insert() Adds new entries to the map P4.Map.translate() Translates a string through the map P4.Map.includes() Returns True if the supplied string is visible through the map P4.Map.reverse() Swap left and right sides of the mapping P4.Map.lhs() Returns the left-hand-side of the map P4.Map.rhs() Returns the right-hand-side of the map P4.Map.as_array() Returns the map as an array Bugs fixed in 2008.2 #176515 (Bug #31367) * Using P4.run_print() in untagged mode throws an exception: IndexError: list index out of range This is now fixed. P4.run_print() can be used both in tagged and untagged mode. #157855 (Bug #29933) * P4Python now correctly loads the value of P4CHARSET from the environment. -------------------------------------------------------------------------- -------------------------------------------------------------------------- New functionality in 2008.1 #157600 * Added support for P4.run_resolve(). The default for run_resolve() is now to accept the merge hint provided by the server unless the hint is "e", indicating a conflict. In this case, run_resolve() will skip the resolve. P4.run_resolve() can also accept a "resolver" keyword argument, which should point to an instance of a subclass of P4.Resolver. The subclass should overwrite the method P4.Resolver.resolve(self, mergeData) and return a string indicating how the resolve should proceed. To get the old behaviour of "resolve", run the command P4.run("resolve"). You will need to set P4.input to the correct response in this case. #152008 (Bug #28761) * Added support for Python 2.4. #152362 (Bug #29024) * The 'P4.env( var )' method has been added to the P4 class. This instance method enables the caller to interrogate the Perforce environment, including reading Perforce variables from P4CONFIG files and, on Windows, the registry. P4.cwd now loads any P4CONFIG file settings that are appropriate to the new working directory. #153547 (Bug #29310) * P4Python now supports Mac OSX 10.5. Bugs fixed in 2008.1 #175062 (Bug #31637) * P4Python sometimes incorrectly decrements the reference count of None when calling p4.run_filelog(). In certain circumstances, this could cause Python to deallocate None, causing a fatal error. This problem has been fixed. #168966 (Bug #31180) * P4Python did not release its output variable correctly. This caused a crash on 64 bit versions of Python when the P4 object went out of scope. This is now fixed. #166644 (Bug #30723) * P4Python connections were not being correctly cleaned up when they were discarded due to a reference counting problem. This problem has been corrected. #161025 (Bug #30076) * Fixed a serious memory leak problem in P4Python. Basically, all results returned from P4.run() had too many reference counts, which prevented the Python garbage collector from being able to clean up these objects. Now P4Python is memory neutral, as can be checked with the debug version of Python, which shows the total number of reference counts. #157844 (Bug #28653) * Fixed an error with p4.run_filelog() when tagged output is off. The "df" variable is now correctly initialized on line 333 of P4.py. #156847 (Bug #28770) * Calling print to retrieve the contents of a file no longer truncates content. #155969 (Bug #29703) * When trying to create an illegal field in a Spec, P4Python would try to raise a P4Error, only to fail because the wrong number of arguments was provided to the Exception. This has been fixed. -------------------------------------------------------------------------- -------------------------------------------------------------------------- Bugs fixed in 2007.3 #149927 (Bug #28703) * The presence of deleted revisions in a file's history could lead to P4Python throwing an error message. This occurred because deleted revisions do not have 'digest' or 'fileSize' fields. This problem has been corrected. #146116 (Bug #28260) * The P4Python test harness, p4test.py, was omitted from the source distribution in error. This problem has been corrected. #146024 (Bug #28077) * P4.Revision doesn't have a depot_file, or depotFile attribute as its counterparts in P4Perl and P4Ruby do. This is now fixed.