[pypy-svn] r18787 - in pypy/dist/pypy/rpython/ootypesystem: . test
arigo at codespeak.net
arigo at codespeak.net
Thu Oct 20 11:47:19 CEST 2005
Author: arigo
Date: Thu Oct 20 11:47:18 2005
New Revision: 18787
Modified:
pypy/dist/pypy/rpython/ootypesystem/ootype.py
pypy/dist/pypy/rpython/ootypesystem/rclass.py
pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py
Log:
ootyper: abstract base methods
Modified: pypy/dist/pypy/rpython/ootypesystem/ootype.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/ootype.py (original)
+++ pypy/dist/pypy/rpython/ootypesystem/ootype.py Thu Oct 20 11:47:18 2005
@@ -73,10 +73,11 @@
# _add_fields adds *descriptions* of fields. This is obvious
# if you are in the right state of mind (swiss?), but
# certainly not necessarily if not.
+ # NB. a None method is a purely abstract one.
for name, method in methods.iteritems():
if self._has_field(name):
raise TypeError("Can't add method %r: field already exists" % name)
- if not isinstance(typeOf(method), Meth):
+ if method is not None and not isinstance(typeOf(method), Meth):
raise TypeError("added methods must be _meths, not %s" % type(defn))
self._methods.update(methods)
Modified: pypy/dist/pypy/rpython/ootypesystem/rclass.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/rclass.py (original)
+++ pypy/dist/pypy/rpython/ootypesystem/rclass.py Thu Oct 20 11:47:18 2005
@@ -123,9 +123,15 @@
if not attrdef.readonly:
continue
mangled = mangle(name)
+ is_method = (classrepr.prepare_method(attrdef.s_value)
+ is not None)
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 is_method and mangled in allclassattributes:
+ raise TyperError("method overrides class attribute")
+ if not is_method and mangled in allmethods:
+ raise TyperError("class attribute overrides method")
if name not in self.classdef.cls.__dict__:
continue
impl = self.classdef.cls.__dict__[name]
@@ -138,14 +144,21 @@
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:
+ if is_method:
+ impl = None # abstract base method
+ else:
+ raise TyperError("class %r has no attribute %r" % (
+ self.classdef.cls, name))
+ if is_method:
# a regular method
- f, inputs, ret = getsignature(self.rtyper, impl)
+ exmpl = impl or attrdef.s_value.prebuiltinstances.keys()[0]
+ f, inputs, ret = getsignature(self.rtyper, exmpl)
M = ootype.Meth([r.lowleveltype for r in inputs[1:]], ret.lowleveltype)
- m = ootype.meth(M, _name=mangled, _callable=impl,
- graph=f.graph)
+ if impl:
+ m = ootype.meth(M, _name=mangled, _callable=impl,
+ graph=f.graph)
+ else:
+ m = None
methods[mangled] = m
allmethods[mangled] = True
else:
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 Thu Oct 20 11:47:18 2005
@@ -491,3 +491,23 @@
return e.attr()
res = interpret(f, [])
assert res == 42
+
+def test_abstract_base_method():
+ class A(object):
+ pass
+ class B(A):
+ def f(self):
+ return 2
+ class C(A):
+ def f(self):
+ return 3
+ def f(flag):
+ if flag:
+ x = B()
+ else:
+ x = C()
+ return x.f()
+ res = interpret(f, [True])
+ assert res == 2
+ res = interpret(f, [False])
+ assert res == 3
More information about the Pypy-commit
mailing list