On Tue, 28 May 2013 18:25:59 -0400, Joel Goldstick wrote: > I wonder > if it is a good idea in general to try to write code like this. -- > combined 2.x/3.x codebase can be a bear to maintain.
Not so much a bear as a tiny little kitten. > I wouldn't do it > unless there was some imposing reason that I must. Its not just print() > -- that isn't bad, but changes in module names (urllib), arithmetic, and > unicode especially make this idea in general, very tricky. Pity the > next developer who needs to try to maintain it. It's not that hard really. Well, like all things, it depends on the circumstances. If you're reliant on external modules, you *may* have a bad time if those modules are 2.x only or 3.x only, but the standard library and built-ins don't provide too much of a challenge. There's no doubt that supporting 2.x and 3.x in one code base is more difficult that just supporting one or the other, but the difficulty is much less than often supposed. Python 2.7, and to a lesser extent, 2.6, are designed to be as easy to port to 3.x as possible, which has the happy side-effect that they are also relatively easy to write code for them that will also run under 3.x. Many of the differences can be eliminated with a few __future__ imports: from __future__ import division, print_function Differences in behaviour of the built-ins can be eliminated: from future_builtins import * Built-ins such as reduce and cmp that have been moved, or eliminated, can easily be restored: if sys.version >= '3': from functools import reduce Or if you prefer a "Better To Ask Forgiveness Than Permission" approach: try: reduce except NameError: from functools import reduce Name changes of modules are easy to deal with: try: import configparser except ImportError: import ConfigParser as configparser The most difficult difference is the difference between strings in 2.x and 3.x, but if you drop support for Python 3.1 and 3.2, you can write code that works in both 2.7 and 3.3 by using the u"" syntax. Or just use ASCII literals, which work perfectly in both. There are really only a very few things that cannot be shared between 2.x and 3.x: syntactical features that are only supported by 3.x. So if you're planning on writing code that runs in both 2.x and 3.x, you need to eschew the 3-only features like keyword-only function arguments and function annotations. But that's no different than writing code to support *any* two versions that don't have identical syntax. E.g. 2.4 and 2.5: 2.5 supports ternary if, `a if condition else b`, while 2.4 does not, so if you need to support both, you can't use ternary if. Nearly all the code I write is for 2.4 or better, and I can assure you that the hardest part is supporting 2.4. Adding 3.x doesn't make it much harder. (My hat goes off to those supporting 2.3 through 3.3 in one code base. That is, frankly, astonishing.) Nobody *likes* to have to support really old versions missing the cool syntax that you want to use, but nobody says that you should even try. 3.x doesn't change that. -- Steven -- http://mail.python.org/mailman/listinfo/python-list