[pypy-svn] r18755 - in pypy/dist/pypy/rpython/ootypesystem: . test
arigo at codespeak.net
arigo at codespeak.net
Wed Oct 19 17:03:38 CEST 2005
Author: arigo
Date: Wed Oct 19 17:03:38 2005
New Revision: 18755
Modified:
pypy/dist/pypy/rpython/ootypesystem/rclass.py
pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py
Log:
fix bug with methods and class attributes not being found
if present in a superclass but used from a subclass.
Modified: pypy/dist/pypy/rpython/ootypesystem/rclass.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/rclass.py (original)
+++ pypy/dist/pypy/rpython/ootypesystem/rclass.py Wed Oct 19 17:03:38 2005
@@ -1,5 +1,5 @@
import types
-from pypy.rpython.rmodel import inputconst
+from pypy.rpython.rmodel import inputconst, TyperError
from pypy.rpython.rclass import AbstractClassRepr, AbstractInstanceRepr, \
getinstancerepr, getclassrepr, get_type_repr
from pypy.rpython.rpbc import getsignature
@@ -95,11 +95,24 @@
for name, attrdef in attrs:
if not attrdef.readonly:
continue
- try:
- impl = self.classdef.cls.__dict__[name]
- except KeyError:
- continue
mangled = mangle(name)
+ if mangled in allmethods or mangled in allclassattributes:
+ # if the method/attr was already found in a parent class,
+ # we register it again only if it is overridden.
+ if name not in self.classdef.cls.__dict__:
+ continue
+ impl = self.classdef.cls.__dict__[name]
+ else:
+ # otherwise, for new method/attrs, we look in all parent
+ # classes to see if it's defined in a parent but only
+ # actually first used in self.classdef.
+ for clsdef in self.classdef.getmro():
+ if name in clsdef.cls.__dict__:
+ impl = clsdef.cls.__dict__[name]
+ break
+ else:
+ raise TyperError("class %r has no attribute %r" % (
+ self.classdef.cls, name))
if classrepr.prepare_method(attrdef.s_value) is not None:
# a regular method
f, inputs, ret = getsignature(self.rtyper, impl)
Modified: pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py (original)
+++ pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py Wed Oct 19 17:03:38 2005
@@ -118,6 +118,18 @@
result = interpret(dummyfn, [False], type_system='ootype')
assert result == 2
+def test_method_used_in_subclasses_only():
+ class A:
+ def meth(self):
+ return 123
+ class B(A):
+ pass
+ def f():
+ x = B()
+ return x.meth()
+ res = interpret(f, [], type_system='ootype')
+ assert res == 123
+
class HasAField(object):
def f(self):
return self.a
@@ -189,6 +201,26 @@
res = interpret(dummyfn, [], type_system='ootype')
assert res == 4
+def test_classattr_used_in_subclasses_only():
+ class Subclass1(HasClassAttr):
+ pass
+ class Subclass2(HasClassAttr):
+ pass
+ class SubSubclass2(Subclass2):
+ a = 5432
+ def dummyfn(flag):
+ inst1 = Subclass1()
+ inst1.a += 42 # used as default
+ if flag:
+ inst2 = Subclass2()
+ else:
+ inst2 = SubSubclass2()
+ return inst1.a + inst2.a
+ res = interpret(dummyfn, [True], type_system='ootype')
+ assert res == (3 + 42) + 3
+ res = interpret(dummyfn, [False], type_system='ootype')
+ assert res == (3 + 42) + 5432
+
def test_name_clashes():
class NameClash1(object):
def _TYPE(self):
More information about the Pypy-commit
mailing list