Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parse user code to AST using compiler flags. #784

Merged
merged 2 commits into from Sep 12, 2011
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 14 additions & 0 deletions IPython/core/compilerop.py
Expand Up @@ -28,6 +28,7 @@
from __future__ import print_function

# Stdlib imports
from ast import PyCF_ONLY_AST
import codeop
import hashlib
import linecache
Expand Down Expand Up @@ -77,6 +78,19 @@ def __init__(self):
# stdlib that call it outside our control go through our codepath
# (otherwise we'd lose our tracebacks).
linecache.checkcache = self.check_cache

def ast_parse(self, source, filename='<unknown>', symbol='exec'):
"""Parse code to an AST with the current compiler flags active.

Arguments are exactly the same as ast.parse (in the standard library),
and are passed to the built-in compile function."""
return compile(source, filename, symbol, self.flags | PyCF_ONLY_AST, 1)

def reset_compiler_flags(self):
"""Reset compiler flags to default state."""
# This value is copied from codeop.Compile.__init__, so if that ever
# changes, it will need to be updated.
self.flags = codeop.PyCF_DONT_IMPLY_DEDENT

@property
def compiler_flags(self):
Expand Down
2 changes: 1 addition & 1 deletion IPython/core/interactiveshell.py
Expand Up @@ -2281,7 +2281,7 @@ def run_cell(self, raw_cell, store_history=True):

with self.display_trap:
try:
code_ast = ast.parse(cell, filename=cell_name)
code_ast = self.compile.ast_parse(cell, filename=cell_name)
except IndentationError:
self.showindentationerror()
self.execution_count += 1
Expand Down
11 changes: 11 additions & 0 deletions IPython/core/tests/test_interactiveshell.py
Expand Up @@ -122,3 +122,14 @@ def __repr__(self):
import IPython.core.formatters
f = IPython.core.formatters.PlainTextFormatter()
f([Spam(),Spam()])

def test_future_flags(self):
"""Check that future flags are used for parsing code (gh-777)"""
ip = get_ipython()
ip.run_cell('from __future__ import print_function')
try:
ip.run_cell('prfunc_return_val = print(1,2, sep=" ")')
assert 'prfunc_return_val' in ip.user_ns
finally:
# Reset compiler flags so we don't mess up other tests.
ip.compile.reset_compiler_flags()