Other situations like this (was RE: [Python-Dev] Nested scopes resolution -- you can breathe again!)
Tim Peters
tim.one@home.com
Fri, 23 Feb 2001 00:30:27 -0500
[Guido]
> We also believe that the magical import mechanism is useful
> enough to be reused for other situations like this; Tim will
> draft a PEP to describe in excruciating detail.
[Jeremy Hylton]
> ...
> I'm happy to hear that Tim will draft this PEP. He didn't mention it
> at lunch today or I would have given him a big hug (or bought him a
> Coke).
Guido's msg was the first I heard of it too. I think this is the same
process by which I got assigned to change Windows imports: the issue came
up, and I opened my mouth <-0.9 wink>.
> As Tim knows, I think the PEP needs to say something about whether
> these magic imports create name bindings and what objects are
> bound to the names.
>
> Will we need an __nested_scopes__.py in the Lib directory?
Offhand, I suggest to create a real Lib/__future__.py, and let import code
get generated as always. The purpose of __future__.py is to record release
info in an *obvious* place to look for it (BTW, best I can tell, sys.version
isn't documented anywhere, so this serves that purpose too <wink>):
------------------------------------------------------------------
"""__future__: Record of phased-in incompatible language changes.
Each line is of the form:
FeatureName = ReleaseInfo
ReleaseInfo is a pair of the form:
(OptionalRelease, MandatoryRelease)
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
)
In the case of MandatoryReleases that have not yet occurred,
MandatoryRelease predicts the release in which the feature will become a
permanent part of the language.
Else MandatoryRelease records when the feature became a permanent part of
the language; in releases at or after that, modules no longer need
from __future__ import FeatureName
to use the feature in question, but may continue to use such imports.
In releases before OptionalRelease, an import from __future__ of FeatureName
will raise an exception.
MandatoryRelease may also be None, meaning that a planned feature got
dropped.
No line is ever to be deleted from this file.
"""
nested_scopes = (2, 1, 0, "beta", 1), (2, 2, 0, "final", 0)
-----------------------------------------------------------------
While this is 100% intended to serve a documentation purpose, I also intend
to use it in my own code, like so (none of which is special to the compiler
except for the first line):
from __future__ import nested_scopes
import sys
assert sys.version_info < nested_scopes[1], "delete this section!"
# Note that the assert above also triggers if MandatoryRelease is None,
# i.e. if the feature got dropped (under 2.1 rules, None is smaller than
# anything else <wink>).
del sys, nested_scopes
Other rules:
# Legal only at module scope, before all non-comment occurrences of
# name, and only when name is known to the compiler.
from __future__ import name
# Ditto. name2 has no special meaning.
from __future__ import name as name2
The purpose of the next two is to allow programmatic manipulation of the
info in __future__.py (generate help msgs, build a histogram of adoption
dates for incompatible changes by decade over the previous two centuries,
whatever).
# Legal anywhere, but no special meaning.
import __future__
import __future__ as name