# HG changeset patch # User Paul Boddie # Date 1473434658 -7200 # Node ID 9ac20871fd928bca3f885f395bdd54d0aefbbd22 # Parent 1d6e47d3637631ef16c9e0fb0c16b6d34cd59070# Parent 011a7abf698c19ae1063c3401c845108aec55f10 Merged changes from the optional-self-parameter branch. diff -r 1d6e47d36376 -r 9ac20871fd92 inspector.py --- a/inspector.py Fri Sep 09 17:23:45 2016 +0200 +++ b/inspector.py Fri Sep 09 17:24:18 2016 +0200 @@ -554,12 +554,38 @@ # Initialise argument and local records. function_name = self.get_object_path(name) + argnames = get_argnames(n.argnames) + is_method = self.in_class and not self.in_function - argnames = self.importer.function_parameters[function_name] = \ - self.function_parameters[function_name] = get_argnames(n.argnames) + # Remove explicit "self" from method parameters. + + if is_method and argnames and argnames[0] == "self": + del argnames[0] + + # Copy and propagate the parameters. + + self.importer.function_parameters[function_name] = \ + self.function_parameters[function_name] = argnames[:] + + # Define all arguments/parameters in the local namespace. + locals = self.function_locals[function_name] = {} - for argname in argnames: + # Insert "self" into method locals. + + if is_method: + argnames.insert(0, "self") + + # Define "self" in terms of the class if in a method. + # This does not diminish the need for type-narrowing in the deducer. + + if argnames: + if self.in_class and not self.in_function and argnames[0] == "self": + locals[argnames[0]] = Reference("", self.in_class) + else: + locals[argnames[0]] = Reference("") + + for argname in argnames[1:]: locals[argname] = Reference("") globals = self.scope_globals[function_name] = set() diff -r 1d6e47d36376 -r 9ac20871fd92 tests/methods.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/methods.py Fri Sep 09 17:24:18 2016 +0200 @@ -0,0 +1,26 @@ +class C: + def __init__(self, x, y, z): + self.x = x + self.y = y + self.z = z + + def c(self): + return self.x + +class D(C): + def d(self): + return self.y + +class E(D): + def c(self): + return self.z + +c = C(1, 2, 3) +d = D(1, 2, 3) +e = E(1, 2, 3) + +result1 = c.c() # 1 +result2 = d.c() # 1 +result3 = e.c() # 3 +result4 = d.d() # 2 +result5 = e.d() # 2 diff -r 1d6e47d36376 -r 9ac20871fd92 tests/methods_selfless.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/methods_selfless.py Fri Sep 09 17:24:18 2016 +0200 @@ -0,0 +1,26 @@ +class C: + def __init__(x, y, z): # no explicit self + self.x = x + self.y = y + self.z = z + + def c(): + return self.x + +class D(C): + def d(): + return self.y + +class E(D): + def c(): + return self.z + +c = C(1, 2, 3) +d = D(1, 2, 3) +e = E(1, 2, 3) + +result1 = c.c() # 1 +result2 = d.c() # 1 +result3 = e.c() # 3 +result4 = d.d() # 2 +result5 = e.d() # 2