micropython

micropython/__init__.py

418:18c62608bfa6
2011-05-10 Paul Boddie Added module identity information to the object table. This permits testing for module object types in guards.
     1 #!/usr/bin/env python     2      3 """     4 The micropython package for processing Python source code. The code originates     5 from the simplify package but has had various details related to that package     6 removed.     7      8 Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Paul Boddie <paul@boddie.org.uk>     9     10 This program is free software; you can redistribute it and/or modify it under    11 the terms of the GNU General Public License as published by the Free Software    12 Foundation; either version 3 of the License, or (at your option) any later    13 version.    14     15 This program is distributed in the hope that it will be useful, but WITHOUT    16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS    17 FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more    18 details.    19     20 You should have received a copy of the GNU General Public License along with    21 this program.  If not, see <http://www.gnu.org/licenses/>.    22     23 --------    24     25 To use this module, an importer should be constructed. Here, the standard path    26 for module searching is employed:    27     28 importer = Importer(sys.path)    29     30 To generate programs, the above importer should be supplied in the    31 initialisation of a program instance, and then various methods are called:    32     33 program = Program(importer)    34 image = program.get_raw_image()    35     36 Such importer and program objects are the most convenient mechanism through    37 which the functionality of the micropython package may be accessed.    38 """    39     40 from micropython.common import ObjectSet, ProcessingError, TableError, \    41     TableGenerationError    42 import micropython.ast    43 import micropython.data    44 import micropython.opt    45 import micropython.inspect    46 import micropython.table    47 import os    48     49 try:    50     set    51 except NameError:    52     from sets import Set as set    53     54 class Program:    55     56     "This class supports the generation of a program image."    57     58     supported_optimisations = micropython.opt.Optimiser.supported_optimisations    59     60     def __init__(self, importer, optimisations=None):    61     62         """    63         Initialise the program representation with an 'importer' which is able    64         to locate and load Python modules.    65     66         The optional 'optimisations' cause certain techniques to be used in    67         reducing program size and improving program efficiency.    68         """    69     70         self.importer = importer    71         self.optimisations = optimisations or set()    72     73         # Remember the tables once generated.    74     75         self.objtable = None    76         self.paramtable = None    77     78         # Main program information.    79     80         self.code = None    81         self.code_location = None    82     83     def get_importer(self):    84         return self.importer    85     86     # Access to finalised program information.    87     88     def finalise(self):    89     90         "Finalise the program."    91     92         # Need the tables to finalise.    93     94         objtable = self.get_object_table()    95         self.get_parameter_table()    96     97         self.importer.vacuum(objtable)    98         self.importer.finalise()    99    100         # Now remove unneeded things from the tables.   101    102         self.get_object_table(reset=1)   103         self.get_parameter_table(reset=1)   104    105     def get_image(self, with_builtins=0):   106    107         """   108         Return the program image including built-in objects if 'with_builtins'   109         is specified and set to a true value.   110         """   111    112         if self.code is not None:   113             return self.code   114    115         # Optimise and regenerate the object table.   116    117         self.finalise()   118         self.code = []   119    120         # Append constants to the image.   121    122         for const in self.importer.constants():   123             self.code.append(const)   124    125         last_module = self.importer.modules_ordered[-1]   126    127         for module in self.importer.modules_ordered:   128             suppress_builtins = not with_builtins and module.name == "__builtins__"   129    130             # Position the module in the image and make a translation.   131    132             trans = micropython.ast.Translation(module, self)   133    134             # Add header details.   135    136             self.code.append(module)   137    138             # Append module attributes to the image.   139    140             attributes = module.module_attributes()   141             self.code += module.attributes_as_list()   142    143             # Append classes and functions to the image.   144    145             for obj in module.all_objects:   146                 if isinstance(obj, micropython.data.Class):   147    148                     # Add header details.   149    150                     self.code.append(obj)   151    152                     # Append class attributes to the image.   153    154                     attributes = obj.class_attributes()   155                     self.code += obj.attributes_as_list()   156    157                     # Omit built-in function code where requested.   158    159                     if suppress_builtins and obj.astnode.doc is None:   160                         continue   161    162                     # Generate the instantiator/initialiser.   163                     # Append the function code to the image.   164    165                     code = trans.get_instantiator_code(obj)   166                     self.code += code   167    168                     # Class-level code is generated separately at the module   169                     # level, and the code location is set within the code   170                     # generation process for the module.   171    172                 elif isinstance(obj, micropython.data.Function):   173    174                     # Add header details.   175    176                     self.code.append(obj)   177    178                     # Append any default values to the image.   179                     # Only do this for functions which are not dynamic.   180    181                     if not obj.is_dynamic():   182                         self.code += obj.default_attrs   183    184                     # Omit built-in function code where requested.   185    186                     if suppress_builtins and obj.astnode.doc is None:   187                         pass   188    189                     # Append the function code to the image.   190    191                     else:   192                         code = trans.get_code(obj)   193                         self.code += code   194    195             # Omit built-in module code where requested.   196    197             if suppress_builtins:   198                 pass   199    200             # Append the module top-level code to the image.   201    202             else:   203                 code = trans.get_module_code()   204                 self.code += code   205    206         return self.code   207    208     def get_raw_image(self, architecture=None, with_builtins=0):   209    210         "Return the raw image representation of the program."   211    212         architecture = architecture or micropython.rsvp   213    214         self.get_image(with_builtins)   215    216         objtable = self.get_object_table()   217         paramtable = self.get_parameter_table()   218    219         # Position the objects.   220    221         pos = 0   222    223         for item in self.code:   224             arch_item = architecture.get_object(item)   225    226             # Get the raw version for the architecture.   227    228             if arch_item is not None:   229                 pos = arch_item.set_location(pos, objtable, with_builtins)   230             else:   231                 pos += 1   232    233         # Generate the raw code.   234    235         self.raw_code = []   236    237         for item in self.code:   238             arch_item = architecture.get_object(item)   239    240             # Get the raw version for the architecture.   241    242             if arch_item is not None:   243                 self.raw_code += arch_item.as_raw(objtable, paramtable, with_builtins)   244                 arch_item.finalise_location(with_builtins)   245             else:   246                 self.raw_code.append(item)   247    248         # Fix the module locations.   249    250         for module in self.importer.modules_ordered:   251    252             if not with_builtins and module.name == "__builtins__":   253                 continue   254    255             module.code_location = module.blocks[0].location   256    257         self.code_location = self.importer.modules["__main__"].code_location   258         return self.raw_code   259    260     def get_object_table(self, reset=0):   261    262         "Return a table with details of attributes for classes and modules."   263    264         if self.objtable is None or reset:   265    266             t = self.objtable = micropython.table.ObjectTable()   267             for module in self.importer.get_modules():   268    269                 # Add module attributes and module identity information.   270    271                 full_name = module.full_name()   272                 attributes = {full_name : module}   273                 attributes.update(module.module_attributes())   274                 t.add(full_name, attributes)   275    276                 # Add class and instance attributes for all classes, together   277                 # with descendant information.   278    279                 for obj in module.all_objects:   280                     if isinstance(obj, micropython.data.Class):   281    282                         # Prevent ambiguous classes.   283    284                         full_name = obj.full_name()   285    286                         #name = obj.name   287                         #if module.has_key(name) and module[name].defines_ambiguous_class():   288                         #    raise TableGenerationError, "Class %r in module %r is ambiguously defined." % (name, module.full_name())   289    290                         # Define a table entry for the class.   291    292                         attributes = {full_name : obj}   293                         attributes.update(obj.all_attributes())   294                         attributes.update(obj.all_descendants())   295                         t.add(full_name, attributes)   296    297         return self.objtable   298    299     def get_parameter_table(self, reset=0):   300    301         "Return a table with details of parameters for functions and methods."   302    303         # Need the object table to get at class details.   304    305         if self.paramtable is None or reset:   306             t = self.paramtable = micropython.table.ParameterTable()   307    308             # Visit each module, getting function and method details.   309    310             for module in self.importer.get_modules():   311                 for obj in module.all_objects:   312                     if isinstance(obj, micropython.data.Function):   313                         t.add(obj.full_name(), obj.parameters())   314    315                     # Classes are callable, too.   316                     # Take details of the appropriate __init__ method to make an   317                     # entry for an instantiation function for the class.   318    319                     elif isinstance(obj, micropython.data.Class):   320                         t.add(obj.get_instantiator().full_name(), obj.get_instantiator().parameters())   321    322             # Filter out all parameter table entries not referenced by keyword   323             # arguments.   324    325             keyword_names = set()   326    327             for module in self.importer.get_modules():   328                 keyword_names.update(module.keyword_names)   329    330             for function_name, parameters in t.table.items():   331                 for name in parameters.keys():   332                     if name in keyword_names:   333                         break   334                 else:   335                     del t.table[function_name]   336    337         return self.paramtable   338    339 class Importer:   340    341     "An import machine, searching for and loading modules."   342    343     predefined_constants = {   344         "None" : None,   345         "True" : True,   346         "False" : False,   347         #"Ellipsis" : Ellipsis,   348         "NotImplemented" : NotImplemented   349         }   350    351     names_always_used = [   352         "bool", "__call__", "__bool__"   353         ]   354    355     def __init__(self, path=None, verbose=0, optimisations=None):   356    357         """   358         Initialise the importer with the given search 'path' - a list of   359         directories to search for Python modules.   360    361         The optional 'verbose' parameter causes output concerning the activities   362         of the object to be produced if set to a true value (not the default).   363    364         The optional 'optimisations' cause certain techniques to be used in   365         reducing program size and improving program efficiency.   366         """   367    368         self.path = path or [os.getcwd()]   369         self.verbose = verbose   370         self.optimisations = optimisations or set()   371    372         self.modules = {}   373         self.modules_ordered = []   374         self.loading = set()   375    376         # Constant records.   377    378         self.constant_values = {}   379         self.constant_list = None # cache for constants   380         self.init_predefined_constants()   381    382         # Attribute usage.   383    384         self.attributes_used = set()   385         self.name_references = {}   386         self.specific_name_references = {}   387    388         # Attribute coverage calculated during collection.   389    390         self.inferred_name_references = {}   391    392         # Attribute coverage status during collection.   393    394         self.attribute_users_visited = set()   395         self.attributes_to_visit = {}   396    397         # Status information.   398    399         self.vacuumed = 0   400         self.finalised = 0   401    402     def get_modules(self):   403    404         "Return all modules known to the importer."   405    406         return self.modules.values()   407    408     def get_module(self, name):   409    410         "Return the module with the given 'name'."   411    412         return self.modules[name]   413    414     # General maintenance.   415    416     def vacuum(self, objtable):   417    418         "Tidy up the modules."   419    420         if self.vacuumed:   421             return   422    423         # Complete the list of attribute names used in the program.   424    425         self.collect_attributes(objtable)   426    427         for name, module in self.modules.items():   428             if module.loaded:   429                 module.vacuum()   430             else:   431                 del self.modules[name]   432    433         self.vacuumed = 1   434    435     def finalise(self):   436    437         "Finalise the program (which should have been vacuumed first)."   438    439         if self.finalised:   440             return   441    442         # Reset any previously compiled information.   443    444         for module in self.get_modules():   445             module.unfinalise()   446    447         # Prepare module information again.   448    449         for module in self.get_modules():   450             module.finalise()   451    452         self.finalised = 1   453    454     # Name accounting.   455    456     def use_name(self, name, from_name, value=None):   457    458         """   459         Register the given 'name' as being used in the program from within an   460         object with the specified 'from_name'. If the optional 'value' is given,   461         note an assignment.   462         """   463    464         if not self.name_references.has_key(from_name):   465             self.name_references[from_name] = set()   466    467         attrnames = ObjectSet([name])   468         usage = (attrnames,)   469         self.name_references[from_name].add((None, None, usage))   470    471     def use_names(self, user, name, usage, from_name):   472    473         """   474         For the given attribute 'user' (which may be None if no specific user is   475         given), register for the given 'name' the given attribute 'usage'   476         (combinations of attribute names), noting the scope of this usage as   477         being the program object with the specified 'from_name'.   478         """   479    480         if not self.name_references.has_key(from_name):   481             self.name_references[from_name] = set()   482    483         self.name_references[from_name].add((user, name, usage))   484    485     def use_specific_name(self, objname, attrname, from_name):   486    487         """   488         Register the given 'objname' (for an object) whose 'attrname' is being   489         used in the program from within an object with the specified   490         'from_name'.   491         """   492    493         if not self.specific_name_references.has_key(from_name):   494             self.specific_name_references[from_name] = set()   495         self.specific_name_references[from_name].add((objname, attrname))   496    497     # Name accounting products.   498    499     def uses_attribute(self, objname, name):   500    501         """   502         Return whether the attribute of the object with the given 'objname'   503         having the given 'name' is used as an attribute in the program.   504         """   505    506         return (objname + "." + name) in self.attributes_used   507    508     def use_attribute(self, objname, name):   509    510         """   511         Indicate that in the object with the given 'objname', the attribute of   512         the given 'name' is used.   513         """   514    515         self.attributes_used.add(objname + "." + name)   516    517     def use_object(self, objname):   518    519         "Indicate that the object with the given 'objname' is used."   520    521         self.attributes_used.add(objname)   522    523     def collect_attributes(self, objtable):   524    525         "Collect attribute references for the entire program."   526    527         # Include names which may not be explicitly used in programs.   528         # NOTE: Potentially declare these when inspecting.   529    530         for attrname in self.names_always_used:   531             for objname in objtable.all_possible_objects([attrname]):   532    533                 # Record attributes of objects for potential visiting.   534    535                 self.add_attribute_to_visit(objname, attrname)   536    537         # Visit all modules, since some may employ initialisation code which has   538         # some kind of side-effect.   539    540         for name in self.modules.keys():   541             self._collect_attributes(name, objtable)   542    543     def add_attribute_to_visit(self, objname, attrname):   544    545         """   546         Queue an attribute of the object with the given 'objname', having the   547         given 'attrname', to the list for potential visiting if the specified   548         object is actually referenced.   549         """   550    551         if not self.attributes_to_visit.has_key(objname):   552             self.attributes_to_visit[objname] = set()   553         self.attributes_to_visit[objname].add(attrname)   554    555     def _collect_attributes_from(self, from_name, objname, attrname, objtable):   556    557         """   558         Record the association between 'from_name' and the attribute of   559         'objname' with the given 'attrname'. Then collect attributes for the   560         referenced attribute using 'objtable'.   561         """   562    563         if not self.inferred_name_references.has_key(from_name):   564             self.inferred_name_references[from_name] = set()   565    566         self.inferred_name_references[from_name].add((objname, attrname))   567         self._collect_attributes(objname + "." + attrname, objtable)   568    569     def _collect_attributes(self, from_name, objtable):   570    571         """   572         Given an object called 'from_name', find all names referenced from such   573         an object according to the register of names, using 'objtable' to infer   574         types.   575         """   576    577         if from_name in self.attribute_users_visited:   578             return   579    580         self.attribute_users_visited.add(from_name)   581    582         # The getattr function is a special case: it can potentially reference   583         # any known attribute. Since accessor attributes must be known   584         # constants, the intersection of known constants and attributes is used   585         # to build a set of objects that might be referenced by getattr.   586    587         if from_name == "__builtins__.getattr":   588             all_attributes = set(objtable.attribute_names())   589             all_string_constants = set([const.get_value() for const in self.constants() if const.value_type_name() == "__builtins__.str"])   590             all_attribute_constants = all_attributes.intersection(all_string_constants)   591    592             # Get the types supporting each attribute and visit the referenced   593             # objects.   594    595             all_objtypes = set()   596    597             for attrname in all_attribute_constants:   598                 objtypes = objtable.any_possible_objects_plus_status([attrname])   599                 all_objtypes.update(objtypes)   600    601             # Attribute assignment does not take place, so an empty list of   602             # values is given.   603    604             self._collect_attributes_for_types(from_name, objtable, all_objtypes,   605                 [{attrname : []} for attrname in all_attribute_constants])   606    607         # Get name references and find possible objects which support such   608         # combinations of attribute names.   609    610         for user, name, usage in self.name_references.get(from_name, []):   611    612             # Using all attribute names for a particular name, attempt to get   613             # specific object types.   614    615             all_objtypes = set()   616    617             for attrnames in usage:   618                 objtypes = objtable.all_possible_objects_plus_status(attrnames)   619                 if not objtypes:   620                     print "Warning: usage in %r for %r finds no object supporting all attributes %r" % (from_name, name, attrnames)   621                     objtypes = objtable.any_possible_objects_plus_status(attrnames)   622                     if not objtypes:   623                         print "Warning: usage in %r for %r finds no object supporting any attributes %r" % (from_name, name, attrnames)   624    625                 all_objtypes.update(objtypes)   626    627             # Record the object types for generating guards.   628    629             if user is not None:   630                 if not hasattr(user, "_attrtypes"):   631                     user._attrtypes = {}   632    633                 user._attrtypes[name] = all_objtypes   634                 self._collect_attributes_for_types(from_name, objtable, all_objtypes, usage)   635    636         # Get specific name references and visit the referenced objects.   637    638         for objname, attrname in self.specific_name_references.get(from_name, []):   639             self.use_attribute(objname, attrname)   640             self._collect_attributes_from(from_name, objname, attrname, objtable)   641    642         # Where the object has an __init__ attribute, assume that it is an   643         # initialiser which is called at some point, and collect attributes used   644         # in this initialiser.   645    646         if "__init__" in objtable.table.get(from_name, []):   647             self.use_attribute(from_name, "__init__")   648             self._collect_attributes_from(from_name, from_name, "__init__", objtable)   649    650         # Visit attributes on this object that were queued in case of the object   651         # being referenced.   652    653         attributes_to_visit = self.attributes_to_visit.get(from_name, [])   654    655         if attributes_to_visit:   656             del self.attributes_to_visit[from_name]   657    658             for attrname in attributes_to_visit:   659                 self.use_attribute(from_name, attrname)   660                 self._collect_attributes_from(from_name, from_name, attrname, objtable)   661    662     def _collect_attributes_for_types(self, from_name, objtable, objtypes, usage):   663    664         """   665         For the unit known as 'from_name' and using the 'objtable' to validate   666         each attribute, identify and attempt to visit attributes found for each   667         of the suggested object types given by 'objtypes' and the 'usage'   668         provided.   669         """   670    671         for objname, is_static in objtypes:   672             for attrnames in usage:   673                 for attrname, attrvalues in attrnames.items():   674    675                     # Test for the presence of an attribute on the suggested   676                     # object type.   677    678                     try:   679                         attr = objtable.access(objname, attrname)   680                     except TableError:   681                         #print "Warning: object type %r does not support attribute %r" % (objname, attrname)   682                         continue   683    684                     # Get the real identity of the attribute in order to   685                     # properly collect usage from it.   686    687                     parent = attr.parent   688                     if isinstance(parent, micropython.data.Instance):   689                         parentname = objname   690                     else:   691                         parentname = parent.full_name()   692    693                     # Test for assignment.   694    695                     if attrvalues:   696                         for attrvalue in attrvalues:   697                             parent.set(attrname, attrvalue, 0)   698    699                     # Visit attributes of objects known to be used.   700    701                     if parentname in self.attributes_used:   702                         self.use_attribute(parentname, attrname)   703                         self._collect_attributes_from(from_name, parentname, attrname, objtable)   704    705                     # Record attributes of other objects for potential visiting.   706    707                     else:   708                         self.add_attribute_to_visit(parentname, attrname)   709    710     # Constant accounting.   711    712     def init_predefined_constants(self):   713    714         "Ensure the predefined constants."   715    716         for name, value in self.predefined_constants.items():   717             self.make_constant(value)   718    719     def get_predefined_constant(self, name):   720    721         "Return the predefined constant for the given 'name'."   722    723         return self.make_constant(self.predefined_constants[name])   724    725     def get_constant(self, value):   726    727         "Return a constant for the given 'value'."   728    729         const = micropython.data.Const(value)   730         return self.constant_values[const]   731    732     def get_constant_type_name(self, value):   733    734         "Return the type name for the given constant 'value'."   735    736         return value.__class__.__name__   737    738     def make_constant(self, value):   739    740         "Make and return a constant for the given 'value'."   741    742         # Make a constant object and return it.   743    744         const = micropython.data.Const(value)   745         if not self.constant_values.has_key(const):   746             self.constant_values[const] = const   747         return self.constant_values[const]   748    749     def constants(self):   750    751         "Return a list of constants."   752    753         if self.constant_list is None:   754             self.constant_list = list(self.constant_values.values())   755    756         return self.constant_list   757    758     # Import methods.   759    760     def find_in_path(self, name):   761    762         """   763         Find the given module 'name' in the search path, returning None where no   764         such module could be found, or a 2-tuple from the 'find' method   765         otherwise.   766         """   767    768         for d in self.path:   769             m = self.find(d, name)   770             if m: return m   771         return None   772    773     def find(self, d, name):   774    775         """   776         In the directory 'd', find the given module 'name', where 'name' can   777         either refer to a single file module or to a package. Return None if the   778         'name' cannot be associated with either a file or a package directory,   779         or a 2-tuple from '_find_package' or '_find_module' otherwise.   780         """   781    782         m = self._find_package(d, name)   783         if m: return m   784         m = self._find_module(d, name)   785         if m: return m   786         return None   787    788     def _find_module(self, d, name):   789    790         """   791         In the directory 'd', find the given module 'name', returning None where   792         no suitable file exists in the directory, or a 2-tuple consisting of   793         None (indicating that no package directory is involved) and a filename   794         indicating the location of the module.   795         """   796    797         name_py = name + os.extsep + "py"   798         filename = self._find_file(d, name_py)   799         if filename:   800             return None, filename   801         return None   802    803     def _find_package(self, d, name):   804    805         """   806         In the directory 'd', find the given package 'name', returning None   807         where no suitable package directory exists, or a 2-tuple consisting of   808         a directory (indicating the location of the package directory itself)   809         and a filename indicating the location of the __init__.py module which   810         declares the package's top-level contents.   811         """   812    813         filename = self._find_file(d, name)   814         if filename:   815             init_py = "__init__" + os.path.extsep + "py"   816             init_py_filename = self._find_file(filename, init_py)   817             if init_py_filename:   818                 return filename, init_py_filename   819         return None   820    821     def _find_file(self, d, filename):   822    823         """   824         Return the filename obtained when searching the directory 'd' for the   825         given 'filename', or None if no actual file exists for the filename.   826         """   827    828         filename = os.path.join(d, filename)   829         if os.path.exists(filename):   830             return filename   831         else:   832             return None   833    834     def load(self, name, return_leaf=0):   835    836         """   837         Load the module or package with the given 'name'. Return an object   838         referencing the loaded module or package, or None if no such module or   839         package exists.   840         """   841    842         if return_leaf:   843             name_for_return = name   844         else:   845             name_for_return = name.split(".")[0]   846    847         if self.modules.has_key(name) and self.modules[name].loaded:   848             #print "Cached (%s)" % name   849             return self.modules[name_for_return]   850    851         if self.verbose:   852             print "Loading", name   853    854         # Split the name into path components, and try to find the uppermost in   855         # the search path.   856    857         path = name.split(".")   858         m = self.find_in_path(path[0])   859         if not m:   860             if self.verbose:   861                 print "Not found (%s)" % path[0]   862             return None # NOTE: Import error.   863         d, filename = m   864    865         # Either acquire a reference to an already-imported module, or load the   866         # module from a file.   867    868         top = module = self.load_from_file(filename, path[0])   869    870         # For hierarchical names, traverse each path component...   871    872         if len(path) > 1:   873             if not d:   874                 if self.verbose:   875                     print "No package (%s)" % filename   876                 return None # NOTE: Import error (package not found).   877             else:   878                 self.add_submodules(d, module)   879    880             path_so_far = path[:1]   881             for p in path[1:]:   882                 path_so_far.append(p)   883    884                 # Find the package or module concerned.   885    886                 m = self.find(d, p)   887                 if not m:   888                     if self.verbose:   889                         print "Not found (%s)" % p   890                     return None # NOTE: Import error.   891                 d, filename = m   892                 module_name = ".".join(path_so_far)   893    894                 # Either reference an imported module or load one from a file.   895    896                 submodule = self.load_from_file(filename, module_name)   897    898                 if d:   899                     self.add_submodules(d, module)   900    901                 # Store the submodule within its parent module.   902    903                 module.set_module(p, submodule)   904                 module = submodule   905    906         # Return either the deepest or the uppermost module.   907    908         if return_leaf:   909             return module   910         else:   911             return top   912    913     def load_from_file(self, name, module_name=None):   914    915         """   916         Load the module with the given 'name' (which may be a full module path).   917         """   918    919         if module_name is None:   920             module_name = "__main__"   921    922         module = self.add_module(module_name)   923         if not module.loaded and module not in self.loading:   924             self.loading.add(module)   925             #print "Parsing", name   926             module.parse(name)   927             #print "Done", name   928             self.loading.remove(module)   929             module.loaded = 1   930    931         # Record the module.   932    933         self.use_object(module.full_name())   934         #print "Loaded", module_name, "with namespace", module.namespace.keys()   935         return module   936    937     def add_module(self, module_name):   938    939         """   940         Return the module with the given 'module_name', adding a new module   941         object if one does not already exist.   942         """   943    944         if not self.modules.has_key(module_name):   945             self.modules[module_name] = module = micropython.inspect.InspectedModule(module_name, self)   946             self.modules_ordered.append(module)   947         else:   948             module = self.modules[module_name]   949         return module   950    951     def add_submodules(self, pathname, module):   952    953         """   954         Work around insufficient __all__ declarations and examine the directory   955         with the given 'pathname', adding submodules to the given 'module'.   956         """   957    958         for filename in os.listdir(pathname):   959             submodule, ext = os.path.splitext(filename)   960             if ext not in ("", ".py"):   961                 continue   962             module.set_module(submodule, self.add_module(module.name + "." + submodule))   963    964 # vim: tabstop=4 expandtab shiftwidth=4