[pypy-svn] r23856 - in pypy/dist/pypy: annotation rpython rpython/lltypesystem rpython/ootypesystem rpython/ootypesystem/test rpython/test
nik at codespeak.net
nik at codespeak.net
Wed Mar 1 19:02:25 CET 2006
Author: nik
Date: Wed Mar 1 19:02:16 2006
New Revision: 23856
Modified:
pypy/dist/pypy/annotation/builtin.py
pypy/dist/pypy/annotation/model.py
pypy/dist/pypy/rpython/lltypesystem/lltype.py
pypy/dist/pypy/rpython/lltypesystem/rclass.py
pypy/dist/pypy/rpython/ootypesystem/ootype.py
pypy/dist/pypy/rpython/ootypesystem/rbuiltin.py
pypy/dist/pypy/rpython/ootypesystem/rclass.py
pypy/dist/pypy/rpython/ootypesystem/rpbc.py
pypy/dist/pypy/rpython/ootypesystem/test/test_ooann.py
pypy/dist/pypy/rpython/ootypesystem/test/test_oopbc.py
pypy/dist/pypy/rpython/ootypesystem/test/test_oortype.py
pypy/dist/pypy/rpython/rclass.py
pypy/dist/pypy/rpython/rmodel.py
pypy/dist/pypy/rpython/rpbc.py
pypy/dist/pypy/rpython/test/test_rpbc.py
Log:
(pedronis, nik)
merge class attributes branch r23804:r23855 back into trunk. class attributes
now work with ootype.
Modified: pypy/dist/pypy/annotation/builtin.py
==============================================================================
--- pypy/dist/pypy/annotation/builtin.py (original)
+++ pypy/dist/pypy/annotation/builtin.py Wed Mar 1 19:02:16 2006
@@ -464,6 +464,11 @@
assert isinstance(i, SomeOOInstance)
return SomeOOClass(i.ootype)
+def subclassof(class1, class2):
+ assert isinstance(class1, SomeOOClass)
+ assert isinstance(class2, SomeOOClass)
+ return SomeBool()
+
def runtimenew(c):
assert isinstance(c, SomeOOClass)
if c.ootype is None:
@@ -480,6 +485,7 @@
BUILTIN_ANALYZERS[ootype.null] = null
BUILTIN_ANALYZERS[ootype.runtimenew] = runtimenew
BUILTIN_ANALYZERS[ootype.classof] = classof
+BUILTIN_ANALYZERS[ootype.subclassof] = subclassof
BUILTIN_ANALYZERS[ootype.ooidentityhash] = ooidentityhash
#________________________________
Modified: pypy/dist/pypy/annotation/model.py
==============================================================================
--- pypy/dist/pypy/annotation/model.py (original)
+++ pypy/dist/pypy/annotation/model.py Wed Mar 1 19:02:16 2006
@@ -565,6 +565,8 @@
return SomeOOInstance(T)
elif isinstance(T, ootype.StaticMethod):
return SomeOOStaticMeth(T)
+ elif T == ootype.Class:
+ return SomeOOClass(ootype.ROOT)
else:
return SomePtr(T)
else:
Modified: pypy/dist/pypy/rpython/lltypesystem/lltype.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/lltype.py (original)
+++ pypy/dist/pypy/rpython/lltypesystem/lltype.py Wed Mar 1 19:02:16 2006
@@ -64,6 +64,8 @@
def __ne__(self, other):
return not (self == other)
+ _is_compatible = __eq__
+
def __hash__(self):
# cannot use saferecursive() -- see test_lltype.test_hash().
# NB. the __cached_hash should neither be used nor updated
@@ -1100,6 +1102,7 @@
return result
def isCompatibleType(TYPE1, TYPE2):
+ return TYPE1._is_compatible(TYPE2)
return TYPE1 == TYPE2
# mark type ADT methods
Modified: pypy/dist/pypy/rpython/lltypesystem/rclass.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/rclass.py (original)
+++ pypy/dist/pypy/rpython/lltypesystem/rclass.py Wed Mar 1 19:02:16 2006
@@ -224,6 +224,8 @@
return llops.genop('cast_pointer', [vcls],
resulttype=self.lowleveltype)
+ fromclasstype = fromtypeptr
+
def getclsfield(self, vcls, attr, llops):
"""Read the given attribute of 'vcls'."""
if attr in self.clsfields:
Modified: pypy/dist/pypy/rpython/ootypesystem/ootype.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/ootype.py (original)
+++ pypy/dist/pypy/rpython/ootypesystem/ootype.py Wed Mar 1 19:02:16 2006
@@ -1,12 +1,23 @@
from pypy.rpython.lltypesystem.lltype import LowLevelType, Signed, Unsigned, Float, Char
-from pypy.rpython.lltypesystem.lltype import Bool, Void, UniChar, typeOf, Primitive
-from pypy.rpython.lltypesystem.lltype import frozendict
+from pypy.rpython.lltypesystem.lltype import Bool, Void, UniChar, typeOf, \
+ Primitive, isCompatibleType
+from pypy.rpython.lltypesystem.lltype import frozendict, isCompatibleType
class OOType(LowLevelType):
- pass
+
+ def _is_compatible(TYPE1, TYPE2):
+ if TYPE1 == TYPE2:
+ return True
+ if isinstance(TYPE1, Instance) and isinstance(TYPE2, Instance):
+ return isSubclass(TYPE1, TYPE2)
+ else:
+ return False
class Class(OOType):
- pass
+
+ def _defl(self):
+ return nullruntimeclass
+
Class = Class()
class Instance(OOType):
@@ -170,7 +181,7 @@
def __setattr__(self, name, value):
self.__getattr__(name)
- if self._TYPE._field_type(name) != typeOf(value):
+ if not isCompatibleType(typeOf(value), self._TYPE._field_type(name)):
raise TypeError("Expected type %r" % self._TYPE._field_type(name))
self.__dict__[name] = value
@@ -333,14 +344,6 @@
c = c._superclass
return None
-def isCompatibleType(TYPE1, TYPE2):
- if TYPE1 == TYPE2:
- return True
- if isinstance(TYPE1, Instance) and isinstance(TYPE2, Instance):
- return isSubclass(TYPE1, TYPE2)
- else:
- return False
-
def ooupcast(INSTANCE, instance):
assert instanceof(instance, INSTANCE)
return instance
Modified: pypy/dist/pypy/rpython/ootypesystem/rbuiltin.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/rbuiltin.py (original)
+++ pypy/dist/pypy/rpython/ootypesystem/rbuiltin.py Wed Mar 1 19:02:16 2006
@@ -10,11 +10,23 @@
return hop.genop('new', vlist,
resulttype = hop.r_result.lowleveltype)
+def rtype_null(hop):
+ assert hop.args_s[0].is_constant()
+ TYPE = hop.args_s[0].const
+ nullvalue = ootype.null(TYPE)
+ return hop.inputconst(TYPE, nullvalue)
+
def rtype_classof(hop):
assert isinstance(hop.args_s[0], annmodel.SomeOOInstance)
return hop.genop('classof', hop.args_v,
resulttype = ootype.Class)
+def rtype_subclassof(hop):
+ assert isinstance(hop.args_s[0], annmodel.SomeOOClass)
+ assert isinstance(hop.args_s[1], annmodel.SomeOOClass)
+ return hop.genop('subclassof', hop.args_v,
+ resulttype = ootype.Bool)
+
def rtype_runtimenew(hop):
assert isinstance(hop.args_s[0], annmodel.SomeOOClass)
return hop.genop('runtimenew', hop.args_v,
@@ -40,7 +52,7 @@
v_obj, v_cls = hop.inputargs(instance_repr, class_repr)
if isinstance(v_cls, Constant):
- c_cls = hop.inputconst(ootype.Void, v_cls.value._INSTANCE)
+ c_cls = hop.inputconst(ootype.Void, v_cls.value.class_._INSTANCE)
return hop.genop('instanceof', [v_obj, c_cls], resulttype=ootype.Bool)
else:
raise TyperError("XXX missing impl of isinstance(x, variable)")
@@ -48,7 +60,9 @@
BUILTIN_TYPER = {}
BUILTIN_TYPER[ootype.new] = rtype_new
+BUILTIN_TYPER[ootype.null] = rtype_null
BUILTIN_TYPER[ootype.classof] = rtype_classof
+BUILTIN_TYPER[ootype.subclassof] = rtype_subclassof
BUILTIN_TYPER[ootype.runtimenew] = rtype_runtimenew
BUILTIN_TYPER[ootype.ooidentityhash] = rtype_ooidentityhash
BUILTIN_TYPER[isinstance] = rtype_builtin_isinstance
Modified: pypy/dist/pypy/rpython/ootypesystem/rclass.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/rclass.py (original)
+++ pypy/dist/pypy/rpython/ootypesystem/rclass.py Wed Mar 1 19:02:16 2006
@@ -1,31 +1,139 @@
import types
from pypy.annotation import model as annmodel
from pypy.annotation import description
+from pypy.objspace.flow import model as flowmodel
from pypy.rpython.rmodel import inputconst, TyperError
+from pypy.rpython.rmodel import mangle as pbcmangle
from pypy.rpython.rclass import AbstractClassRepr, AbstractInstanceRepr, \
getinstancerepr, getclassrepr, get_type_repr
from pypy.rpython.ootypesystem import ootype
from pypy.annotation.pairtype import pairtype
from pypy.tool.sourcetools import func_with_new_name
-CLASSTYPE = ootype.Class
+CLASSTYPE = ootype.Instance("Object_meta", ootype.ROOT,
+ fields={"class_": ootype.Class})
+OBJECT = ootype.Instance("Object", ootype.ROOT,
+ fields={'meta': CLASSTYPE})
+
class ClassRepr(AbstractClassRepr):
def __init__(self, rtyper, classdef):
AbstractClassRepr.__init__(self, rtyper, classdef)
- self.lowleveltype = ootype.Class
+ if self.classdef is not None:
+ self.rbase = getclassrepr(self.rtyper, self.classdef.basedef)
+ base_type = self.rbase.lowleveltype
+ self.lowleveltype = ootype.Instance(
+ self.classdef.name + "_meta", base_type)
+ else:
+ # we are ROOT
+ self.lowleveltype = CLASSTYPE
def _setup_repr(self):
- pass # not actually needed?
+ clsfields = {}
+ pbcfields = {}
+ if self.classdef is not None:
+ # class attributes
+ llfields = []
+ """
+ attrs = self.classdef.attrs.items()
+ attrs.sort()
+ for name, attrdef in attrs:
+ if attrdef.readonly:
+ s_value = attrdef.s_value
+ s_unboundmethod = self.prepare_method(s_value)
+ if s_unboundmethod is not None:
+ allmethods[name] = True
+ s_value = s_unboundmethod
+ r = self.rtyper.getrepr(s_value)
+ mangled_name = 'cls_' + name
+ clsfields[name] = mangled_name, r
+ llfields.append((mangled_name, r.lowleveltype))
+ """
+ # attributes showing up in getattrs done on the class as a PBC
+ extra_access_sets = self.rtyper.class_pbc_attributes.get(
+ self.classdef, {})
+ for access_set, counter in extra_access_sets.items():
+ for attr, s_value in access_set.attrs.items():
+ r = self.rtyper.getrepr(s_value)
+ mangled_name = pbcmangle('pbc%d' % counter, attr)
+ pbcfields[access_set, attr] = mangled_name, r
+ llfields.append((mangled_name, r.lowleveltype))
+
+ self.rbase.setup()
+ ootype.addFields(self.lowleveltype, dict(llfields))
+ #self.clsfields = clsfields
+ self.pbcfields = pbcfields
+ self.meta_instance = None
+
+ def get_meta_instance(self, cast_to_root_meta=True):
+ if self.meta_instance is None:
+ self.meta_instance = ootype.new(self.lowleveltype)
+ self.setup_meta_instance(self.meta_instance, self)
+
+ meta_instance = self.meta_instance
+ if cast_to_root_meta:
+ meta_instance = ootype.ooupcast(CLASSTYPE, meta_instance)
+ return meta_instance
- def getruntime(self):
- return getinstancerepr(self.rtyper, self.classdef).lowleveltype._class
+ def setup_meta_instance(self, meta_instance, rsubcls):
+ if self.classdef is None:
+ rinstance = getinstancerepr(self.rtyper, rsubcls.classdef)
+ setattr(meta_instance, 'class_', rinstance.lowleveltype._class)
+ else:
+ # setup class attributes: for each attribute name at the level
+ # of 'self', look up its value in the subclass rsubcls
+ def assign(mangled_name, value):
+ if isinstance(value, flowmodel.Constant) and isinstance(value.value, staticmethod):
+ value = flowmodel.Constant(value.value.__get__(42)) # staticmethod => bare function
+ llvalue = r.convert_desc_or_const(value)
+ setattr(meta_instance, mangled_name, llvalue)
+
+ #mro = list(rsubcls.classdef.getmro())
+ #for fldname in self.clsfields:
+ # mangled_name, r = self.clsfields[fldname]
+ # if r.lowleveltype is Void:
+ # continue
+ # value = rsubcls.classdef.classdesc.read_attribute(fldname, None)
+ # if value is not None:
+ # assign(mangled_name, value)
+ # extra PBC attributes
+ for (access_set, attr), (mangled_name, r) in self.pbcfields.items():
+ if rsubcls.classdef.classdesc not in access_set.descs:
+ continue # only for the classes in the same pbc access set
+ if r.lowleveltype is ootype.Void:
+ continue
+ attrvalue = rsubcls.classdef.classdesc.read_attribute(attr, None)
+ if attrvalue is not None:
+ assign(mangled_name, attrvalue)
+
+ # then initialize the 'super' portion of the vtable
+ meta_instance_super = ootype.ooupcast(
+ self.rbase.lowleveltype, meta_instance)
+ self.rbase.setup_meta_instance(meta_instance_super, rsubcls)
+
+ getruntime = get_meta_instance
+
+ def fromclasstype(self, vclass, llops):
+ return llops.genop('oodowncast', [vclass],
+ resulttype=self.lowleveltype)
+
+ def getpbcfield(self, vcls, access_set, attr, llops):
+ if (access_set, attr) not in self.pbcfields:
+ raise TyperError("internal error: missing PBC field")
+ mangled_name, r = self.pbcfields[access_set, attr]
+ v_meta = self.fromclasstype(vcls, llops)
+ cname = inputconst(ootype.Void, mangled_name)
+ return llops.genop('oogetfield', [v_meta, cname], resulttype=r)
def rtype_issubtype(self, hop):
class_repr = get_type_repr(self.rtyper)
- vlist = hop.inputargs(class_repr, class_repr)
- return hop.genop('subclassof', vlist, resulttype=ootype.Bool)
+ vmeta1, vmeta2 = hop.inputargs(class_repr, class_repr)
+ return hop.gendirectcall(ll_issubtype, vmeta1, vmeta2)
+def ll_issubtype(meta1, meta2):
+ class1 = meta1.class_
+ class2 = meta2.class_
+ return ootype.subclassof(class1, class2)
# ____________________________________________________________
@@ -45,14 +153,14 @@
self.baserepr = None
if self.classdef is None:
- self.lowleveltype = ootype.ROOT
+ self.lowleveltype = OBJECT
else:
b = self.classdef.basedef
if b is not None:
self.baserepr = getinstancerepr(rtyper, b)
b = self.baserepr.lowleveltype
else:
- b = ootype.ROOT
+ b = OBJECT
self.lowleveltype = ootype.Instance(classdef.shortname, b, {}, {})
self.prebuiltinstances = {} # { id(x): (x, _ptr) }
@@ -259,7 +367,8 @@
if hop.args_s[0].can_be_none():
return hop.gendirectcall(ll_inst_type, vinst)
else:
- return hop.genop('classof', [vinst], resulttype=ootype.Class)
+ cmeta = inputconst(ootype.Void, "meta")
+ return hop.genop('oogetfield', [vinst, cmeta], resulttype=CLASSTYPE)
def rtype_hash(self, hop):
if self.classdef is None:
@@ -305,15 +414,23 @@
def new_instance(self, llops):
"""Build a new instance, without calling __init__."""
-
- return llops.genop("new",
+ classrepr = getclassrepr(self.rtyper, self.classdef)
+ v_instance = llops.genop("new",
[inputconst(ootype.Void, self.lowleveltype)], self.lowleveltype)
-
+ cmeta = inputconst(ootype.Void, "meta")
+ cmeta_instance = inputconst(CLASSTYPE, classrepr.get_meta_instance())
+ llops.genop("oosetfield", [v_instance, cmeta, cmeta_instance],
+ resulttype=ootype.Void)
+ return v_instance
+
def initialize_prebuilt_instance(self, value, result):
# then add instance attributes from this level
+ classrepr = getclassrepr(self.rtyper, self.classdef)
for mangled, (oot, default) in self.lowleveltype._allfields().items():
if oot is ootype.Void:
llattrvalue = None
+ elif mangled == 'meta':
+ llattrvalue = classrepr.get_meta_instance()
elif mangled == '_hash_cache_': # hash() support
llattrvalue = hash(value)
else:
@@ -370,7 +487,7 @@
def ll_inst_type(obj):
if obj:
- return ootype.classof(obj)
+ return obj.meta
else:
# type(None) -> NULL (for now)
- return ootype.nullruntimeclass
+ return ootype.null(CLASSTYPE)
Modified: pypy/dist/pypy/rpython/ootypesystem/rpbc.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/rpbc.py (original)
+++ pypy/dist/pypy/rpython/ootypesystem/rpbc.py Wed Mar 1 19:02:16 2006
@@ -18,9 +18,15 @@
classdef = hop.s_result.classdef
if self.lowleveltype is not ootype.Void:
# instantiating a class from multiple possible classes
- vclass = hop.inputarg(self, arg=0)
+ v_meta = hop.inputarg(self, arg=0)
+ c_class_ = hop.inputconst(ootype.Void, "class_")
+ v_class = hop.genop('oogetfield', [v_meta, c_class_],
+ resulttype=ootype.Class)
resulttype = getinstancerepr(hop.rtyper, classdef).lowleveltype
- v_instance = hop.genop('runtimenew', [vclass], resulttype=resulttype)
+ v_instance = hop.genop('runtimenew', [v_class], resulttype=resulttype)
+ c_meta = hop.inputconst(ootype.Void, "meta")
+ hop.genop('oosetfield', [v_instance, c_meta, v_meta],
+ resulttype=ootype.Void)
else:
# instantiating a single class
v_instance = rtype_new_instance(hop.rtyper, classdef, hop.llops)
Modified: pypy/dist/pypy/rpython/ootypesystem/test/test_ooann.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/test/test_ooann.py (original)
+++ pypy/dist/pypy/rpython/ootypesystem/test/test_ooann.py Wed Mar 1 19:02:16 2006
@@ -57,6 +57,21 @@
assert s == annmodel.SomeOOClass(I)
+def test_subclassof():
+ I = Instance("test", ROOT, {'a': Signed})
+ I1 = Instance("test1", I)
+
+ def oof():
+ i = new(I)
+ i1 = new(I1)
+ return subclassof(classof(i1), classof(i))
+
+ a = RPythonAnnotator()
+ s = a.build_types(oof, [])
+ #a.translator.view()
+
+ assert s == annmodel.SomeBool()
+
def test_simple_runtimenew():
I = Instance("test", ROOT, {'a': Signed})
Modified: pypy/dist/pypy/rpython/ootypesystem/test/test_oopbc.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/test/test_oopbc.py (original)
+++ pypy/dist/pypy/rpython/ootypesystem/test/test_oopbc.py Wed Mar 1 19:02:16 2006
@@ -64,3 +64,20 @@
assert 3 == interpret(f1, [], type_system="ootype")
assert 6 == interpret(f2, [], type_system="ootype")
+def test_classes_attribute():
+ class A:
+ a = 3
+ class B(A):
+ a = 2
+ def f(i):
+ if i == 1:
+ cls = B
+ else:
+ cls = A
+ instance = cls()
+ return cls.a
+ res = interpret(f, [0], type_system='ootype')
+ assert res == 3
+ res = interpret(f, [1], type_system='ootype')
+ assert res == 2
+
Modified: pypy/dist/pypy/rpython/ootypesystem/test/test_oortype.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/test/test_oortype.py (original)
+++ pypy/dist/pypy/rpython/ootypesystem/test/test_oortype.py Wed Mar 1 19:02:16 2006
@@ -72,3 +72,28 @@
assert res is False
res = interpret(oof, [False], type_system='ootype')
assert res is True
+
+def test_simple_classof():
+ I = Instance("test", ROOT, {'a': Signed})
+
+ def oof():
+ i = new(I)
+ return classof(i)
+
+ g = gengraph(oof, [])
+ rettype = g.getreturnvar().concretetype
+ assert rettype == Class
+
+def test_subclassof():
+ I = Instance("test", ROOT, {'a': Signed})
+ I1 = Instance("test1", I)
+
+ def oof():
+ i = new(I)
+ i1 = new(I1)
+ return subclassof(classof(i1), classof(i))
+
+ g = gengraph(oof, [])
+ rettype = g.getreturnvar().concretetype
+ assert rettype == Bool
+
Modified: pypy/dist/pypy/rpython/rclass.py
==============================================================================
--- pypy/dist/pypy/rpython/rclass.py (original)
+++ pypy/dist/pypy/rpython/rclass.py Wed Mar 1 19:02:16 2006
@@ -71,7 +71,7 @@
if self.classdef.commonbase(subclassdef) != self.classdef:
raise TyperError("not a subclass of %r: %r" % (
self.classdef.name, desc))
- #
+
return getclassrepr(self.rtyper, subclassdef).getruntime()
def convert_const(self, value):
Modified: pypy/dist/pypy/rpython/rmodel.py
==============================================================================
--- pypy/dist/pypy/rpython/rmodel.py (original)
+++ pypy/dist/pypy/rpython/rmodel.py Wed Mar 1 19:02:16 2006
@@ -4,7 +4,7 @@
from pypy.objspace.flow.model import Constant
from pypy.rpython.lltypesystem.lltype import \
Void, Bool, Float, Signed, Char, UniChar, \
- typeOf, LowLevelType, Ptr, PyObject
+ typeOf, LowLevelType, Ptr, PyObject, isCompatibleType
from pypy.rpython.ootypesystem import ootype
from pypy.rpython.error import TyperError, MissingRTypeOperation
@@ -329,7 +329,7 @@
realtype = typeOf(value)
except (AssertionError, AttributeError):
realtype = '???'
- if realtype != lltype:
+ if not isCompatibleType(realtype, lltype):
raise TyperError("inputconst(reqtype = %s, value = %s):\n"
"expected a %r,\n"
" got a %r" % (reqtype, value,
Modified: pypy/dist/pypy/rpython/rpbc.py
==============================================================================
--- pypy/dist/pypy/rpython/rpbc.py (original)
+++ pypy/dist/pypy/rpython/rpbc.py Wed Mar 1 19:02:16 2006
@@ -634,7 +634,7 @@
r_clspbc.rtyper.type_system.rclass.CLASSTYPE)
if not r_clspbc.get_class_repr().classdef.issubclass(r_cls.classdef):
return NotImplemented
- return r_cls.fromtypeptr(v, llops)
+ return r_cls.fromclasstype(v, llops)
class __extend__(pairtype(AbstractClassesPBCRepr, AbstractClassesPBCRepr)):
def convert_from_to((r_clspbc1, r_clspbc2), v, llops):
Modified: pypy/dist/pypy/rpython/test/test_rpbc.py
==============================================================================
--- pypy/dist/pypy/rpython/test/test_rpbc.py (original)
+++ pypy/dist/pypy/rpython/test/test_rpbc.py Wed Mar 1 19:02:16 2006
@@ -345,24 +345,24 @@
res = interpret(f1, [], type_system=self.ts)
assert res == 1
-def test_call_memo_with_class():
- class A: pass
- class FooBar(A): pass
- def memofn(cls):
- return len(cls.__name__)
- memofn._annspecialcase_ = "specialize:memo"
-
- def f1(i):
- if i == 1:
- cls = A
- else:
- cls = FooBar
- FooBar() # make sure we have ClassDefs
- return memofn(cls)
- res = interpret(f1, [1])
- assert res == 1
- res = interpret(f1, [2])
- assert res == 6
+ def test_call_memo_with_class(self):
+ class A: pass
+ class FooBar(A): pass
+ def memofn(cls):
+ return len(cls.__name__)
+ memofn._annspecialcase_ = "specialize:memo"
+
+ def f1(i):
+ if i == 1:
+ cls = A
+ else:
+ cls = FooBar
+ FooBar() # make sure we have ClassDefs
+ return memofn(cls)
+ res = interpret(f1, [1], type_system=self.ts)
+ assert res == 1
+ res = interpret(f1, [2], type_system=self.ts)
+ assert res == 6
def test_rpbc_bound_method_static_call():
class R:
More information about the Pypy-commit
mailing list