# HG changeset patch # User Paul Boddie # Date 1308442078 -7200 # Node ID 36ceaeeee09185cf6d2c2b49ee85e90faf0b6bc1 # Parent c6d14167bc209655c36ec5c3fb067ff9c675202e Prevent the recording of attribute usage for names defined and referenced in a local scope. An exception is made for module-level names. Introduced explicit support for function aliases by making an attribute usage link from the alias to the original function's attribute, working with/around the vacuuming mechanism which will remove unused functions if their defining attribute is unused. Added some tests of function assignment within classes where only certain attributes should be exposed depending on usage. diff -r c6d14167bc20 -r 36ceaeeee091 micropython/data.py --- a/micropython/data.py Sun Jun 19 02:01:51 2011 +0200 +++ b/micropython/data.py Sun Jun 19 02:07:58 2011 +0200 @@ -174,7 +174,7 @@ node._scope = scope self.note_scope(name, scope) - if full_name is not None: + if full_name is not None and (scope != "local" or self is self.module): self.use_specific_attribute(full_name, name) return attr @@ -470,7 +470,7 @@ # These shadow various methods in the InspectedModule class, and provide # implementations generally. - def _use_specific_attribute(self, objname, attrname): + def _use_specific_attribute(self, objname, attrname, from_name=None): """ Note attribute usage specifically on 'objname' - an object which is @@ -480,7 +480,7 @@ This bypasses attribute user mechanisms. """ - from_name = self.full_name() + from_name = from_name or self.full_name() objname = objname or from_name module = self.module importer = module and module.importer diff -r c6d14167bc20 -r 36ceaeeee091 micropython/inspect.py --- a/micropython/inspect.py Sun Jun 19 02:01:51 2011 +0200 +++ b/micropython/inspect.py Sun Jun 19 02:07:58 2011 +0200 @@ -398,7 +398,7 @@ return self.get_namespace()._use_attribute(name, attrname, value) - def use_specific_attribute(self, objname, attrname): + def use_specific_attribute(self, objname, attrname, from_name=None): """ Note usage on the object having the given 'objname' of the attribute @@ -406,7 +406,7 @@ object providing the attribute. """ - return self.get_namespace()._use_specific_attribute(objname, attrname) + return self.get_namespace()._use_specific_attribute(objname, attrname, from_name) # Visitor methods. @@ -657,7 +657,14 @@ # NOTE: Consider not registering assignments involving methods, since # NOTE: this is merely creating aliases for such methods. - self.use_specific_attribute(None, node.name) + if isinstance(self.get_namespace(), (Class, Module)): + if not isinstance(self.expr, Attr) or not isinstance(self.expr.get_value(), Function): + self.use_specific_attribute(None, node.name) + else: + fn = self.expr.get_value() + ns = self.get_namespace().full_name() + self.use_specific_attribute(fn.parent.full_name(), fn.name, "%s.%s" % (ns, node.name)) + return None visitAssTuple = visitAssList diff -r c6d14167bc20 -r 36ceaeeee091 tests/class_function_assignment.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/class_function_assignment.py Sun Jun 19 02:07:58 2011 +0200 @@ -0,0 +1,16 @@ +#!/usr/bin/env python + +def f(self, x): + return 2 + +class C: + def g(self, x): + return 1 + h = f + +c = C() +result_1 = c.g(123) +#result_2 = c.h(123) +result_2 = f(123, 456) + +# vim: tabstop=4 expandtab shiftwidth=4 diff -r c6d14167bc20 -r 36ceaeeee091 tests/class_function_assignment_unused.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/class_function_assignment_unused.py Sun Jun 19 02:07:58 2011 +0200 @@ -0,0 +1,16 @@ +#!/usr/bin/env python + +def f(self, x): + return 2 + +class C: + def g(self, x): + return 1 + h = f + +c = C() +result_1 = c.g(123) +#result_2 = c.h(123) +#result_2 = f(123, 456) + +# vim: tabstop=4 expandtab shiftwidth=4 diff -r c6d14167bc20 -r 36ceaeeee091 tests/class_function_assignment_using_target.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/class_function_assignment_using_target.py Sun Jun 19 02:07:58 2011 +0200 @@ -0,0 +1,16 @@ +#!/usr/bin/env python + +def f(self, x): + return 2 + +class C: + def g(self, x): + return 1 + h = f + +c = C() +result_1 = c.g(123) +result_2 = c.h(123) +#result_2 = f(123, 456) + +# vim: tabstop=4 expandtab shiftwidth=4