Lichen

importer.py

641:c71722209a3d
2017-03-01 Paul Boddie Added support for preserving attribute and parameter locations, avoiding misidentification issues in existing, preserved object code.
     1 #!/usr/bin/env python     2      3 """     4 Import logic.     5      6 Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013,     7               2014, 2015, 2016, 2017 Paul Boddie <paul@boddie.org.uk>     8      9 This program is free software; you can redistribute it and/or modify it under    10 the terms of the GNU General Public License as published by the Free Software    11 Foundation; either version 3 of the License, or (at your option) any later    12 version.    13     14 This program is distributed in the hope that it will be useful, but WITHOUT    15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS    16 FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more    17 details.    18     19 You should have received a copy of the GNU General Public License along with    20 this program.  If not, see <http://www.gnu.org/licenses/>.    21 """    22     23 from errors import ProgramError    24 from os.path import exists, extsep, getmtime, join    25 from os import listdir, makedirs, remove    26 from common import init_item, readfile, writefile    27 from modules import CachedModule    28 from referencing import Reference    29 import inspector    30 import sys    31     32 class Importer:    33     34     "An import machine, searching for and loading modules."    35     36     special_attributes = ("__args__", "__file__", "__fn__", "__name__", "__parent__")    37     38     def __init__(self, path, cache=None, verbose=False, warnings=None):    39     40         """    41         Initialise the importer with the given search 'path' - a list of    42         directories to search for Python modules.    43     44         The optional 'cache' should be the name of a directory used to store    45         cached module information.    46     47         The optional 'verbose' parameter causes output concerning the activities    48         of the object to be produced if set to a true value (not the default).    49     50         The optional 'warnings' parameter may indicate classes of warnings to be    51         produced.    52         """    53     54         self.path = path    55         self.cache = cache    56         self.verbose = verbose    57         self.warnings = warnings    58     59         # Module importing queue, required modules, removed modules and active    60         # modules in the final program.    61     62         self.to_import = set()    63         self.required = set(["__main__"])    64         self.removed = {}    65         self.modules = {}    66     67         # Module relationships and invalidated cached modules.    68     69         self.accessing_modules = {}    70         self.invalidated = set()    71     72         # Object relationships and dependencies.    73     74         self.depends = {}    75         self.module_depends = {}    76     77         # Basic program information.    78     79         self.objects = {}    80         self.classes = {}    81         self.function_parameters = {}    82         self.function_defaults = {}    83         self.function_locals = {}    84         self.function_targets = {}    85         self.function_arguments = {}    86     87         # Unresolved names.    88     89         self.missing = set()    90     91         # Derived information.    92     93         self.subclasses = {}    94     95         # Attributes of different object types.    96     97         self.all_class_attrs = {}    98         self.all_instance_attrs = {}    99         self.all_instance_attr_constants = {}   100         self.all_combined_attrs = {}   101         self.all_module_attrs = {}   102         self.all_shadowed_attrs = {}   103    104         # References to external names and aliases within program units.   105    106         self.all_name_references = {}   107         self.all_initialised_names = {}   108         self.all_aliased_names = {}   109    110         # General attribute accesses.   111    112         self.all_attr_accesses = {}   113         self.all_const_accesses = {}   114         self.all_attr_access_modifiers = {}   115    116         # Constant literals and values.   117    118         self.all_constants = {}   119         self.all_constant_values = {}   120    121         self.make_cache()   122    123     def give_warning(self, name):   124    125         "Return whether the indicated warning 'name' should be given."   126    127         return self.warnings and (name in self.warnings or "all" in self.warnings)   128    129     def make_cache(self):   130    131         "Make a cache directory if it does not already exist."   132    133         if self.cache and not exists(self.cache):   134             makedirs(self.cache)   135    136     def check_cache(self, details):   137    138         """   139         Check whether the cache applies for the given 'details', invalidating it   140         if it does not.   141         """   142    143         recorded_details = self.get_cache_details()   144    145         if recorded_details != details:   146             self.remove_cache()   147    148         writefile(self.get_cache_details_filename(), details)   149    150     def get_cache_details_filename(self):   151    152         "Return the filename for the cache details."   153    154         return join(self.cache, "$details")   155    156     def get_cache_details(self):   157    158         "Return details of the cache."   159    160         details_filename = self.get_cache_details_filename()   161    162         if not exists(details_filename):   163             return None   164         else:   165             return readfile(details_filename)   166    167     def remove_cache(self):   168    169         "Remove the contents of the cache."   170    171         for filename in listdir(self.cache):   172             remove(join(self.cache, filename))   173    174     def to_cache(self):   175    176         "Write modules to the cache."   177    178         if self.cache:   179             for module_name, module in self.modules.items():   180                 module.to_cache(join(self.cache, module_name))   181    182     # Object retrieval and storage.   183    184     def get_object(self, name):   185    186         """   187         Return a reference for the given 'name' or None if no such object   188         exists.   189         """   190    191         return self.objects.get(name)   192    193     def set_object(self, name, value=None):   194    195         "Set the object with the given 'name' and the given 'value'."   196    197         if isinstance(value, Reference):   198             ref = value.alias(name)   199         else:   200             ref = Reference(value, name)   201    202         self.objects[name] = ref   203    204     # Identification of both stored object names and name references.   205    206     def identify(self, name):   207    208         "Identify 'name' using stored object and external name records."   209    210         return self.objects.get(name) or self.all_name_references.get(name)   211    212     # Indirect object retrieval.   213    214     def get_attributes(self, ref, attrname):   215    216         """   217         Return attributes provided by 'ref' for 'attrname'. Class attributes   218         may be provided by instances.   219         """   220    221         kind = ref.get_kind()   222         if kind == "<class>":   223             ref = self.get_class_attribute(ref.get_origin(), attrname)   224             return ref and set([ref]) or set()   225         elif kind == "<instance>":   226             return self.get_combined_attributes(ref.get_origin(), attrname)   227         elif kind == "<module>":   228             ref = self.get_module_attribute(ref.get_origin(), attrname)   229             return ref and set([ref]) or set()   230         else:   231             return set()   232    233     def get_class_attribute(self, object_type, attrname):   234    235         "Return from 'object_type' the details of class attribute 'attrname'."   236    237         attrs = self.all_class_attrs.get(object_type)   238         attr = attrs and attrs.get(attrname)   239         return attr and self.get_object(attr)   240    241     def get_instance_attributes(self, object_type, attrname):   242    243         """   244         Return from 'object_type' the details of instance attribute 'attrname'.   245         """   246    247         consts = self.all_instance_attr_constants.get(object_type)   248         attrs = set()   249         for attr in self.all_instance_attrs[object_type].get(attrname, []):   250             attrs.add(consts and consts.get(attrname) or Reference("<var>", attr))   251         return attrs   252    253     def get_combined_attributes(self, object_type, attrname):   254    255         """   256         Return from 'object_type' the details of class or instance attribute   257         'attrname'.   258         """   259    260         ref = self.get_class_attribute(object_type, attrname)   261         refs = ref and set([ref]) or set()   262         refs.update(self.get_instance_attributes(object_type, attrname))   263         return refs   264    265     def get_module_attribute(self, object_type, attrname):   266    267         "Return from 'object_type' the details of module attribute 'attrname'."   268    269         if attrname in self.all_module_attrs[object_type]:   270             return self.get_object("%s.%s" % (object_type, attrname))   271         else:   272             return None   273    274     # Convenience methods for deducing which kind of object provided an   275     # attribute.   276    277     def get_attribute_provider(self, ref, attrname):   278    279         """   280         Return the kind of provider of the attribute accessed via 'ref' using   281         'attrname'.   282         """   283    284         kind = ref.get_kind()   285    286         if kind in ["<class>", "<module>"]:   287             return kind   288         else:   289             return self.get_instance_attribute_provider(ref.get_origin(), attrname)   290    291     def get_instance_attribute_provider(self, object_type, attrname):   292    293         """   294         Return the kind of provider of the attribute accessed via an instance of   295         'object_type' using 'attrname'.   296         """   297    298         if self.get_class_attribute(object_type, attrname):   299             return "<class>"   300         else:   301             return "<instance>"   302    303     # Module management.   304    305     def queue_module(self, name, accessor, required=False):   306    307         """   308         Queue the module with the given 'name' for import from the given   309         'accessor' module. If 'required' is true (it is false by default), the   310         module will be required in the final program.   311         """   312    313         if not self.modules.has_key(name):   314             self.to_import.add(name)   315    316         if required:   317             self.required.add(name)   318    319         init_item(self.accessing_modules, name, set)   320         self.accessing_modules[name].add(accessor.name)   321    322     def get_modules(self):   323    324         "Return all modules known to the importer."   325    326         return self.modules.values()   327    328     def get_module(self, name):   329    330         "Return the module with the given 'name'."   331    332         if not self.modules.has_key(name):   333             return None   334    335         return self.modules[name]   336    337     # Program operations.   338    339     def initialise(self, filename, reset=False):   340    341         """   342         Initialise a program whose main module is 'filename', resetting the   343         cache if 'reset' is true. Return the main module.   344         """   345    346         if reset:   347             self.remove_cache()   348         self.check_cache(filename)   349    350         # Load the program itself.   351    352         m = self.load_from_file(filename)   353    354         # Load any queued modules.   355    356         while self.to_import:   357             for name in list(self.to_import): # avoid mutation issue   358                 self.load(name)   359    360         # Resolve dependencies between modules.   361    362         self.resolve()   363    364         # Record the type of all classes.   365    366         self.type_ref = self.get_object("__builtins__.type")   367    368         # Resolve dependencies within the program.   369    370         for module in self.modules.values():   371             module.complete()   372    373         # Remove unneeded modules.   374    375         all_modules = self.modules.items()   376    377         for name, module in all_modules:   378             if name not in self.required:   379                 module.unpropagate()   380                 del self.modules[name]   381                 self.removed[name] = module   382    383         # Collect redundant objects.   384    385         for module in self.removed.values():   386             module.collect()   387    388         # Assert module objects where aliases have been removed.   389    390         for name in self.required:   391             if not self.objects.has_key(name):   392                 self.objects[name] = Reference("<module>", name)   393    394         return m   395    396     def finalise(self):   397    398         """   399         Finalise the inspected program, returning whether the program could be   400         finalised.   401         """   402    403         self.finalise_classes()   404         self.add_init_dependencies()   405         self.to_cache()   406    407         if self.missing:   408             return False   409    410         self.set_class_types()   411         self.define_instantiators()   412         self.collect_constants()   413    414         return True   415    416     # Supporting operations.   417    418     def resolve(self):   419    420         "Resolve dependencies between modules."   421    422         self.waiting = {}   423    424         for module in self.modules.values():   425    426             # Resolve all deferred references in each module.   427    428             original_deferred = []   429    430             for ref in module.deferred:   431    432                 # Retain original references for caching.   433    434                 original_deferred.append(ref.copy())   435    436                 # Update references throughout the program.   437    438                 found = self.find_dependency(ref)   439                 if not found:   440                     self.missing.add((module.name, ref.get_origin()))   441    442                 # Record the resolved names and identify required modules.   443    444                 else:   445                     # Find the providing module of this reference.   446                     # Where definitive details of the origin cannot be found,   447                     # identify the provider using the deferred reference.   448                     # NOTE: This may need to test for static origins.   449    450                     provider = self.get_module_provider(found.unresolved() and ref or found)   451                     ref.mutate(found)   452    453                     # Record any external dependency.   454    455                     if provider and provider != module.name:   456    457                         # Handle built-in modules accidentally referenced by   458                         # names.   459    460                         if provider == "__builtins__" and found.has_kind("<module>"):   461                             raise ProgramError("Name %s, used by %s, refers to module %s." %   462                                                (found.leaf(), module.name, found.get_origin()))   463    464                         # Record the provider dependency.   465    466                         module.required.add(provider)   467                         self.accessing_modules[provider].add(module.name)   468    469                         # Postpone any inclusion of the provider until this   470                         # module becomes required.   471    472                         if module.name not in self.required:   473                             init_item(self.waiting, module.name, set)   474                             self.waiting[module.name].add(provider)   475                             if self.verbose:   476                                 print >>sys.stderr, "Noting", provider, "for", ref, "from", module.name   477    478                         # Make this module required in the accessing module.   479    480                         elif provider not in self.required:   481                             self.required.add(provider)   482                             if self.verbose:   483                                 print >>sys.stderr, "Requiring", provider, "for", ref, "from", module.name   484    485                         # Record a module ordering dependency.   486    487                         if not found.static() or self.is_dynamic_class(found) or self.is_dynamic_callable(found):   488                             self.add_module_dependency(module.name, provider)   489    490             # Restore the original references so that they may be read back in   491             # and produce the same results.   492    493             module.deferred = original_deferred   494    495         # Check modules again to see if they are now required and should now   496         # cause the inclusion of other modules providing objects to the program.   497    498         for module_name in self.waiting.keys():   499             self.require_providers(module_name)   500    501         self.add_special_dependencies()   502         self.add_module_dependencies()   503    504     def require_providers(self, module_name):   505    506         """   507         Test if 'module_name' is itself required and, if so, require modules   508         containing objects provided to the module.   509         """   510    511         if module_name in self.required and self.waiting.has_key(module_name):   512             for provider in self.waiting[module_name]:   513                 if provider not in self.required:   514                     self.required.add(provider)   515                     if self.verbose:   516                         print >>sys.stderr, "Requiring", provider   517                     self.require_providers(provider)   518    519     def add_special_dependencies(self):   520    521         "Add dependencies due to the use of special names in namespaces."   522    523         for module in self.modules.values():   524             for ref, paths in module.special.values():   525                 for path in paths:   526                     self.add_dependency(path, ref.get_origin())   527    528     def add_init_dependencies(self):   529    530         "Add dependencies related to object initialisation."   531    532         for name in self.classes.keys():   533             if self.is_dynamic_class(name):   534    535                 # Make subclasses depend on any class with non-static   536                 # attributes, plus its module for the initialisation.   537    538                 for subclass in self.subclasses[name]:   539                     ref = Reference("<class>", subclass)   540                     self.add_dependency(subclass, name)   541                     self.add_dependency(subclass, self.get_module_provider(ref))   542    543                 # Also make the class dependent on its module for   544                 # initialisation.   545    546                 ref = Reference("<class>", name)   547                 self.add_dependency(name, self.get_module_provider(ref))   548    549         for name in self.function_defaults.keys():   550             if self.is_dynamic_callable(name):   551    552                 # Make functions with defaults requiring initialisation depend   553                 # on the parent scope, if a function, or the module scope.   554    555                 ref = Reference("<function>", name)   556                 parent_ref = self.get_object(ref.parent())   557    558                 # Function no longer present in the program.   559    560                 if not parent_ref:   561                     continue   562    563                 if parent_ref.has_kind("<class>"):   564                     parent = self.get_module_provider(parent_ref)   565                 else:   566                     parent = parent_ref.get_origin()   567    568                 self.add_dependency(name, parent)   569    570     def add_module_dependencies(self):   571    572         "Record module-based dependencies."   573    574         for module_name, providers in self.module_depends.items():   575             if self.modules.has_key(module_name):   576                 for provider in providers:   577                     if self.modules.has_key(provider):   578                         self.add_dependency(module_name, provider)   579    580     def add_dependency(self, path, origin):   581    582         "Add dependency details for 'path' involving 'origin'."   583    584         if origin and not origin.startswith("%s." % path):   585             init_item(self.depends, path, set)   586             self.depends[path].add(origin)   587    588     def add_module_dependency(self, module_name, provider):   589    590         "Add dependency details for 'module_name' involving 'provider'."   591    592         if provider:   593             init_item(self.module_depends, module_name, set)   594             self.module_depends[module_name].add(provider)   595    596     def condense_dependencies(self):   597    598         """   599         Condense the dependencies by removing all functions that do not need   600         initialisation.   601         """   602    603         d = {}   604         for path, depends in self.depends.items():   605             d[path] = {}   606             d[path] = self.condense_dependency_entry(depends, d)   607    608         self.depends = {}   609    610         for path, depends in d.items():   611             if depends:   612                 self.depends[path] = depends   613    614     def condense_dependency_entry(self, depends, d):   615         l = set()   616         for depend in depends:   617             if self.modules.has_key(depend) or self.classes.has_key(depend) or \   618                self.is_dynamic_callable(depend):   619    620                 l.add(depend)   621             else:   622                 deps = d.get(depend)   623                 if deps:   624                     l.update(self.condense_dependency_entry(deps, d))   625         return l   626    627     def is_dynamic(self, ref):   628         return not ref or not ref.static() and not ref.is_constant_alias() and not ref.is_predefined_value()   629    630     def is_dynamic_class(self, name):   631    632         """   633         Return whether 'name' refers to a class with members that must be   634         initialised dynamically.   635         """   636    637         attrs = self.all_class_attrs.get(name)   638    639         if not attrs:   640             return False   641    642         for attrname, attr in attrs.items():   643             if attrname in self.special_attributes:   644                 continue   645             ref = attr and self.get_object(attr)   646             if self.is_dynamic(ref):   647                 return True   648    649         return False   650    651     def is_dynamic_callable(self, name):   652    653         """   654         Return whether 'name' refers to a callable employing defaults that may   655         need initialising before the callable can be used.   656         """   657    658         # Find any defaults for the function or method.   659    660         defaults = self.function_defaults.get(name)   661         if not defaults:   662             return False   663    664         # Identify non-constant defaults.   665    666         for name, ref in defaults:   667             if self.is_dynamic(ref):   668                 return True   669    670         return False   671    672     def order_objects(self):   673    674         "Produce an object initialisation ordering."   675    676         self.condense_dependencies()   677    678         # Record the number of modules using or depending on each module.   679    680         usage = {}   681    682         # Record path-based dependencies.   683    684         for path in self.depends.keys():   685             usage[path] = set()   686    687         for path, depends in self.depends.items():   688             for origin in depends:   689                 init_item(usage, origin, set)   690                 usage[origin].add(path)   691    692         # Produce an ordering by obtaining exposed modules (required by modules   693         # already processed) and putting them at the start of the list.   694    695         ordered = []   696    697         while usage:   698             have_next = False   699    700             for path, n in usage.items():   701                 if not n:   702                     ordered.insert(0, path)   703                     depends = self.depends.get(path)   704    705                     # Reduce usage of the referenced objects.   706    707                     if depends:   708                         for origin in depends:   709                             usage[origin].remove(path)   710    711                     del usage[path]   712                     have_next = True   713    714             if not have_next:   715                 raise ProgramError("Modules with unresolvable dependencies exist: %s" % ", ".join(usage.keys()))   716    717         if "__main__" in ordered:   718             ordered.remove("__main__")   719    720         ordered.append("__main__")   721         return ordered   722    723     def order_modules(self):   724    725         "Produce a module initialisation ordering."   726    727         ordered = self.order_objects()   728         filtered = []   729    730         for module_name in self.modules.keys():   731             if module_name not in ordered:   732                 filtered.append(module_name)   733    734         for path in ordered:   735             if self.modules.has_key(path):   736                 filtered.append(path)   737    738         return filtered   739    740     def find_dependency(self, ref):   741    742         "Find the ultimate dependency for 'ref'."   743    744         found = set()   745         while ref and ref.has_kind("<depends>") and not ref in found:   746             found.add(ref)   747             ref = self.identify(ref.get_origin())   748         return ref   749    750     def get_module_provider(self, ref):   751    752         "Identify the provider of the given 'ref'."   753    754         for ancestor in ref.ancestors():   755             if self.modules.has_key(ancestor):   756                 return ancestor   757         return None   758    759     def finalise_classes(self):   760    761         "Finalise the class relationships and attributes."   762    763         self.derive_inherited_attrs()   764         self.derive_subclasses()   765         self.derive_shadowed_attrs()   766    767     def derive_inherited_attrs(self):   768    769         "Derive inherited attributes for classes throughout the program."   770    771         for name in self.classes.keys():   772             self.propagate_attrs_for_class(name)   773    774     def propagate_attrs_for_class(self, name, visited=None):   775    776         "Propagate inherited attributes for class 'name'."   777    778         # Visit classes only once.   779    780         if self.all_combined_attrs.has_key(name):   781             return   782    783         visited = visited or []   784    785         if name in visited:   786             raise ProgramError, "Class %s may not inherit from itself: %s -> %s." % (name, " -> ".join(visited), name)   787    788         visited.append(name)   789    790         class_attrs = {}   791         instance_attrs = {}   792    793         # Aggregate the attributes from base classes, recording the origins of   794         # applicable attributes.   795    796         for base in self.classes[name][::-1]:   797    798             # Get the identity of the class from the reference.   799    800             base = base.get_origin()   801    802             # Define the base class completely before continuing with this   803             # class.   804    805             self.propagate_attrs_for_class(base, visited)   806             class_attrs.update(self.all_class_attrs[base])   807    808             # Instance attribute origins are combined if different.   809    810             for key, values in self.all_instance_attrs[base].items():   811                 init_item(instance_attrs, key, set)   812                 instance_attrs[key].update(values)   813    814         # Class attributes override those defined earlier in the hierarchy.   815    816         class_attrs.update(self.all_class_attrs.get(name, {}))   817    818         # Instance attributes are merely added if not already defined.   819    820         for key in self.all_instance_attrs.get(name, []):   821             if not instance_attrs.has_key(key):   822                 instance_attrs[key] = set(["%s.%s" % (name, key)])   823    824         self.all_class_attrs[name] = class_attrs   825         self.all_instance_attrs[name] = instance_attrs   826         self.all_combined_attrs[name] = set(class_attrs.keys()).union(instance_attrs.keys())   827    828     def derive_subclasses(self):   829    830         "Derive subclass details for classes."   831    832         for name, bases in self.classes.items():   833             for base in bases:   834    835                 # Get the identity of the class from the reference.   836    837                 base = base.get_origin()   838                 self.subclasses[base].add(name)   839    840     def derive_shadowed_attrs(self):   841    842         "Derive shadowed attributes for classes."   843    844         for name, attrs in self.all_instance_attrs.items():   845             attrs = set(attrs.keys()).intersection(self.all_class_attrs[name].keys())   846             if attrs:   847                 self.all_shadowed_attrs[name] = attrs   848    849     def set_class_types(self):   850    851         "Set the type of each class."   852    853         for attrs in self.all_class_attrs.values():   854             attrs["__class__"] = self.type_ref.get_origin()   855    856     def define_instantiators(self):   857    858         """   859         Consolidate parameter and default details, incorporating initialiser   860         details to define instantiator signatures.   861         """   862    863         for cls, attrs in self.all_class_attrs.items():   864             initialiser = attrs["__init__"]   865             self.function_parameters[cls] = self.function_parameters[initialiser]   866             self.function_defaults[cls] = self.function_defaults[initialiser]   867    868     def collect_constants(self):   869    870         "Get constants from all active modules."   871    872         for module in self.modules.values():   873             self.all_constants.update(module.constants)   874    875     # Import methods.   876    877     def find_in_path(self, name):   878    879         """   880         Find the given module 'name' in the search path, returning None where no   881         such module could be found, or a 2-tuple from the 'find' method   882         otherwise.   883         """   884    885         for d in self.path:   886             m = self.find(d, name)   887             if m: return m   888         return None   889    890     def find(self, d, name):   891    892         """   893         In the directory 'd', find the given module 'name', where 'name' can   894         either refer to a single file module or to a package. Return None if the   895         'name' cannot be associated with either a file or a package directory,   896         or a 2-tuple from '_find_package' or '_find_module' otherwise.   897         """   898    899         m = self._find_package(d, name)   900         if m: return m   901         m = self._find_module(d, name)   902         if m: return m   903         return None   904    905     def _find_module(self, d, name):   906    907         """   908         In the directory 'd', find the given module 'name', returning None where   909         no suitable file exists in the directory, or a 2-tuple consisting of   910         None (indicating that no package directory is involved) and a filename   911         indicating the location of the module.   912         """   913    914         name_py = name + extsep + "py"   915         filename = self._find_file(d, name_py)   916         if filename:   917             return None, filename   918         return None   919    920     def _find_package(self, d, name):   921    922         """   923         In the directory 'd', find the given package 'name', returning None   924         where no suitable package directory exists, or a 2-tuple consisting of   925         a directory (indicating the location of the package directory itself)   926         and a filename indicating the location of the __init__.py module which   927         declares the package's top-level contents.   928         """   929    930         filename = self._find_file(d, name)   931         if filename:   932             init_py = "__init__" + extsep + "py"   933             init_py_filename = self._find_file(filename, init_py)   934             if init_py_filename:   935                 return filename, init_py_filename   936         return None   937    938     def _find_file(self, d, filename):   939    940         """   941         Return the filename obtained when searching the directory 'd' for the   942         given 'filename', or None if no actual file exists for the filename.   943         """   944    945         filename = join(d, filename)   946         if exists(filename):   947             return filename   948         else:   949             return None   950    951     def load(self, name):   952    953         """   954         Load the module or package with the given 'name'. Return an object   955         referencing the loaded module or package, or None if no such module or   956         package exists.   957         """   958    959         # Loaded modules are returned immediately.   960         # Modules may be known but not yet loading (having been registered as   961         # submodules), loading, loaded, or completely unknown.   962    963         module = self.get_module(name)   964    965         if module:   966             return self.modules[name]   967    968         # Otherwise, modules are loaded.   969    970         # Split the name into path components, and try to find the uppermost in   971         # the search path.   972    973         path = name.split(".")   974         path_so_far = []   975         module = None   976    977         for p in path:   978    979             # Get the module's filesystem details.   980    981             if not path_so_far:   982                 m = self.find_in_path(p)   983             elif d:   984                 m = self.find(d, p)   985             else:   986                 m = None   987    988             path_so_far.append(p)   989             module_name = ".".join(path_so_far)   990    991             # Raise an exception if the module could not be located.   992    993             if not m:   994                 raise ProgramError("Module not found: %s" % name)   995    996             # Get the directory and module filename.   997    998             d, filename = m   999   1000         # Get the module itself.  1001   1002         return self.load_from_file(filename, module_name)  1003   1004     def load_from_file(self, filename, module_name=None):  1005   1006         "Load the module from the given 'filename'."  1007   1008         if module_name is None:  1009             module_name = "__main__"  1010   1011         module = self.modules.get(module_name)  1012   1013         if not module:  1014   1015             # Try to load from cache.  1016   1017             module = self.load_from_cache(filename, module_name)  1018             if module:  1019                 return module  1020   1021             # If no cache entry exists, load from file.  1022   1023             module = inspector.InspectedModule(module_name, self)  1024             self.add_module(module_name, module)  1025             self.update_cache_validity(module)  1026   1027             self._load(module, module_name, lambda m: m.parse, filename)  1028   1029         return module  1030   1031     def update_cache_validity(self, module):  1032   1033         "Make 'module' valid in the cache, but invalidate accessing modules."  1034   1035         accessing = self.accessing_modules.get(module.name)  1036         if accessing:  1037             self.invalidated.update(accessing)  1038         if module.name in self.invalidated:  1039             self.invalidated.remove(module.name)  1040   1041     def source_is_new(self, filename, module_name):  1042   1043         "Return whether 'filename' is newer than the cached 'module_name'."  1044   1045         if self.cache:  1046             cache_filename = join(self.cache, module_name)  1047             return not exists(cache_filename) or \  1048                 getmtime(filename) > getmtime(cache_filename) or \  1049                 module_name in self.invalidated  1050         else:  1051             return True  1052   1053     def load_from_cache(self, filename, module_name):  1054   1055         "Return a module residing in the cache."  1056   1057         module = self.modules.get(module_name)  1058   1059         if not module and not self.source_is_new(filename, module_name):  1060             module = CachedModule(module_name, self)  1061             self.add_module(module_name, module)  1062   1063             filename = join(self.cache, module_name)  1064             self._load(module, module_name, lambda m: m.from_cache, filename)  1065   1066         return module  1067   1068     def _load(self, module, module_name, fn, filename):  1069   1070         """  1071         Load 'module' for the given 'module_name', and with 'fn' performing an  1072         invocation on the module with the given 'filename'.  1073         """  1074   1075         # Load the module.  1076   1077         if self.verbose:  1078             print >>sys.stderr, module_name in self.required and "Required" or "Loading", module_name, "from", filename  1079         fn(module)(filename)  1080   1081         # Add the module object if not already defined.  1082   1083         if not self.objects.has_key(module_name):  1084             self.objects[module_name] = Reference("<module>", module_name)  1085   1086     def add_module(self, module_name, module):  1087   1088         """  1089         Return the module with the given 'module_name', adding a new module  1090         object if one does not already exist.  1091         """  1092   1093         self.modules[module_name] = module  1094         if module_name in self.to_import:  1095             self.to_import.remove(module_name)  1096   1097 # vim: tabstop=4 expandtab shiftwidth=4