Show More
@@ -1,7 +1,7 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 | """Magic functions for InteractiveShell. |
|
2 | """Magic functions for InteractiveShell. | |
3 |
|
3 | |||
4 |
$Id: Magic.py 27 |
|
4 | $Id: Magic.py 2763 2007-09-14 06:35:44Z fperez $""" | |
5 |
|
5 | |||
6 | #***************************************************************************** |
|
6 | #***************************************************************************** | |
7 | # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de> and |
|
7 | # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de> and | |
@@ -1037,6 +1037,10 b' Currently the magic system has the following functions:\\n"""' | |||||
1037 | user_ns = self.shell.user_ns |
|
1037 | user_ns = self.shell.user_ns | |
1038 | for i in self.magic_who_ls(): |
|
1038 | for i in self.magic_who_ls(): | |
1039 | del(user_ns[i]) |
|
1039 | del(user_ns[i]) | |
|
1040 | ||||
|
1041 | # Also flush the private list of module references kept for script | |||
|
1042 | # execution protection | |||
|
1043 | self.shell._user_main_modules[:] = [] | |||
1040 |
|
1044 | |||
1041 | def magic_logstart(self,parameter_s=''): |
|
1045 | def magic_logstart(self,parameter_s=''): | |
1042 | """Start logging anywhere in a session. |
|
1046 | """Start logging anywhere in a session. | |
@@ -1519,11 +1523,13 b' Currently the magic system has the following functions:\\n"""' | |||||
1519 | sys.argv = [filename]+ arg_lst[1:] # put in the proper filename |
|
1523 | sys.argv = [filename]+ arg_lst[1:] # put in the proper filename | |
1520 |
|
1524 | |||
1521 | if opts.has_key('i'): |
|
1525 | if opts.has_key('i'): | |
|
1526 | # Run in user's interactive namespace | |||
1522 | prog_ns = self.shell.user_ns |
|
1527 | prog_ns = self.shell.user_ns | |
1523 | __name__save = self.shell.user_ns['__name__'] |
|
1528 | __name__save = self.shell.user_ns['__name__'] | |
1524 | prog_ns['__name__'] = '__main__' |
|
1529 | prog_ns['__name__'] = '__main__' | |
1525 | main_mod = FakeModule(prog_ns) |
|
1530 | main_mod = FakeModule(prog_ns) | |
1526 | else: |
|
1531 | else: | |
|
1532 | # Run in a fresh, empty namespace | |||
1527 | if opts.has_key('n'): |
|
1533 | if opts.has_key('n'): | |
1528 | name = os.path.splitext(os.path.basename(filename))[0] |
|
1534 | name = os.path.splitext(os.path.basename(filename))[0] | |
1529 | else: |
|
1535 | else: | |
@@ -1531,6 +1537,10 b' Currently the magic system has the following functions:\\n"""' | |||||
1531 | main_mod = FakeModule() |
|
1537 | main_mod = FakeModule() | |
1532 | prog_ns = main_mod.__dict__ |
|
1538 | prog_ns = main_mod.__dict__ | |
1533 | prog_ns['__name__'] = name |
|
1539 | prog_ns['__name__'] = name | |
|
1540 | # The shell MUST hold a reference to main_mod so after %run exits, | |||
|
1541 | # the python deletion mechanism doesn't zero it out (leaving | |||
|
1542 | # dangling references) | |||
|
1543 | self.shell._user_main_modules.append(main_mod) | |||
1534 |
|
1544 | |||
1535 | # Since '%run foo' emulates 'python foo.py' at the cmd line, we must |
|
1545 | # Since '%run foo' emulates 'python foo.py' at the cmd line, we must | |
1536 | # set the __file__ global in the script's namespace |
|
1546 | # set the __file__ global in the script's namespace | |
@@ -1542,7 +1552,7 b' Currently the magic system has the following functions:\\n"""' | |||||
1542 | restore_main = sys.modules['__main__'] |
|
1552 | restore_main = sys.modules['__main__'] | |
1543 | else: |
|
1553 | else: | |
1544 | restore_main = False |
|
1554 | restore_main = False | |
1545 |
|
1555 | |||
1546 | sys.modules[prog_ns['__name__']] = main_mod |
|
1556 | sys.modules[prog_ns['__name__']] = main_mod | |
1547 |
|
1557 | |||
1548 | stats = None |
|
1558 | stats = None | |
@@ -1594,6 +1604,7 b' Currently the magic system has the following functions:\\n"""' | |||||
1594 | if runner is None: |
|
1604 | if runner is None: | |
1595 | runner = self.shell.safe_execfile |
|
1605 | runner = self.shell.safe_execfile | |
1596 | if opts.has_key('t'): |
|
1606 | if opts.has_key('t'): | |
|
1607 | # timed execution | |||
1597 | try: |
|
1608 | try: | |
1598 | nruns = int(opts['N'][0]) |
|
1609 | nruns = int(opts['N'][0]) | |
1599 | if nruns < 1: |
|
1610 | if nruns < 1: | |
@@ -1627,6 +1638,7 b' Currently the magic system has the following functions:\\n"""' | |||||
1627 | print " System: %10s s, %10s s." % (t_sys,t_sys/nruns) |
|
1638 | print " System: %10s s, %10s s." % (t_sys,t_sys/nruns) | |
1628 |
|
1639 | |||
1629 | else: |
|
1640 | else: | |
|
1641 | # regular execution | |||
1630 | runner(filename,prog_ns,prog_ns,exit_ignore=exit_ignore) |
|
1642 | runner(filename,prog_ns,prog_ns,exit_ignore=exit_ignore) | |
1631 | if opts.has_key('i'): |
|
1643 | if opts.has_key('i'): | |
1632 | self.shell.user_ns['__name__'] = __name__save |
|
1644 | self.shell.user_ns['__name__'] = __name__save |
@@ -5,7 +5,7 b' General purpose utilities.' | |||||
5 | This is a grab-bag of stuff I find useful in most programs I write. Some of |
|
5 | This is a grab-bag of stuff I find useful in most programs I write. Some of | |
6 | these things are also convenient when working at the command line. |
|
6 | these things are also convenient when working at the command line. | |
7 |
|
7 | |||
8 |
$Id: genutils.py 27 |
|
8 | $Id: genutils.py 2763 2007-09-14 06:35:44Z fperez $""" | |
9 |
|
9 | |||
10 | #***************************************************************************** |
|
10 | #***************************************************************************** | |
11 | # Copyright (C) 2001-2006 Fernando Perez. <fperez@colorado.edu> |
|
11 | # Copyright (C) 2001-2006 Fernando Perez. <fperez@colorado.edu> | |
@@ -22,6 +22,7 b' __license__ = Release.license' | |||||
22 | # required modules from the Python standard library |
|
22 | # required modules from the Python standard library | |
23 | import __main__ |
|
23 | import __main__ | |
24 | import commands |
|
24 | import commands | |
|
25 | import doctest | |||
25 | import os |
|
26 | import os | |
26 | import re |
|
27 | import re | |
27 | import shlex |
|
28 | import shlex | |
@@ -836,6 +837,36 b' def dhook_wrap(func,*a,**k):' | |||||
836 | return f |
|
837 | return f | |
837 |
|
838 | |||
838 | #---------------------------------------------------------------------------- |
|
839 | #---------------------------------------------------------------------------- | |
|
840 | def doctest_reload(): | |||
|
841 | """Properly reload doctest to reuse it interactively. | |||
|
842 | ||||
|
843 | This routine: | |||
|
844 | ||||
|
845 | - reloads doctest | |||
|
846 | ||||
|
847 | - resets its global 'master' attribute to None, so that multiple uses of | |||
|
848 | the module interactively don't produce cumulative reports. | |||
|
849 | ||||
|
850 | - Monkeypatches its core test runner method to protect it from IPython's | |||
|
851 | modified displayhook. Doctest expects the default displayhook behavior | |||
|
852 | deep down, so our modification breaks it completely. For this reason, a | |||
|
853 | hard monkeypatch seems like a reasonable solution rather than asking | |||
|
854 | users to manually use a different doctest runner when under IPython.""" | |||
|
855 | ||||
|
856 | import doctest | |||
|
857 | reload(doctest) | |||
|
858 | doctest.master=None | |||
|
859 | ||||
|
860 | try: | |||
|
861 | doctest.DocTestRunner | |||
|
862 | except AttributeError: | |||
|
863 | # This is only for python 2.3 compatibility, remove once we move to | |||
|
864 | # 2.4 only. | |||
|
865 | pass | |||
|
866 | else: | |||
|
867 | doctest.DocTestRunner.run = dhook_wrap(doctest.DocTestRunner.run) | |||
|
868 | ||||
|
869 | #---------------------------------------------------------------------------- | |||
839 | class HomeDirError(Error): |
|
870 | class HomeDirError(Error): | |
840 | pass |
|
871 | pass | |
841 |
|
872 |
@@ -6,7 +6,7 b' Requires Python 2.3 or newer.' | |||||
6 |
|
6 | |||
7 | This file contains all the classes and helper functions specific to IPython. |
|
7 | This file contains all the classes and helper functions specific to IPython. | |
8 |
|
8 | |||
9 |
$Id: iplib.py 27 |
|
9 | $Id: iplib.py 2763 2007-09-14 06:35:44Z fperez $ | |
10 | """ |
|
10 | """ | |
11 |
|
11 | |||
12 | #***************************************************************************** |
|
12 | #***************************************************************************** | |
@@ -41,7 +41,6 b' import StringIO' | |||||
41 | import bdb |
|
41 | import bdb | |
42 | import cPickle as pickle |
|
42 | import cPickle as pickle | |
43 | import codeop |
|
43 | import codeop | |
44 | import doctest |
|
|||
45 | import exceptions |
|
44 | import exceptions | |
46 | import glob |
|
45 | import glob | |
47 | import inspect |
|
46 | import inspect | |
@@ -344,6 +343,20 b' class InteractiveShell(object,Magic):' | |||||
344 | #print 'main_name:',main_name # dbg |
|
343 | #print 'main_name:',main_name # dbg | |
345 | sys.modules[main_name] = FakeModule(self.user_ns) |
|
344 | sys.modules[main_name] = FakeModule(self.user_ns) | |
346 |
|
345 | |||
|
346 | # Now that FakeModule produces a real module, we've run into a nasty | |||
|
347 | # problem: after script execution (via %run), the module where the user | |||
|
348 | # code ran is deleted. Now that this object is a true module (needed | |||
|
349 | # so docetst and other tools work correctly), the Python module | |||
|
350 | # teardown mechanism runs over it, and sets to None every variable | |||
|
351 | # present in that module. This means that later calls to functions | |||
|
352 | # defined in the script (which have become interactively visible after | |||
|
353 | # script exit) fail, because they hold references to objects that have | |||
|
354 | # become overwritten into None. The only solution I see right now is | |||
|
355 | # to protect every FakeModule used by %run by holding an internal | |||
|
356 | # reference to it. This private list will be used for that. The | |||
|
357 | # %reset command will flush it as well. | |||
|
358 | self._user_main_modules = [] | |||
|
359 | ||||
347 | # List of input with multi-line handling. |
|
360 | # List of input with multi-line handling. | |
348 | # Fill its zero entry, user counter starts at 1 |
|
361 | # Fill its zero entry, user counter starts at 1 | |
349 | self.input_hist = InputList(['\n']) |
|
362 | self.input_hist = InputList(['\n']) | |
@@ -681,21 +694,10 b' class InteractiveShell(object,Magic):' | |||||
681 | self.sys_displayhook = sys.displayhook |
|
694 | self.sys_displayhook = sys.displayhook | |
682 | sys.displayhook = self.outputcache |
|
695 | sys.displayhook = self.outputcache | |
683 |
|
696 | |||
684 | # Monkeypatch doctest so that its core test runner method is protected |
|
697 | # Do a proper resetting of doctest, including the necessary displayhook | |
685 | # from IPython's modified displayhook. Doctest expects the default |
|
698 | # monkeypatching | |
686 | # displayhook behavior deep down, so our modification breaks it |
|
699 | doctest_reload() | |
687 | # completely. For this reason, a hard monkeypatch seems like a |
|
700 | ||
688 | # reasonable solution rather than asking users to manually use a |
|
|||
689 | # different doctest runner when under IPython. |
|
|||
690 | try: |
|
|||
691 | doctest.DocTestRunner |
|
|||
692 | except AttributeError: |
|
|||
693 | # This is only for python 2.3 compatibility, remove once we move to |
|
|||
694 | # 2.4 only. |
|
|||
695 | pass |
|
|||
696 | else: |
|
|||
697 | doctest.DocTestRunner.run = dhook_wrap(doctest.DocTestRunner.run) |
|
|||
698 |
|
||||
699 | # Set user colors (don't do it in the constructor above so that it |
|
701 | # Set user colors (don't do it in the constructor above so that it | |
700 | # doesn't crash if colors option is invalid) |
|
702 | # doesn't crash if colors option is invalid) | |
701 | self.magic_colors(rc.colors) |
|
703 | self.magic_colors(rc.colors) |
@@ -1,3 +1,15 b'' | |||||
|
1 | 2007-09-14 Fernando Perez <Fernando.Perez@colorado.edu> | |||
|
2 | ||||
|
3 | * IPython/genutils.py (doctest_reload): expose the doctest | |||
|
4 | reloader to the user so that people can easily reset doctest while | |||
|
5 | using it interactively. Fixes a problem reported by Jorgen. | |||
|
6 | ||||
|
7 | * IPython/iplib.py (InteractiveShell.__init__): protect the | |||
|
8 | FakeModule instances used for __main__ in %run calls from | |||
|
9 | deletion, so that user code defined in them isn't left with | |||
|
10 | dangling references due to the Python module deletion machinery. | |||
|
11 | This should fix the problems reported by Darren. | |||
|
12 | ||||
1 | 2007-09-10 Darren Dale <dd55@cornell.edu> |
|
13 | 2007-09-10 Darren Dale <dd55@cornell.edu> | |
2 |
|
14 | |||
3 | * Cleanup of IPShellQt and IPShellQt4 |
|
15 | * Cleanup of IPShellQt and IPShellQt4 |
General Comments 0
You need to be logged in to leave comments.
Login now