# HG changeset patch # User paulb@localhost.localdomain # Date 1168295873 -3600 # Node ID cdf6d3c636eb9fd7b7e8f41576c02aa1141cbebe # Parent 79b255e8af48e8efbb191d026caea3551e595008 Added an exception to the locally defined function names rule: within a class definition, methods should not be accessible via their plain names alone (ie. like functions). diff -r 79b255e8af48 -r cdf6d3c636eb annotate.py --- a/annotate.py Sun Jan 07 23:44:39 2007 +0100 +++ b/annotate.py Mon Jan 08 23:37:53 2007 +0100 @@ -949,9 +949,10 @@ using_module_namespace = 0 # NOTE: Avoid PEP 227 (nested scopes) whilst permitting references to a - # NOTE: subprogram within itself. + # NOTE: subprogram within itself. Do not define the name of the function + # NOTE: within a method definition. - if hasattr(target, "name") and target.name is not None: + if getattr(target, "name", None) is not None and not getattr(target, "is_method", 0): namespace.store(target.name, [Attribute(None, target)]) # Process the subprogram. diff -r 79b255e8af48 -r cdf6d3c636eb fixnames.py --- a/fixnames.py Sun Jan 07 23:44:39 2007 +0100 +++ b/fixnames.py Mon Jan 08 23:37:53 2007 +0100 @@ -165,9 +165,10 @@ self.namespace.merge_namespace(namespace) # NOTE: Avoid PEP 227 (nested scopes) whilst permitting references to a - # NOTE: subprogram within itself. + # NOTE: subprogram within itself. Do not define the name of the function + # NOTE: within a method definition. - if hasattr(node, "name") and node.name is not None: + if getattr(node, "name", None) is not None and not getattr(node, "is_method", 0): self.namespace.store(node.name) # Register the names of parameters in the namespace. diff -r 79b255e8af48 -r cdf6d3c636eb simplify.py --- a/simplify.py Sun Jan 07 23:44:39 2007 +0100 +++ b/simplify.py Mon Jan 08 23:37:53 2007 +0100 @@ -73,6 +73,7 @@ self.constants = {} # Constants. self.current_subprograms = [] # Current subprograms being processed. self.current_structures = [] # Current structures being processed. + self.within_class = 0 # Whether a class is being defined. self.builtins = builtins # Whether the builtins are being processed. # Convenience attributes. @@ -434,6 +435,8 @@ structure = Class(name=class_.name, module=self.module, bases=self.dispatches(bases)) self.structures.append(structure) + within_class = self.within_class + self.within_class = 1 # Make a subprogram which initialises the class structure. @@ -445,6 +448,7 @@ subprogram.code = self.dispatch(class_.code) + [ReturnFromBlock()] + self.within_class = within_class self.current_structures.pop() self.current_subprograms.pop() self.subprograms.append(subprogram); self.subnames[subprogram.full_name()] = subprogram @@ -803,10 +807,15 @@ """ subprogram = Subprogram(name=function.name, module=self.module, structures=self.current_structures[:], - internal=0, returns_value=1, star=None, dstar=None) + internal=0, returns_value=1, star=None, dstar=None, is_method=self.within_class) self.current_subprograms.append(subprogram) + within_class = self.within_class + self.within_class = 0 + subprogram.code = self.dispatch(function.code) + [ReturnFromFunction()] + + self.within_class = within_class self.current_subprograms.pop() self._visitFunction(function, subprogram) diff -r 79b255e8af48 -r cdf6d3c636eb tests/nested_functions.py --- a/tests/nested_functions.py Sun Jan 07 23:44:39 2007 +0100 +++ b/tests/nested_functions.py Mon Jan 08 23:37:53 2007 +0100 @@ -1,3 +1,14 @@ +class C: + def f(self): + return f + + def f2(self): + def g2(x): + if x <= 0: + return x + return g2(x - 1) + x + return g2 + def f(): def g(x): if x <= 0: @@ -7,3 +18,7 @@ a = f() b = a(3) +c = C() +c.f() +d = c.f2() +e = d(3)