Show More
@@ -108,6 +108,9 b' try:' | |||||
108 | except NameError: |
|
108 | except NameError: | |
109 | from imp import reload |
|
109 | from imp import reload | |
110 |
|
110 | |||
|
111 | from IPython.utils import pyfile | |||
|
112 | from IPython.utils.py3compat import PY3 | |||
|
113 | ||||
111 | def _get_compiled_ext(): |
|
114 | def _get_compiled_ext(): | |
112 | """Official way to get the extension of compiled files (.pyc or .pyo)""" |
|
115 | """Official way to get the extension of compiled files (.pyc or .pyo)""" | |
113 | for ext, mode, typ in imp.get_suffixes(): |
|
116 | for ext, mode, typ in imp.get_suffixes(): | |
@@ -198,11 +201,14 b' class ModuleReloader(object):' | |||||
198 |
|
201 | |||
199 | if ext.lower() == '.py': |
|
202 | if ext.lower() == '.py': | |
200 | ext = PY_COMPILED_EXT |
|
203 | ext = PY_COMPILED_EXT | |
201 |
pyc_filename = p |
|
204 | pyc_filename = pyfile.cache_from_source(filename) | |
202 | py_filename = filename |
|
205 | py_filename = filename | |
203 | else: |
|
206 | else: | |
204 | pyc_filename = filename |
|
207 | pyc_filename = filename | |
205 | py_filename = filename[:-1] |
|
208 | try: | |
|
209 | py_filename = pyfile.source_from_cache(filename) | |||
|
210 | except ValueError: | |||
|
211 | continue | |||
206 |
|
212 | |||
207 | if ext != PY_COMPILED_EXT: |
|
213 | if ext != PY_COMPILED_EXT: | |
208 | continue |
|
214 | continue | |
@@ -229,10 +235,16 b' class ModuleReloader(object):' | |||||
229 | # superreload |
|
235 | # superreload | |
230 | #------------------------------------------------------------------------------ |
|
236 | #------------------------------------------------------------------------------ | |
231 |
|
237 | |||
|
238 | if PY3: | |||
|
239 | func_attrs = ['__code__', '__defaults__', '__doc__', | |||
|
240 | '__closure__', '__globals__', '__dict__'] | |||
|
241 | else: | |||
|
242 | func_attrs = ['func_code', 'func_defaults', 'func_doc', | |||
|
243 | 'func_closure', 'func_globals', 'func_dict'] | |||
|
244 | ||||
232 | def update_function(old, new): |
|
245 | def update_function(old, new): | |
233 | """Upgrade the code object of a function""" |
|
246 | """Upgrade the code object of a function""" | |
234 | for name in ['func_code', 'func_defaults', 'func_doc', |
|
247 | for name in func_attrs: | |
235 | 'func_closure', 'func_globals', 'func_dict']: |
|
|||
236 | try: |
|
248 | try: | |
237 | setattr(old, name, getattr(new, name)) |
|
249 | setattr(old, name, getattr(new, name)) | |
238 | except (AttributeError, TypeError): |
|
250 | except (AttributeError, TypeError): | |
@@ -271,18 +283,26 b' def isinstance2(a, b, typ):' | |||||
271 | return isinstance(a, typ) and isinstance(b, typ) |
|
283 | return isinstance(a, typ) and isinstance(b, typ) | |
272 |
|
284 | |||
273 | UPDATE_RULES = [ |
|
285 | UPDATE_RULES = [ | |
274 |
(lambda a, b: isinstance2(a, b, type |
|
286 | (lambda a, b: isinstance2(a, b, type), | |
275 | update_class), |
|
|||
276 | (lambda a, b: isinstance2(a, b, types.TypeType), |
|
|||
277 | update_class), |
|
287 | update_class), | |
278 | (lambda a, b: isinstance2(a, b, types.FunctionType), |
|
288 | (lambda a, b: isinstance2(a, b, types.FunctionType), | |
279 | update_function), |
|
289 | update_function), | |
280 | (lambda a, b: isinstance2(a, b, property), |
|
290 | (lambda a, b: isinstance2(a, b, property), | |
281 | update_property), |
|
291 | update_property), | |
282 | (lambda a, b: isinstance2(a, b, types.MethodType), |
|
|||
283 | lambda a, b: update_function(a.im_func, b.im_func)), |
|
|||
284 | ] |
|
292 | ] | |
285 |
|
293 | |||
|
294 | if PY3: | |||
|
295 | UPDATE_RULES.extend([(lambda a, b: isinstance2(a, b, types.MethodType), | |||
|
296 | lambda a, b: update_function(a.__func__, b.__func__)), | |||
|
297 | ]) | |||
|
298 | else: | |||
|
299 | UPDATE_RULES.extend([(lambda a, b: isinstance2(a, b, types.ClassType), | |||
|
300 | update_class), | |||
|
301 | (lambda a, b: isinstance2(a, b, types.MethodType), | |||
|
302 | lambda a, b: update_function(a.im_func, b.im_func)), | |||
|
303 | ]) | |||
|
304 | ||||
|
305 | ||||
286 | def update_generic(a, b): |
|
306 | def update_generic(a, b): | |
287 | for type_check, update in UPDATE_RULES: |
|
307 | for type_check, update in UPDATE_RULES: | |
288 | if type_check(a, b): |
|
308 | if type_check(a, b): | |
@@ -317,7 +337,7 b' def superreload(module, reload=reload, old_objects={}):' | |||||
317 | except TypeError: |
|
337 | except TypeError: | |
318 | # weakref doesn't work for all types; |
|
338 | # weakref doesn't work for all types; | |
319 | # create strong references for 'important' cases |
|
339 | # create strong references for 'important' cases | |
320 | if isinstance(obj, types.ClassType): |
|
340 | if not PY3 and isinstance(obj, types.ClassType): | |
321 | old_objects.setdefault(key, []).append(StrongRef(obj)) |
|
341 | old_objects.setdefault(key, []).append(StrongRef(obj)) | |
322 |
|
342 | |||
323 | # reload module |
|
343 | # reload module |
@@ -294,12 +294,8 b' x = -99' | |||||
294 | self.shell.run_code("pass") # trigger reload |
|
294 | self.shell.run_code("pass") # trigger reload | |
295 | nt.assert_equal(mod.x, -99) |
|
295 | nt.assert_equal(mod.x, -99) | |
296 |
|
296 | |||
297 | # The autoreload extension needs to be updated for Python 3.2, as .pyc files |
|
|||
298 | # are stored in a different location. See gh-846. |
|
|||
299 | @knownfailureif(sys.version_info >= (3,2)) |
|
|||
300 | def test_smoketest_aimport(self): |
|
297 | def test_smoketest_aimport(self): | |
301 | self._check_smoketest(use_aimport=True) |
|
298 | self._check_smoketest(use_aimport=True) | |
302 |
|
299 | |||
303 | @knownfailureif(sys.version_info >= (3,2)) |
|
|||
304 | def test_smoketest_autoreload(self): |
|
300 | def test_smoketest_autoreload(self): | |
305 | self._check_smoketest(use_aimport=False) |
|
301 | self._check_smoketest(use_aimport=False) |
General Comments 0
You need to be logged in to leave comments.
Login now