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. |
|
268 | self.shell.push({'_':self._, | |
269 |
|
|
269 | '__':self.__, | |
270 |
|
|
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. |
|
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, |
|
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_ |
|
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_ |
|
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_ |
|
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 dict |
|
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 |
|
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 |
|
|
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 = |
|
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': |
|
932 | self.ns_table = {'user_global':self.user_module.__dict__, | |
950 |
'user_ |
|
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_ |
|
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_ |
|
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( |
|
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 |
f |
|
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 |
|
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 |
|
|
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. |
|
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 |
('I |
|
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 |
|
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. |
|
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_ |
|
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_ |
|
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, |
|
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, |
|
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, |
|
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 |
|
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 |
|
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_ |
|
192 | self.user_module = module | |
187 |
|
193 | |||
188 |
# |
|
194 | # But the user/local one is tricky: ipython needs it to store internal | |
189 |
# data, but we also need the locals. |
|
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 |
|
|
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 |
|
|
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_ |
|
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_ |
|
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