Skip to content

Commit 3472072

Browse files
committed
Merge pull request ipython#1289 from takluyver/autoreload-py3
Make autoreload extension work on Python 3.
2 parents c8d17d8 + 2911f3e commit 3472072

File tree

2 files changed

+30
-18
lines changed

2 files changed

+30
-18
lines changed

IPython/extensions/autoreload.py

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,9 @@
108108
except NameError:
109109
from imp import reload
110110

111+
from IPython.utils import pyfile
112+
from IPython.utils.py3compat import PY3
113+
111114
def _get_compiled_ext():
112115
"""Official way to get the extension of compiled files (.pyc or .pyo)"""
113116
for ext, mode, typ in imp.get_suffixes():
@@ -198,14 +201,14 @@ def check(self, check_all=False):
198201

199202
if ext.lower() == '.py':
200203
ext = PY_COMPILED_EXT
201-
pyc_filename = path + PY_COMPILED_EXT
204+
pyc_filename = pyfile.cache_from_source(filename)
202205
py_filename = filename
203206
else:
204207
pyc_filename = filename
205-
py_filename = filename[:-1]
206-
207-
if ext != PY_COMPILED_EXT:
208-
continue
208+
try:
209+
py_filename = pyfile.source_from_cache(filename)
210+
except ValueError:
211+
continue
209212

210213
try:
211214
pymtime = os.stat(py_filename).st_mtime
@@ -229,10 +232,16 @@ def check(self, check_all=False):
229232
# superreload
230233
#------------------------------------------------------------------------------
231234

235+
if PY3:
236+
func_attrs = ['__code__', '__defaults__', '__doc__',
237+
'__closure__', '__globals__', '__dict__']
238+
else:
239+
func_attrs = ['func_code', 'func_defaults', 'func_doc',
240+
'func_closure', 'func_globals', 'func_dict']
241+
232242
def update_function(old, new):
233243
"""Upgrade the code object of a function"""
234-
for name in ['func_code', 'func_defaults', 'func_doc',
235-
'func_closure', 'func_globals', 'func_dict']:
244+
for name in func_attrs:
236245
try:
237246
setattr(old, name, getattr(new, name))
238247
except (AttributeError, TypeError):
@@ -271,18 +280,26 @@ def isinstance2(a, b, typ):
271280
return isinstance(a, typ) and isinstance(b, typ)
272281

273282
UPDATE_RULES = [
274-
(lambda a, b: isinstance2(a, b, types.ClassType),
275-
update_class),
276-
(lambda a, b: isinstance2(a, b, types.TypeType),
283+
(lambda a, b: isinstance2(a, b, type),
277284
update_class),
278285
(lambda a, b: isinstance2(a, b, types.FunctionType),
279286
update_function),
280287
(lambda a, b: isinstance2(a, b, property),
281288
update_property),
282-
(lambda a, b: isinstance2(a, b, types.MethodType),
283-
lambda a, b: update_function(a.im_func, b.im_func)),
284289
]
285290

291+
if PY3:
292+
UPDATE_RULES.extend([(lambda a, b: isinstance2(a, b, types.MethodType),
293+
lambda a, b: update_function(a.__func__, b.__func__)),
294+
])
295+
else:
296+
UPDATE_RULES.extend([(lambda a, b: isinstance2(a, b, types.ClassType),
297+
update_class),
298+
(lambda a, b: isinstance2(a, b, types.MethodType),
299+
lambda a, b: update_function(a.im_func, b.im_func)),
300+
])
301+
302+
286303
def update_generic(a, b):
287304
for type_check, update in UPDATE_RULES:
288305
if type_check(a, b):
@@ -317,7 +334,7 @@ def superreload(module, reload=reload, old_objects={}):
317334
except TypeError:
318335
# weakref doesn't work for all types;
319336
# create strong references for 'important' cases
320-
if isinstance(obj, types.ClassType):
337+
if not PY3 and isinstance(obj, types.ClassType):
321338
old_objects.setdefault(key, []).append(StrongRef(obj))
322339

323340
# reload module

IPython/extensions/tests/test_autoreload.py

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111

1212
from IPython.extensions.autoreload import AutoreloadInterface
1313
from IPython.core.hooks import TryNext
14-
from IPython.testing.decorators import knownfailureif
1514

1615
#-----------------------------------------------------------------------------
1716
# Test fixture
@@ -294,12 +293,8 @@ def check_module_contents():
294293
self.shell.run_code("pass") # trigger reload
295294
nt.assert_equal(mod.x, -99)
296295

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))
300296
def test_smoketest_aimport(self):
301297
self._check_smoketest(use_aimport=True)
302298

303-
@knownfailureif(sys.version_info >= (3,2))
304299
def test_smoketest_autoreload(self):
305300
self._check_smoketest(use_aimport=False)

0 commit comments

Comments
 (0)