Skip to content
This repository

Fix deepreload on Python 3 #1625

Merged
merged 1 commit into from about 2 years ago

2 participants

Thomas Kluyver Fernando Perez
Thomas Kluyver
Collaborator

As described in #1622, it seems that imp.find_module() on Python 3.2 imports other modules, like io, while running. We don't want deepreload to catch those, so this restores the original import hook for find_module.

It's not terribly neat, but I don't currently see a better way of doing it. Ideally, we'd just delay installing our __import__ until after find_module had run, but our implementation of __import__ can itself call find_module, so this little dance seems to be necessary.

Closes gh-1622, and hopefully fixes a test failure we saw last night.

Fernando Perez
Owner

Great, thanks! Looks clean, merging now. And yet again, the Panda shines and caught this! I'm really happy that you set that up, we're reaping the benefits every day.

Fernando Perez fperez merged commit 0eb2ae9 into from April 18, 2012
Fernando Perez fperez closed this April 18, 2012
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Showing 1 unique commit by 1 author.

Apr 18, 2012
Thomas Kluyver Fix deepreload on Python 3.
Closes gh-1622
74f5db3
This page is out of date. Refresh to see the latest.

Showing 1 changed file with 24 additions and 6 deletions. Show diff stats Hide diff stats

  1. 30  IPython/lib/deepreload.py
30  IPython/lib/deepreload.py
@@ -25,12 +25,24 @@
25 25
 #*****************************************************************************
26 26
 
27 27
 import __builtin__
  28
+from contextlib import contextmanager
28 29
 import imp
29 30
 import sys
30 31
 
31 32
 from types import ModuleType
32 33
 from warnings import warn
33 34
 
  35
+original_import = __builtin__.__import__
  36
+
  37
+@contextmanager
  38
+def replace_import_hook(new_import):
  39
+    saved_import = __builtin__.__import__
  40
+    __builtin__.__import__ = new_import
  41
+    try:
  42
+        yield
  43
+    finally:
  44
+        __builtin__.__import__ = saved_import
  45
+
34 46
 def get_parent(globals, level):
35 47
     """
36 48
     parent, name = get_parent(globals, level)
@@ -167,7 +179,11 @@ def import_submodule(mod, subname, fullname):
167 179
             return None
168 180
 
169 181
         try:
170  
-            fp, filename, stuff  = imp.find_module(subname, path)
  182
+            # This appears to be necessary on Python 3, because imp.find_module()
  183
+            # tries to import standard libraries (like io) itself, and we don't
  184
+            # want them to be processed by our deep_import_hook.
  185
+            with replace_import_hook(original_import):
  186
+                fp, filename, stuff = imp.find_module(subname, path)
171 187
         except ImportError:
172 188
             return None
173 189
 
@@ -273,7 +289,11 @@ def deep_reload_hook(m):
273 289
         path = getattr(parent, "__path__", None)
274 290
 
275 291
     try:
276  
-        fp, filename, stuff  = imp.find_module(subname, path)
  292
+        # This appears to be necessary on Python 3, because imp.find_module()
  293
+        # tries to import standard libraries (like io) itself, and we don't
  294
+        # want them to be processed by our deep_import_hook.
  295
+        with replace_import_hook(original_import):
  296
+            fp, filename, stuff  = imp.find_module(subname, path)
277 297
     finally:
278 298
         modules_reloading.clear()
279 299
 
@@ -306,12 +326,10 @@ def reload(module, exclude=['sys', 'os.path', '__builtin__', '__main__']):
306 326
     global found_now
307 327
     for i in exclude:
308 328
         found_now[i] = 1
309  
-    original_import = __builtin__.__import__
310  
-    __builtin__.__import__ = deep_import_hook
311 329
     try:
312  
-        ret = deep_reload_hook(module)
  330
+        with replace_import_hook(deep_import_hook):
  331
+            ret = deep_reload_hook(module)
313 332
     finally:
314  
-        __builtin__.__import__ = original_import
315 333
         found_now = {}
316 334
     return ret
317 335
 
Commit_comment_tip

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.