The hackfest is over and a lot of things got fixed but unfortunately Python3 support was broken. I just committed a couple of patches to fix this. Here are some things PyGObject developers should look out for. When I note to only use something in tests it means that there is a compat module that is only available to the tests. Actual code should either add the workaround to the top of their module or try not to have a distinction between things such as unicode and longs which no longer exist in Python 3.
- use range instead of xrange – loss of performance in Python 2 but Python 3 treats range similarly to python 2’s xrange
- use dict.items() instead of dict.iteritems() – same as the xrange issue
- callable does not exist in 3.x, use hasattr(obj, ‘__call__’) or
if sys.version_info > (3, 0): def callable(obj): return hasattr(obj, '__call__') - using unicode in tests is tricky, you can’t use u” even in a versioned conditional as python3’s parser chokes on it. Do this in tests (and only i
in tests):from compathelper import _unicode unicode_string = _unicode('this is a unicode string') - exception caching changed in 2.7, instead of except Exception, e we now use except Exception as e. Do this to be compatible with older versions:
except Exception: etype, e = sys.exc_info()[:2] - Unbound methods with an im_func attribute no longer exits in 3.x. Unbound methods are now just functions so class.method in 3.x is equivalent to class.method.im_func in 2.x. If you have to go this low level do this:
func = class.method if sys.version_info < (3,0): func = func.im_funcUpdate: It was pointed out to me that this can be expressed as a simple getattr triple:
getattr(class.method, 'im_func', class.method) - all numbers are long in 3.x so 42L is invalid in 3.x. In tests (and only in tests) do this:
from compathelper import _long l = _long(42)[read this post in: ar de es fr it ja ko pt ru zh-CN ]
are you sure that these tricks are a good idea for python2+3 compatibility? afair, “the way to go” is the 2to3 script, which handles most issues you were pointing out (e.g. replaces xrange with range, replaces iteritems with items, converts the except clause syntax, removes the L from 42L etc.).
the unicode part is a bit trickier as especially in test cases you’d like to have good control over the types involved, but usually 2to3 should do something reasonable even here.
Comment by chrysn — January 27, 2011 @ 5:00 am
just looked up the links:
* http://www.python.org/dev/peps/pep-3000/#compatibility-and-transition states that “There is no requirement that Python 2.6 code will run unmodified on Python 3.0″
* http://docs.python.org/library/2to3.html describes the 2to3 tool that can be used to convert version 2 code to version 3 code (for an independent -3 release)
Comment by chrysn — January 27, 2011 @ 10:08 am
We are targeting Python 3.0 while keeping a minimum of compatibility with 2.6. Once Debian and RHEL moves to a default 2.7 or above we will drop support for the older versions (though it might take awhile for this to happen). Since we are targeting 3.0 I rather, for maintainability reasons, have the hacks there. They are used very sparingly and mostly in the test cases for checking each type.
Comment by J5 — January 27, 2011 @ 10:50 am