1"""ImportSpy 2 3Keeps track of modules not imported directly by Webware for Python. 4 5This module helps save the filepath of every module which is imported. 6This is used by the `AutoReloadingAppServer` (see doc strings for more 7information) to restart the server if any source files change. 8 9Other than keeping track of the filepaths, the behaviour of this module 10loader is identical to Python's default behaviour. 11 12If the system supports FAM (file alteration monitor) and python-fam is 13installed, then the need for reloading can be monitored very effectively 14with the use of ImportSpy. Otherwise, ImportSpy will not have much benefit. 15 16Note that ImportSpy is based on the new import hooks of Python described 17in PEP 302. It is possible to suppress the use of ImportSpy by setting 18`UseImportSpy` in AppServer.config to False. 19""" 20 21from os.path import isdir 22from sys import path_hooks, path_importer_cache 23 24 25class ImportSpy(object): 26 """New style import tracker.""" 27 28 _imp = None 29 30 def __init__(self, path=None): 31 """Create importer.""" 32 assert self._imp 33 if path and isdir(path): 34 self.path = path 35 else: 36 raise ImportError 37 38 def find_module(self, fullname): 39 """Replaces imp.find_module.""" 40 try: 41 self.file, self.filename, self.info = self._imp.find_module( 42 fullname.rsplit('.', 1)[-1], [self.path]) 43 except ImportError: 44 pass 45 else: 46 return self 47 48 def load_module(self, fullname): 49 """Replaces imp.load_module.""" 50 mod = self._imp.load_module(fullname, self.file, self.filename, self.info) 51 if mod: 52 mod.__loader__ = self 53 return mod 54 55 56def activate(impManager): 57 """Activate ImportSpy.""" 58 assert not ImportSpy._imp 59 ImportSpy._imp = impManager 60 path_hooks.append(ImportSpy) 61 path_importer_cache.clear() 62 impManager.recordModules() 63