__future__ and eval()
Hi guys, when developing my dedent tool, I stumbled over the following behavior: In dedent, I had the line from __future__ import print_function Later in the script, I do some exec(the_script) and I was surprised: The exec() script inherited the __future__ statement! It behaved like the future statement were implicitly there. Is that a bug or a feature? You can try the effect by "pip install dedent" and adding the future statement there. I'd like to know if this is a bug (and I think so) -- Christian Tismer :^) tismer@stackless.com Software Consulting : http://www.stackless.com/ Karl-Liebknecht-Str. 121 : https://github.com/PySide 14482 Potsdam : GPG key -> 0xFB7BEE0E phone +49 173 24 18 776 fax +49 (30) 700143-0023
On Sat, Oct 1, 2016 at 9:39 PM, Christian Tismer <tismer@stackless.com> wrote:
The exec() script inherited the __future__ statement! It behaved like the future statement were implicitly there.
Is that a bug or a feature?
It's documented, but not very noisily. https://docs.python.org/2/reference/simple_stmts.html#future-statements So if you want to isolate the execution environments, you can use compile() explicitly. Without isolation: Python 2.7.12+ (default, Sep 1 2016, 20:27:38) [GCC 6.2.0 20160822] on linux2 Type "help", "copyright", "credits" or "license" for more information.
exec(compile("print('hello','world')", "-", "exec")) ('hello', 'world') exec(compile("from __future__ import print_function; print('hello','world')", "-", "exec")) hello world from __future__ import print_function exec(compile("print('hello','world')", "-", "exec")) hello world exec(compile("from __future__ import print_function; print('hello','world')", "-", "exec")) hello world
With isolation:
exec(compile("print('hello','world')", "-", "exec", 0, 1)) ('hello', 'world') exec(compile("from __future__ import print_function; print('hello','world')", "-", "exec", 0, 1)) hello world
So I'd call it a feature, but possibly one that warrants a mention in the exec and eval docs. Maybe something like: https://docs.python.org/2/reference/simple_stmts.html#the-exec-statement [2] When strings are executed, __future__ directives active in the surrounding context will be active for the compiled code also. If this is not desired, see the compile() function's dont_inherit parameter. Would that clarify? ChrisA
On Sat, Oct 1, 2016 at 10:17 PM, Chris Angelico <rosuav@gmail.com> wrote:
So I'd call it a feature, but possibly one that warrants a mention in the exec and eval docs.
To clarify: This *is* documented under __future__, but not under exec/eval. I'm just suggesting adding another cross-reference. ChrisA
On 1 October 2016 at 22:18, Chris Angelico <rosuav@gmail.com> wrote:
On Sat, Oct 1, 2016 at 10:17 PM, Chris Angelico <rosuav@gmail.com> wrote:
So I'd call it a feature, but possibly one that warrants a mention in the exec and eval docs.
To clarify: This *is* documented under __future__, but not under exec/eval. I'm just suggesting adding another cross-reference.
The most appropriate cross-reference would probably be to the compile() docs rather than the language reference though: https://docs.python.org/2/library/functions.html#compile Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia
Ah, interesting! Thanks for the clarification. So it is really possible to write code with an implicit future statement in it, or to switch the behavior off. Good to know. I will probably not use it, since I can't decide on a good default, but getting rid of print_statement is tempting...
https://docs.python.org/2/reference/simple_stmts.html#the-exec-statement
[2] When strings are executed, __future__ directives active in the surrounding context will be active for the compiled code also. If this is not desired, see the compile() function's dont_inherit parameter.
Would that clarify?
Yes please, that would be a good place to document it. For some reason I did not look up __future__. Thanks -- Chris On 01/10/16 14:17, Chris Angelico wrote:
On Sat, Oct 1, 2016 at 9:39 PM, Christian Tismer <tismer@stackless.com> wrote:
The exec() script inherited the __future__ statement! It behaved like the future statement were implicitly there.
Is that a bug or a feature?
It's documented, but not very noisily.
https://docs.python.org/2/reference/simple_stmts.html#future-statements
So if you want to isolate the execution environments, you can use compile() explicitly. Without isolation:
Python 2.7.12+ (default, Sep 1 2016, 20:27:38) [GCC 6.2.0 20160822] on linux2 Type "help", "copyright", "credits" or "license" for more information.
exec(compile("print('hello','world')", "-", "exec")) ('hello', 'world') exec(compile("from __future__ import print_function; print('hello','world')", "-", "exec")) hello world from __future__ import print_function exec(compile("print('hello','world')", "-", "exec")) hello world exec(compile("from __future__ import print_function; print('hello','world')", "-", "exec")) hello world
With isolation:
exec(compile("print('hello','world')", "-", "exec", 0, 1)) ('hello', 'world') exec(compile("from __future__ import print_function; print('hello','world')", "-", "exec", 0, 1)) hello world
So I'd call it a feature, but possibly one that warrants a mention in the exec and eval docs. Maybe something like:
https://docs.python.org/2/reference/simple_stmts.html#the-exec-statement
[2] When strings are executed, __future__ directives active in the surrounding context will be active for the compiled code also. If this is not desired, see the compile() function's dont_inherit parameter.
Would that clarify?
ChrisA _______________________________________________ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/tismer%40stackless.com
-- Christian Tismer :^) tismer@stackless.com Software Consulting : http://www.stackless.com/ Karl-Liebknecht-Str. 121 : https://github.com/PySide 14482 Potsdam : GPG key -> 0xFB7BEE0E phone +49 173 24 18 776 fax +49 (30) 700143-0023
participants (3)
-
Chris Angelico -
Christian Tismer -
Nick Coghlan