@@ -212,50 +212,51 @@ def __init__(self, watcher, loader):
212212self .watcher = watcher
213213self .loader = loader
214214
215- def load_module (self ,name ):
215+ def __getattr__ (self ,name ):
216+ if name == "create_module" and hasattr (self .loader ,name ):
217+ return self ._create_module
218+ if name == "load_module" and hasattr (self .loader ,name ):
219+ return self ._load_module
220+ return getattr (self .loader ,name )
221+
222+ def _create_module (self ,spec ):
223+ spec = self .loader .create_module (spec )
224+ if getattr (spec ,"origin" ,None )is not None and spec .origin != "builtin" :
225+ self .watcher .track_module (spec .origin )
226+ return spec
227+
228+ def _load_module (self ,name ):
216229module = self .loader .load_module (name )
217230if hasattr (module ,"__file__" ):
218231self .watcher .track_module (module .__file__ )
219232return module
220233
221234
222235class ImportFinder :
223- def __init__ (self ,watcher , old_meta_path ):
236+ def __init__ (self ,finder , watcher ):
224237self .watcher = watcher
225- self .old_meta_path = old_meta_path
226-
227- def find_distributions (self ,context ):
228- for finder in self .old_meta_path :
229- distribution_finder = getattr (finder ,"find_distributions" ,None )
230- if distribution_finder is not None :
231- loader = finder .find_distributions (context )
232- if loader is not None :
233- return loader
234-
235- return None
236-
237- def find_spec (self ,fullname ,path ,target = None ):
238- for finder in self .old_meta_path :
239- # Consider the finder only if it implements find_spec
240- if getattr (finder ,"find_spec" ,None )is None :
241- continue
242- # Attempt to find the spec
243- spec = finder .find_spec (fullname ,path ,target )
244- if spec is not None :
245- if getattr (spec ,"__loader__" ,None )is not None :
246- # Patch the loader to enable reloading
247- spec .__loader__ = ImportLoader (
248- self .watcher ,spec .__loader__
249- )
250- return spec
251-
252- def find_module (self ,fullname ,path = None ):
253- for finder in self .old_meta_path :
254- loader = finder .find_module (fullname ,path )
255- if loader is not None :
256- return ImportLoader (self .watcher ,loader )
257-
258- return None
238+ self .finder = finder
239+
240+ def __getattr__ (self ,name ):
241+ if name == "find_spec" and hasattr (self .finder ,name ):
242+ return self ._find_spec
243+ if name == "find_module" and hasattr (self .finder ,name ):
244+ return self ._find_module
245+ return getattr (self .finder ,name )
246+
247+ def _find_spec (self ,fullname ,path ,target = None ):
248+ # Attempt to find the spec
249+ spec = self .finder .find_spec (fullname ,path ,target )
250+ if spec is not None :
251+ if getattr (spec ,"__loader__" ,None )is not None :
252+ # Patch the loader to enable reloading
253+ spec .__loader__ = ImportLoader (self .watcher ,spec .__loader__ )
254+ return spec
255+
256+ def _find_module (self ,fullname ,path = None ):
257+ loader = self .finder .find_module (fullname ,path )
258+ if loader is not None :
259+ return ImportLoader (self .watcher ,loader )
259260
260261
261262class BaseRepl (BpythonRepl ):
@@ -531,7 +532,17 @@ def __enter__(self):
531532
532533self .orig_meta_path = sys .meta_path
533534if self .watcher :
534- sys .meta_path = [ImportFinder (self .watcher ,self .orig_meta_path )]
535+ meta_path = []
536+ for finder in sys .meta_path :
537+ # All elements get wrapped in ImportFinder instances execepted for instances of
538+ # _SixMetaPathImporter (from six). When importing six, it will check if the importer
539+ # is already part of sys.meta_path and will remove instances. We do not want to
540+ # break this feature (see also #874).
541+ if type (finder ).__name__ == "_SixMetaPathImporter" :
542+ meta_path .append (finder )
543+ else :
544+ meta_path .append (ImportFinder (finder ,self .watcher ))
545+ sys .meta_path = meta_path
535546
536547sitefix .monkeypatch_quit ()
537548return self