##// END OF EJS Templates
Make autoreload extension work on Python 3....
Thomas Kluyver -
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 = path + PY_COMPILED_EXT
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, types.ClassType),
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