Show More
@@ -84,67 +84,6 b' def _run_ns_sync(self,arg_s,runner=None):' | |||
|
84 | 84 | return get_ipython().magic_run_ori(arg_s, runner, finder) |
|
85 | 85 | |
|
86 | 86 | |
|
87 | class ipnsdict(dict): | |
|
88 | """A special subclass of dict for use as an IPython namespace in doctests. | |
|
89 | ||
|
90 | This subclass adds a simple checkpointing capability so that when testing | |
|
91 | machinery clears it (we use it as the test execution context), it doesn't | |
|
92 | get completely destroyed. | |
|
93 | ||
|
94 | In addition, it can handle the presence of the '_' key in a special manner, | |
|
95 | which is needed because of how Python's doctest machinery operates with | |
|
96 | '_'. See constructor and :meth:`update` for details. | |
|
97 | """ | |
|
98 | ||
|
99 | def __init__(self,*a): | |
|
100 | dict.__init__(self,*a) | |
|
101 | self._savedict = {} | |
|
102 | # If this flag is True, the .update() method will unconditionally | |
|
103 | # remove a key named '_'. This is so that such a dict can be used as a | |
|
104 | # namespace in doctests that call '_'. | |
|
105 | self.protect_underscore = False | |
|
106 | ||
|
107 | def clear(self): | |
|
108 | dict.clear(self) | |
|
109 | self.update(self._savedict) | |
|
110 | ||
|
111 | def _checkpoint(self): | |
|
112 | self._savedict.clear() | |
|
113 | self._savedict.update(self) | |
|
114 | ||
|
115 | def update(self,other): | |
|
116 | self._checkpoint() | |
|
117 | dict.update(self,other) | |
|
118 | ||
|
119 | if self.protect_underscore: | |
|
120 | # If '_' is in the namespace, python won't set it when executing | |
|
121 | # code *in doctests*, and we have multiple doctests that use '_'. | |
|
122 | # So we ensure that the namespace is always 'clean' of it before | |
|
123 | # it's used for test code execution. | |
|
124 | # This flag is only turned on by the doctest machinery, so that | |
|
125 | # normal test code can assume the _ key is updated like any other | |
|
126 | # key and can test for its presence after cell executions. | |
|
127 | self.pop('_', None) | |
|
128 | ||
|
129 | # The builtins namespace must *always* be the real __builtin__ module, | |
|
130 | # else weird stuff happens. The main ipython code does have provisions | |
|
131 | # to ensure this after %run, but since in this class we do some | |
|
132 | # aggressive low-level cleaning of the execution namespace, we need to | |
|
133 | # correct for that ourselves, to ensure consitency with the 'real' | |
|
134 | # ipython. | |
|
135 | self['__builtins__'] = builtin_mod | |
|
136 | ||
|
137 | def __delitem__(self, key): | |
|
138 | """Part of the test suite checks that we can release all | |
|
139 | references to an object. So we need to make sure that we're not | |
|
140 | keeping a reference in _savedict.""" | |
|
141 | dict.__delitem__(self, key) | |
|
142 | try: | |
|
143 | del self._savedict[key] | |
|
144 | except KeyError: | |
|
145 | pass | |
|
146 | ||
|
147 | ||
|
148 | 87 | def get_ipython(): |
|
149 | 88 | # This will get replaced by the real thing once we start IPython below |
|
150 | 89 | return start_ipython() |
@@ -189,7 +128,6 b' def start_ipython():' | |||
|
189 | 128 | |
|
190 | 129 | # Create and initialize our test-friendly IPython instance. |
|
191 | 130 | shell = TerminalInteractiveShell.instance(config=config, |
|
192 | user_ns=ipnsdict(), | |
|
193 | 131 | ) |
|
194 | 132 | |
|
195 | 133 | # A few more tweaks needed for playing nicely with doctests... |
@@ -19,7 +19,7 b' Limitations:' | |||
|
19 | 19 | # Module imports |
|
20 | 20 | |
|
21 | 21 | # From the standard library |
|
22 | import __builtin__ | |
|
22 | import __builtin__ as builtin_mod | |
|
23 | 23 | import commands |
|
24 | 24 | import doctest |
|
25 | 25 | import inspect |
@@ -267,18 +267,18 b' class DocTestCase(doctests.DocTestCase):' | |||
|
267 | 267 | def setUp(self): |
|
268 | 268 | """Modified test setup that syncs with ipython namespace""" |
|
269 | 269 | #print "setUp test", self._dt_test.examples # dbg |
|
270 | if isinstance(self._dt_test.examples[0],IPExample): | |
|
270 | if isinstance(self._dt_test.examples[0], IPExample): | |
|
271 | 271 | # for IPython examples *only*, we swap the globals with the ipython |
|
272 | 272 | # namespace, after updating it with the globals (which doctest |
|
273 | 273 | # fills with the necessary info from the module being tested). |
|
274 | 274 | self.user_ns_orig = {} |
|
275 | 275 | self.user_ns_orig.update(_ip.user_ns) |
|
276 | 276 | _ip.user_ns.update(self._dt_test.globs) |
|
277 | # We must remove the _ key in the namespace, so that Python's | |
|
278 | # doctest code sets it naturally | |
|
279 | _ip.user_ns.pop('_', None) | |
|
280 | _ip.user_ns['__builtins__'] = builtin_mod | |
|
277 | 281 | self._dt_test.globs = _ip.user_ns |
|
278 | # IPython must protect the _ key in the namespace (it can't exist) | |
|
279 | # so that Python's doctest code sets it naturally, so we enable | |
|
280 | # this feature of our testing namespace. | |
|
281 | _ip.user_ns.protect_underscore = True | |
|
282 | 282 | |
|
283 | 283 | super(DocTestCase, self).setUp() |
|
284 | 284 | |
@@ -286,13 +286,10 b' class DocTestCase(doctests.DocTestCase):' | |||
|
286 | 286 | |
|
287 | 287 | # Undo the test.globs reassignment we made, so that the parent class |
|
288 | 288 | # teardown doesn't destroy the ipython namespace |
|
289 | if isinstance(self._dt_test.examples[0],IPExample): | |
|
289 | if isinstance(self._dt_test.examples[0], IPExample): | |
|
290 | 290 | self._dt_test.globs = self._dt_test_globs_ori |
|
291 | 291 | _ip.user_ns.clear() |
|
292 | 292 | _ip.user_ns.update(self.user_ns_orig) |
|
293 | # Restore the behavior of the '_' key in the user namespace to | |
|
294 | # normal after each doctest, so that unittests behave normally | |
|
295 | _ip.user_ns.protect_underscore = False | |
|
296 | 293 | |
|
297 | 294 | # XXX - fperez: I am not sure if this is truly a bug in nose 0.11, but |
|
298 | 295 | # it does look like one to me: its tearDown method tries to run |
General Comments 0
You need to be logged in to leave comments.
Login now