##// END OF EJS Templates
Merge pull request #648 from takluyver/usermod...
Fernando Perez -
r5467:a1e4911b merge
parent child Browse files
Show More
@@ -265,16 +265,16 b' class DisplayHook(Configurable):'
265 self.___ = self.__
265 self.___ = self.__
266 self.__ = self._
266 self.__ = self._
267 self._ = result
267 self._ = result
268 self.shell.user_ns.update({'_':self._,
268 self.shell.push({'_':self._,
269 '__':self.__,
269 '__':self.__,
270 '___':self.___})
270 '___':self.___}, interactive=False)
271
271
272 # hackish access to top-level namespace to create _1,_2... dynamically
272 # hackish access to top-level namespace to create _1,_2... dynamically
273 to_main = {}
273 to_main = {}
274 if self.do_full_cache:
274 if self.do_full_cache:
275 new_result = '_'+`self.prompt_count`
275 new_result = '_'+`self.prompt_count`
276 to_main[new_result] = result
276 to_main[new_result] = result
277 self.shell.user_ns.update(to_main)
277 self.shell.push(to_main, interactive=False)
278 self.shell.user_ns['_oh'][self.prompt_count] = result
278 self.shell.user_ns['_oh'][self.prompt_count] = result
279
279
280 def log_output(self, format_dict):
280 def log_output(self, format_dict):
@@ -559,7 +559,8 b' class HistoryManager(HistoryAccessor):'
559 '_ii': self._ii,
559 '_ii': self._ii,
560 '_iii': self._iii,
560 '_iii': self._iii,
561 new_i : self._i00 }
561 new_i : self._i00 }
562 self.shell.user_ns.update(to_main)
562
563 self.shell.push(to_main, interactive=False)
563
564
564 def store_output(self, line_num):
565 def store_output(self, line_num):
565 """If database output logging is enabled, this saves all the
566 """If database output logging is enabled, this saves all the
@@ -29,6 +29,7 b' import re'
29 import sys
29 import sys
30 import tempfile
30 import tempfile
31 import types
31 import types
32
32 try:
33 try:
33 from contextlib import nested
34 from contextlib import nested
34 except:
35 except:
@@ -372,7 +373,7 b' class InteractiveShell(SingletonConfigurable, Magic):'
372 _post_execute = Instance(dict)
373 _post_execute = Instance(dict)
373
374
374 def __init__(self, config=None, ipython_dir=None, profile_dir=None,
375 def __init__(self, config=None, ipython_dir=None, profile_dir=None,
375 user_ns=None, user_global_ns=None,
376 user_module=None, user_ns=None,
376 custom_exceptions=((), None)):
377 custom_exceptions=((), None)):
377
378
378 # This is where traits with a config_key argument are updated
379 # This is where traits with a config_key argument are updated
@@ -387,7 +388,7 b' class InteractiveShell(SingletonConfigurable, Magic):'
387 self.init_environment()
388 self.init_environment()
388
389
389 # Create namespaces (user_ns, user_global_ns, etc.)
390 # Create namespaces (user_ns, user_global_ns, etc.)
390 self.init_create_namespaces(user_ns, user_global_ns)
391 self.init_create_namespaces(user_module, user_ns)
391 # This has to be done after init_create_namespaces because it uses
392 # This has to be done after init_create_namespaces because it uses
392 # something in self.user_ns, but before init_sys_modules, which
393 # something in self.user_ns, but before init_sys_modules, which
393 # is the first thing to modify sys.
394 # is the first thing to modify sys.
@@ -639,17 +640,14 b' class InteractiveShell(SingletonConfigurable, Magic):'
639 def save_sys_module_state(self):
640 def save_sys_module_state(self):
640 """Save the state of hooks in the sys module.
641 """Save the state of hooks in the sys module.
641
642
642 This has to be called after self.user_ns is created.
643 This has to be called after self.user_module is created.
643 """
644 """
644 self._orig_sys_module_state = {}
645 self._orig_sys_module_state = {}
645 self._orig_sys_module_state['stdin'] = sys.stdin
646 self._orig_sys_module_state['stdin'] = sys.stdin
646 self._orig_sys_module_state['stdout'] = sys.stdout
647 self._orig_sys_module_state['stdout'] = sys.stdout
647 self._orig_sys_module_state['stderr'] = sys.stderr
648 self._orig_sys_module_state['stderr'] = sys.stderr
648 self._orig_sys_module_state['excepthook'] = sys.excepthook
649 self._orig_sys_module_state['excepthook'] = sys.excepthook
649 try:
650 self._orig_sys_modules_main_name = self.user_module.__name__
650 self._orig_sys_modules_main_name = self.user_ns['__name__']
651 except KeyError:
652 pass
653
651
654 def restore_sys_module_state(self):
652 def restore_sys_module_state(self):
655 """Restore the state of the sys module."""
653 """Restore the state of the sys module."""
@@ -659,10 +657,7 b' class InteractiveShell(SingletonConfigurable, Magic):'
659 except AttributeError:
657 except AttributeError:
660 pass
658 pass
661 # Reset what what done in self.init_sys_modules
659 # Reset what what done in self.init_sys_modules
662 try:
660 sys.modules[self.user_module.__name__] = self._orig_sys_modules_main_name
663 sys.modules[self.user_ns['__name__']] = self._orig_sys_modules_main_name
664 except (AttributeError, KeyError):
665 pass
666
661
667 #-------------------------------------------------------------------------
662 #-------------------------------------------------------------------------
668 # Things related to hooks
663 # Things related to hooks
@@ -860,7 +855,7 b' class InteractiveShell(SingletonConfigurable, Magic):'
860 # Things related to IPython's various namespaces
855 # Things related to IPython's various namespaces
861 #-------------------------------------------------------------------------
856 #-------------------------------------------------------------------------
862
857
863 def init_create_namespaces(self, user_ns=None, user_global_ns=None):
858 def init_create_namespaces(self, user_module=None, user_ns=None):
864 # Create the namespace where the user will operate. user_ns is
859 # Create the namespace where the user will operate. user_ns is
865 # normally the only one used, and it is passed to the exec calls as
860 # normally the only one used, and it is passed to the exec calls as
866 # the locals argument. But we do carry a user_global_ns namespace
861 # the locals argument. But we do carry a user_global_ns namespace
@@ -894,26 +889,14 b' class InteractiveShell(SingletonConfigurable, Magic):'
894 # should start with "import __builtin__" (note, no 's') which will
889 # should start with "import __builtin__" (note, no 's') which will
895 # definitely give you a module. Yeah, it's somewhat confusing:-(.
890 # definitely give you a module. Yeah, it's somewhat confusing:-(.
896
891
897 # These routines return properly built dicts as needed by the rest of
892 # These routines return a properly built module and dict as needed by
898 # the code, and can also be used by extension writers to generate
893 # the rest of the code, and can also be used by extension writers to
899 # properly initialized namespaces.
894 # generate properly initialized namespaces.
900 user_ns, user_global_ns = self.make_user_namespaces(user_ns,
895 self.user_module, self.user_ns = self.prepare_user_module(user_module, user_ns)
901 user_global_ns)
902
896
903 # Assign namespaces
897 # A record of hidden variables we have added to the user namespace, so
904 # This is the namespace where all normal user variables live
898 # we can list later only variables defined in actual interactive use.
905 self.user_ns = user_ns
899 self.user_ns_hidden = set()
906 self.user_global_ns = user_global_ns
907
908 # An auxiliary namespace that checks what parts of the user_ns were
909 # loaded at startup, so we can list later only variables defined in
910 # actual interactive use. Since it is always a subset of user_ns, it
911 # doesn't need to be separately tracked in the ns_table.
912 self.user_ns_hidden = {}
913
914 # A namespace to keep track of internal data structures to prevent
915 # them from cluttering user-visible stuff. Will be updated later
916 self.internal_ns = {}
917
900
918 # Now that FakeModule produces a real module, we've run into a nasty
901 # Now that FakeModule produces a real module, we've run into a nasty
919 # problem: after script execution (via %run), the module where the user
902 # problem: after script execution (via %run), the module where the user
@@ -946,78 +929,61 b' class InteractiveShell(SingletonConfigurable, Magic):'
946
929
947 # A table holding all the namespaces IPython deals with, so that
930 # A table holding all the namespaces IPython deals with, so that
948 # introspection facilities can search easily.
931 # introspection facilities can search easily.
949 self.ns_table = {'user':user_ns,
932 self.ns_table = {'user_global':self.user_module.__dict__,
950 'user_global':user_global_ns,
933 'user_local':user_ns,
951 'internal':self.internal_ns,
952 'builtin':builtin_mod.__dict__
934 'builtin':builtin_mod.__dict__
953 }
935 }
936
937 @property
938 def user_global_ns(self):
939 return self.user_module.__dict__
954
940
955 # Similarly, track all namespaces where references can be held and that
941 def prepare_user_module(self, user_module=None, user_ns=None):
956 # we can safely clear (so it can NOT include builtin). This one can be
942 """Prepare the module and namespace in which user code will be run.
957 # a simple list. Note that the main execution namespaces, user_ns and
943
958 # user_global_ns, can NOT be listed here, as clearing them blindly
944 When IPython is started normally, both parameters are None: a new module
959 # causes errors in object __del__ methods. Instead, the reset() method
945 is created automatically, and its __dict__ used as the namespace.
960 # clears them manually and carefully.
946
961 self.ns_refs_table = [ self.user_ns_hidden,
947 If only user_module is provided, its __dict__ is used as the namespace.
962 self.internal_ns, self._main_ns_cache ]
948 If only user_ns is provided, a dummy module is created, and user_ns
963
949 becomes the global namespace. If both are provided (as they may be
964 def make_user_namespaces(self, user_ns=None, user_global_ns=None):
950 when embedding), user_ns is the local namespace, and user_module
965 """Return a valid local and global user interactive namespaces.
951 provides the global namespace.
966
967 This builds a dict with the minimal information needed to operate as a
968 valid IPython user namespace, which you can pass to the various
969 embedding classes in ipython. The default implementation returns the
970 same dict for both the locals and the globals to allow functions to
971 refer to variables in the namespace. Customized implementations can
972 return different dicts. The locals dictionary can actually be anything
973 following the basic mapping protocol of a dict, but the globals dict
974 must be a true dict, not even a subclass. It is recommended that any
975 custom object for the locals namespace synchronize with the globals
976 dict somehow.
977
978 Raises TypeError if the provided globals namespace is not a true dict.
979
952
980 Parameters
953 Parameters
981 ----------
954 ----------
982 user_ns : dict-like, optional
955 user_module : module, optional
983 The current user namespace. The items in this namespace should
956 The current user module in which IPython is being run. If None,
984 be included in the output. If None, an appropriate blank
957 a clean module will be created.
985 namespace should be created.
958 user_ns : dict, optional
986 user_global_ns : dict, optional
959 A namespace in which to run interactive commands.
987 The current user global namespace. The items in this namespace
988 should be included in the output. If None, an appropriate
989 blank namespace should be created.
990
960
991 Returns
961 Returns
992 -------
962 -------
993 A pair of dictionary-like object to be used as the local namespace
963 A tuple of user_module and user_ns, each properly initialised.
994 of the interpreter and a dict to be used as the global namespace.
995 """
964 """
996
965 if user_module is None and user_ns is not None:
997
966 user_ns.setdefault("__name__", "__main__")
967 class DummyMod(object):
968 "A dummy module used for IPython's interactive namespace."
969 pass
970 user_module = DummyMod()
971 user_module.__dict__ = user_ns
972
973 if user_module is None:
974 user_module = types.ModuleType("__main__",
975 doc="Automatically created module for IPython interactive environment")
976
998 # We must ensure that __builtin__ (without the final 's') is always
977 # We must ensure that __builtin__ (without the final 's') is always
999 # available and pointing to the __builtin__ *module*. For more details:
978 # available and pointing to the __builtin__ *module*. For more details:
1000 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
979 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
1001
980 user_module.__dict__.setdefault('__builtin__', builtin_mod)
981 user_module.__dict__.setdefault('__builtins__', builtin_mod)
982
1002 if user_ns is None:
983 if user_ns is None:
1003 # Set __name__ to __main__ to better match the behavior of the
984 user_ns = user_module.__dict__
1004 # normal interpreter.
1005 user_ns = {'__name__' :'__main__',
1006 py3compat.builtin_mod_name: builtin_mod,
1007 '__builtins__' : builtin_mod,
1008 }
1009 else:
1010 user_ns.setdefault('__name__','__main__')
1011 user_ns.setdefault(py3compat.builtin_mod_name,builtin_mod)
1012 user_ns.setdefault('__builtins__',builtin_mod)
1013
1014 if user_global_ns is None:
1015 user_global_ns = user_ns
1016 if type(user_global_ns) is not dict:
1017 raise TypeError("user_global_ns must be a true dict; got %r"
1018 % type(user_global_ns))
1019
985
1020 return user_ns, user_global_ns
986 return user_module, user_ns
1021
987
1022 def init_sys_modules(self):
988 def init_sys_modules(self):
1023 # We need to insert into sys.modules something that looks like a
989 # We need to insert into sys.modules something that looks like a
@@ -1036,13 +1002,8 b' class InteractiveShell(SingletonConfigurable, Magic):'
1036 # embedded in).
1002 # embedded in).
1037
1003
1038 # This is overridden in the InteractiveShellEmbed subclass to a no-op.
1004 # This is overridden in the InteractiveShellEmbed subclass to a no-op.
1039
1005 main_name = self.user_module.__name__
1040 try:
1006 sys.modules[main_name] = self.user_module
1041 main_name = self.user_ns['__name__']
1042 except KeyError:
1043 raise KeyError('user_ns dictionary MUST have a "__name__" key')
1044 else:
1045 sys.modules[main_name] = FakeModule(self.user_ns)
1046
1007
1047 def init_user_ns(self):
1008 def init_user_ns(self):
1048 """Initialize all user-visible namespaces to their minimum defaults.
1009 """Initialize all user-visible namespaces to their minimum defaults.
@@ -1073,8 +1034,8 b' class InteractiveShell(SingletonConfigurable, Magic):'
1073
1034
1074 # For more details:
1035 # For more details:
1075 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
1036 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
1076 ns = dict(__builtin__ = builtin_mod)
1037 ns = dict()
1077
1038
1078 # Put 'help' in the user namespace
1039 # Put 'help' in the user namespace
1079 try:
1040 try:
1080 from site import _Helper
1041 from site import _Helper
@@ -1096,7 +1057,7 b' class InteractiveShell(SingletonConfigurable, Magic):'
1096
1057
1097 # Store myself as the public api!!!
1058 # Store myself as the public api!!!
1098 ns['get_ipython'] = self.get_ipython
1059 ns['get_ipython'] = self.get_ipython
1099
1060
1100 ns['exit'] = self.exiter
1061 ns['exit'] = self.exiter
1101 ns['quit'] = self.exiter
1062 ns['quit'] = self.exiter
1102
1063
@@ -1110,6 +1071,16 b' class InteractiveShell(SingletonConfigurable, Magic):'
1110
1071
1111 # Finally, update the real user's namespace
1072 # Finally, update the real user's namespace
1112 self.user_ns.update(ns)
1073 self.user_ns.update(ns)
1074
1075 @property
1076 def all_ns_refs(self):
1077 """Get a list of references to all the namespace dictionaries in which
1078 IPython might store a user-created object.
1079
1080 Note that this does not include the displayhook, which also caches
1081 objects from the output."""
1082 return [self.user_ns, self.user_global_ns,
1083 self._user_main_module.__dict__] + self._main_ns_cache.values()
1113
1084
1114 def reset(self, new_session=True):
1085 def reset(self, new_session=True):
1115 """Clear all internal namespaces, and attempt to release references to
1086 """Clear all internal namespaces, and attempt to release references to
@@ -1127,20 +1098,21 b' class InteractiveShell(SingletonConfigurable, Magic):'
1127 if self.displayhook.do_full_cache:
1098 if self.displayhook.do_full_cache:
1128 self.displayhook.flush()
1099 self.displayhook.flush()
1129
1100
1130 # Restore the user namespaces to minimal usability
1131 for ns in self.ns_refs_table:
1132 ns.clear()
1133
1134 # The main execution namespaces must be cleared very carefully,
1101 # The main execution namespaces must be cleared very carefully,
1135 # skipping the deletion of the builtin-related keys, because doing so
1102 # skipping the deletion of the builtin-related keys, because doing so
1136 # would cause errors in many object's __del__ methods.
1103 # would cause errors in many object's __del__ methods.
1137 for ns in [self.user_ns, self.user_global_ns]:
1104 if self.user_ns is not self.user_global_ns:
1138 drop_keys = set(ns.keys())
1105 self.user_ns.clear()
1139 drop_keys.discard('__builtin__')
1106 ns = self.user_global_ns
1140 drop_keys.discard('__builtins__')
1107 drop_keys = set(ns.keys())
1141 for k in drop_keys:
1108 drop_keys.discard('__builtin__')
1142 del ns[k]
1109 drop_keys.discard('__builtins__')
1143
1110 drop_keys.discard('__name__')
1111 for k in drop_keys:
1112 del ns[k]
1113
1114 self.user_ns_hidden.clear()
1115
1144 # Restore the user namespaces to minimal usability
1116 # Restore the user namespaces to minimal usability
1145 self.init_user_ns()
1117 self.init_user_ns()
1146
1118
@@ -1170,10 +1142,9 b' class InteractiveShell(SingletonConfigurable, Magic):'
1170 """
1142 """
1171 if varname in ('__builtin__', '__builtins__'):
1143 if varname in ('__builtin__', '__builtins__'):
1172 raise ValueError("Refusing to delete %s" % varname)
1144 raise ValueError("Refusing to delete %s" % varname)
1173 ns_refs = self.ns_refs_table + [self.user_ns,
1174 self.user_global_ns, self._user_main_module.__dict__] +\
1175 self._main_ns_cache.values()
1176
1145
1146 ns_refs = self.all_ns_refs
1147
1177 if by_name: # Delete by name
1148 if by_name: # Delete by name
1178 for ns in ns_refs:
1149 for ns in ns_refs:
1179 try:
1150 try:
@@ -1214,7 +1185,7 b' class InteractiveShell(SingletonConfigurable, Magic):'
1214 raise TypeError('regex must be a string or compiled pattern')
1185 raise TypeError('regex must be a string or compiled pattern')
1215 # Search for keys in each namespace that match the given regex
1186 # Search for keys in each namespace that match the given regex
1216 # If a match is found, delete the key/value pair.
1187 # If a match is found, delete the key/value pair.
1217 for ns in self.ns_refs_table:
1188 for ns in self.all_ns_refs:
1218 for var in ns:
1189 for var in ns:
1219 if m.search(var):
1190 if m.search(var):
1220 del ns[var]
1191 del ns[var]
@@ -1260,13 +1231,11 b' class InteractiveShell(SingletonConfigurable, Magic):'
1260 self.user_ns.update(vdict)
1231 self.user_ns.update(vdict)
1261
1232
1262 # And configure interactive visibility
1233 # And configure interactive visibility
1263 config_ns = self.user_ns_hidden
1234 user_ns_hidden = self.user_ns_hidden
1264 if interactive:
1235 if interactive:
1265 for name, val in vdict.iteritems():
1236 user_ns_hidden.difference_update(vdict)
1266 config_ns.pop(name, None)
1267 else:
1237 else:
1268 for name,val in vdict.iteritems():
1238 user_ns_hidden.update(vdict)
1269 config_ns[name] = val
1270
1239
1271 def drop_by_id(self, variables):
1240 def drop_by_id(self, variables):
1272 """Remove a dict of variables from the user namespace, if they are the
1241 """Remove a dict of variables from the user namespace, if they are the
@@ -1284,7 +1253,7 b' class InteractiveShell(SingletonConfigurable, Magic):'
1284 for name, obj in variables.iteritems():
1253 for name, obj in variables.iteritems():
1285 if name in self.user_ns and self.user_ns[name] is obj:
1254 if name in self.user_ns and self.user_ns[name] is obj:
1286 del self.user_ns[name]
1255 del self.user_ns[name]
1287 self.user_ns_hidden.pop(name, None)
1256 self.user_ns_hidden.discard(name)
1288
1257
1289 #-------------------------------------------------------------------------
1258 #-------------------------------------------------------------------------
1290 # Things related to object introspection
1259 # Things related to object introspection
@@ -1308,7 +1277,7 b' class InteractiveShell(SingletonConfigurable, Magic):'
1308 # Put them in a list. The order is important so that we
1277 # Put them in a list. The order is important so that we
1309 # find things in the same order that Python finds them.
1278 # find things in the same order that Python finds them.
1310 namespaces = [ ('Interactive', self.user_ns),
1279 namespaces = [ ('Interactive', self.user_ns),
1311 ('IPython internal', self.internal_ns),
1280 ('Interactive (global)', self.user_global_ns),
1312 ('Python builtin', builtin_mod.__dict__),
1281 ('Python builtin', builtin_mod.__dict__),
1313 ('Alias', self.alias_manager.alias_table),
1282 ('Alias', self.alias_manager.alias_table),
1314 ]
1283 ]
@@ -748,11 +748,10 b' Currently the magic system has the following functions:\\n"""'
748 """
748 """
749
749
750 user_ns = self.shell.user_ns
750 user_ns = self.shell.user_ns
751 internal_ns = self.shell.internal_ns
752 user_ns_hidden = self.shell.user_ns_hidden
751 user_ns_hidden = self.shell.user_ns_hidden
753 out = [ i for i in user_ns
752 out = [ i for i in user_ns
754 if not i.startswith('_') \
753 if not i.startswith('_') \
755 and not (i in internal_ns or i in user_ns_hidden) ]
754 and not i in user_ns_hidden ]
756
755
757 typelist = parameter_s.split()
756 typelist = parameter_s.split()
758 if typelist:
757 if typelist:
@@ -86,7 +86,7 b' def is_shadowed(identifier, ip):'
86 than ifun, because it can not contain a '.' character."""
86 than ifun, because it can not contain a '.' character."""
87 # This is much safer than calling ofind, which can change state
87 # This is much safer than calling ofind, which can change state
88 return (identifier in ip.user_ns \
88 return (identifier in ip.user_ns \
89 or identifier in ip.internal_ns \
89 or identifier in ip.user_global_ns \
90 or identifier in ip.ns_table['builtin'])
90 or identifier in ip.ns_table['builtin'])
91
91
92
92
@@ -25,6 +25,7 b' import shutil'
25 import tempfile
25 import tempfile
26 import unittest
26 import unittest
27 from os.path import join
27 from os.path import join
28 import sys
28 from StringIO import StringIO
29 from StringIO import StringIO
29
30
30 from IPython.testing import decorators as dec
31 from IPython.testing import decorators as dec
@@ -128,6 +129,7 b' class InteractiveShellTestCase(unittest.TestCase):'
128 f = IPython.core.formatters.PlainTextFormatter()
129 f = IPython.core.formatters.PlainTextFormatter()
129 f([Spam(),Spam()])
130 f([Spam(),Spam()])
130
131
132
131 def test_future_flags(self):
133 def test_future_flags(self):
132 """Check that future flags are used for parsing code (gh-777)"""
134 """Check that future flags are used for parsing code (gh-777)"""
133 ip = get_ipython()
135 ip = get_ipython()
@@ -151,6 +153,37 b' class InteractiveShellTestCase(unittest.TestCase):'
151 finally:
153 finally:
152 # Reset compiler flags so we don't mess up other tests.
154 # Reset compiler flags so we don't mess up other tests.
153 ip.compile.reset_compiler_flags()
155 ip.compile.reset_compiler_flags()
156
157 def test_can_pickle(self):
158 "Can we pickle objects defined interactively (GH-29)"
159 ip = get_ipython()
160 ip.reset()
161 ip.run_cell(("class Mylist(list):\n"
162 " def __init__(self,x=[]):\n"
163 " list.__init__(self,x)"))
164 ip.run_cell("w=Mylist([1,2,3])")
165
166 from cPickle import dumps
167
168 # We need to swap in our main module - this is only necessary
169 # inside the test framework, because IPython puts the interactive module
170 # in place (but the test framework undoes this).
171 _main = sys.modules['__main__']
172 sys.modules['__main__'] = ip.user_module
173 try:
174 res = dumps(ip.user_ns["w"])
175 finally:
176 sys.modules['__main__'] = _main
177 self.assertTrue(isinstance(res, bytes))
178
179 def test_global_ns(self):
180 "Code in functions must be able to access variables outside them."
181 ip = get_ipython()
182 ip.run_cell("a = 10")
183 ip.run_cell(("def f(x):\n"
184 " return x + a"))
185 ip.run_cell("b = f(12)")
186 self.assertEqual(ip.user_ns["b"], 22)
154
187
155 def test_bad_custom_tb(self):
188 def test_bad_custom_tb(self):
156 """Check that InteractiveShell is protected from bad custom exception handlers"""
189 """Check that InteractiveShell is protected from bad custom exception handlers"""
@@ -28,12 +28,8 b' ip = get_ipython()'
28 # Test functions
28 # Test functions
29 #-----------------------------------------------------------------------------
29 #-----------------------------------------------------------------------------
30
30
31 @dec.parametric
32 def test_reset():
31 def test_reset():
33 """reset must clear most namespaces."""
32 """reset must clear most namespaces."""
34 # The number of variables in the private user_ns_hidden is not zero, but it
35 # should be constant regardless of what we do
36 nvars_config_ns = len(ip.user_ns_hidden)
37
33
38 # Check that reset runs without error
34 # Check that reset runs without error
39 ip.reset()
35 ip.reset()
@@ -41,6 +37,7 b' def test_reset():'
41 # Once we've reset it (to clear of any junk that might have been there from
37 # Once we've reset it (to clear of any junk that might have been there from
42 # other tests, we can count how many variables are in the user's namespace
38 # other tests, we can count how many variables are in the user's namespace
43 nvars_user_ns = len(ip.user_ns)
39 nvars_user_ns = len(ip.user_ns)
40 nvars_hidden = len(ip.user_ns_hidden)
44
41
45 # Now add a few variables to user_ns, and check that reset clears them
42 # Now add a few variables to user_ns, and check that reset clears them
46 ip.user_ns['x'] = 1
43 ip.user_ns['x'] = 1
@@ -49,15 +46,8 b' def test_reset():'
49
46
50 # Finally, check that all namespaces have only as many variables as we
47 # Finally, check that all namespaces have only as many variables as we
51 # expect to find in them:
48 # expect to find in them:
52 for ns in ip.ns_refs_table:
49 nt.assert_equals(len(ip.user_ns), nvars_user_ns)
53 if ns is ip.user_ns:
50 nt.assert_equals(len(ip.user_ns_hidden), nvars_hidden)
54 nvars_expected = nvars_user_ns
55 elif ns is ip.user_ns_hidden:
56 nvars_expected = nvars_config_ns
57 else:
58 nvars_expected = 0
59
60 yield nt.assert_equals(len(ns), nvars_expected)
61
51
62
52
63 # Tests for reporting of exceptions in various modes, handling of SystemExit,
53 # Tests for reporting of exceptions in various modes, handling of SystemExit,
@@ -228,3 +228,15 b' tclass.py: deleting object: C-third'
228 else:
228 else:
229 err = None
229 err = None
230 tt.ipexec_validate(self.fname, out, err)
230 tt.ipexec_validate(self.fname, out, err)
231
232 def test_run_i_after_reset(self):
233 """Check that %run -i still works after %reset (gh-693)"""
234 src = "yy = zz\n"
235 self.mktmp(src)
236 _ip.run_cell("zz = 23")
237 _ip.magic('run -i %s' % self.fname)
238 tt.assert_equals(_ip.user_ns['yy'], 23)
239 _ip.magic('reset -f')
240 _ip.run_cell("zz = 23")
241 _ip.magic('run -i %s' % self.fname)
242 tt.assert_equals(_ip.user_ns['yy'], 23)
@@ -72,13 +72,13 b' class InteractiveShellEmbed(TerminalInteractiveShell):'
72 display_banner = CBool(True)
72 display_banner = CBool(True)
73
73
74 def __init__(self, config=None, ipython_dir=None, user_ns=None,
74 def __init__(self, config=None, ipython_dir=None, user_ns=None,
75 user_global_ns=None, custom_exceptions=((),None),
75 user_module=None, custom_exceptions=((),None),
76 usage=None, banner1=None, banner2=None,
76 usage=None, banner1=None, banner2=None,
77 display_banner=None, exit_msg=u''):
77 display_banner=None, exit_msg=u''):
78
78
79 super(InteractiveShellEmbed,self).__init__(
79 super(InteractiveShellEmbed,self).__init__(
80 config=config, ipython_dir=ipython_dir, user_ns=user_ns,
80 config=config, ipython_dir=ipython_dir, user_ns=user_ns,
81 user_global_ns=user_global_ns, custom_exceptions=custom_exceptions,
81 user_module=user_module, custom_exceptions=custom_exceptions,
82 usage=usage, banner1=banner1, banner2=banner2,
82 usage=usage, banner1=banner1, banner2=banner2,
83 display_banner=display_banner
83 display_banner=display_banner
84 )
84 )
@@ -95,7 +95,7 b' class InteractiveShellEmbed(TerminalInteractiveShell):'
95 def init_sys_modules(self):
95 def init_sys_modules(self):
96 pass
96 pass
97
97
98 def __call__(self, header='', local_ns=None, global_ns=None, dummy=None,
98 def __call__(self, header='', local_ns=None, module=None, dummy=None,
99 stack_depth=1):
99 stack_depth=1):
100 """Activate the interactive interpreter.
100 """Activate the interactive interpreter.
101
101
@@ -140,14 +140,14 b' class InteractiveShellEmbed(TerminalInteractiveShell):'
140
140
141 # Call the embedding code with a stack depth of 1 so it can skip over
141 # Call the embedding code with a stack depth of 1 so it can skip over
142 # our call and get the original caller's namespaces.
142 # our call and get the original caller's namespaces.
143 self.mainloop(local_ns, global_ns, stack_depth=stack_depth)
143 self.mainloop(local_ns, module, stack_depth=stack_depth)
144
144
145 self.banner2 = self.old_banner2
145 self.banner2 = self.old_banner2
146
146
147 if self.exit_msg is not None:
147 if self.exit_msg is not None:
148 print self.exit_msg
148 print self.exit_msg
149
149
150 def mainloop(self, local_ns=None, global_ns=None, stack_depth=0,
150 def mainloop(self, local_ns=None, module=None, stack_depth=0,
151 display_banner=None):
151 display_banner=None):
152 """Embeds IPython into a running python program.
152 """Embeds IPython into a running python program.
153
153
@@ -172,32 +172,37 b' class InteractiveShellEmbed(TerminalInteractiveShell):'
172 there is no fundamental reason why it can't work perfectly."""
172 there is no fundamental reason why it can't work perfectly."""
173
173
174 # Get locals and globals from caller
174 # Get locals and globals from caller
175 if local_ns is None or global_ns is None:
175 if local_ns is None or module is None:
176 call_frame = sys._getframe(stack_depth).f_back
176 call_frame = sys._getframe(stack_depth).f_back
177
177
178 if local_ns is None:
178 if local_ns is None:
179 local_ns = call_frame.f_locals
179 local_ns = call_frame.f_locals
180 if global_ns is None:
180 if module is None:
181 global_ns = call_frame.f_globals
181 global_ns = call_frame.f_globals
182
182 module = sys.modules[global_ns['__name__']]
183
184 # Save original namespace and module so we can restore them after
185 # embedding; otherwise the shell doesn't shut down correctly.
186 orig_user_module = self.user_module
187 orig_user_ns = self.user_ns
188
183 # Update namespaces and fire up interpreter
189 # Update namespaces and fire up interpreter
184
190
185 # The global one is easy, we can just throw it in
191 # The global one is easy, we can just throw it in
186 self.user_global_ns = global_ns
192 self.user_module = module
187
193
188 # but the user/local one is tricky: ipython needs it to store internal
194 # But the user/local one is tricky: ipython needs it to store internal
189 # data, but we also need the locals. We'll copy locals in the user
195 # data, but we also need the locals. We'll throw our hidden variables
190 # one, but will track what got copied so we can delete them at exit.
196 # like _ih and get_ipython() into the local namespace, but delete them
191 # This is so that a later embedded call doesn't see locals from a
197 # later.
192 # previous call (which most likely existed in a separate scope).
198 self.user_ns = local_ns
193 local_varnames = local_ns.keys()
199 self.init_user_ns()
194 self.user_ns.update(local_ns)
195 #self.user_ns['local_ns'] = local_ns # dbg
196
200
197 # Patch for global embedding to make sure that things don't overwrite
201 # Patch for global embedding to make sure that things don't overwrite
198 # user globals accidentally. Thanks to Richard <rxe@renre-europe.com>
202 # user globals accidentally. Thanks to Richard <rxe@renre-europe.com>
199 # FIXME. Test this a bit more carefully (the if.. is new)
203 # FIXME. Test this a bit more carefully (the if.. is new)
200 if local_ns is None and global_ns is None:
204 # N.B. This can't now ever be called. Not sure what it was for.
205 if local_ns is None and module is None:
201 self.user_global_ns.update(__main__.__dict__)
206 self.user_global_ns.update(__main__.__dict__)
202
207
203 # make sure the tab-completer has the correct frame information, so it
208 # make sure the tab-completer has the correct frame information, so it
@@ -206,13 +211,14 b' class InteractiveShellEmbed(TerminalInteractiveShell):'
206
211
207 with nested(self.builtin_trap, self.display_trap):
212 with nested(self.builtin_trap, self.display_trap):
208 self.interact(display_banner=display_banner)
213 self.interact(display_banner=display_banner)
209
214
210 # now, purge out the user namespace from anything we might have added
215 # now, purge out the local namespace of IPython's hidden variables.
211 # from the caller's local namespace
216 for name in self.user_ns_hidden:
212 delvar = self.user_ns.pop
217 local_ns.pop(name, None)
213 for var in local_varnames:
218
214 delvar(var,None)
219 # Restore original namespace so shell can shut down when we exit.
215
220 self.user_module = orig_user_module
221 self.user_ns = orig_user_ns
216
222
217 _embedded_shell = None
223 _embedded_shell = None
218
224
@@ -172,13 +172,13 b' class TerminalInteractiveShell(InteractiveShell):'
172 )
172 )
173
173
174 def __init__(self, config=None, ipython_dir=None, profile_dir=None, user_ns=None,
174 def __init__(self, config=None, ipython_dir=None, profile_dir=None, user_ns=None,
175 user_global_ns=None, custom_exceptions=((),None),
175 user_module=None, custom_exceptions=((),None),
176 usage=None, banner1=None, banner2=None,
176 usage=None, banner1=None, banner2=None,
177 display_banner=None):
177 display_banner=None):
178
178
179 super(TerminalInteractiveShell, self).__init__(
179 super(TerminalInteractiveShell, self).__init__(
180 config=config, profile_dir=profile_dir, user_ns=user_ns,
180 config=config, profile_dir=profile_dir, user_ns=user_ns,
181 user_global_ns=user_global_ns, custom_exceptions=custom_exceptions
181 user_module=user_module, custom_exceptions=custom_exceptions
182 )
182 )
183 # use os.system instead of utils.process.system by default,
183 # use os.system instead of utils.process.system by default,
184 # because piped system doesn't make sense in the Terminal:
184 # because piped system doesn't make sense in the Terminal:
@@ -190,7 +190,6 b' def start_ipython():'
190 # Create and initialize our test-friendly IPython instance.
190 # Create and initialize our test-friendly IPython instance.
191 shell = TerminalInteractiveShell.instance(config=config,
191 shell = TerminalInteractiveShell.instance(config=config,
192 user_ns=ipnsdict(),
192 user_ns=ipnsdict(),
193 user_global_ns={}
194 )
193 )
195
194
196 # A few more tweaks needed for playing nicely with doctests...
195 # A few more tweaks needed for playing nicely with doctests...
@@ -206,8 +205,7 b' def start_ipython():'
206 # can capture subcommands and print them to Python's stdout, otherwise the
205 # can capture subcommands and print them to Python's stdout, otherwise the
207 # doctest machinery would miss them.
206 # doctest machinery would miss them.
208 shell.system = py3compat.MethodType(xsys, shell)
207 shell.system = py3compat.MethodType(xsys, shell)
209
208
210
211 shell._showtraceback = py3compat.MethodType(_showtraceback, shell)
209 shell._showtraceback = py3compat.MethodType(_showtraceback, shell)
212
210
213 # IPython is ready, now clean up some global state...
211 # IPython is ready, now clean up some global state...
@@ -271,6 +271,8 b' class DocTestCase(doctests.DocTestCase):'
271 # for IPython examples *only*, we swap the globals with the ipython
271 # for IPython examples *only*, we swap the globals with the ipython
272 # namespace, after updating it with the globals (which doctest
272 # namespace, after updating it with the globals (which doctest
273 # fills with the necessary info from the module being tested).
273 # fills with the necessary info from the module being tested).
274 self.user_ns_orig = {}
275 self.user_ns_orig.update(_ip.user_ns)
274 _ip.user_ns.update(self._dt_test.globs)
276 _ip.user_ns.update(self._dt_test.globs)
275 self._dt_test.globs = _ip.user_ns
277 self._dt_test.globs = _ip.user_ns
276 # IPython must protect the _ key in the namespace (it can't exist)
278 # IPython must protect the _ key in the namespace (it can't exist)
@@ -286,6 +288,8 b' class DocTestCase(doctests.DocTestCase):'
286 # teardown doesn't destroy the ipython namespace
288 # teardown doesn't destroy the ipython namespace
287 if isinstance(self._dt_test.examples[0],IPExample):
289 if isinstance(self._dt_test.examples[0],IPExample):
288 self._dt_test.globs = self._dt_test_globs_ori
290 self._dt_test.globs = self._dt_test_globs_ori
291 _ip.user_ns.clear()
292 _ip.user_ns.update(self.user_ns_orig)
289 # Restore the behavior of the '_' key in the user namespace to
293 # Restore the behavior of the '_' key in the user namespace to
290 # normal after each doctest, so that unittests behave normally
294 # normal after each doctest, so that unittests behave normally
291 _ip.user_ns.protect_underscore = False
295 _ip.user_ns.protect_underscore = False
@@ -97,6 +97,10 b' Major Bugs fixed'
97 * IPython no longer crashes when started on recent versions of Python 3 in
97 * IPython no longer crashes when started on recent versions of Python 3 in
98 Windows (:ghissue:`737`).
98 Windows (:ghissue:`737`).
99
99
100 * Instances of classes defined interactively can now be pickled (:ghissue:`29`;
101 :ghpull:`648`). Note that pickling saves a reference to the class definition,
102 so unpickling the instances will only work where the class has been defined.
103
100 .. * use bullet list
104 .. * use bullet list
101
105
102 Backwards incompatible changes
106 Backwards incompatible changes
@@ -132,4 +136,10 b' Backwards incompatible changes'
132 The full path will still work, and is necessary for using custom launchers not in
136 The full path will still work, and is necessary for using custom launchers not in
133 IPython's launcher module.
137 IPython's launcher module.
134
138
139 * For embedding a shell, note that the parameter ``user_global_ns`` has been
140 replaced by ``user_module``, and expects a module-like object, rather than
141 a namespace dict. The ``user_ns`` parameter works the same way as before, and
142 calling :func:`~IPython.frontend.terminal.embed.embed` with no arguments still
143 works the same way.
144
135 .. * use bullet list
145 .. * use bullet list
General Comments 0
You need to be logged in to leave comments. Login now