##// END OF EJS Templates
Merge Fernando's recent work (see log for details)
Fernando Perez -
r1923:ad503246 merge
parent child Browse files
Show More
@@ -0,0 +1,41 b''
1 """Minimal script to reproduce our nasty reference counting bug.
2
3 The problem is related to https://bugs.launchpad.net/ipython/+bug/269966
4
5 The original fix for that appeared to work, but John D. Hunter found a
6 matplotlib example which, when run twice in a row, would break. The problem
7 were references held by open figures to internals of Tkinter.
8
9 This code reproduces the problem that John saw, without matplotlib.
10
11 This script is meant to be called by other parts of the test suite that call it
12 via %run as if it were executed interactively by the user. As of 2009-04-13,
13 test_magic.py calls it.
14 """
15
16 #-----------------------------------------------------------------------------
17 # Module imports
18 #-----------------------------------------------------------------------------
19 import sys
20
21 from IPython import ipapi
22
23 #-----------------------------------------------------------------------------
24 # Globals
25 #-----------------------------------------------------------------------------
26 ip = ipapi.get()
27
28 if not '_refbug_cache' in ip.user_ns:
29 ip.user_ns['_refbug_cache'] = []
30
31
32 aglobal = 'Hello'
33 def f():
34 return aglobal
35
36 cache = ip.user_ns['_refbug_cache']
37 cache.append(f)
38
39 def call_f():
40 for func in cache:
41 print 'lowercased:',func().lower()
@@ -0,0 +1,17 b''
1 """Tests for the FakeModule objects.
2 """
3
4 import nose.tools as nt
5
6 from IPython.FakeModule import FakeModule, init_fakemod_dict
7
8 # Make a fakemod and check a few properties
9 def test_mk_fakemod():
10 fm = FakeModule()
11 yield nt.assert_true,fm
12 yield nt.assert_true,lambda : hasattr(fm,'__file__')
13
14 def test_mk_fakemod_fromdict():
15 """Test making a FakeModule object with initial data"""
16 fm = FakeModule(dict(hello=True))
17 nt.assert_true(fm.hello)
@@ -15,6 +15,37 b' sessions.'
15
15
16 import types
16 import types
17
17
18 def init_fakemod_dict(fm,adict=None):
19 """Initialize a FakeModule instance __dict__.
20
21 Kept as a standalone function and not a method so the FakeModule API can
22 remain basically empty.
23
24 This should be considered for private IPython use, used in managing
25 namespaces for %run.
26
27 Parameters
28 ----------
29
30 fm : FakeModule instance
31
32 adict : dict, optional
33 """
34
35 dct = {}
36 # It seems pydoc (and perhaps others) needs any module instance to
37 # implement a __nonzero__ method, so we add it if missing:
38 dct.setdefault('__nonzero__',lambda : True)
39 dct.setdefault('__file__',__file__)
40
41 if adict is not None:
42 dct.update(adict)
43
44 # Hard assignment of the object's __dict__. This is nasty but deliberate.
45 fm.__dict__.clear()
46 fm.__dict__.update(dct)
47
48
18 class FakeModule(types.ModuleType):
49 class FakeModule(types.ModuleType):
19 """Simple class with attribute access to fake a module.
50 """Simple class with attribute access to fake a module.
20
51
@@ -29,14 +60,7 b' class FakeModule(types.ModuleType):'
29
60
30 # tmp to force __dict__ instance creation, else self.__dict__ fails
61 # tmp to force __dict__ instance creation, else self.__dict__ fails
31 self.__iptmp = None
62 self.__iptmp = None
32
33 # It seems pydoc (and perhaps others) needs any module instance to
34 # implement a __nonzero__ method, so we add it if missing:
35 self.__dict__.setdefault('__nonzero__',lambda : True)
36 self.__dict__.setdefault('__file__',__file__)
37
38 # cleanup our temp trick
63 # cleanup our temp trick
39 del self.__iptmp
64 del self.__iptmp
40
65 # Now, initialize the actual data in the instance dict.
41 if adict is not None:
66 init_fakemod_dict(self,adict)
42 self.__dict__.update(adict)
@@ -1584,23 +1584,17 b' Currently the magic system has the following functions:\\n"""'
1584 prog_ns = self.shell.user_ns
1584 prog_ns = self.shell.user_ns
1585 __name__save = self.shell.user_ns['__name__']
1585 __name__save = self.shell.user_ns['__name__']
1586 prog_ns['__name__'] = '__main__'
1586 prog_ns['__name__'] = '__main__'
1587 main_mod = FakeModule(prog_ns)
1587 main_mod = self.shell.new_main_mod(prog_ns)
1588 else:
1588 else:
1589 # Run in a fresh, empty namespace
1589 # Run in a fresh, empty namespace
1590 if opts.has_key('n'):
1590 if opts.has_key('n'):
1591 name = os.path.splitext(os.path.basename(filename))[0]
1591 name = os.path.splitext(os.path.basename(filename))[0]
1592 else:
1592 else:
1593 name = '__main__'
1593 name = '__main__'
1594 main_mod = FakeModule()
1594
1595 main_mod = self.shell.new_main_mod()
1595 prog_ns = main_mod.__dict__
1596 prog_ns = main_mod.__dict__
1596 prog_ns['__name__'] = name
1597 prog_ns['__name__'] = name
1597
1598 # The shell MUST hold a reference to main_mod so after %run exits,
1599 # the python deletion mechanism doesn't zero it out (leaving
1600 # dangling references). However, we should drop old versions of
1601 # main_mod. There is now a proper API to manage this caching in
1602 # the main shell object, we use that.
1603 self.shell.cache_main_mod(main_mod)
1604
1598
1605 # Since '%run foo' emulates 'python foo.py' at the cmd line, we must
1599 # Since '%run foo' emulates 'python foo.py' at the cmd line, we must
1606 # set the __file__ global in the script's namespace
1600 # set the __file__ global in the script's namespace
@@ -1703,9 +1697,14 b' Currently the magic system has the following functions:\\n"""'
1703 else:
1697 else:
1704 # regular execution
1698 # regular execution
1705 runner(filename,prog_ns,prog_ns,exit_ignore=exit_ignore)
1699 runner(filename,prog_ns,prog_ns,exit_ignore=exit_ignore)
1700
1706 if opts.has_key('i'):
1701 if opts.has_key('i'):
1707 self.shell.user_ns['__name__'] = __name__save
1702 self.shell.user_ns['__name__'] = __name__save
1708 else:
1703 else:
1704 # The shell MUST hold a reference to prog_ns so after %run
1705 # exits, the python deletion mechanism doesn't zero it out
1706 # (leaving dangling references).
1707 self.shell.cache_main_mod(prog_ns,filename)
1709 # update IPython interactive namespace
1708 # update IPython interactive namespace
1710 del prog_ns['__name__']
1709 del prog_ns['__name__']
1711 self.shell.user_ns.update(prog_ns)
1710 self.shell.user_ns.update(prog_ns)
@@ -1719,6 +1718,7 b' Currently the magic system has the following functions:\\n"""'
1719 # added. Otherwise it will trap references to objects
1718 # added. Otherwise it will trap references to objects
1720 # contained therein.
1719 # contained therein.
1721 del sys.modules[main_mod_name]
1720 del sys.modules[main_mod_name]
1721
1722 self.shell.reloadhist()
1722 self.shell.reloadhist()
1723
1723
1724 return stats
1724 return stats
@@ -1800,7 +1800,28 b' Currently the magic system has the following functions:\\n"""'
1800 import timeit
1800 import timeit
1801 import math
1801 import math
1802
1802
1803 units = [u"s", u"ms", u"\xb5s", u"ns"]
1803 # XXX: Unfortunately the unicode 'micro' symbol can cause problems in
1804 # certain terminals. Until we figure out a robust way of
1805 # auto-detecting if the terminal can deal with it, use plain 'us' for
1806 # microseconds. I am really NOT happy about disabling the proper
1807 # 'micro' prefix, but crashing is worse... If anyone knows what the
1808 # right solution for this is, I'm all ears...
1809 #
1810 # Note: using
1811 #
1812 # s = u'\xb5'
1813 # s.encode(sys.getdefaultencoding())
1814 #
1815 # is not sufficient, as I've seen terminals where that fails but
1816 # print s
1817 #
1818 # succeeds
1819 #
1820 # See bug: https://bugs.launchpad.net/ipython/+bug/348466
1821
1822 #units = [u"s", u"ms",u'\xb5',"ns"]
1823 units = [u"s", u"ms",u'us',"ns"]
1824
1804 scaling = [1, 1e3, 1e6, 1e9]
1825 scaling = [1, 1e3, 1e6, 1e9]
1805
1826
1806 opts, stmt = self.parse_options(parameter_s,'n:r:tcp:',
1827 opts, stmt = self.parse_options(parameter_s,'n:r:tcp:',
@@ -1839,9 +1860,9 b' Currently the magic system has the following functions:\\n"""'
1839 # determine number so that 0.2 <= total time < 2.0
1860 # determine number so that 0.2 <= total time < 2.0
1840 number = 1
1861 number = 1
1841 for i in range(1, 10):
1862 for i in range(1, 10):
1842 number *= 10
1843 if timer.timeit(number) >= 0.2:
1863 if timer.timeit(number) >= 0.2:
1844 break
1864 break
1865 number *= 10
1845
1866
1846 best = min(timer.repeat(repeat, number)) / number
1867 best = min(timer.repeat(repeat, number)) / number
1847
1868
@@ -128,7 +128,7 b' prompt_specials_color = {'
128 r'\N': '${self.cache.prompt_count}',
128 r'\N': '${self.cache.prompt_count}',
129 # Prompt/history count, with the actual digits replaced by dots. Used
129 # Prompt/history count, with the actual digits replaced by dots. Used
130 # mainly in continuation prompts (prompt_in2)
130 # mainly in continuation prompts (prompt_in2)
131 r'\D': '${"."*len(str(self.cache.prompt_count))}',
131 r'\D': '${"."*__builtins__.len(__builtins__.str(self.cache.prompt_count))}',
132 # Current working directory
132 # Current working directory
133 r'\w': '${os.getcwd()}',
133 r'\w': '${os.getcwd()}',
134 # Current time
134 # Current time
@@ -20,10 +20,10 b" name = 'ipython'"
20 # because bdist_rpm does not accept dashes (an RPM) convention, and
20 # because bdist_rpm does not accept dashes (an RPM) convention, and
21 # bdist_deb does not accept underscores (a Debian convention).
21 # bdist_deb does not accept underscores (a Debian convention).
22
22
23 development = False # change this to False to do a release
23 development = True # change this to False to do a release
24 version_base = '0.9.1'
24 version_base = '0.10'
25 branch = 'ipython'
25 branch = 'ipython'
26 revision = '1143'
26 revision = '1195'
27
27
28 if development:
28 if development:
29 if branch == 'ipython':
29 if branch == 'ipython':
@@ -54,7 +54,7 b' from pprint import pprint, pformat'
54 from IPython import Debugger,OInspect,PyColorize,ultraTB
54 from IPython import Debugger,OInspect,PyColorize,ultraTB
55 from IPython.ColorANSI import ColorScheme,ColorSchemeTable # too long names
55 from IPython.ColorANSI import ColorScheme,ColorSchemeTable # too long names
56 from IPython.Extensions import pickleshare
56 from IPython.Extensions import pickleshare
57 from IPython.FakeModule import FakeModule
57 from IPython.FakeModule import FakeModule, init_fakemod_dict
58 from IPython.Itpl import Itpl,itpl,printpl,ItplNS,itplns
58 from IPython.Itpl import Itpl,itpl,printpl,ItplNS,itplns
59 from IPython.Logger import Logger
59 from IPython.Logger import Logger
60 from IPython.Magic import Magic
60 from IPython.Magic import Magic
@@ -108,6 +108,197 b' def softspace(file, newvalue):'
108 return oldvalue
108 return oldvalue
109
109
110
110
111 def user_setup(ipythondir,rc_suffix,mode='install',interactive=True):
112 """Install or upgrade the user configuration directory.
113
114 Can be called when running for the first time or to upgrade the user's
115 .ipython/ directory.
116
117 Parameters
118 ----------
119 ipythondir : path
120 The directory to be used for installation/upgrade. In 'install' mode,
121 if this path already exists, the function exits immediately.
122
123 rc_suffix : str
124 Extension for the config files. On *nix platforms it is typically the
125 empty string, while Windows normally uses '.ini'.
126
127 mode : str, optional
128 Valid modes are 'install' and 'upgrade'.
129
130 interactive : bool, optional
131 If False, do not wait for user input on any errors. Normally after
132 printing its status information, this function waits for the user to
133 hit Return before proceeding. This is because the default use case is
134 when first installing the IPython configuration, so we want the user to
135 acknowledge the initial message, which contains some useful
136 information.
137 """
138
139 # For automatic use, deactivate all i/o
140 if interactive:
141 def wait():
142 try:
143 raw_input("Please press <RETURN> to start IPython.")
144 except EOFError:
145 print >> Term.cout
146 print '*'*70
147
148 def printf(s):
149 print s
150 else:
151 wait = lambda : None
152 printf = lambda s : None
153
154 # Install mode should be re-entrant: if the install dir already exists,
155 # bail out cleanly
156 if mode == 'install' and os.path.isdir(ipythondir):
157 return
158
159 cwd = os.getcwd() # remember where we started
160 glb = glob.glob
161
162 printf('*'*70)
163 if mode == 'install':
164 printf(
165 """Welcome to IPython. I will try to create a personal configuration directory
166 where you can customize many aspects of IPython's functionality in:\n""")
167 else:
168 printf('I am going to upgrade your configuration in:')
169
170 printf(ipythondir)
171
172 rcdirend = os.path.join('IPython','UserConfig')
173 cfg = lambda d: os.path.join(d,rcdirend)
174 try:
175 rcdir = filter(os.path.isdir,map(cfg,sys.path))[0]
176 printf("Initializing from configuration: %s" % rcdir)
177 except IndexError:
178 warning = """
179 Installation error. IPython's directory was not found.
180
181 Check the following:
182
183 The ipython/IPython directory should be in a directory belonging to your
184 PYTHONPATH environment variable (that is, it should be in a directory
185 belonging to sys.path). You can copy it explicitly there or just link to it.
186
187 IPython will create a minimal default configuration for you.
188
189 """
190 warn(warning)
191 wait()
192
193 if sys.platform =='win32':
194 inif = 'ipythonrc.ini'
195 else:
196 inif = 'ipythonrc'
197 minimal_setup = {'ipy_user_conf.py' : 'import ipy_defaults',
198 inif : '# intentionally left blank' }
199 os.makedirs(ipythondir, mode = 0777)
200 for f, cont in minimal_setup.items():
201 # In 2.5, this can be more cleanly done using 'with'
202 fobj = file(ipythondir + '/' + f,'w')
203 fobj.write(cont)
204 fobj.close()
205
206 return
207
208 if mode == 'install':
209 try:
210 shutil.copytree(rcdir,ipythondir)
211 os.chdir(ipythondir)
212 rc_files = glb("ipythonrc*")
213 for rc_file in rc_files:
214 os.rename(rc_file,rc_file+rc_suffix)
215 except:
216 warning = """
217
218 There was a problem with the installation:
219 %s
220 Try to correct it or contact the developers if you think it's a bug.
221 IPython will proceed with builtin defaults.""" % sys.exc_info()[1]
222 warn(warning)
223 wait()
224 return
225
226 elif mode == 'upgrade':
227 try:
228 os.chdir(ipythondir)
229 except:
230 printf("""
231 Can not upgrade: changing to directory %s failed. Details:
232 %s
233 """ % (ipythondir,sys.exc_info()[1]) )
234 wait()
235 return
236 else:
237 sources = glb(os.path.join(rcdir,'[A-Za-z]*'))
238 for new_full_path in sources:
239 new_filename = os.path.basename(new_full_path)
240 if new_filename.startswith('ipythonrc'):
241 new_filename = new_filename + rc_suffix
242 # The config directory should only contain files, skip any
243 # directories which may be there (like CVS)
244 if os.path.isdir(new_full_path):
245 continue
246 if os.path.exists(new_filename):
247 old_file = new_filename+'.old'
248 if os.path.exists(old_file):
249 os.remove(old_file)
250 os.rename(new_filename,old_file)
251 shutil.copy(new_full_path,new_filename)
252 else:
253 raise ValueError('unrecognized mode for install: %r' % mode)
254
255 # Fix line-endings to those native to each platform in the config
256 # directory.
257 try:
258 os.chdir(ipythondir)
259 except:
260 printf("""
261 Problem: changing to directory %s failed.
262 Details:
263 %s
264
265 Some configuration files may have incorrect line endings. This should not
266 cause any problems during execution. """ % (ipythondir,sys.exc_info()[1]) )
267 wait()
268 else:
269 for fname in glb('ipythonrc*'):
270 try:
271 native_line_ends(fname,backup=0)
272 except IOError:
273 pass
274
275 if mode == 'install':
276 printf("""
277 Successful installation!
278
279 Please read the sections 'Initial Configuration' and 'Quick Tips' in the
280 IPython manual (there are both HTML and PDF versions supplied with the
281 distribution) to make sure that your system environment is properly configured
282 to take advantage of IPython's features.
283
284 Important note: the configuration system has changed! The old system is
285 still in place, but its setting may be partly overridden by the settings in
286 "~/.ipython/ipy_user_conf.py" config file. Please take a look at the file
287 if some of the new settings bother you.
288
289 """)
290 else:
291 printf("""
292 Successful upgrade!
293
294 All files in your directory:
295 %(ipythondir)s
296 which would have been overwritten by the upgrade were backed up with a .old
297 extension. If you had made particular customizations in those files you may
298 want to merge them back into the new files.""" % locals() )
299 wait()
300 os.chdir(cwd)
301
111 #****************************************************************************
302 #****************************************************************************
112 # Local use exceptions
303 # Local use exceptions
113 class SpaceInInput(exceptions.Exception): pass
304 class SpaceInInput(exceptions.Exception): pass
@@ -308,13 +499,24 b' class InteractiveShell(object,Magic):'
308 # calling functions defined in the script that use other things from
499 # calling functions defined in the script that use other things from
309 # the script will fail, because the function's closure had references
500 # the script will fail, because the function's closure had references
310 # to the original objects, which are now all None. So we must protect
501 # to the original objects, which are now all None. So we must protect
311 # these modules from deletion by keeping a cache. To avoid keeping
502 # these modules from deletion by keeping a cache.
312 # stale modules around (we only need the one from the last run), we use
503 #
313 # a dict keyed with the full path to the script, so only the last
504 # To avoid keeping stale modules around (we only need the one from the
314 # version of the module is held in the cache. The %reset command will
505 # last run), we use a dict keyed with the full path to the script, so
315 # flush this cache. See the cache_main_mod() and clear_main_mod_cache()
506 # only the last version of the module is held in the cache. Note,
316 # methods for details on use.
507 # however, that we must cache the module *namespace contents* (their
317 self._user_main_modules = {}
508 # __dict__). Because if we try to cache the actual modules, old ones
509 # (uncached) could be destroyed while still holding references (such as
510 # those held by GUI objects that tend to be long-lived)>
511 #
512 # The %reset command will flush this cache. See the cache_main_mod()
513 # and clear_main_mod_cache() methods for details on use.
514
515 # This is the cache used for 'main' namespaces
516 self._main_ns_cache = {}
517 # And this is the single instance of FakeModule whose __dict__ we keep
518 # copying and clearing for reuse on each %run
519 self._user_main_module = FakeModule()
318
520
319 # A table holding all the namespaces IPython deals with, so that
521 # A table holding all the namespaces IPython deals with, so that
320 # introspection facilities can search easily.
522 # introspection facilities can search easily.
@@ -330,7 +532,7 b' class InteractiveShell(object,Magic):'
330 # a simple list.
532 # a simple list.
331 self.ns_refs_table = [ user_ns, user_global_ns, self.user_config_ns,
533 self.ns_refs_table = [ user_ns, user_global_ns, self.user_config_ns,
332 self.alias_table, self.internal_ns,
534 self.alias_table, self.internal_ns,
333 self._user_main_modules ]
535 self._main_ns_cache ]
334
536
335 # We need to insert into sys.modules something that looks like a
537 # We need to insert into sys.modules something that looks like a
336 # module but which accesses the IPython namespace, for shelve and
538 # module but which accesses the IPython namespace, for shelve and
@@ -1114,156 +1316,11 b' class InteractiveShell(object,Magic):'
1114 def user_setup(self,ipythondir,rc_suffix,mode='install'):
1316 def user_setup(self,ipythondir,rc_suffix,mode='install'):
1115 """Install the user configuration directory.
1317 """Install the user configuration directory.
1116
1318
1117 Can be called when running for the first time or to upgrade the user's
1319 Note
1118 .ipython/ directory with the mode parameter. Valid modes are 'install'
1320 ----
1119 and 'upgrade'."""
1321 DEPRECATED: use the top-level user_setup() function instead.
1120
1322 """
1121 def wait():
1323 return user_setup(ipythondir,rc_suffix,mode)
1122 try:
1123 raw_input("Please press <RETURN> to start IPython.")
1124 except EOFError:
1125 print >> Term.cout
1126 print '*'*70
1127
1128 cwd = os.getcwd() # remember where we started
1129 glb = glob.glob
1130 print '*'*70
1131 if mode == 'install':
1132 print \
1133 """Welcome to IPython. I will try to create a personal configuration directory
1134 where you can customize many aspects of IPython's functionality in:\n"""
1135 else:
1136 print 'I am going to upgrade your configuration in:'
1137
1138 print ipythondir
1139
1140 rcdirend = os.path.join('IPython','UserConfig')
1141 cfg = lambda d: os.path.join(d,rcdirend)
1142 try:
1143 rcdir = filter(os.path.isdir,map(cfg,sys.path))[0]
1144 print "Initializing from configuration",rcdir
1145 except IndexError:
1146 warning = """
1147 Installation error. IPython's directory was not found.
1148
1149 Check the following:
1150
1151 The ipython/IPython directory should be in a directory belonging to your
1152 PYTHONPATH environment variable (that is, it should be in a directory
1153 belonging to sys.path). You can copy it explicitly there or just link to it.
1154
1155 IPython will create a minimal default configuration for you.
1156
1157 """
1158 warn(warning)
1159 wait()
1160
1161 if sys.platform =='win32':
1162 inif = 'ipythonrc.ini'
1163 else:
1164 inif = 'ipythonrc'
1165 minimal_setup = {'ipy_user_conf.py' : 'import ipy_defaults',
1166 inif : '# intentionally left blank' }
1167 os.makedirs(ipythondir, mode = 0777)
1168 for f, cont in minimal_setup.items():
1169 open(ipythondir + '/' + f,'w').write(cont)
1170
1171 return
1172
1173 if mode == 'install':
1174 try:
1175 shutil.copytree(rcdir,ipythondir)
1176 os.chdir(ipythondir)
1177 rc_files = glb("ipythonrc*")
1178 for rc_file in rc_files:
1179 os.rename(rc_file,rc_file+rc_suffix)
1180 except:
1181 warning = """
1182
1183 There was a problem with the installation:
1184 %s
1185 Try to correct it or contact the developers if you think it's a bug.
1186 IPython will proceed with builtin defaults.""" % sys.exc_info()[1]
1187 warn(warning)
1188 wait()
1189 return
1190
1191 elif mode == 'upgrade':
1192 try:
1193 os.chdir(ipythondir)
1194 except:
1195 print """
1196 Can not upgrade: changing to directory %s failed. Details:
1197 %s
1198 """ % (ipythondir,sys.exc_info()[1])
1199 wait()
1200 return
1201 else:
1202 sources = glb(os.path.join(rcdir,'[A-Za-z]*'))
1203 for new_full_path in sources:
1204 new_filename = os.path.basename(new_full_path)
1205 if new_filename.startswith('ipythonrc'):
1206 new_filename = new_filename + rc_suffix
1207 # The config directory should only contain files, skip any
1208 # directories which may be there (like CVS)
1209 if os.path.isdir(new_full_path):
1210 continue
1211 if os.path.exists(new_filename):
1212 old_file = new_filename+'.old'
1213 if os.path.exists(old_file):
1214 os.remove(old_file)
1215 os.rename(new_filename,old_file)
1216 shutil.copy(new_full_path,new_filename)
1217 else:
1218 raise ValueError,'unrecognized mode for install:',`mode`
1219
1220 # Fix line-endings to those native to each platform in the config
1221 # directory.
1222 try:
1223 os.chdir(ipythondir)
1224 except:
1225 print """
1226 Problem: changing to directory %s failed.
1227 Details:
1228 %s
1229
1230 Some configuration files may have incorrect line endings. This should not
1231 cause any problems during execution. """ % (ipythondir,sys.exc_info()[1])
1232 wait()
1233 else:
1234 for fname in glb('ipythonrc*'):
1235 try:
1236 native_line_ends(fname,backup=0)
1237 except IOError:
1238 pass
1239
1240 if mode == 'install':
1241 print """
1242 Successful installation!
1243
1244 Please read the sections 'Initial Configuration' and 'Quick Tips' in the
1245 IPython manual (there are both HTML and PDF versions supplied with the
1246 distribution) to make sure that your system environment is properly configured
1247 to take advantage of IPython's features.
1248
1249 Important note: the configuration system has changed! The old system is
1250 still in place, but its setting may be partly overridden by the settings in
1251 "~/.ipython/ipy_user_conf.py" config file. Please take a look at the file
1252 if some of the new settings bother you.
1253
1254 """
1255 else:
1256 print """
1257 Successful upgrade!
1258
1259 All files in your directory:
1260 %(ipythondir)s
1261 which would have been overwritten by the upgrade were backed up with a .old
1262 extension. If you had made particular customizations in those files you may
1263 want to merge them back into the new files.""" % locals()
1264 wait()
1265 os.chdir(cwd)
1266 # end user_setup()
1267
1324
1268 def atexit_operations(self):
1325 def atexit_operations(self):
1269 """This will be executed at the time of exit.
1326 """This will be executed at the time of exit.
@@ -1441,35 +1498,53 b' want to merge them back into the new files.""" % locals()'
1441 return True
1498 return True
1442 return ask_yes_no(prompt,default)
1499 return ask_yes_no(prompt,default)
1443
1500
1444 def cache_main_mod(self,mod):
1501 def new_main_mod(self,ns=None):
1445 """Cache a main module.
1502 """Return a new 'main' module object for user code execution.
1503 """
1504 main_mod = self._user_main_module
1505 init_fakemod_dict(main_mod,ns)
1506 return main_mod
1507
1508 def cache_main_mod(self,ns,fname):
1509 """Cache a main module's namespace.
1446
1510
1447 When scripts are executed via %run, we must keep a reference to their
1511 When scripts are executed via %run, we must keep a reference to the
1448 __main__ module (a FakeModule instance) around so that Python doesn't
1512 namespace of their __main__ module (a FakeModule instance) around so
1449 clear it, rendering objects defined therein useless.
1513 that Python doesn't clear it, rendering objects defined therein
1514 useless.
1450
1515
1451 This method keeps said reference in a private dict, keyed by the
1516 This method keeps said reference in a private dict, keyed by the
1452 absolute path of the module object (which corresponds to the script
1517 absolute path of the module object (which corresponds to the script
1453 path). This way, for multiple executions of the same script we only
1518 path). This way, for multiple executions of the same script we only
1454 keep one copy of __main__ (the last one), thus preventing memory leaks
1519 keep one copy of the namespace (the last one), thus preventing memory
1455 from old references while allowing the objects from the last execution
1520 leaks from old references while allowing the objects from the last
1456 to be accessible.
1521 execution to be accessible.
1522
1523 Note: we can not allow the actual FakeModule instances to be deleted,
1524 because of how Python tears down modules (it hard-sets all their
1525 references to None without regard for reference counts). This method
1526 must therefore make a *copy* of the given namespace, to allow the
1527 original module's __dict__ to be cleared and reused.
1457
1528
1529
1458 Parameters
1530 Parameters
1459 ----------
1531 ----------
1460 mod : a module object
1532 ns : a namespace (a dict, typically)
1533
1534 fname : str
1535 Filename associated with the namespace.
1461
1536
1462 Examples
1537 Examples
1463 --------
1538 --------
1464
1539
1465 In [10]: import IPython
1540 In [10]: import IPython
1466
1541
1467 In [11]: _ip.IP.cache_main_mod(IPython)
1542 In [11]: _ip.IP.cache_main_mod(IPython.__dict__,IPython.__file__)
1468
1543
1469 In [12]: IPython.__file__ in _ip.IP._user_main_modules
1544 In [12]: IPython.__file__ in _ip.IP._main_ns_cache
1470 Out[12]: True
1545 Out[12]: True
1471 """
1546 """
1472 self._user_main_modules[os.path.abspath(mod.__file__) ] = mod
1547 self._main_ns_cache[os.path.abspath(fname)] = ns.copy()
1473
1548
1474 def clear_main_mod_cache(self):
1549 def clear_main_mod_cache(self):
1475 """Clear the cache of main modules.
1550 """Clear the cache of main modules.
@@ -1481,17 +1556,17 b' want to merge them back into the new files.""" % locals()'
1481
1556
1482 In [15]: import IPython
1557 In [15]: import IPython
1483
1558
1484 In [16]: _ip.IP.cache_main_mod(IPython)
1559 In [16]: _ip.IP.cache_main_mod(IPython.__dict__,IPython.__file__)
1485
1560
1486 In [17]: len(_ip.IP._user_main_modules) > 0
1561 In [17]: len(_ip.IP._main_ns_cache) > 0
1487 Out[17]: True
1562 Out[17]: True
1488
1563
1489 In [18]: _ip.IP.clear_main_mod_cache()
1564 In [18]: _ip.IP.clear_main_mod_cache()
1490
1565
1491 In [19]: len(_ip.IP._user_main_modules) == 0
1566 In [19]: len(_ip.IP._main_ns_cache) == 0
1492 Out[19]: True
1567 Out[19]: True
1493 """
1568 """
1494 self._user_main_modules.clear()
1569 self._main_ns_cache.clear()
1495
1570
1496 def _should_recompile(self,e):
1571 def _should_recompile(self,e):
1497 """Utility routine for edit_syntax_error"""
1572 """Utility routine for edit_syntax_error"""
@@ -61,7 +61,7 b' def main():'
61 # plugin needs to be gone through with a fine
61 # plugin needs to be gone through with a fine
62 # toothed comb to find what is causing the problem.
62 # toothed comb to find what is causing the problem.
63 # '--with-ipdoctest',
63 # '--with-ipdoctest',
64 '--doctest-tests','--doctest-extension=txt',
64 '--ipdoctest-tests','--ipdoctest-extension=txt',
65 '--detailed-errors',
65 '--detailed-errors',
66
66
67 # We add --exe because of setuptools' imbecility (it
67 # We add --exe because of setuptools' imbecility (it
@@ -81,11 +81,13 b' def main():'
81 (':' in arg and '.py' in arg):
81 (':' in arg and '.py' in arg):
82 has_tests = True
82 has_tests = True
83 break
83 break
84
84 # If nothing was specifically requested, test full IPython
85 # If nothing was specifically requested, test full IPython
85 if not has_tests:
86 if not has_tests:
86 argv.append('IPython')
87 argv.append('IPython')
87
88
88 # Construct list of plugins, omitting the existing doctest plugin.
89 # Construct list of plugins, omitting the existing doctest plugin, which
90 # ours replaces (and extends).
89 plugins = [IPythonDoctest(EXCLUDE)]
91 plugins = [IPythonDoctest(EXCLUDE)]
90 for p in nose.plugins.builtin.plugins:
92 for p in nose.plugins.builtin.plugins:
91 plug = p()
93 plug = p()
@@ -15,7 +15,6 b' Limitations:'
15 won't even have these special _NN variables set at all.
15 won't even have these special _NN variables set at all.
16 """
16 """
17
17
18
19 #-----------------------------------------------------------------------------
18 #-----------------------------------------------------------------------------
20 # Module imports
19 # Module imports
21
20
@@ -123,6 +122,13 b' class ipnsdict(dict):'
123 def start_ipython():
122 def start_ipython():
124 """Start a global IPython shell, which we need for IPython-specific syntax.
123 """Start a global IPython shell, which we need for IPython-specific syntax.
125 """
124 """
125
126 # This function should only ever run once!
127 if hasattr(start_ipython,'already_called'):
128 return
129 start_ipython.already_called = True
130
131 # Ok, first time we're called, go ahead
126 import new
132 import new
127
133
128 import IPython
134 import IPython
@@ -691,6 +697,7 b' class ExtensionDoctest(doctests.Doctest):'
691 to exclude any filename which matches them from inclusion in the test
697 to exclude any filename which matches them from inclusion in the test
692 suite (using pattern.search(), NOT pattern.match() ).
698 suite (using pattern.search(), NOT pattern.match() ).
693 """
699 """
700
694 if exclude_patterns is None:
701 if exclude_patterns is None:
695 exclude_patterns = []
702 exclude_patterns = []
696 self.exclude_patterns = map(re.compile,exclude_patterns)
703 self.exclude_patterns = map(re.compile,exclude_patterns)
@@ -836,15 +843,33 b' class IPythonDoctest(ExtensionDoctest):'
836 optionflags=optionflags,
843 optionflags=optionflags,
837 checker=self.checker)
844 checker=self.checker)
838
845
839 def configure(self, options, config):
846 def options(self, parser, env=os.environ):
847 Plugin.options(self, parser, env)
848 parser.add_option('--ipdoctest-tests', action='store_true',
849 dest='ipdoctest_tests',
850 default=env.get('NOSE_IPDOCTEST_TESTS',True),
851 help="Also look for doctests in test modules. "
852 "Note that classes, methods and functions should "
853 "have either doctests or non-doctest tests, "
854 "not both. [NOSE_IPDOCTEST_TESTS]")
855 parser.add_option('--ipdoctest-extension', action="append",
856 dest="ipdoctest_extension",
857 help="Also look for doctests in files with "
858 "this extension [NOSE_IPDOCTEST_EXTENSION]")
859 # Set the default as a list, if given in env; otherwise
860 # an additional value set on the command line will cause
861 # an error.
862 env_setting = env.get('NOSE_IPDOCTEST_EXTENSION')
863 if env_setting is not None:
864 parser.set_defaults(ipdoctest_extension=tolist(env_setting))
840
865
866 def configure(self, options, config):
841 Plugin.configure(self, options, config)
867 Plugin.configure(self, options, config)
842 self.doctest_tests = options.doctest_tests
868 self.doctest_tests = options.ipdoctest_tests
843 self.extension = tolist(options.doctestExtension)
869 self.extension = tolist(options.ipdoctest_extension)
844
870
845 self.parser = IPDocTestParser()
871 self.parser = IPDocTestParser()
846 self.finder = DocTestFinder(parser=self.parser)
872 self.finder = DocTestFinder(parser=self.parser)
847 self.checker = IPDoctestOutputChecker()
873 self.checker = IPDoctestOutputChecker()
848 self.globs = None
874 self.globs = None
849 self.extraglobs = None
875 self.extraglobs = None
850
@@ -6,8 +6,9 b' This is used by a companion test case.'
6 import gc
6 import gc
7
7
8 class C(object):
8 class C(object):
9 def __del__(self):
9 def __del__(self):
10 print 'deleting object...'
10 pass
11 #print 'deleting object...' # dbg
11
12
12 c = C()
13 c = C()
13
14
@@ -39,13 +39,10 b' def doctest_ivars():'
39 Out[6]: 1
39 Out[6]: 1
40 """
40 """
41
41
42 @dec.skip_doctest
42 #@dec.skip_doctest
43 def doctest_refs():
43 def doctest_refs():
44 """DocTest reference holding issues when running scripts.
44 """DocTest reference holding issues when running scripts.
45
45
46 In [32]: run show_refs.py
46 In [32]: run show_refs.py
47 c referrers: [<type 'dict'>]
47 c referrers: [<type 'dict'>]
48
49 In [33]: map(type,gc.get_referrers(c))
50 Out[33]: [<type 'dict'>]
51 """
48 """
@@ -26,7 +26,7 b' import sys'
26
26
27 class A(object):
27 class A(object):
28 def __del__(self):
28 def __del__(self):
29 print 'object A deleted'
29 print 'obj_del.py: object A deleted'
30
30
31 a = A()
31 a = A()
32
32
@@ -16,11 +16,12 b' class C(object):'
16 self.name = name
16 self.name = name
17
17
18 def __del__(self):
18 def __del__(self):
19 print 'Deleting object:',self.name
19 print 'tclass.py: deleting object:',self.name
20
20
21 try:
21 try:
22 name = sys.argv[1]
22 name = sys.argv[1]
23 except IndexError:
23 except IndexError:
24 pass
24 pass
25 else:
25 else:
26 c = C(name)
26 if name.startswith('C'):
27 c = C(name)
@@ -1,17 +1,68 b''
1 """Tests for the key iplib module, where the main ipython class is defined.
1 """Tests for the key iplib module, where the main ipython class is defined.
2 """
2 """
3 #-----------------------------------------------------------------------------
4 # Module imports
5 #-----------------------------------------------------------------------------
3
6
7 # stdlib
8 import os
9 import shutil
10 import tempfile
11
12 # third party
4 import nose.tools as nt
13 import nose.tools as nt
5
14
15 # our own packages
16 from IPython import iplib
17
18 #-----------------------------------------------------------------------------
19 # Globals
20 #-----------------------------------------------------------------------------
21
22 # Useful global ipapi object and main IPython one. Unfortunately we have a
23 # long precedent of carrying the 'ipapi' global object which is injected into
24 # the system namespace as _ip, but that keeps a pointer to the actual IPython
25 # InteractiveShell instance, which is named IP. Since in testing we do need
26 # access to the real thing (we want to probe beyond what ipapi exposes), make
27 # here a global reference to each. In general, things that are exposed by the
28 # ipapi instance should be read from there, but we also will often need to use
29 # the actual IPython one.
30
31 ip = _ip # This is the ipapi instance
32 IP = ip.IP # This is the actual IPython shell 'raw' object.
33
34 #-----------------------------------------------------------------------------
35 # Test functions
36 #-----------------------------------------------------------------------------
6
37
7 def test_reset():
38 def test_reset():
8 """reset must clear most namespaces."""
39 """reset must clear most namespaces."""
9 ip = _ip.IP
40 IP.reset() # first, it should run without error
10 ip.reset() # first, it should run without error
11 # Then, check that most namespaces end up empty
41 # Then, check that most namespaces end up empty
12 for ns in ip.ns_refs_table:
42 for ns in IP.ns_refs_table:
13 if ns is ip.user_ns:
43 if ns is IP.user_ns:
14 # The user namespace is reset with some data, so we can't check for
44 # The user namespace is reset with some data, so we can't check for
15 # it being empty
45 # it being empty
16 continue
46 continue
17 nt.assert_equals(len(ns),0)
47 nt.assert_equals(len(ns),0)
48
49
50 # make sure that user_setup can be run re-entrantly in 'install' mode.
51 def test_user_setup():
52 # use a lambda to pass kwargs to the generator
53 user_setup = lambda a,k: iplib.user_setup(*a,**k)
54 kw = dict(mode='install', interactive=False)
55
56 # Call the user setup and verify that the directory exists
57 yield user_setup, (ip.options.ipythondir,''), kw
58 yield os.path.isdir, ip.options.ipythondir
59
60 # Now repeat the operation with a non-existent directory. Check both that
61 # the call succeeds and that the directory is created.
62 tmpdir = tempfile.mktemp(prefix='ipython-test-')
63 try:
64 yield user_setup, (tmpdir,''), kw
65 yield os.path.isdir, tmpdir
66 finally:
67 # In this case, clean up the temp dir once done
68 shutil.rmtree(tmpdir)
@@ -37,7 +37,7 b' def test_rehashx():'
37 def doctest_run_ns():
37 def doctest_run_ns():
38 """Classes declared %run scripts must be instantiable afterwards.
38 """Classes declared %run scripts must be instantiable afterwards.
39
39
40 In [11]: run tclass
40 In [11]: run tclass foo
41
41
42 In [12]: isinstance(f(),foo)
42 In [12]: isinstance(f(),foo)
43 Out[12]: True
43 Out[12]: True
@@ -47,12 +47,10 b' def doctest_run_ns():'
47 def doctest_run_ns2():
47 def doctest_run_ns2():
48 """Classes declared %run scripts must be instantiable afterwards.
48 """Classes declared %run scripts must be instantiable afterwards.
49
49
50 In [3]: run tclass.py
50 In [4]: run tclass C-first_pass
51
51
52 In [4]: run tclass first_pass
52 In [5]: run tclass C-second_pass
53
53 tclass.py: deleting object: C-first_pass
54 In [5]: run tclass second_pass
55 Deleting object: first_pass
56 """
54 """
57
55
58
56
@@ -85,7 +83,7 b' def test_obj_del():'
85 test_dir = os.path.dirname(__file__)
83 test_dir = os.path.dirname(__file__)
86 del_file = os.path.join(test_dir,'obj_del.py')
84 del_file = os.path.join(test_dir,'obj_del.py')
87 out = _ip.IP.getoutput('ipython %s' % del_file)
85 out = _ip.IP.getoutput('ipython %s' % del_file)
88 nt.assert_equals(out,'object A deleted')
86 nt.assert_equals(out,'obj_del.py: object A deleted')
89
87
90
88
91 def test_shist():
89 def test_shist():
@@ -133,3 +131,21 b' def test_fail_dec2(*a,**k):'
133 def test_fail_dec3(*a,**k):
131 def test_fail_dec3(*a,**k):
134 yield nt.assert_true, False
132 yield nt.assert_true, False
135
133
134
135 def doctest_refbug():
136 """Very nasty problem with references held by multiple runs of a script.
137 See: https://bugs.launchpad.net/ipython/+bug/269966
138
139 In [1]: _ip.IP.clear_main_mod_cache()
140
141 In [2]: run refbug
142
143 In [3]: call_f()
144 lowercased: hello
145
146 In [4]: run refbug
147
148 In [5]: call_f()
149 lowercased: hello
150 lowercased: hello
151 """
@@ -345,6 +345,37 b' nosetests option. For example, you can use ``--pdb`` or ``--pdb-failures`` to'
345 automatically activate the interactive Pdb debugger on errors or failures. See
345 automatically activate the interactive Pdb debugger on errors or failures. See
346 the nosetests documentation for further details.
346 the nosetests documentation for further details.
347
347
348 .. warning::
349
350 Note that right now we have a nasty interaction between ipdoctest and
351 twisted. Until we figure this out, please use the following instructions to
352 ensure that at least you run all the tests.
353
354 Right now, if you now run::
355
356 $ iptest [any options] [any submodules]
357
358 it will NOT load ipdoctest but won't cause any Twisted problems.
359
360 Once you're happy that you didn't break Twisted, run::
361
362 $ iptest --with-ipdoctest [any options] [any submodules]
363
364 This MAY give a Twisted AlreadyCalledError exception at the end, but it will
365 also correctly load up all of the ipython-specific tests and doctests.
366
367 The above can be made easier with a trivial shell alias::
368
369 $ alias iptest2='iptest --with-ipdoctest'
370
371 So that you can run::
372
373 $ iptest ...
374 # Twisted happy
375 # iptest2 ...
376 # ignore possible Twisted error, this checks all the rest.
377
378
348 A few tips for writing tests
379 A few tips for writing tests
349 ----------------------------
380 ----------------------------
350
381
General Comments 0
You need to be logged in to leave comments. Login now