[Python-Dev] Proposal: from __future__import unicode_string_literals

"Martin v. Löwis" martin at v.loewis.de
Tue Mar 25 03:37:15 CET 2008


> | Just to repeat myself: With that patch to Django, you can
> | a) support all versions of Python simultaneously, from 2.x to 3.0
> 
> I find this surprising for two reasons.
> 
> 1. I had the impression from discussions over the past year that fully 
> automatic use of 2to3 would presume use of 2.6 and its backported 3.0 
> features and __future__ imports.  If it really works with ealier 2.x code, 
> great, but please pardon any initial surprise or scepticism.

This is precisely why I started this porting experiment. If you are
still skeptic, please substantiate your skepticism with facts: run
my patch, and tell me why it doesn't work, or couldn't be completed.
If you are now merely surprised, but not skeptic anymore: my pleasure.

The believe that you must port to 2.6 first is wide-spread. It probably
originates from the statement that the official porting strategy
involves porting to 2.6 first. That strategy does so, however, to enable
you to run the -3 option, so you can find porting problems more easily.
If you can find the porting problems the hard way, i.e. by running the
software and testing it, you don't need the -3 warnings.

When I started a week ago, a few essential 2to3 fixers did not exist
(in particular the one David Wolever wrote to make implicit relative
imports explicit). That fixer really falls into the 2to2.5 category;
it would have been possible to change the code to use relative imports
everywhere, thereby breaking 2.3 compatibility. It is possible that
other examples like this still exist (i.e. 2to3 doesn't fix it, but
doesn't have to if you can assume 2.5), but I'm not aware of any

(actually, that's not entirely true - the email module renaming
 is of the same kind. However, this can be dealt with by ImportError
 guards. Still, having a fixer for that might be useful)

> 2. You report has caveats such as
> 
> * there are certainly large parts of the code base that I haven't touched, 
> so more issues are likely to show up

True.

> *This port attempts to maintain compatibility with older Python versions 
> from a single code base; the goal is to support all versions that Django 
> supports, plus 3.0. The current patch fails to do so in certain details, 
> due to bugs in the 2to3 tool.
> 
> *This approach mostly works, and has the following flaws:
>  some of the fixers work incorrectly (bugs 2453, 2446, 2468)

These bugs are really shallow, and some have been fixed already.

> *I have worked with sqlite3 only; all the other databases have not been 
> tested.

True.

> So your unqualified assertion seems more like an anticipated future 
> (certain to you but maybe not to others) than present reality.

Likewise, the statement that you *can't* possibly use the same code
base from 2.1 to 3.0 is unfounded, and, unlike my claim, doesn't have
any kind of proof behind it.

> 3. Also, you said you worked around some 2to3 failings with conditional 
> blocks like, I presume, the following.
> 
> if sys.version < (3,0,0): <old 2.x code>
> else: <revised 3.0 code>
> 
> Do I assume correctly that you, rather than 2to3 had to do such?

Indeed.

> Will 2to3 remove the wrapper to leave just the 3.0 code?

Currently, it leaves the code unchanged. It could fairly easily remove
it, but doing so might shift line numbers, which in turn is undesirable.
2to3 has support for optional fixers, and that might be a use case.

> Or would someone have to go thru by hand to get clean 3.0 code?

See above. Writing a fixer for it is fairly easy, and somebody will
certainly do that, but I would only run it when using a "burn the
bridges" run.

> I understand that this is a standard method for multiple release code, but 
> it seems a bit like cheating since the point of 2to3 is to not to have to 
> do this.  Or is converting 'types.ClassType' to 'types' a future fixer 
> item?

No. This is the sort of change that 2to3 can't do right. If Django would
require Python 2.5, the conditional could go away, as this appears in a
context of creating exception classes on-the-fly; they can be new-style
classes in 2.5.

However, I consider conditional code blocks not as cheating at all. If
you want to provide backwards compatibility, you *always* have to
compromise readability for portability. This was even the case within
2.x, where you can't use True and False if you want to support Python
versions that didn't have it, or where you can use generators, or
iterators, or ..., when older Python versions need to be supported.

The main point of 2to3 is not to have the 3.x code "look nice", in
fact, in many cases, it won't, since 2to3 must make conservative
assumptions in some cases, so to not break the semantics of the program.

Instead, the main point of 2to3 is to replace syntax that is going
away with the 3.x equivalent syntax. In the cases where I
conventionalize on the Python version, it's not syntax that has changed.

Regards,
Martin



More information about the Python-Dev mailing list