##// END OF EJS Templates
Merge pull request #3555 from takluyver/i3547...
Fernando Perez -
r11297:6217a475 merge
parent child Browse files
Show More
@@ -819,53 +819,32 b' class InteractiveShell(SingletonConfigurable):'
819 # Things related to the "main" module
819 # Things related to the "main" module
820 #-------------------------------------------------------------------------
820 #-------------------------------------------------------------------------
821
821
822 def new_main_mod(self,ns=None):
822 def new_main_mod(self, filename):
823 """Return a new 'main' module object for user code execution.
823 """Return a new 'main' module object for user code execution.
824 """
824
825 main_mod = self._user_main_module
825 ``filename`` should be the path of the script which will be run in the
826 init_fakemod_dict(main_mod,ns)
826 module. Requests with the same filename will get the same module, with
827 return main_mod
827 its namespace cleared.
828
828
829 def cache_main_mod(self,ns,fname):
829 When scripts are executed via %run, we must keep a reference to their
830 """Cache a main module's namespace.
830 __main__ module (a FakeModule instance) around so that Python doesn't
831
831 clear it, rendering references to module globals useless.
832 When scripts are executed via %run, we must keep a reference to the
833 namespace of their __main__ module (a FakeModule instance) around so
834 that Python doesn't clear it, rendering objects defined therein
835 useless.
836
832
837 This method keeps said reference in a private dict, keyed by the
833 This method keeps said reference in a private dict, keyed by the
838 absolute path of the module object (which corresponds to the script
834 absolute path of the script. This way, for multiple executions of the
839 path). This way, for multiple executions of the same script we only
835 same script we only keep one copy of the namespace (the last one),
840 keep one copy of the namespace (the last one), thus preventing memory
836 thus preventing memory leaks from old references while allowing the
841 leaks from old references while allowing the objects from the last
837 objects from the last execution to be accessible.
842 execution to be accessible.
843
844 Note: we can not allow the actual FakeModule instances to be deleted,
845 because of how Python tears down modules (it hard-sets all their
846 references to None without regard for reference counts). This method
847 must therefore make a *copy* of the given namespace, to allow the
848 original module's __dict__ to be cleared and reused.
849
850
851 Parameters
852 ----------
853 ns : a namespace (a dict, typically)
854
855 fname : str
856 Filename associated with the namespace.
857
858 Examples
859 --------
860
861 In [10]: import IPython
862
863 In [11]: _ip.cache_main_mod(IPython.__dict__,IPython.__file__)
864
865 In [12]: IPython.__file__ in _ip._main_ns_cache
866 Out[12]: True
867 """
838 """
868 self._main_ns_cache[os.path.abspath(fname)] = ns.copy()
839 filename = os.path.abspath(filename)
840 try:
841 main_mod = self._main_mod_cache[filename]
842 except KeyError:
843 main_mod = self._main_mod_cache[filename] = FakeModule()
844 else:
845 init_fakemod_dict(main_mod)
846
847 return main_mod
869
848
870 def clear_main_mod_cache(self):
849 def clear_main_mod_cache(self):
871 """Clear the cache of main modules.
850 """Clear the cache of main modules.
@@ -877,17 +856,17 b' class InteractiveShell(SingletonConfigurable):'
877
856
878 In [15]: import IPython
857 In [15]: import IPython
879
858
880 In [16]: _ip.cache_main_mod(IPython.__dict__,IPython.__file__)
859 In [16]: m = _ip.new_main_mod(IPython.__file__)
881
860
882 In [17]: len(_ip._main_ns_cache) > 0
861 In [17]: len(_ip._main_mod_cache) > 0
883 Out[17]: True
862 Out[17]: True
884
863
885 In [18]: _ip.clear_main_mod_cache()
864 In [18]: _ip.clear_main_mod_cache()
886
865
887 In [19]: len(_ip._main_ns_cache) == 0
866 In [19]: len(_ip._main_mod_cache) == 0
888 Out[19]: True
867 Out[19]: True
889 """
868 """
890 self._main_ns_cache.clear()
869 self._main_mod_cache.clear()
891
870
892 #-------------------------------------------------------------------------
871 #-------------------------------------------------------------------------
893 # Things related to debugging
872 # Things related to debugging
@@ -1017,10 +996,7 b' class InteractiveShell(SingletonConfigurable):'
1017 # and clear_main_mod_cache() methods for details on use.
996 # and clear_main_mod_cache() methods for details on use.
1018
997
1019 # This is the cache used for 'main' namespaces
998 # This is the cache used for 'main' namespaces
1020 self._main_ns_cache = {}
999 self._main_mod_cache = {}
1021 # And this is the single instance of FakeModule whose __dict__ we keep
1022 # copying and clearing for reuse on each %run
1023 self._user_main_module = FakeModule()
1024
1000
1025 # A table holding all the namespaces IPython deals with, so that
1001 # A table holding all the namespaces IPython deals with, so that
1026 # introspection facilities can search easily.
1002 # introspection facilities can search easily.
@@ -1174,8 +1150,8 b' class InteractiveShell(SingletonConfigurable):'
1174
1150
1175 Note that this does not include the displayhook, which also caches
1151 Note that this does not include the displayhook, which also caches
1176 objects from the output."""
1152 objects from the output."""
1177 return [self.user_ns, self.user_global_ns,
1153 return [self.user_ns, self.user_global_ns] + \
1178 self._user_main_module.__dict__] + self._main_ns_cache.values()
1154 [m.__dict__ for m in self._main_mod_cache.values()]
1179
1155
1180 def reset(self, new_session=True):
1156 def reset(self, new_session=True):
1181 """Clear all internal namespaces, and attempt to release references to
1157 """Clear all internal namespaces, and attempt to release references to
@@ -1219,9 +1195,6 b' class InteractiveShell(SingletonConfigurable):'
1219 # execution protection
1195 # execution protection
1220 self.clear_main_mod_cache()
1196 self.clear_main_mod_cache()
1221
1197
1222 # Clear out the namespace from the last %run
1223 self.new_main_mod()
1224
1225 def del_var(self, varname, by_name=False):
1198 def del_var(self, varname, by_name=False):
1226 """Delete a variable from the various namespaces, so that, as
1199 """Delete a variable from the various namespaces, so that, as
1227 far as possible, we're not keeping any hidden references to it.
1200 far as possible, we're not keeping any hidden references to it.
@@ -508,7 +508,7 b' python-profiler package from non-free.""")'
508 prog_ns = self.shell.user_ns
508 prog_ns = self.shell.user_ns
509 __name__save = self.shell.user_ns['__name__']
509 __name__save = self.shell.user_ns['__name__']
510 prog_ns['__name__'] = '__main__'
510 prog_ns['__name__'] = '__main__'
511 main_mod = self.shell.new_main_mod(prog_ns)
511 main_mod = self.shell.user_module
512 else:
512 else:
513 # Run in a fresh, empty namespace
513 # Run in a fresh, empty namespace
514 if 'n' in opts:
514 if 'n' in opts:
@@ -516,7 +516,10 b' python-profiler package from non-free.""")'
516 else:
516 else:
517 name = '__main__'
517 name = '__main__'
518
518
519 main_mod = self.shell.new_main_mod()
519 # The shell MUST hold a reference to prog_ns so after %run
520 # exits, the python deletion mechanism doesn't zero it out
521 # (leaving dangling references). See interactiveshell for details
522 main_mod = self.shell.new_main_mod(filename)
520 prog_ns = main_mod.__dict__
523 prog_ns = main_mod.__dict__
521 prog_ns['__name__'] = name
524 prog_ns['__name__'] = name
522
525
@@ -593,10 +596,6 b' python-profiler package from non-free.""")'
593 if 'i' in opts:
596 if 'i' in opts:
594 self.shell.user_ns['__name__'] = __name__save
597 self.shell.user_ns['__name__'] = __name__save
595 else:
598 else:
596 # The shell MUST hold a reference to prog_ns so after %run
597 # exits, the python deletion mechanism doesn't zero it out
598 # (leaving dangling references).
599 self.shell.cache_main_mod(prog_ns, filename)
600 # update IPython interactive namespace
599 # update IPython interactive namespace
601
600
602 # Some forms of read errors on the file may mean the
601 # Some forms of read errors on the file may mean the
@@ -244,7 +244,6 b' class TestMagicRunSimple(tt.TempFileMixin):'
244 err = None
244 err = None
245 tt.ipexec_validate(self.fname, 'object A deleted', err)
245 tt.ipexec_validate(self.fname, 'object A deleted', err)
246
246
247 @dec.skip_known_failure
248 def test_aggressive_namespace_cleanup(self):
247 def test_aggressive_namespace_cleanup(self):
249 """Test that namespace cleanup is not too aggressive GH-238
248 """Test that namespace cleanup is not too aggressive GH-238
250
249
@@ -258,11 +257,26 b' class TestMagicRunSimple(tt.TempFileMixin):'
258 " try:\n"
257 " try:\n"
259 " ip.magic('run %s')\n"
258 " ip.magic('run %s')\n"
260 " except NameError as e:\n"
259 " except NameError as e:\n"
261 " print i;break\n" % empty.fname)
260 " print(i)\n"
262 self.mktmp(py3compat.doctest_refactor_print(src))
261 " break\n" % empty.fname)
262 self.mktmp(src)
263 _ip.magic('run %s' % self.fname)
263 _ip.magic('run %s' % self.fname)
264 _ip.run_cell('ip == get_ipython()')
264 _ip.run_cell('ip == get_ipython()')
265 nt.assert_equal(_ip.user_ns['i'], 5)
265 nt.assert_equal(_ip.user_ns['i'], 4)
266
267 def test_run_second(self):
268 """Test that running a second file doesn't clobber the first, gh-3547
269 """
270 self.mktmp("avar = 1\n"
271 "def afunc():\n"
272 " return avar\n")
273
274 empty = tt.TempFileMixin()
275 empty.mktmp("")
276
277 _ip.magic('run %s' % self.fname)
278 _ip.magic('run %s' % empty.fname)
279 nt.assert_equal(_ip.user_ns['afunc'](), 1)
266
280
267 @dec.skip_win32
281 @dec.skip_win32
268 def test_tclass(self):
282 def test_tclass(self):
@@ -48,3 +48,7 b' Backwards incompatible changes'
48 :func:`IPython.utils.doctestreload.doctest_reload` to make doctests run
48 :func:`IPython.utils.doctestreload.doctest_reload` to make doctests run
49 correctly inside IPython. Python releases since those versions are unaffected.
49 correctly inside IPython. Python releases since those versions are unaffected.
50 For details, see :ghpull:`3068` and `Python issue 8048 <http://bugs.python.org/issue8048>`_.
50 For details, see :ghpull:`3068` and `Python issue 8048 <http://bugs.python.org/issue8048>`_.
51 * The ``InteractiveShell.cache_main_mod()`` method has been removed, and
52 :meth:`~IPython.core.interactiveshell.InteractiveShell.new_main_mod` has a
53 different signature, expecting a filename where earlier versions expected
54 a namespace. See :ghpull:`3555` for details.
General Comments 0
You need to be logged in to leave comments. Login now