1.1 --- a/micropython/inspect.py Wed Jul 04 01:25:34 2012 +0200
1.2 +++ b/micropython/inspect.py Fri Jul 06 01:52:10 2012 +0200
1.3 @@ -90,9 +90,8 @@
1.4 order:
1.5
1.6 1. parse
1.7 - 2. process_functions
1.8 - 3. vacuum
1.9 - 4. finalise
1.10 + 2. vacuum
1.11 + 3. finalise
1.12
1.13 A module importer can be expected to perform these invocations.
1.14 """
1.15 @@ -158,6 +157,10 @@
1.16
1.17 self.finalise_attribute_usage()
1.18
1.19 + # Visit functions.
1.20 +
1.21 + self.process_functions()
1.22 +
1.23 # Add references to other modules declared using the __all__ global.
1.24
1.25 if self.has_key("__all__"):
1.26 @@ -196,11 +199,11 @@
1.27 for name in n.names:
1.28
1.29 # Each name may potentially be assigned many times.
1.30 - # NOTE: We don't try and find out the specifics at this
1.31 - # NOTE: point and just set an instance instead.
1.32 + # We don't try and find out the specifics at this point and
1.33 + # just indicate that the name cannot be relied upon for
1.34 + # various observations.
1.35
1.36 - self.set(name, make_instance(), False)
1.37 - self.modified_names.add(name)
1.38 + module.modify_name(name)
1.39
1.40 else:
1.41 self.process_globals(n)
1.42 @@ -1007,8 +1010,8 @@
1.43 if module and not module.loaded:
1.44 print >>sys.stderr, "Warning: a circular import of %s is being attempted in %s" % (node.modname, self.full_name())
1.45
1.46 - #if module is None:
1.47 - # print >>sys.stderr, "Warning:", node.modname, "not imported."
1.48 + if module is None and self.importer.verbose:
1.49 + print >>sys.stderr, "Warning:", node.modname, "not imported."
1.50
1.51 for name, alias in node.names:
1.52
1.53 @@ -1036,7 +1039,16 @@
1.54 self.store(alias or name, attr)
1.55 self.use_specific_attribute(module.full_name(), name)
1.56 if isinstance(attr.get_value(), Module) and not attr.get_value().loaded:
1.57 - self.importer.load(attr.get_value().name, importer=node)
1.58 + submodule = self.importer.load(attr.get_value().name, importer=node)
1.59 +
1.60 + # For circular imports, invalidate attribute usage for
1.61 + # all exported names of submodules whose names are
1.62 + # specified in the from statement.
1.63 +
1.64 + if submodule and not submodule.loaded:
1.65 + for n in submodule.keys():
1.66 + submodule.modify_name(n)
1.67 +
1.68 continue
1.69
1.70 # Support the import of names from missing modules.
1.71 @@ -1053,7 +1065,15 @@
1.72 self.store(n, attr)
1.73 self.use_specific_attribute(module.full_name(), n)
1.74 if isinstance(attr.get_value(), Module) and not attr.get_value().loaded:
1.75 - self.importer.load(attr.get_value().name, importer=node)
1.76 + submodule = self.importer.load(attr.get_value().name, importer=node)
1.77 +
1.78 + # For circular imports, invalidate attribute usage
1.79 + # for all exported names of submodules provided by
1.80 + # the module.
1.81 +
1.82 + if submodule and not submodule.loaded:
1.83 + for subn in submodule.keys():
1.84 + submodule.modify_name(subn)
1.85
1.86 def visitFunction(self, node):
1.87 return self._visitFunction(node, node.name)
1.88 @@ -1131,6 +1151,15 @@
1.89 module = self.importer.load(name, importer=node) or UnresolvedName(None, name.split(".")[0], self)
1.90 self.store(name.split(".")[0], module)
1.91
1.92 + circular = module and not module.loaded
1.93 +
1.94 + # For circular imports, invalidate attribute usage for all exported
1.95 + # names of modules.
1.96 +
1.97 + if module and not module.loaded:
1.98 + for n in module.keys():
1.99 + module.modify_name(n)
1.100 +
1.101 visitInvert = _visitUnary
1.102
1.103 def visitKeyword(self, node):