Show More
@@ -84,67 +84,6 b' def _run_ns_sync(self,arg_s,runner=None):' | |||||
84 | return get_ipython().magic_run_ori(arg_s, runner, finder) |
|
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 | def get_ipython(): |
|
87 | def get_ipython(): | |
149 | # This will get replaced by the real thing once we start IPython below |
|
88 | # This will get replaced by the real thing once we start IPython below | |
150 | return start_ipython() |
|
89 | return start_ipython() | |
@@ -189,7 +128,6 b' def start_ipython():' | |||||
189 |
|
128 | |||
190 | # Create and initialize our test-friendly IPython instance. |
|
129 | # Create and initialize our test-friendly IPython instance. | |
191 | shell = TerminalInteractiveShell.instance(config=config, |
|
130 | shell = TerminalInteractiveShell.instance(config=config, | |
192 | user_ns=ipnsdict(), |
|
|||
193 | ) |
|
131 | ) | |
194 |
|
132 | |||
195 | # A few more tweaks needed for playing nicely with doctests... |
|
133 | # A few more tweaks needed for playing nicely with doctests... |
@@ -19,7 +19,7 b' Limitations:' | |||||
19 | # Module imports |
|
19 | # Module imports | |
20 |
|
20 | |||
21 | # From the standard library |
|
21 | # From the standard library | |
22 | import __builtin__ |
|
22 | import __builtin__ as builtin_mod | |
23 | import commands |
|
23 | import commands | |
24 | import doctest |
|
24 | import doctest | |
25 | import inspect |
|
25 | import inspect | |
@@ -267,18 +267,18 b' class DocTestCase(doctests.DocTestCase):' | |||||
267 | def setUp(self): |
|
267 | def setUp(self): | |
268 | """Modified test setup that syncs with ipython namespace""" |
|
268 | """Modified test setup that syncs with ipython namespace""" | |
269 | #print "setUp test", self._dt_test.examples # dbg |
|
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 | # 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 = {} |
|
274 | self.user_ns_orig = {} | |
275 | self.user_ns_orig.update(_ip.user_ns) |
|
275 | self.user_ns_orig.update(_ip.user_ns) | |
276 | _ip.user_ns.update(self._dt_test.globs) |
|
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 | self._dt_test.globs = _ip.user_ns |
|
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 | super(DocTestCase, self).setUp() |
|
283 | super(DocTestCase, self).setUp() | |
284 |
|
284 | |||
@@ -286,13 +286,10 b' class DocTestCase(doctests.DocTestCase):' | |||||
286 |
|
286 | |||
287 | # Undo the test.globs reassignment we made, so that the parent class |
|
287 | # Undo the test.globs reassignment we made, so that the parent class | |
288 | # teardown doesn't destroy the ipython namespace |
|
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 | self._dt_test.globs = self._dt_test_globs_ori |
|
290 | self._dt_test.globs = self._dt_test_globs_ori | |
291 | _ip.user_ns.clear() |
|
291 | _ip.user_ns.clear() | |
292 | _ip.user_ns.update(self.user_ns_orig) |
|
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 | # XXX - fperez: I am not sure if this is truly a bug in nose 0.11, but |
|
294 | # XXX - fperez: I am not sure if this is truly a bug in nose 0.11, but | |
298 | # it does look like one to me: its tearDown method tries to run |
|
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