Saturday, June 27, 2009

Python 3.1 released!

I'm happy to announce that today Python 3.1 was released. I won't dwell the new features, since those are more completely listed elsewhere. I'm quite happy with this release. A lot of work has been put into 3.x as stable as its older 2.x siblings. I would like to see a lot of libraries and applications start serious looking at the port to 3.x now. As always there's a bunch of core developers waiting to help on the python-porting mailing list.

Anyway, 3.1 is available for download in source and several binary formats on python.org.

Wednesday, May 6, 2009

Python 3.1 beta 1 released

I'm pleased to announce that the first beta of Python 3.1 has been released. In addition to the features found in the previous alphas, the beta has several more improvements. Most importantly, I think, is PEP 383. It defines a way for undecodable paths in file systems to be safely round tripped from Unicode strings. The repr of floats also now uses a new algorithm which determines the shortest possible value.

It is planned that this will be the only beta in order for 3.1 to make a final in late June. Please download it and try it out. This is 3.x's future, and in my opinion, much of an improvement. As always, you can submit any problems you see to bugs.python.org

Tuesday, March 24, 2009

unittest - now with test skipping (finally)

Yesterday, I was happy to commit a patch which added test skipping and expected failure support to the venerable unittest module. It adds a skip() method to TestCase, which marks the current test being run as skipped, as well as a set of useful decorators. Here's a short example:

import sys
import unittest

class SkippingExample(unittest.TestCase):

@unittest.skip("testing skipping")
def test_skip_me(self):
self.fail("shouldn't happen")

def test_normal(self):
self.assertEqual(1, 1)

@unittest.skipIf(sys.version_info < (2, 6),
"not supported in this veresion")
def test_show_skip_if(self):
# testing some things here
pass

@unittest.expectedFailure
def test_expected_failure(self):
self.fail("this should happen unfortunately")


# Yes, you can skip whole classes, too!
@unittest.skip("classing skipping")
class CompletelySkippedTest(unittest.TestCase):

def test_not_run_at_all(self):
self.fail("shouldn't happen")


if __name__ == "__main__":
unittest.main()


Running it in verbose mode gives:


__main__.CompletelySkippedTest ... skipped 'classing skipping'
test_expected_failure (__main__.SkippingExample) ... expected failure
test_normal (__main__.SkippingExample) ... ok
test_show_skip_if (__main__.SkippingExample) ... ok
test_skip_me (__main__.SkippingExample) ... skipped 'testing skipping'

----------------------------------------------------------------------
Ran 5 tests in 0.010s

OK (skipped=2, expected failures=1)


I have high hopes for this and Python's regression tests. Hopefully it will simplify the ugly system of test skipping we have now. It should also help us pacify other implementations who want CPython implementation detail tests skipped.

Saturday, February 14, 2009

Python 3.0.1 released

The first bugfix release, 3.0.1, of the new Python 3.x series has been released! Many embarrassing bugs have been fixed. Among other things:


  • The wsgiref package has been fixed for 3.x.

  • A few hideous bugs in the new IO implementation have been squashed. In addition, a few cases have been optimized. (Note that IO in 3.x is still quite a bit slower than 2.x; more on that later.)

  • Unbuffered standard streams (the "-u" flag) have been restored.



This is actually a bit more than an average point release. Somehow, the builtin cmp() and __cmp__ slipped into the final release and has been removed in 3.0.1.

Our next goal is 3.1. We plan to compress our rather huge release cycle to make 3.1 between 1/2 and 1 year after 3.0. The focus of 3.1 will be stabilizing the feature set and change in 3.x. This is includes the rewrite of IO in C for speed and Brett's rewrite of import in Python.

Thursday, January 1, 2009

MRO magic

Here's some more less publicized evil you can accomplish with metaclasses. Here's a simple example file: (Note that although I'm using Python 3.0, this works with all new-style class supporting versions.)

# mromagic.py
class A(object):

def a_method(self):
print("A")

class B(object):

def b_method(self):
print("B")

class MROMagicMeta(type):

def mro(cls):
return (cls, B, object)

class C(A, metaclass=MROMagicMeta):

def c_method(self):
print("C")


Now let's play with this a little:

>>> import mromagic
>>> mycls = mromagic.C()
>>> mycls
<mromagic.C object at 0x622890>
>>> mycls.c_method()
C
>>> mycls.a_method()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'C' object has no attribute 'a_method'
>>> mycls.b_method()
B
>>> type(mycls).__mro__
(<class 'mromagic.C'>, <class 'mromagic.B'>, <class 'object'>)
>>> type(mycls).__bases__
(<class 'mromagic.A'>,)


How does this work? By overriding mro() on the a metaclass we can define a custom __mro__ for our class. Python will then traverse it instead of the default implementation, which is provided by type.mro().

Thursday, December 11, 2008

Get help porting your package!

To help the community with porting their packages to Python 3, we have created the python-porting mailing list. Many core developers are subscribed to the list, so you should be able to get excellent advice on 2to3, the bytes/unicode split, C-API, or other incompatibilities.

Wednesday, December 3, 2008

Is it all futile?

Today, the much anticipated Python 3.0 final was released. Truly, this is a historic release for the Python community, the first intentional incompatible Python release. It's been a long time in the making, and I applaud everybody who is responsible for proving Py3k is not vaporware. Guido and the other decision makers on Python-dev also deserve credit for not making py3k changes too gratuitous; many revolutionary ideas and features were proposed and rejected. I have every confidence that every incompatibility was well thought out. Much thought has also been given to making the transition as easy as possible for the community. The suggested migration path, fixing Py3k warnings in 2.6 and then applying 2to3, has been used with a fair amount of success on several projects. We've even had several Py3k love letters!

Still, I can't help being a little worried. I think the bytes and str divide will be difficult for people especially with IO where everything has to be dealt with in bytes. We may see many "x.encode('ascii')" lines popping up all over codebases. Userland libraries will need to maintain compatibility with 2.4 and 2.5 for a while; that significantly complicates the dream of maintaining just one branch for 2.x and py3k. 2to3 is not even close to perfect and will only correct the surface incompatibilities of syntax between the versions. I'm also concerned about burn out. The excitement of a new major version will certainly spur an interest in porting for a few months, but I suspect it won't be so fun after the aura wears off a bit. I hope common base libraries (PIL, Twisted, lxml, etc...) are ported soon. It will build the bridge for everything else to cross over too.

Of course, what I'm forgetting is the amazing Python community. Whatever the results, a new era has certainly begun. We just need time.