From b70ac127e2c3698ea643b15af7d6bb5783ff3e7e 2012-07-18 16:11:47 From: Bradley M. Froehle Date: 2012-07-18 16:11:47 Subject: [PATCH] embed(): Default to the future compile flags of the calling frame. --- diff --git a/IPython/core/compilerop.py b/IPython/core/compilerop.py index 51d5bfa..ee0de31 100644 --- a/IPython/core/compilerop.py +++ b/IPython/core/compilerop.py @@ -28,13 +28,26 @@ Authors from __future__ import print_function # Stdlib imports +import __future__ from ast import PyCF_ONLY_AST import codeop +import functools import hashlib import linecache +import operator import time #----------------------------------------------------------------------------- +# Constants +#----------------------------------------------------------------------------- + +# Roughtly equal to PyCF_MASK | PyCF_MASK_OBSOLETE as defined in pythonrun.h, +# this is used as a bitmask to extract future-related code flags. +PyCF_MASK = functools.reduce(operator.or_, + (getattr(__future__, fname).compiler_flag + for fname in __future__.all_feature_names)) + +#----------------------------------------------------------------------------- # Local utilities #----------------------------------------------------------------------------- diff --git a/IPython/frontend/terminal/embed.py b/IPython/frontend/terminal/embed.py index f6506ee..5335b60 100644 --- a/IPython/frontend/terminal/embed.py +++ b/IPython/frontend/terminal/embed.py @@ -34,7 +34,7 @@ try: except: from IPython.utils.nested_context import nested -from IPython.core import ultratb +from IPython.core import ultratb, compilerop from IPython.core.magic import Magics, magics_class, line_magic from IPython.frontend.terminal.interactiveshell import TerminalInteractiveShell from IPython.frontend.terminal.ipapp import load_default_config @@ -162,7 +162,7 @@ class InteractiveShellEmbed(TerminalInteractiveShell): print self.exit_msg def mainloop(self, local_ns=None, module=None, stack_depth=0, - display_banner=None, global_ns=None): + display_banner=None, global_ns=None, compile_flags=None): """Embeds IPython into a running python program. Input: @@ -180,6 +180,11 @@ class InteractiveShellEmbed(TerminalInteractiveShell): the namespace from the intended level in the stack. By default (0) it will get its locals and globals from the immediate caller. + - compile_flags: A bit field identifying the __future__ features + that are enabled, as passed to the builtin `compile` function. If + given as None, they are automatically taken from the scope where the + shell was called. + Warning: it's possible to use this in a program which is being run by IPython itself (via %run), but some funny things will happen (a few globals get overwritten). In the future this will be cleaned up, as @@ -202,11 +207,15 @@ class InteractiveShellEmbed(TerminalInteractiveShell): if module is None: global_ns = call_frame.f_globals module = sys.modules[global_ns['__name__']] + if compile_flags is None: + compile_flags = (call_frame.f_code.co_flags & + compilerop.PyCF_MASK) # Save original namespace and module so we can restore them after # embedding; otherwise the shell doesn't shut down correctly. orig_user_module = self.user_module orig_user_ns = self.user_ns + orig_compile_flags = self.compile.flags # Update namespaces and fire up interpreter @@ -222,6 +231,9 @@ class InteractiveShellEmbed(TerminalInteractiveShell): self.user_ns = local_ns self.init_user_ns() + # Compiler flags + self.compile.flags = compile_flags + # Patch for global embedding to make sure that things don't overwrite # user globals accidentally. Thanks to Richard # FIXME. Test this a bit more carefully (the if.. is new) @@ -247,6 +259,7 @@ class InteractiveShellEmbed(TerminalInteractiveShell): # Restore original namespace so shell can shut down when we exit. self.user_module = orig_user_module self.user_ns = orig_user_ns + self.compile.flags = orig_compile_flags _embedded_shell = None