[Python-Dev] Python "2migr8"

Chris Angelico rosuav at gmail.com
Mon Apr 14 18:04:22 CEST 2014


On Tue, Apr 15, 2014 at 1:32 AM, Steve Dower <Steve.Dower at microsoft.com> wrote:
> My best idea so far would be to have a magic comment (to ensure 2.7 compatibility better than a "from __future__ ...") near the top of the file that marks that file as "must straddle 2.7 and 3.3". Adding this comment causes (for example) the parser to treat "except x, y" as a syntax error in this file, forces "from __future__ import ...", hides "dict.iterkeys", undefines "basestring", etc., but only for this file.
>

So if I understand you, this isn't really a "new version of Python" so
much as "Python 2.7 with checks for anything that would break on 3.3".
(BTW, any particular reason for targeting 3.3 specifically? PEP 461,
currently slated for 3.5, may make your job rather easier.) And the
file should run perfectly on both 2.7 and 3.3, and have the exact same
semantics. Is that correct?

If that's the case, how critical are false positives and false
negatives? You could make something that heuristically tries to figure
out when something could be a problem, and in dubious cases issues a
warning. That could afford to be a bit more aggressive in its warnings
than something that actually throws stuff out. You could even do a
whole lot of messy monkey-patching that checks stuff at run-time; if
performance becomes a problem, just switch back to 2.7 and it'll still
all run fine.

Ultimately, the best test of whether or not a piece of code runs in
2.7 and 3.3 is to simply run it in 2.7 and 3.3, but obviously that's
hard to do on a partial codebase. The trouble with a directive like
this is that it's hard to pin-point the source of a problem. For
instance, you say:

> ... it isn't unreasonable to make more significant changes, like having dict.keys returning a list that warns if it is mutated.
>

Suppose function foo calls function bar, passing it the .keys() of a
dict; function bar treats its argument as a list. Which one is at
fault? If they're in different modules and only one of them is marked
for migration mode, do you get a warning/error or not? Going for
warnings is the safe option here. You could warn for both half-cases
and error for the double. That is, dict.keys() returns a subclass of
list that, on mutation, will warn if the calling module is marked
migration-safe xor the module that originally created it is so marked,
and throws an error if both were marked. But for that to work, you
have to accept that there'll be both false positives (warnings issued
when the problem isn't in the migration-safe code) and false negatives
(warnings, rather than errors, when your code has a problem). Does
that kill the proposal's usefulness, or is that an acceptable cost?

ChrisA


More information about the Python-Dev mailing list