New PEP: The directive statement

Tim Peters tim.one at home.com
Sat Mar 24 02:17:34 EST 2001


[Martin von Loewis]
>>> Furthermore, what is the use of that information to a program?

[Tim]
>> Primarily, it's what makes it possible to write a simple tool
>> that nukes obsolete future statements.

[Martin von Loewis]
> I'd question this use of the information.  It has yet to be written,

True, but I've written many harder analyzers + translators for Python, and
several have been in the distribution for years (e.g., tabnanny.py,
checkappend.py, most recently reindent.py for 2.1).  So this FUD won't fly.

In return, neither is there a tool to nuke obsolete transitional directives.
The difference is that I don't know how to write the latter, in the absence
of PEP 236's __future__.py release-info database.

> but I hope it won't operate in automatic "nuke all" mode. E.g. when
> case insensitivity is the default in Python 2.5, Python 2.3 will still
> be around (say). So the author of some package may want to nuke the
> nested_scope directives, since nobody uses Python 2.1 anymore, but
> would leave the case_insensitive directives.

Sure.

> In short, I hope that the program would have a dry-run mode,

Different issue, but e.g. reindent.py has a dry-run mode, and I expect to
derive a future-nuker via transforming reindent.py.

> where it reports all directives it finds, and a nuking mode, where
> it is given a list of directives that it will remove.

Ah, note that I'm not signing up for writing a general *directive*
manipulation tool.  That's too open-ended for me.  The tool PEP 236
hypothesizes is limited to nuking obsolete future stmts, and PEP 236 is not
an open-ended scheme.  The tool is easy because the PEP is limited.

>> In another vein, in my own code I don't hesitate to use new features,
>> and couldn't care less if rare incompatible changes require me to
>> rewrite some code.  So I'll likely use future_statements much more
>> than most people.  I already have code that does
>>
>>     from __future__ import nested_scopes
>>     import sys
>>     assert nested_scopes.getMandatoryRelease() > sys.version_info
>>
>> This will assert-fail as soon as I run it under a release where
>> nested_scopes is the rule, and at that point I'll simply delete the
>> future_statement and move on.

> That sounds like a legitimite use, but I have my problems
> understanding it.  Are you relying on nested scopes in your code?

Yes, else I wouldn't have bothered to include the

    from __future__ import nested_scopes

line.

> If so, why do put the assert statement there?

I put the assert near the line it's complaining about, because the line it's
complaining about is the line I want to get rid of someday, and I want the
assert to tell me that.  Maybe a wordier version would be clearer:

    assert nested_scopes.getMandatoryRelease() > sys.version_info, \
         "no more need for the nested_scopes stmt above -- nuke it"

> Or does your code give a warning and you want to shut it up using
> the future import?

No.

> In that case, wouldn't it be better to use the warning framework?

People can do that too, or instead, if they like.  I was just giving examples
of ways the __future__ repository *can* be used.  As a passive data
repository, it's mechanism not policy.  People can *use* the info in any way
whatsoever they can dream up code to implement.

>> Code like this also works fine:
>>
>> import __future__
>> if __future__.nested_scopes.getMandatoryRelease() > sys.version_info:
>>     import old_version_of_module as amodule
>> else:
>>     import amodule
>>
>> I don't know that I'll have an acute need for that wrt nested_scopes
>> specifically

> Why are you checking the mandatory release here? Doesn't amodule have
> a future import in it?

Since I'm checking MandatoryRelease, it's irrelevant whether amodule has a
future import in it (amodule won't be imported unless the release I'm running
under is such that __future__ import of nested_scopes has no effect).

As I said above, I'll nuke obsolute future stmts in my own code ASAP, so in
*my* code checking MandatoryRelease is appropriate.  In *your* code perhaps
you'd like to check OptionalRelease instead, and keep old future stmts around
forever.  I'm not telling you which you should do, just giving an example of
what *I'd* do.  Again, __future__ is mechanism not policy:  you can code it
any way *you* like.  OK by me, because I can still code it the way *I* like
it, and I've generally got no interest in clinging to old versions.

>> In that case I may very well have an acute need to ship one version
>> of my source that exploits the new semantics but falls back to an
>> older & slower module if the compiler it's running under can't play
>> along.

> People routinely use sys.*version* for that; I'm really curious
> whether they'd prefer to investigate other variables instead.

I think PEP 236 is extremely clear that the release info in __future__.py is
in sys.version_info format:

    ...
    where, normally, OptionalRelease <  MandatoryRelease, and both are
    5-tuples of the same form as sys.version_info:

    (PY_MAJOR_VERSION, # the 2 in 2.1.0a3; an int
     PY_MINOR_VERSION, # the 1; an int
     PY_MICRO_VERSION, # the 0; an int
     PY_RELEASE_LEVEL, # "alpha", "beta", "candidate" or "final"; string
     PY_RELEASE_SERIAL # the 3; an int
    )

How could it be clearer?  Nobody complained; Barry pointed out that he
generally uses sys.hexversion (not sys.version) instead, but allowed that
sys.version_info is easier to read; and I can't imagine that anyone in their
right mind uses sys.version for stuff like this, since that's a string and is
not defined in a way that supports correct comparison (e.g., "10.0" < "2.1",
when we get that far).

BTW, note that the std test test___future__.py verifies that the info in
__future__.py *is* of the form described above.

Note too that, as you pointed out two msgs back, even if you're wedded to
sys.hexversion, it's not possible to write a hard-coded version check that's
guaranteed to *work* for these things across releases, since the
MandatoryRelease for a given feature may change across releases.  You really
need to access some form of info that ships with the compiler in order for
this to work correctly.  Putting the info in the std library makes it
painless to get at, and PEP 236 covers that too.

have-yet-to-hear-a-complaint-from-anyone-using-it<0.6-wink>-ly y'rs  - tim





More information about the Python-list mailing list