micropython

micropython/inspect.py

501:0d0cb0b43c38
2012-05-11 Paul Boddie Added support for loading submodules given as imported names in "from" statements (such as "module" in "from imported_package import module" referring to "imported_package.module").
     1 #!/usr/bin/env python     2      3 """     4 Inspect source files, obtaining details of classes and attributes.     5      6 Copyright (C) 2007, 2008, 2009, 2010, 2011 Paul Boddie <paul@boddie.org.uk>     7      8 This program is free software; you can redistribute it and/or modify it under     9 the terms of the GNU General Public License as published by the Free Software    10 Foundation; either version 3 of the License, or (at your option) any later    11 version.    12     13 This program is distributed in the hope that it will be useful, but WITHOUT    14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS    15 FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more    16 details.    17     18 You should have received a copy of the GNU General Public License along with    19 this program.  If not, see <http://www.gnu.org/licenses/>.    20     21 --------    22     23 The results of inspecting a module are as follows:    24     25 Constants    26 ---------    27     28 All constants identified within the code shall be registered.    29     30 Classes    31 -------    32     33 All global classes shall be registered; local classes (within functions) or    34 nested classes (within classes) are not currently registered.    35     36 Base classes must be detected and constant.    37     38 All classes without bases are made to inherit from __builtins__.object in order    39 to support some standard methods.    40     41 Functions    42 ---------    43     44 All functions and lambda definitions shall be registered.    45     46 Namespaces    47 ----------    48     49 Modules define their own "global" namespace, within which classes, functions    50 and lambda definitions establish a hierarchy of namespaces.    51     52 Only local, global and built-in namespaces are recognised; closures are not    53 supported.    54     55 Assignments    56 -----------    57     58 Name assignment and attribute assignment involving modules and classes cause    59 names to be associated with values within namespaces.    60     61 Any assignments within loops are considered to cause the targets of such    62 assignments to provide non-constant values.    63     64 Assignments to names are only really considered to cause the targets of such    65 assignments to provide constant values if the targets reside in the module    66 namespace or in class namespaces, subject to the above conditions.    67     68 Assignments to names within functions are not generally considered to cause the    69 targets of such assignments to provide constant values since functions can be    70 invoked many times with different inputs. This affects particularly the    71 definition of functions or lambdas within functions. However, there may be    72 benefits in considering a local to be constant within a single invocation.    73 """    74     75 from micropython.common import *    76 from micropython.data import *    77 import compiler.ast    78     79 # Program visitors.    80     81 class InspectedModule(ASTVisitor, Module):    82     83     """    84     An inspected module, providing core details via the Module superclass, but    85     capable of being used as an AST visitor.    86     """    87     88     def __init__(self, name, importer):    89     90         """    91         Initialise this visitor with a module 'name' and an 'importer' which is    92         used to provide access to other modules when required.    93         """    94     95         Module.__init__(self, name, importer)    96         self.visitor = self    97     98         # Import machinery links.    99    100         self.optimisations = self.importer.optimisations   101         self.builtins = self.importer.modules.get("__builtins__")   102         self.loaded = 0   103    104         # Current expression state.   105    106         self.expr = None   107         self.in_assignment = 0  # For slice and subscript handling.   108    109         # Namespace state.   110    111         self.in_method = 0      # Find instance attributes in all methods.   112         self.in_function = 0    # Note function presence, affecting definitions.   113         self.in_loop = 0        # Note loop "membership", affecting assignments.   114         self.namespaces = []   115         self.functions = []   116    117     def parse(self, filename):   118    119         "Parse the file having the given 'filename'."   120    121         module = compiler.parseFile(filename)   122         self.process(module)   123    124     def process(self, module):   125    126         "Process the given 'module'."   127    128         self.astnode = module   129    130         # Add __name__ to the namespace.   131    132         self.store("__name__", self._visitConst(self.full_name()))   133    134         # First, visit module-level code, recording global names.   135    136         processed = self.dispatch(module)   137    138         # Then, for each function, detect and record globals declared in those   139         # functions.    140    141         for node, namespaces in self.functions:   142             self.process_globals(node)   143    144         self.finalise_attribute_usage()   145    146         # Then, visit each function, recording other names.   147    148         for node, namespaces in self.functions:   149             self._visitFunctionBody(node, namespaces)   150             namespaces[-1].finalise_attribute_usage()   151    152         # Add references to other modules declared using the __all__ global.   153    154         if self.has_key("__all__"):   155             all = self["__all__"]   156             if isinstance(all, compiler.ast.List):   157                 for n in all.nodes:   158                     self.store(n.value, self.importer.add_module(self.name + "." + n.value))   159    160         return processed   161    162     def process_globals(self, node):   163    164         """   165         Within the given 'node', process global declarations, adjusting the   166         module namespace.   167         """   168    169         for n in node.getChildNodes():   170             if isinstance(n, compiler.ast.Global):   171                 for name in n.names:   172                     if not self.has_key(name):   173                         self[name] = make_instance()   174             else:   175                 self.process_globals(n)   176    177     def vacuum(self):   178    179         """   180         Vacuum the module namespace, removing unreferenced objects and unused   181         names.   182         """   183    184         if self.should_optimise_unused_objects():   185             self.vacuum_object(self)   186    187             all_objects = list(self.all_objects)   188    189             for obj in all_objects:   190                 self.vacuum_object(obj)   191    192     def vacuum_object(self, obj, delete_all=0):   193    194         "Vacuum the given object 'obj'."   195    196         # Get all constant objects in apparent use.   197    198         if delete_all:   199             obj_objects = set()   200         else:   201             obj_objects = []   202             for name, attr in obj.items_for_vacuum():   203    204                 # Get constant objects for attributes in use.   205    206                 if self.importer.uses_attribute(obj.full_name(), name) and \   207                     attr is not None and attr.is_constant():   208    209                     value = attr.get_value()   210                     obj_objects.append(value)   211    212         # Now vacuum unused attributes and objects not in use.   213    214         for name, attr in obj.items_for_vacuum():   215    216             # Only consider deleting entire unused objects or things accessible   217             # via names which are never used.   218    219             if delete_all or not self.importer.uses_attribute(obj.full_name(), name):   220                 obj.vacuum_item(name)   221    222                 # Delete any unambiguous attribute value. Such values can only   223                 # have been defined within the object and therefore are not   224                 # redefined by other code regions.   225    226                 if attr is not None and attr.is_constant():   227                     value = attr.get_value()   228    229                     # The value must have this object as a parent.   230                     # However, it must not be shared by several names.   231    232                     if value is not obj and value.parent is obj and \   233                         value in self.all_objects and value not in obj_objects:   234    235                         self.all_objects.remove(value)   236    237                         # Delete class contents and lambdas from functions.   238    239                         self.vacuum_object(value, 1)   240    241     def unfinalise(self):   242    243         "Reset finalised information for the module."   244    245         for obj in self.all_objects:   246             obj.unfinalise_attributes()   247    248     def finalise(self, objtable):   249    250         "Finalise the module."   251    252         for obj in self.all_objects:   253             obj.finalise(objtable)   254    255         self.finalise_users(objtable)   256    257     def add_object(self, obj, any_scope=0):   258    259         """   260         Record 'obj' if non-local or if the optional 'any_scope' is set to a   261         true value.   262         """   263    264         if any_scope or not (self.namespaces and isinstance(self.namespaces[-1], Function)):   265             self.all_objects.add(obj)   266    267     # Optimisation tests.   268    269     def should_optimise_unused_objects(self):   270         return "unused_objects" in self.optimisations   271    272     # Namespace methods.   273    274     def in_class(self, namespaces=None):   275         namespaces = namespaces or self.namespaces   276         return len(namespaces) > 1 and isinstance(namespaces[-2], Class)   277    278     def store(self, name, obj):   279    280         "Record attribute or local 'name', storing 'obj'."   281    282         # Store in the module.   283    284         if not self.namespaces:   285             if self.in_loop and self.used_in_scope(name, "builtins"):   286                 raise InspectError("Name %r already used as a built-in." % name)   287             else:   288                 self.set(name, obj, not self.in_loop)   289    290         # Or store locally.   291    292         else:   293             locals = self.namespaces[-1]   294    295             if self.in_loop and locals.used_in_scope(name, "global") and not name in locals.globals:   296                 raise InspectError("Name %r already used as global." % name)   297             elif self.in_loop and locals.used_in_scope(name, "builtins"):   298                 raise InspectError("Name %r already used as a built-in." % name)   299             else:   300                 locals.set(name, obj, not self.in_loop)   301    302     def store_lambda(self, obj):   303    304         "Store a lambda function 'obj'."   305    306         self.add_object(obj)   307         self.get_namespace().add_lambda(obj)   308    309     def store_module_attr(self, name, module):   310    311         """   312         Record module attribute 'name' in the given 'module' using the current   313         expression.   314         """   315    316         module.set(name, self.expr, 0)   317         self.use_specific_attribute(module.full_name(), name)   318    319     def store_class_attr(self, name, cls):   320    321         """   322         Record class attribute 'name' in the given class 'cls' using the current   323         expression.   324         """   325    326         cls.set(name, self.expr, 0)   327         self.use_specific_attribute(cls.full_name(), name)   328    329     def store_instance_attr(self, name):   330    331         "Record instance attribute 'name' in the current class."   332    333         if self.in_method:   334    335             # Current namespace is the function.   336             # Previous namespace is the class.   337    338             cls = self.namespaces[-2]   339             cls.add_instance_attribute(name)   340    341             # NOTE: The instance attribute, although defined in a specific   342             # NOTE: class, obviously appears in all descendant classes.   343    344             self.use_specific_attribute(cls.full_name(), name)   345    346     def get_namespace(self):   347    348         "Return the parent (or most recent) namespace currently exposed."   349    350         return (self.namespaces[-1:] or [self])[0]   351    352     def use_name(self, name, node=None, value=None):   353    354         """   355         Use the given 'name' within the current namespace/unit, either in   356         conjunction with a particular object (if 'node' is specified and not   357         None) or unconditionally.   358         """   359    360         if node is not None and isinstance(node, compiler.ast.Name):   361             self.use_attribute(node.name, name, value)   362    363         # For general name usage, declare usage of the given name from this   364         # particular unit.   365    366         else:   367             unit = self.get_namespace()   368             self.importer.use_name(name, unit.full_name(), value)   369    370     def use_constant(self, const):   371    372         "Use the given 'const' within the current namespace/unit."   373    374         unit = self.get_namespace()   375         self.importer.use_constant(const, unit.full_name())   376    377     # Attribute usage methods.   378     # These are convenience methods which refer to the specific namespace's   379     # implementation of these operations.   380    381     def new_branchpoint(self, loop_node=None):   382         self.get_namespace()._new_branchpoint(loop_node)   383    384     def new_branch(self, node):   385         self.get_namespace()._new_branch(node)   386    387     def abandon_branch(self):   388         self.get_namespace()._abandon_branch()   389    390     def suspend_broken_branch(self):   391         self.get_namespace()._suspend_broken_branch()   392    393     def suspend_continuing_branch(self):   394         self.get_namespace()._suspend_continuing_branch()   395    396     def shelve_branch(self):   397         self.get_namespace()._shelve_branch()   398    399     def merge_branches(self):   400         self.get_namespace()._merge_branches()   401    402     def resume_broken_branches(self):   403         self.get_namespace()._resume_broken_branches()   404    405     def resume_continuing_branches(self):   406         self.get_namespace()._resume_continuing_branches()   407    408     def define_attribute_user(self, node):   409    410         """   411         Define 'node' as the user of attributes, indicating the point where the   412         user is defined.   413         """   414    415         self.get_namespace()._define_attribute_user(node)   416    417     def use_attribute(self, name, attrname, value=None):   418    419         """   420         Note usage on the attribute user 'name' of the attribute 'attrname',   421         noting an assignment if 'value' is specified.   422         """   423    424         return self.get_namespace()._use_attribute(name, attrname, value)   425    426     def use_specific_attribute(self, objname, attrname, from_name=None):   427    428         """   429         Note usage on the object having the given 'objname' of the attribute   430         'attrname'. If 'objname' is None, the current namespace is chosen as the   431         object providing the attribute.   432         """   433    434         return self.get_namespace()._use_specific_attribute(objname, attrname, from_name)   435    436     # Visitor methods.   437    438     def default(self, node, *args):   439         raise InspectError("Node class %r is not supported." % node.__class__)   440    441     def NOP(self, node):   442         for n in node.getChildNodes():   443             self.dispatch(n)   444    445     def NOP_ABANDON(self, node):   446         self.NOP(node)   447         self.abandon_branch()   448    449     def TEST_NOP(self, node):   450         self.use_name("__bool__", node)   451         self.NOP(node)   452    453     def OP(self, node):   454         for n in node.getChildNodes():   455             self.dispatch(n)   456         return make_instance()   457    458     def TEST_OP(self, node):   459         self.use_name("__bool__", node)   460         return self.OP(node)   461    462     # Generic support for classes of operations.   463    464     def _ensureOperators(self):   465         attr, scope, namespace = self._get_with_scope("$operator")   466         if attr is None:   467             module = self.importer.load("operator")   468             self["$operator"] = module   469         else:   470             module = attr.get_value()   471         return module   472    473     def _visitOperator(self, node, operator_name=None):   474    475         "Accounting method for the operator 'node'."   476    477         operator_module = self._ensureOperators()   478         operator_fn = operator_functions[operator_name or node.__class__.__name__]   479         self.use_specific_attribute(operator_module.full_name(), operator_fn)   480         return self.OP(node)   481    482     _visitBinary = _visitOperator   483     _visitUnary = _visitOperator   484    485     def _visitAttr(self, expr, attrname, node):   486    487         """   488         Process the attribute provided by the given 'expr' with the given   489         'attrname' and involving the given 'node'.   490         """   491    492         # Attempt to identify the nature of the attribute.   493    494         if isinstance(expr, Attr):   495             value = expr.get_value()   496    497             # Get the attribute and record its usage.   498    499             if isinstance(value, (Class, Module)):   500    501                 # Check for class.__class__.   502    503                 if attrname == "__class__" and isinstance(value, Class):   504                     attr = type_class   505                 else:   506                     attr = value.get(attrname) or make_instance()   507                 self.use_specific_attribute(value.full_name(), attrname)   508    509             elif isinstance(value, UnresolvedName):   510                 attr = UnresolvedName(attrname, value.full_name(), self)   511    512             # The actual attribute is not readily identifiable and is assumed   513             # to be an instance.   514    515             else:   516                 attr = make_instance()   517    518                 # Note usage of the attribute where a local is involved.   519    520                 self._visitAttrUser(expr, attrname, node)   521    522         # No particular attribute has been identified, thus a general instance   523         # is assumed.   524    525         else:   526             attr = make_instance()   527             self.use_name(attrname, node)   528    529         return attr   530    531     def _visitAttrUser(self, expr, attrname, node, value=None):   532    533         """   534         Note usage of the attribute provided by 'expr' with the given 'attrname'   535         where a local is involved, annotating the given 'node'. If the optional   536         'value' is given, note an assignment for future effects on attributes   537         where such attributes are inferred from the usage.   538         """   539    540         # Access to attribute via a local.   541    542         if expr.parent is self.get_namespace():   543    544             # NOTE: Revisiting of nodes may occur for loops.   545    546             if not hasattr(node, "_attrusers"):   547                 node._attrusers = set()   548    549             node._attrusers.update(self.use_attribute(expr.name, attrname, value))   550             node._username = expr.name   551         else:   552             self.use_name(attrname, node.expr, value)   553    554     def _visitConst(self, value):   555    556         """   557         Register the constant given by 'value', if necessary, returning the   558         resulting object. The type name is noted as being used, thus preserving   559         the class in any generated program.   560         """   561    562         self.use_specific_attribute("__builtins__", self.importer.get_constant_type_name(value))   563         const = self.importer.make_constant(value)   564         self.use_constant(const)   565         return const   566    567     def _visitFunction(self, node, name):   568    569         """   570         Return a function object for the function defined by 'node' with the   571         given 'name'. If a lambda expression is being visited, 'name' should be   572         None.   573         """   574    575         # Define the function object.   576    577         function = Function(   578             name,   579             self.get_namespace(),   580             node.argnames,   581             node.defaults,   582             (node.flags & 4 != 0),   583             (node.flags & 8 != 0),   584             self.in_loop or self.in_function,   585             self,   586             node   587             )   588    589         self.add_object(function, any_scope=1)   590    591         # Make a back reference from the node for code generation.   592    593         node.unit = function   594    595         # Process the defaults.   596    597         for n in node.defaults:   598             self.expr = self.dispatch(n)   599             function.store_default(self.expr)   600    601         # Note attribute usage where tuple parameters are involved.   602    603         if function.tuple_parameters():   604             self.use_name("__getitem__", node)   605    606         # Record the namespace context of the function for later processing.   607    608         self.functions.append((node, self.namespaces + [function]))   609    610         # Store the function.   611    612         if name is not None:   613             self.store(name, function)   614         else:   615             self.store_lambda(function)   616    617         # Test the defaults and assess whether an dynamic object will result.   618    619         function.make_dynamic()   620         return function   621    622     def _visitFunctionBody(self, node, namespaces):   623    624         "Enter the function."   625    626         # Current namespace is the function.   627         # Previous namespace is the class.   628    629         if self.in_class(namespaces):   630             self.in_method = 1   631    632         in_function = self.in_function   633         in_loop = self.in_loop   634         self.in_function = 1   635         self.in_loop = 0   636    637         self.namespaces = namespaces   638         self.dispatch(node.code)   639    640         self.in_loop = in_loop   641         self.in_function = in_function   642         self.in_method = 0   643    644     # Specific handler methods.   645    646     visitAdd = _visitBinary   647    648     visitAnd = TEST_OP   649    650     visitAssert = NOP   651    652     def visitAssign(self, node):   653         self.expr = self.dispatch(node.expr)   654         self.in_assignment = 1   655         for n in node.nodes:   656             self.dispatch(n)   657         self.in_assignment = 0   658    659     def visitAssAttr(self, node):   660         expr = self.dispatch(node.expr)   661         attrname = node.attrname   662    663         # Record the attribute on the presumed target.   664    665         if isinstance(expr, Attr):   666             value = expr.get_value()   667    668             if expr.name == "self":   669                 self.store_instance_attr(attrname)   670                 self.use_attribute(expr.name, attrname, value) # NOTE: Impose constraints on the type given the hierarchy.   671                 self._visitAttrUser(expr, attrname, node, self.expr)   672    673             elif isinstance(value, Module):   674                 self.store_module_attr(attrname, value)   675                 print "Warning: attribute %r of module %r set outside the module." % (node.attrname, expr.get_value().name)   676    677             elif isinstance(value, Class):   678                 self.store_class_attr(attrname, value)   679    680             # Note usage of the attribute where a local is involved.   681    682             else:   683                 self._visitAttrUser(expr, attrname, node, self.expr)   684    685         else:   686             self.use_name(attrname, node)   687    688     def visitAssList(self, node):   689    690         # Declare names which will be used by generated code.   691    692         self.use_name("__getitem__", node)   693    694         # Process the assignment.   695    696         for i, n in enumerate(node.nodes):   697             self.dispatch(n)   698             self._visitConst(i) # for __getitem__(i) at run-time   699    700     def visitAssName(self, node):   701         if hasattr(node, "flags") and node.flags == "OP_DELETE":   702             print "Warning: deletion of attribute %r in %r is not supported." % (node.name, self.full_name())   703             #raise InspectError("Deletion of attribute %r is not supported." % node.name)   704    705         self.store(node.name, self.expr)   706         self.define_attribute_user(node)   707    708         # Ensure the presence of the given name in this namespace.   709         # NOTE: Consider not registering assignments involving methods, since   710         # NOTE: this is merely creating aliases for such methods.   711    712         if isinstance(self.get_namespace(), (Class, Module)):   713             if not isinstance(self.expr, Attr) or not isinstance(self.expr.get_value(), Function):   714                 self.use_specific_attribute(None, node.name)   715             else:   716                 fn = self.expr.get_value()   717                 ns = self.get_namespace().full_name()   718                 self.use_specific_attribute(fn.parent.full_name(), fn.name, "%s.%s" % (ns, node.name))   719    720     visitAssTuple = visitAssList   721    722     def visitAugAssign(self, node):   723    724         # Accounting.   725    726         operator_fn = operator_functions.get(node.op)   727         operator_module = self._ensureOperators()   728         self.use_specific_attribute(operator_module.full_name(), operator_fn)   729    730         # Process the assignment.   731    732         self.expr = self.dispatch(node.expr)   733    734         # NOTE: Similar to micropython.ast handler code.   735         # NOTE: Slices and subscripts are supported by __setitem__(slice) and   736         # NOTE: not __setslice__.   737    738         if isinstance(node.node, compiler.ast.Name):   739             self.visitAssName(node.node)   740         elif isinstance(node.node, compiler.ast.Getattr):   741             self.visitAssAttr(node.node)   742         else:   743             self.use_specific_attribute("__builtins__", "slice")   744             self.use_name("__setitem__", node)   745    746     visitBackquote = OP   747    748     visitBitand = _visitBinary   749    750     visitBitor = _visitBinary   751    752     visitBitxor = _visitBinary   753    754     def visitBreak(self, node):   755         self.NOP(node)   756         self.suspend_broken_branch()   757    758     visitCallFunc = OP   759    760     def visitClass(self, node):   761    762         """   763         Register the class at the given 'node' subject to the restrictions   764         mentioned in the module docstring.   765         """   766    767         if self.namespaces:   768             print "Warning: class %r in %r is not global: ignored." % (node.name, self.namespaces[-1].full_name())   769             return   770         else:   771             if self.in_loop:   772                 print "Warning: class %r in %r defined in a loop." % (node.name, self.full_name())   773    774             cls = get_class(node.name, self.get_namespace(), self, node)   775    776             # Make a back reference from the node for code generation.   777    778             node.unit = cls   779    780             # Process base classes in the context of the class's namespace.   781             # This confines references to such classes to the class instead of   782             # the namespace in which it is defined.   783    784             self.namespaces.append(cls)   785    786             # Visit the base class expressions, attempting to find concrete   787             # definitions of classes.   788    789             for base in node.bases:   790                 expr = self.dispatch(base)   791    792                 # Each base class must be constant and known at compile-time.   793    794                 if isinstance(expr, Attr):   795                     if expr.assignments != 1:   796                         raise InspectError("Base class %r for %r is not constant: %r" % (base, cls.full_name(), expr))   797                     else:   798                         cls.add_base(expr.get_value())   799    800                 # Where no expression value is available, the base class is   801                 # not identifiable.   802    803                 else:   804                     raise InspectError("Base class %r for %r is not found: it may be hidden in some way." % (base, cls.full_name()))   805    806             # NOTE: Potentially dubious measure to permit __init__ availability.   807             # If no bases exist, adopt the 'object' class.   808    809             if not node.bases and not (self.name == "__builtins__" and node.name == "object") :   810                 expr = self.dispatch(compiler.ast.Name("object"))   811                 cls.add_base(expr.get_value())   812    813             # Make an entry for the class in the parent namespace.   814    815             self.namespaces.pop()   816             self.store(node.name, cls)   817             self.add_object(cls)   818    819             # Process the class body in its own namespace.   820             # Add __name__ to the namespace.   821    822             self.namespaces.append(cls)   823             self.store("__name__", self._visitConst(node.name))   824             self.dispatch(node.code)   825             self.namespaces.pop()   826    827             cls.finalise_attribute_usage()   828             return cls   829    830     def visitCompare(self, node):   831    832         # Accounting.   833         # NOTE: Replicates some code in micropython.ast.visitCompare.   834    835         self.use_name("__bool__", node)   836    837         this_node = node   838    839         for op in node.ops:   840             op_name, next_node = op   841    842             # Define name/attribute usage.   843             # Get the applicable operation.   844    845             operator_fn = operator_functions.get(op_name)   846    847             # For operators, reference the specific function involved.   848    849             if operator_fn is not None:   850                 operator_module = self._ensureOperators()   851                 self.use_specific_attribute(operator_module.full_name(), operator_fn)   852    853             # Define __contains__ usage on the next node.   854    855             elif op_name.endswith("in"):   856                 self.use_name("__contains__", next_node)   857    858             this_node = next_node   859    860         return self.OP(node)   861    862     def visitConst(self, node):   863         return self._visitConst(node.value)   864    865     def visitContinue(self, node):   866         self.NOP(node)   867         self.suspend_continuing_branch()   868    869     visitDecorators = NOP   870    871     visitDict = OP   872    873     visitDiscard = NOP   874    875     visitDiv = _visitBinary   876    877     visitEllipsis = NOP   878    879     visitExec = NOP   880    881     visitExpression = OP   882    883     visitFloorDiv = _visitBinary   884    885     def visitFor(self, node):   886         self.new_branchpoint(node)   887    888         # Declare names which will be used by generated code.   889    890         self.use_name("__iter__", node.list)   891         self.use_name("next")   892         self.use_name("StopIteration")   893    894         in_loop = self.in_loop   895         self.in_loop = 1   896         self.dispatch(node.list)   897    898         # NOTE: Could generate AST nodes for the actual operations instead of   899         # NOTE: manually generating code in micropython.ast.   900    901         self.expr = make_instance() # each element is a result of a function call   902         self.dispatch(node.assign)   903    904         # Enter the loop.   905         # Propagate attribute usage to branches.   906    907         self.new_branch(node)   908         self.dispatch(node.body)   909    910         self.resume_continuing_branches()   911    912         self.shelve_branch()   913    914         self.in_loop = in_loop   915    916         # A null branch is used to record a path around the loop.   917    918         self.new_branch(node.else_ or NullBranch())   919         self.shelve_branch()   920    921         self.merge_branches()   922    923         # The else clause is evaluated outside any branch.   924    925         if node.else_ is not None:   926             self.dispatch(node.else_)   927    928         # Any suspended branches from the loop can now be resumed.   929    930         self.resume_broken_branches()   931    932     def visitFrom(self, node):   933         module = self.importer.load(node.modname, 1)   934    935         #if module is None:   936         #    print "Warning:", node.modname, "not imported."   937    938         for name, alias in node.names:   939             if name != "*":   940                 if module is not None:   941    942                     # Missing names may refer to submodules.   943    944                     if not module.has_key(name):   945                         submodule = self.importer.load(node.modname + "." + name, 1)   946                         if submodule is not None:   947                             module.store(name, submodule)   948    949                     # Complete the import if the name was found.   950    951                     if module.has_key(name):   952                         attr = module[name]   953                         self.store(alias or name, attr)   954                         self.use_specific_attribute(module.full_name(), name)   955                         if isinstance(attr.get_value(), Module) and not attr.get_value().loaded:   956                             self.importer.load(attr.get_value().name)   957                         continue   958    959                 # Support the import of names from missing modules.   960    961                 self.store(alias or name, UnresolvedName(name, node.modname, self))   962    963             else:   964                 if module is not None:   965                     for n in module.keys():   966                         attr = module[n]   967                         self.store(n, attr)   968                         self.use_specific_attribute(module.full_name(), n)   969                         if isinstance(attr.get_value(), Module) and not attr.get_value().loaded:   970                             self.importer.load(attr.get_value().name)   971    972     def visitFunction(self, node):   973         return self._visitFunction(node, node.name)   974    975     visitGenExpr = OP   976    977     visitGenExprFor = NOP   978    979     visitGenExprIf = NOP   980    981     visitGenExprInner = NOP   982    983     def visitGetattr(self, node):   984         expr = self.dispatch(node.expr)   985         attrname = node.attrname   986         return self._visitAttr(expr, attrname, node)   987    988     def visitGlobal(self, node):   989         if self.namespaces:   990             for name in node.names:   991                 ns = self.namespaces[-1]   992                 if not ns.make_global(name):   993                     raise InspectError("Name %r is global and local in %r" % (name, ns.full_name()))   994    995                 # The name is recorded in an earlier process.   996    997     def visitIf(self, node):   998         self.use_name("__bool__", node)   999         self.new_branchpoint()  1000   1001         # Propagate attribute usage to branches.  1002   1003         for test, body in node.tests:  1004             self.dispatch(test)  1005   1006             self.new_branch(body)  1007             self.dispatch(body)  1008             self.shelve_branch()  1009   1010         # Maintain a branch for the else clause.  1011   1012         self.new_branch(node.else_ or NullBranch())  1013         if node.else_ is not None:  1014             self.dispatch(node.else_)  1015         self.shelve_branch()  1016   1017         self.merge_branches()  1018   1019     def visitIfExp(self, node):  1020         self.use_name("__bool__", node)  1021         self.new_branchpoint()  1022   1023         # Propagate attribute usage to branches.  1024   1025         self.dispatch(node.test)  1026   1027         self.new_branch(node.then)  1028         self.dispatch(node.then)  1029         self.shelve_branch()  1030   1031         self.new_branch(node.else_)  1032         self.dispatch(node.else_)  1033         self.shelve_branch()  1034   1035         self.merge_branches()  1036         return make_instance() # either outcome is possible  1037   1038     def visitImport(self, node):  1039         for name, alias in node.names:  1040             if alias is not None:  1041                 module = self.importer.load(name, 1) or UnresolvedName(None, name, self)  1042                 self.store(alias, module)  1043             else:  1044                 module = self.importer.load(name) or UnresolvedName(None, name.split(".")[0], self)  1045                 self.store(name.split(".")[0], module)  1046   1047     visitInvert = _visitUnary  1048   1049     def visitKeyword(self, node):  1050         self.dispatch(node.expr)  1051         self._visitConst(node.name)  1052         self.keyword_names.add(node.name)  1053   1054     def visitLambda(self, node):  1055         fn = self._visitFunction(node, None)  1056         self.use_specific_attribute(None, fn.name)  1057         return fn  1058   1059     visitLeftShift = _visitBinary  1060   1061     def visitList(self, node):  1062         self.use_specific_attribute("__builtins__", "list")  1063         return self.OP(node)  1064   1065     def visitListComp(self, node):  1066         for qual in node.quals:  1067             self.dispatch(qual)  1068         self.dispatch(node.expr)  1069         return make_instance()  1070   1071     def visitListCompFor(self, node):  1072         self.new_branchpoint()  1073   1074         # Declare names which will be used by generated code.  1075   1076         self.use_name("__iter__", node.list)  1077         self.use_name("next")  1078   1079         in_loop = self.in_loop  1080         self.in_loop = 1  1081         self.dispatch(node.list)  1082   1083         # NOTE: Could generate AST nodes for the actual operations instead of  1084         # NOTE: manually generating code in micropython.ast.  1085   1086         self.expr = make_instance() # each element is a result of a function call  1087         self.dispatch(node.assign)  1088   1089         # Enter the loop.  1090         # Propagate attribute usage to branches.  1091   1092         self.new_branch(node)  1093   1094         for if_ in node.ifs:  1095             self.dispatch(if_)  1096   1097         self.shelve_branch()  1098         self.in_loop = in_loop  1099   1100         self.merge_branches()  1101   1102     visitListCompIf = TEST_NOP  1103   1104     visitMod = _visitBinary  1105   1106     def visitModule(self, node):  1107   1108         # Make a back reference from the node for code generation.  1109   1110         node.unit = self  1111         return self.dispatch(node.node)  1112   1113     visitMul = _visitBinary  1114   1115     def visitName(self, node):  1116         return self.get_namespace().get_using_node(node.name, node) or make_instance()  1117   1118     visitNot = TEST_OP  1119   1120     visitOr = TEST_OP  1121   1122     visitPass = NOP  1123   1124     visitPower = _visitBinary  1125   1126     def _visitPrint(self, node, function_name):  1127         self.NOP(node)  1128         self.use_specific_attribute("__builtins__", function_name)  1129   1130     def visitPrint(self, node):  1131         self._visitPrint(node, "_print")  1132   1133     def visitPrintnl(self, node):  1134         self._visitPrint(node, "_printnl")  1135   1136     visitRaise = NOP_ABANDON  1137   1138     visitReturn = NOP_ABANDON  1139   1140     visitRightShift = _visitBinary  1141   1142     def visitSlice(self, node):  1143         return self._visitOperator(node, self.in_assignment and "AssSlice" or "Slice")  1144   1145     visitSliceobj = OP  1146   1147     def visitStmt(self, node):  1148         for n in node.nodes:  1149             self.dispatch(n)  1150   1151     visitSub = _visitBinary  1152   1153     def visitSubscript(self, node):  1154         return self._visitOperator(node, self.in_assignment and "AssSubscript" or "Subscript")  1155   1156     def visitTryExcept(self, node):  1157         self.dispatch(node.body)  1158   1159         self.new_branchpoint()  1160   1161         for name, var, n in node.handlers:  1162             self.new_branch(node)  1163   1164             # Establish the local for the handler.  1165   1166             if var is not None:  1167                 self.dispatch(var)  1168             if n is not None:  1169                 self.dispatch(n)  1170   1171             self.shelve_branch()  1172   1173         self.new_branch(node.else_ or NullBranch())  1174         if node.else_ is not None:  1175             self.dispatch(node.else_)  1176         self.shelve_branch()  1177   1178         self.merge_branches()  1179   1180     visitTryFinally = NOP  1181   1182     visitTuple = OP  1183   1184     visitUnaryAdd = _visitUnary  1185   1186     visitUnarySub = _visitUnary  1187   1188     def visitWhile(self, node):  1189         self.use_name("__bool__", node)  1190         self.new_branchpoint(node)  1191   1192         # Propagate attribute usage to branches.  1193   1194         in_loop = self.in_loop  1195         self.in_loop = 1  1196   1197         # The test is evaluated initially and again in the loop.  1198   1199         self.dispatch(node.test)  1200   1201         self.new_branch(node)  1202         self.dispatch(node.body)  1203   1204         self.resume_continuing_branches()  1205   1206         self.dispatch(node.test)  1207         self.shelve_branch()  1208   1209         self.in_loop = in_loop  1210   1211         # A null branch is used to record a path around the loop.  1212   1213         self.new_branch(node.else_ or NullBranch())  1214         self.shelve_branch()  1215   1216         self.merge_branches()  1217   1218         # The else clause is evaluated outside any branch.  1219   1220         if node.else_ is not None:  1221             self.dispatch(node.else_)  1222   1223         # Any suspended branches from the loop can now be resumed.  1224   1225         self.resume_broken_branches()  1226   1227     visitWith = NOP  1228   1229     visitYield = NOP  1230   1231 # vim: tabstop=4 expandtab shiftwidth=4