# HG changeset patch # User Paul Boddie # Date 1309716673 -7200 # Node ID af19598efe329ca43827eaecee8e599ddeffc03c # Parent b547786f38c7332e28c5b41465853c0a49b41888 Fixed attribute access inspection to not associate built-in attributes with unknown accesses since this is almost never desirable, especially in compound attribute accesses such as a.b.c where a.b may not be generally inferred. Changed __name__ assignment to modules, also adding __name__ assignment to classes. Added some visitor tests. diff -r b547786f38c7 -r af19598efe32 micropython/inspect.py --- a/micropython/inspect.py Sat Jul 02 02:41:33 2011 +0200 +++ b/micropython/inspect.py Sun Jul 03 20:11:13 2011 +0200 @@ -128,13 +128,9 @@ self.astnode = module - # Add __name__ to the namespace by adding an explicit assignment to the - # module. + # Add __name__ to the namespace. - module.node.nodes.insert(0, compiler.ast.Assign( - [compiler.ast.AssName("__name__", 0)], - compiler.ast.Const(self.full_name()) - )) + self.store("__name__", self._visitConst(self.full_name())) # First, visit module-level code, recording global names. @@ -479,10 +475,6 @@ self._visitAttrUser(expr, attrname, node) - elif self.builtins is not None: - attr = self.builtins.get(attrname) - self.use_specific_attribute(self.builtins.full_name(), attrname) - else: attr = None self.use_name(attrname, node) @@ -510,6 +502,17 @@ else: self.use_name(attrname, node.expr, value) + def _visitConst(self, value): + + """ + Register the constant given by 'value', if necessary, returning the + resulting object. The type name is noted as being used, thus preserving + the class in any generated program. + """ + + self.use_specific_attribute("__builtins__", self.importer.get_constant_type_name(value)) + return self.importer.make_constant(value) + def _visitFunction(self, node, name): """ @@ -642,7 +645,7 @@ for i, n in enumerate(node.nodes): self.dispatch(n) - self.importer.make_constant(i) # for __getitem__(i) at run-time + self._visitConst(i) # for __getitem__(i) at run-time return None def visitAssName(self, node): @@ -769,8 +772,10 @@ self.add_object(cls) # Process the class body in its own namespace. + # Add __name__ to the namespace. self.namespaces.append(cls) + self.store("__name__", self._visitConst(node.name)) self.dispatch(node.code) self.namespaces.pop() @@ -808,13 +813,7 @@ return self.OP(node) def visitConst(self, node): - - # Register the constant, if necessary, returning the resulting object. - # The type name is noted as being used, thus preserving the class in any - # generated program. - - self.use_specific_attribute("__builtins__", self.importer.get_constant_type_name(node.value)) - return self.importer.make_constant(node.value) + return self._visitConst(node.value) def visitContinue(self, node): self.NOP(node) @@ -974,7 +973,7 @@ def visitKeyword(self, node): self.dispatch(node.expr) - self.importer.make_constant(node.name) + self._visitConst(node.name) self.keyword_names.add(node.name) return None diff -r b547786f38c7 -r af19598efe32 tests/visitor_explicit.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/visitor_explicit.py Sun Jul 03 20:11:13 2011 +0200 @@ -0,0 +1,44 @@ +#!/usr/bin/env python + +class Branch: + def __init__(self, nodes): + self.nodes = nodes + + def visit(self, visitor): + return visitor.visitBranch(self) + +class Leaf: + def __init__(self, value): + self.value = value + + def visit(self, visitor): + return visitor.visitLeaf(self) + +class Visitor: + def visit(self, node): + return node.visit(self) + + # Visitor-specific functionality. + + def visitBranch(self, node): + sum = 0 + for node in node.nodes: + sum += self.visit(node) + return sum + + def visitLeaf(self, node): + return node.value + +tree = \ + Branch(( + Branch(( + Leaf(10), + Leaf(5) + )), + Leaf(2) + )) + +visitor = Visitor() +result_17 = visitor.visit(tree) + +# vim: tabstop=4 expandtab shiftwidth=4 diff -r b547786f38c7 -r af19598efe32 tests/visitor_getattr.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/visitor_getattr.py Sun Jul 03 20:11:13 2011 +0200 @@ -0,0 +1,40 @@ +#!/usr/bin/env python + +class Branch: + def __init__(self, nodes): + self.nodes = nodes + +class Leaf: + def __init__(self, value): + self.value = value + +class Visitor: + def visit(self, node): + method = getattr(self, node.__class__.__name__) + return method(node) + + # Visitor-specific functionality. + # Note that getattr does not support "visit" + __class__.__name__. + + def Branch(self, node): + sum = 0 + for node in node.nodes: + sum += self.visit(node) + return sum + + def Leaf(self, node): + return node.value + +tree = \ + Branch(( + Branch(( + Leaf(10), + Leaf(5) + )), + Leaf(2) + )) + +visitor = Visitor() +result_17 = visitor.visit(tree) + +# vim: tabstop=4 expandtab shiftwidth=4