def _import(name, globals=None, locals=None, fromlist=None, level=-1): # Trackourcurrentparentmodule. Thisisusedtofindourcurrent # placeinthedependencygraph. global _parent parent = _parent _parent = name
# Performtheactualimportusingthebaseimportfunction. m = _baseimport(name, globals, locals, fromlist, level)
# Ifwehaveaparent (i.e. thisisanestedimport) andthisisa # reloadable (source-based) module, we append ourself to our parent's # dependencylist. if parent is not None and hasattr(m, '__file__'): l = _dependencies.setdefault(parent, <input type=checkbox>) l.append(m)
# Clear this module's list of dependencies. Some import statements # may have been removed. We'll rebuild the dependency list as part # ofthereloadoperationbelow. try: del _dependencies[name] exceptKeyError: pass
# Because we're triggering a reload and not an import, the module # itself won't run through our _import hook. In order for this # module's dependencies (which will pass through the _import hook) to # beassociatedwiththismodule, weneedtosetourparentpointer # beforehand. global _parent _parent = name
# If the module has a __reload__(d) function, we'll call it with a # copy of the original module's dictionary after it's been reloaded. callback = getattr(m, '__reload__', None) ifcallbackisnotNone: d = _deepcopy_module_dict(m) imp.reload(m) callback(d) else: imp.reload(m) </code>
def _deepcopy_module_dict(m): """Make a deep copy of a module's dictionary.""" importcopy
# We can't deepcopy() everything in the module's dictionary because # some items, such as '__builtins__', aren't deepcopy()-able. # Toworkaroundthat, westartbymakingashallowcopyofthe # dictionary, givingusawaytoremovekeysbeforeperformingthe # deepcopy. d = vars(m).copy() deld['__builtins__'] returncopy.deepcopy(d) </code>
def _scan(self): # We're only interested in file-based modules (not C extensions). modules = [m.__file__ for m in sys.modules.values() if '__file__' in m.__dict__]
forfilenameinmodules: # We're only interested in the source .py files. if filename.endswith('.pyc') or filename.endswith('.pyo'): filename = filename[:-1]
# stat() thefile. Thismightfailifthemoduleispart # ofabundle (.egg). Wesimplyskipthosemodulesbecause # they're not really reloadable anyway. try: stat = os.stat(filename) exceptOSError: continue
# Check if we've seen this file before. We don't need to do # anythingfornewfiles. iffilenameinself.mtimes: # If this file's mtime has changed, queue it for reload. if mtime != self.mtimes[filename]: self.queue.put(filename)
# Record this filename's current mtime. self.mtimes[filename] = mtime </code>