Welcome to SpellCoder Sign in | Join | Help

Python 2.5 Release and What's New


Python 2.5 is now released, with some new performance and language improvements.
I had a fast review on Python 2.5, and I noticed some new language stuff like

1- Conditional Expressions
if you are familiar with C style syntax so you know syntax like this
x = y > 10 ? 10 : 0
which means
if(y > 10)
{
x = 10;
}
else
{
x= 0;
}
Python didn't have similar syntax before but in this version this was added like this
x = 10 if y > 0 else 0

2- Partial Function Application

This is really a very cool feature, and I think no c-style language had this feature before.
a functools module is added to support some functional programming features so you can write a function f (a, b, c) then you can create new function g(b, c) that is equivalent to f(a, b, 1).
consider this example.

import functools
def Add(a, b, c):
    return a + b + c

Add2 = functools.partial(Add, c=1)

so now you can call Add2(1,1) and the result will be equivalent to Add(1,1,1) because we made Add2 as a partial call of Add(a, b, 1)

3- Unified Try/Except/Finally

Until Python 2.5, the try statement came in two flavours. You could use a finally block to ensure that code is always executed, or one or more except blocks to catch specific exceptions. You couldn't combine both except blocks and a finally block, because generating the right bytecode for the combined version was complicated and it wasn't clear what the semantics of the combined should be.

Guido van Rossum spent some time working with Java, which does support the equivalent of combining except blocks and a finally block, and this clarified what the statement should mean. In Python 2.5, you can now write:

try:
    block-1 ...
except Exception1:
    handler-1 ...
except Exception2:
    handler-2 ...
else:
    else-block
finally:
    final-block

The code in block-1 is executed. If the code raises an exception, the various except blocks are tested: if the exception is of class Exception1, handler-1 is executed; otherwise if it's of class Exception2, handler-2 is executed, and so forth. If no exception is raised, the else-block is executed.

No matter what happened previously, the final-block is executed once the code block is complete and any raised exceptions handled. Even if there's an error in an exception handler or the else-block and a new exception is raised, the code in the final-block is still run.

4- The with Statement
this statement is very much similar to the using block in C#.
consider an example of opening a file and making sure that it is closed after the block ends

with open('/etc/passwd', 'r') as f:
    for line in f:
        print line

so after the with block ends the f object is completly distroyed and the file is closed.
and like C# the f object should implement some kind of cleanup functions to make it possible for the with block to call these functions automatically, in C# the object should implement IDisposable in python
  • The expression is evaluated and should result in an object called a ``context manager''. The context manager must have __enter__() and __exit__() methods.
  • The context manager's __enter__() method is called. The value returned is assigned to VAR. If no 'as VAR' clause is present, the value is simply discarded.
  • The code in BLOCK is executed.
  • If BLOCK raises an exception, the __exit__(type, value, traceback) is called with the exception details, the same values returned by sys.exc_info(). The method's return value controls whether the exception is re-raised: any false value re-raises the exception, and True will result in suppressing it. You'll only rarely want to suppress the exception, because if you do the author of the code containing the 'with' statement will never realize anything went wrong.
  • If BLOCK didn't raise an exception, the __exit__() method is still called, but type, value, and traceback are all None.
5- Exception as New-Style Classes

Exception classes can now be new-style classes, not just classic classes, and the built-in Exception class and all the standard built-in exceptions (NameError, ValueError, etc.) are now new-style classes.

The inheritance hierarchy for exceptions has been rearranged a bit. In 2.5, the inheritance relationships are:

BaseException       # New in Python 2.5
|- KeyboardInterrupt
|- SystemExit
|- Exception
   |- (all other current built-in exceptions)

This rearrangement was done because people often want to catch all exceptions that indicate program errors. KeyboardInterrupt and SystemExit aren't errors, though, and usually represent an explicit action such as the user hitting Control-C or code calling sys.exit(). A bare except: will catch all exceptions, so you commonly need to list KeyboardInterrupt and SystemExit in order to re-raise them. The usual pattern is:

try:
    ...
except (KeyboardInterrupt, SystemExit):
    raise
except:
    # Log error... 
    # Continue running program...

Optimizations

Several of the optimizations were developed at the NeedForSpeed sprint, an event held in Reykjavik, Iceland, from May 21-28 2006. The sprint focused on speed enhancements to the CPython implementation and was funded by EWT LLC with local support from CCP Games. Those optimizations added at this sprint are specially marked in the following list.

  • When they were introduced in Python 2.4, the built-in set and frozenset types were built on top of Python's dictionary type. In 2.5 the internal data structure has been customized for implementing sets, and as a result sets will use a third less memory and are somewhat faster. (Implemented by Raymond Hettinger.)
  • The speed of some Unicode operations, such as finding substrings, string splitting, and character map encoding and decoding, has been improved. (Substring search and splitting improvements were added by Fredrik Lundh and Andrew Dalke at the NeedForSpeed sprint. Character maps were improved by Walter Dörwald and Martin von Löwis.)
  • The long(str, base) function is now faster on long digit strings because fewer intermediate results are calculated. The peak is for strings of around 800-1000 digits where the function is 6 times faster. (Contributed by Alan McIntyre and committed at the NeedForSpeed sprint.)
  • The struct module now compiles structure format strings into an internal representation and caches this representation, yielding a 20% speedup. (Contributed by Bob Ippolito at the NeedForSpeed sprint.)
  • The re module got a 1 or 2% speedup by switching to Python's allocator functions instead of the system's malloc() and free(). (Contributed by Jack Diederich at the NeedForSpeed sprint.)
  • The code generator's peephole optimizer now performs simple constant folding in expressions. If you write something like a = 2+3, the code generator will do the arithmetic and produce code corresponding to a = 5. (Proposed and implemented by Raymond Hettinger.)
  • Function calls are now faster because code objects now keep the most recently finished frame (a ``zombie frame'') in an internal field of the code object, reusing it the next time the code object is invoked. (Original patch by Michael Hudson, modified by Armin Rigo and Richard Jones; committed at the NeedForSpeed sprint.)

    Frame objects are also slightly smaller, which may improve cache locality and reduce memory usage a bit. (Contributed by Neal Norwitz.)

  • Python's built-in exceptions are now new-style classes, a change that speeds up instantiation considerably. Exception handling in Python 2.5 is therefore about 30% faster than in 2.4. (Contributed by Richard Jones, Georg Brandl and Sean Reifschneider at the NeedForSpeed sprint.)
  • Importing now caches the paths tried, recording whether they exist or not so that the interpreter makes fewer open() and stat() calls on startup. (Contributed by Martin von Löwis and Georg Brandl.)
Porting To Python 2.5

  • ASCII is now the default encoding for modules. It's now a syntax error if a module contains string literals with 8-bit characters but doesn't have an encoding declaration. In Python 2.4 this triggered a warning, not a syntax error.
  • Previously, the gi_frame attribute of a generator was always a frame object. Because of the PEP 342 changes described in section 7, it's now possible for gi_frame to be None.
  • A new warning, UnicodeWarning, is triggered when you attempt to compare a Unicode string and an 8-bit string that can't be converted to Unicode using the default ASCII encoding. Previously such comparisons would raise a UnicodeDecodeError exception.
  • Library: the csv module is now stricter about multi-line quoted fields. If your files contain newlines embedded within fields, the input should be split into lines in a manner which preserves the newline characters.
  • Library: the locale module's format() function's would previously accept any string as long as no more than one %char specifier appeared. In Python 2.5, the argument must be exactly one %char specifier with no surrounding text.
  • Library: The pickle and cPickle modules no longer accept a return value of None from the __reduce__() method; the method must return a tuple of arguments instead. The modules also no longer accept the deprecated bin keyword parameter.
  • Library: The SimpleXMLRPCServer and DocXMLRPCServer classes now have a rpc_paths attribute that constrains XML-RPC operations to a limited set of URL paths; the default is to allow only '/' and '/RPC2'. Setting rpc_paths to None or an empty tuple disables this path checking.
  • C API: Many functions now use Py_ssize_t instead of int to allow processing more data on 64-bit machines. Extension code may need to make the same change to avoid warnings and to support 64-bit machines. See the earlier section 10 for a discussion of this change.
  • C API: The obmalloc changes mean that you must be careful to not mix usage of the PyMem_*() and PyObject_*() families of functions. Memory allocated with one family's *_Malloc() must be freed with the corresponding family's *_Free() function.
Give this version a try now

Published Monday, September 25, 2006 6:07 PM by Mohammed Hossam
Filed Under:

Comments

No Comments

Anonymous comments are disabled