[Python-ideas] Making it easy to prepare for PEP479
Steven D'Aprano
steve at pearwood.info
Mon May 18 18:18:27 CEST 2015
On Tue, May 19, 2015 at 12:13:21AM +1000, Chris Angelico wrote:
> On Mon, May 18, 2015 at 11:32 PM, Joao S. O. Bueno
> <jsbueno at python.org.br> wrote:
> > Indeed - importing as NOP would surely be broken -
> >
> > The nice fix would be to be able to do
> > from __future__ import jaberwock
> >
> > and have a plain "ImportError" that could be catched.
>
> Indeed. Though I'm not sure what a correctly-spelled "from __future__
> import jabberwock" would do; exceptions already "burble" up the call
> stack until they meet "the clause that catch[es]" them. :)
You cannot catch errors in "from __future__ import" lines, because they
are compile-time errors, not runtime errors. Any __future__ lines must
be the first lines of executable code in the module. Only comments,
blank lines, the module docstring, and other __future__ lines can
preceed them, so this cannot work:
try:
from __future__ import feature
except:
pass
for the same reason that this cannot work:
try:
thing = }{
except SyntaxError:
thing = {}
It is best to think of the __future__ imports as directives to the
compiler. They tell the compiler to produce different code, change
syntax, or similar. Except in the interactive interpreter, you cannot
change the compiler settings part way through compiling the module.
There is a real __future__ module, but it exists only for introspection
purposes.
[...]
> The way to make this work would be two-fold. Firstly, an incorrect
> __future__ directive would have to no longer be a SyntaxError; and
> secondly, __future__ directives would have to be permitted after a try
> statement (currently, they're not allowed to follow anything, so the
> 'try' would have to be special-cased to be allowed in).
It's not enough to merely change the wording of the error from
SyntaxError to something else. You have to change when it occurs: it can
no longer be raised at compile time, but has to happen at run time. That
means that __future__ imports have to have compile to something which
runs at run time, instead of just being a directive to the compiler.
As for the changes necessary to the compiler, I have no idea how
extensive they would be, but my guess is "extremely".
Also, consider that once you are allowing __future__ directives to occur
after a try statement, expect there to be a lot more pressure to allow
it after any arbitrary code. After all, I might want to write:
if sys.version != '3.7' and read_config('config.ini')['allow_jabberwocky']:
from __future__ import jabberwocky
so you're opening the doors to a LOT more complexity.
Which, as far as I am concerned, is a good thing, because it makes the
chances of this actually happening to be somewhere between Buckley's and
none *wink*
--
Steve
More information about the Python-ideas
mailing list