# HG changeset patch # User Paul Boddie # Date 1372637423 -7200 # Node ID 56396b2453d84859052400ed7fd616614dd39825 # Parent e148fb5f222a56cf71b3ecf398f8056bf645a19c Introduced numbered functions where rebinding occurs in namespaces. Added an original name attribute to classes and functions, revised the check for usage of functions when generating code or reports, and added rebinding statements to module "main program" syspython output. Fixed the attribute operation generated by syspython when acquiring module attributes for a "from" statement. diff -r e148fb5f222a -r 56396b2453d8 docs/syspython.txt --- a/docs/syspython.txt Mon Jul 01 00:47:43 2013 +0200 +++ b/docs/syspython.txt Mon Jul 01 02:10:23 2013 +0200 @@ -71,9 +71,8 @@ def __main__(): __globalnames__(...) ... - method = module.C.method if something: - __storeattr__(module.C, something) + __storeattr__(module.C, method, something) Imports ------- diff -r e148fb5f222a -r 56396b2453d8 micropython/common.py --- a/micropython/common.py Mon Jul 01 00:47:43 2013 +0200 +++ b/micropython/common.py Mon Jul 01 02:10:23 2013 +0200 @@ -237,7 +237,7 @@ program unit within which it is found. """ - return node.unit and node.unit.parent.has_key(node.unit.name) + return node.unit and node.unit.parent.has_key(node.unit.original_name) # Useful data. diff -r e148fb5f222a -r 56396b2453d8 micropython/data.py --- a/micropython/data.py Mon Jul 01 00:47:43 2013 +0200 +++ b/micropython/data.py Mon Jul 01 02:10:23 2013 +0200 @@ -554,7 +554,7 @@ "A base class for common/normal classes and the type class." - def __init__(self, name, parent=None, module=None, node=None): + def __init__(self, name, parent=None, module=None, node=None, original_name=None): """ Initialise the class with the given 'name', optional 'parent' object, @@ -566,6 +566,7 @@ self.name = name self.parent = parent self.astnode = node + self.original_name = original_name or name # Superclasses, descendants and attributes. @@ -975,7 +976,7 @@ "An inspected function." def __init__(self, name, parent, argnames, defaults, has_star, has_dstar, - dynamic_def=0, module=None, node=None): + dynamic_def=0, module=None, node=None, original_name=None): """ Initialise the function with the given 'name', 'parent', list of @@ -995,6 +996,8 @@ self.name = name self._is_lambda = False + self.original_name = original_name or name + self.parent = parent self.argnames = argnames self.defaults = defaults @@ -1487,10 +1490,12 @@ # Where names are reused in a namespace, differentiate between classes # using a name index. + original_name = name + if parent.has_key(name): name = "%s#%d" % (name, parent[name].assignments + 1) - cls = Class(name, parent, module, node) + cls = Class(name, parent, module, node, original_name) # Add a reference for the class's "shadow" name. @@ -1498,6 +1503,31 @@ return cls +# Function construction. + +def get_function(name, parent, argnames, defaults, has_star, has_dstar, + dynamic_def=0, module=None, node=None): + + """ + Return a Function instance for the class with the given 'name', 'parent', + and other details. + """ + + original_name = name + + if parent.has_key(name): + name = "%s#%d" % (name, parent[name].assignments + 1) + + fn = Function(name, parent, argnames, defaults, has_star, has_dstar, + dynamic_def, module, node, original_name) + + # Add a reference for the function's "shadow" name. + + if name: + parent.use_specific_attribute(parent.full_name(), name) + + return fn + # Lambda sequence numbering. lambda_index = 0 diff -r e148fb5f222a -r 56396b2453d8 micropython/inspect.py --- a/micropython/inspect.py Mon Jul 01 00:47:43 2013 +0200 +++ b/micropython/inspect.py Mon Jul 01 02:10:23 2013 +0200 @@ -752,7 +752,7 @@ # Define the function object. - function = Function( + function = get_function( name, self.get_namespace(), node.argnames, diff -r e148fb5f222a -r 56396b2453d8 micropython/syspython.py --- a/micropython/syspython.py Mon Jul 01 00:47:43 2013 +0200 +++ b/micropython/syspython.py Mon Jul 01 02:10:23 2013 +0200 @@ -299,7 +299,7 @@ compiler.ast.Assign( [special_name(alias or name)], compiler.ast.CallFunc( - special_name("__loadattribute__"), + special_name("__loadattr__"), [special_name(node.modname), special_name(name)] ) ) @@ -314,10 +314,19 @@ self.units.append(node.unit) try: - # Ignore functions when generating the main function. + if self.in_main: + + # Generate rebindings of functions. - if self.in_main: - return compiler.ast.Stmt([]) + fn = node.unit + if fn.name == fn.original_name: + return compiler.ast.Stmt([]) + else: + return compiler.ast.CallFunc( + special_name("__storeattr__"), + [quoted_ref(fn.parent), special_name(fn.original_name), + quoted_ref(fn)] + ) else: return self._visitFunctionDefinition(node) finally: diff -r e148fb5f222a -r 56396b2453d8 tests/class_method_changed.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/class_method_changed.py Mon Jul 01 02:10:23 2013 +0200 @@ -0,0 +1,22 @@ +#!/usr/bin/env python + +class C: + def f(self): + return 1 + + def g(self): + return 2 + + def f(self): # is f#2 + return 3 + + g = f # g = f#2 + + def f(self): # is f#3 + return 5 + +c = C() +result1_3 = c.f() +result2_3 = c.g() + +# vim: tabstop=4 expandtab shiftwidth=4 diff -r e148fb5f222a -r 56396b2453d8 tests/class_method_multiple.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/class_method_multiple.py Mon Jul 01 02:10:23 2013 +0200 @@ -0,0 +1,18 @@ +#!/usr/bin/env python + +class C: + def f(self): + return 1 + def f(self): + return 2 + + def g(self): + return 2 + def g(self): + return 3 + +c = C() +result_2 = c.f() +result_3 = c.g() + +# vim: tabstop=4 expandtab shiftwidth=4