# HG changeset patch # User Paul Boddie # Date 1300667111 -3600 # Node ID 7696283f65991c705dfd728cca7b1340211ba7fe # Parent 5c0225bbbd03e4881ace1d5a771b0adc5d9c9099 Fixed attribute coverage analysis to obtain the real identity of attributes in order to properly follow attribute references. Added various tests of instance attribute definition, usage and preservation. diff -r 5c0225bbbd03 -r 7696283f6599 micropython/__init__.py --- a/micropython/__init__.py Sun Mar 20 23:00:45 2011 +0100 +++ b/micropython/__init__.py Mon Mar 21 01:25:11 2011 +0100 @@ -617,23 +617,31 @@ #print "Warning: object type %r does not support attribute %r" % (objname, attrname) continue + # Get the real identity of the attribute in order to + # properly collect usage from it. + + parent = attr.parent + if isinstance(parent, micropython.data.Instance): + parentname = objname + else: + parentname = parent.full_name() + # Test for assignment. if attrvalues: - parent = attr.parent for attrvalue in attrvalues: parent.set(attrname, attrvalue, 0) # Visit attributes of objects known to be used. - if objname in self.attributes_used: - self.use_attribute(objname, attrname) - self._collect_attributes_from(from_name, objname, attrname, objtable) + if parentname in self.attributes_used: + self.use_attribute(parentname, attrname) + self._collect_attributes_from(from_name, parentname, attrname, objtable) # Record attributes of other objects for potential visiting. else: - self.add_attribute_to_visit(objname, attrname) + self.add_attribute_to_visit(parentname, attrname) # Get specific name references and visit the referenced objects. diff -r 5c0225bbbd03 -r 7696283f6599 micropython/inspect.py --- a/micropython/inspect.py Sun Mar 20 23:00:45 2011 +0100 +++ b/micropython/inspect.py Mon Mar 21 01:25:11 2011 +0100 @@ -319,6 +319,10 @@ cls = self.namespaces[-2] cls.add_instance_attribute(name) + + # NOTE: The instance attribute, although defined in a specific + # NOTE: class, obviously appears in all descendant classes. + self.use_specific_attribute(cls.full_name(), name) def get_namespace(self): diff -r 5c0225bbbd03 -r 7696283f6599 tests/attributes_instance_defined_in_method_used_by_subclass.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/attributes_instance_defined_in_method_used_by_subclass.py Mon Mar 21 01:25:11 2011 +0100 @@ -0,0 +1,15 @@ +#!/usr/bin/env python + +class C: + def init(self): + self.x = 456 + +class D(C): + def f(self): + return self.x + +d = D() +d.init() +result_456 = d.f() + +# vim: tabstop=4 expandtab shiftwidth=4 diff -r 5c0225bbbd03 -r 7696283f6599 tests/attributes_instance_unused.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/attributes_instance_unused.py Mon Mar 21 01:25:11 2011 +0100 @@ -0,0 +1,10 @@ +#!/usr/bin/env python + +class C: + def m(self): + self.x = 456 + +c = C() +result_1 = 1 # no real test: just make sure that c.x is not allocated + +# vim: tabstop=4 expandtab shiftwidth=4 diff -r 5c0225bbbd03 -r 7696283f6599 tests/attributes_instance_used_by_subclass.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/attributes_instance_used_by_subclass.py Mon Mar 21 01:25:11 2011 +0100 @@ -0,0 +1,14 @@ +#!/usr/bin/env python + +class C: + def __init__(self): + self.x = 456 + +class D(C): + def f(self): + return self.x + +d = D() +result_456 = d.f() + +# vim: tabstop=4 expandtab shiftwidth=4