[pypy-svn] r17617 - in pypy/dist/pypy/rpython: . test
cfbolz at codespeak.net
cfbolz at codespeak.net
Sat Sep 17 18:14:15 CEST 2005
Author: cfbolz
Date: Sat Sep 17 18:14:12 2005
New Revision: 17617
Modified:
pypy/dist/pypy/rpython/exceptiondata.py
pypy/dist/pypy/rpython/extfunctable.py
pypy/dist/pypy/rpython/normalizecalls.py
pypy/dist/pypy/rpython/rbuiltin.py
pypy/dist/pypy/rpython/rclass.py
pypy/dist/pypy/rpython/test/test_exception.py
pypy/dist/pypy/rpython/test/test_rbuiltin.py
Log:
issue141: testing
implemented issubclass checks using relative numbering including some more
isinstance tests. This required quite some fixes in various places because of
exceptions.
Modified: pypy/dist/pypy/rpython/exceptiondata.py
==============================================================================
--- pypy/dist/pypy/rpython/exceptiondata.py (original)
+++ pypy/dist/pypy/rpython/exceptiondata.py Sat Sep 17 18:14:12 2005
@@ -4,7 +4,7 @@
from pypy.rpython.lltype import Array, malloc, Ptr, PyObject, pyobjectptr
from pypy.rpython.lltype import FuncType, functionptr, Signed
from pypy.rpython.extfunctable import standardexceptions
-
+from pypy.annotation.classdef import FORCE_ATTRIBUTES_INTO_CLASSES
class ExceptionData:
"""Public information for the code generators to help with exceptions."""
@@ -70,7 +70,7 @@
if (clsdef and clsdef.cls is not Exception
and issubclass(clsdef.cls, Exception)):
cls = clsdef.cls
- if cls in self.standardexceptions:
+ if cls in self.standardexceptions and cls not in FORCE_ATTRIBUTES_INTO_CLASSES:
is_standard = True
assert not clsdef.attrs, (
"%r should not have grown atributes" % (cls,))
Modified: pypy/dist/pypy/rpython/extfunctable.py
==============================================================================
--- pypy/dist/pypy/rpython/extfunctable.py (original)
+++ pypy/dist/pypy/rpython/extfunctable.py Sat Sep 17 18:14:12 2005
@@ -214,4 +214,9 @@
ZeroDivisionError: True,
MemoryError : True,
IOError : True,
+ OSError : True,
+ StopIteration : True,
+ KeyError : True,
+ IndexError : True,
+ AssertionError : True,
}
Modified: pypy/dist/pypy/rpython/normalizecalls.py
==============================================================================
--- pypy/dist/pypy/rpython/normalizecalls.py (original)
+++ pypy/dist/pypy/rpython/normalizecalls.py Sat Sep 17 18:14:12 2005
@@ -340,7 +340,19 @@
annotator.setbinding(graph.getreturnvar(), generalizedresult)
classdef.my_instantiate = my_instantiate
-
+def assign_inheritance_ids(annotator):
+ def assign_id(classdef, nextid):
+ classdef.minid = nextid
+ nextid += 1
+ for subclass in classdef.subdefs.values():
+ nextid = assign_id(subclass, nextid)
+ classdef.maxid = nextid
+ return classdef.maxid
+ id_ = 0
+ for cls, classdef in annotator.getuserclasses().items():
+ if classdef.basedef is None:
+ id_ = assign_id(classdef, id_)
+
def perform_normalizations(rtyper):
create_class_constructors(rtyper)
rtyper.annotator.frozen += 1
@@ -348,6 +360,7 @@
normalize_function_signatures(rtyper.annotator)
specialize_pbcs_by_memotables(rtyper.annotator)
merge_classpbc_getattr_into_classdef(rtyper)
+ assign_inheritance_ids(rtyper.annotator)
finally:
rtyper.annotator.frozen -= 1
create_instantiate_functions(rtyper.annotator)
Modified: pypy/dist/pypy/rpython/rbuiltin.py
==============================================================================
--- pypy/dist/pypy/rpython/rbuiltin.py (original)
+++ pypy/dist/pypy/rpython/rbuiltin.py Sat Sep 17 18:14:12 2005
@@ -151,8 +151,13 @@
instance_repr = hop.args_r[0].common_repr()
v_obj, v_cls = hop.inputargs(instance_repr, class_repr)
-
- return hop.gendirectcall(rclass.ll_isinstance, v_obj, v_cls)
+ if isinstance(v_cls, Constant):
+ minid = hop.inputconst(lltype.Signed, v_cls.value.subclassrange_min)
+ maxid = hop.inputconst(lltype.Signed, v_cls.value.subclassrange_max)
+ return hop.gendirectcall(rclass.ll_isinstance_const, v_obj, minid,
+ maxid)
+ else:
+ return hop.gendirectcall(rclass.ll_isinstance, v_obj, v_cls)
#def rtype_builtin_range(hop): see rrange.py
Modified: pypy/dist/pypy/rpython/rclass.py
==============================================================================
--- pypy/dist/pypy/rpython/rclass.py (original)
+++ pypy/dist/pypy/rpython/rclass.py Sat Sep 17 18:14:12 2005
@@ -1,7 +1,9 @@
+import sys
import types
from pypy.annotation.pairtype import pairtype, pair
from pypy.annotation import model as annmodel
from pypy.annotation.classdef import isclassdef
+from pypy.objspace.flow.model import Constant
from pypy.rpython.rmodel import Repr, TyperError, inputconst, warning, needsgc
from pypy.rpython.lltype import ForwardReference, GcForwardReference
from pypy.rpython.lltype import Ptr, Struct, GcStruct, malloc
@@ -17,6 +19,8 @@
# struct object_vtable {
# struct object_vtable* parenttypeptr;
# RuntimeTypeInfo * rtti;
+# Signed subclassrange_min; //this is also the id of the class itself
+# Signed subclassrange_max;
# array { char } * name;
# struct object * instantiate();
# }
@@ -47,6 +51,8 @@
OBJECTPTR = Ptr(OBJECT)
OBJECT_VTABLE.become(Struct('object_vtable',
('parenttypeptr', TYPEPTR),
+ ('subclassrange_min', Signed),
+ ('subclassrange_max', Signed),
('rtti', Ptr(RuntimeTypeInfo)),
('name', Ptr(Array(Char))),
('instantiate', Ptr(FuncType([], OBJECTPTR)))))
@@ -230,6 +236,11 @@
# initialize the 'parenttypeptr' and 'name' fields
if rsubcls.classdef is not None:
vtable.parenttypeptr = rsubcls.rbase.getvtable()
+ vtable.subclassrange_min = rsubcls.classdef.minid
+ vtable.subclassrange_max = rsubcls.classdef.maxid
+ else: #for the root class
+ vtable.subclassrange_min = 0
+ vtable.subclassrange_max = sys.maxint
rinstance = getinstancerepr(self.rtyper, rsubcls.classdef)
rinstance.setup()
if rinstance.needsgc: # only gc-case
@@ -338,7 +349,13 @@
def rtype_issubtype(self, hop):
class_repr = get_type_repr(self.rtyper)
v_cls1, v_cls2 = hop.inputargs(class_repr, class_repr)
- return hop.gendirectcall(ll_issubclass, v_cls1, v_cls2)
+ if isinstance(v_cls2, Constant):
+ minid = hop.inputconst(Signed, v_cls2.value.subclassrange_min)
+ maxid = hop.inputconst(Signed, v_cls2.value.subclassrange_max)
+ return hop.gendirectcall(ll_issubclass_const, v_cls1, minid, maxid)
+ else:
+ v_cls1, v_cls2 = hop.inputargs(class_repr, class_repr)
+ return hop.gendirectcall(ll_issubclass, v_cls1, v_cls2)
def get_type_repr(rtyper):
return getclassrepr(rtyper, None)
@@ -717,11 +734,11 @@
return cast_pointer(OBJECTPTR, obj).typeptr
def ll_issubclass(subcls, cls):
- while subcls != cls:
- if not subcls:
- return False
- subcls = subcls.parenttypeptr
- return True
+ return cls.subclassrange_min <= subcls.subclassrange_min < cls.subclassrange_max
+
+def ll_issubclass_const(subcls, minid, maxid):
+ return minid <= subcls.subclassrange_min < maxid
+
def ll_isinstance(obj, cls): # obj should be cast to OBJECT or NONGCOBJECT
if not obj:
@@ -729,6 +746,11 @@
obj_cls = obj.typeptr
return ll_issubclass(obj_cls, cls)
+def ll_isinstance_const(obj, minid, maxid):
+ if not obj:
+ return False
+ return ll_issubclass_const(obj.typeptr, minid, maxid)
+
def ll_runtime_type_info(obj):
return obj.typeptr.rtti
Modified: pypy/dist/pypy/rpython/test/test_exception.py
==============================================================================
--- pypy/dist/pypy/rpython/test/test_exception.py (original)
+++ pypy/dist/pypy/rpython/test/test_exception.py Sat Sep 17 18:14:12 2005
@@ -42,9 +42,9 @@
classdef = a.bookkeeper.getclassdef(OverflowError)
assert ovferr_inst.typeptr == t.rtyper.class_reprs[classdef].getvtable()
- keyerr_inst = data.ll_pyexcclass2exc(pyobjectptr(KeyError))
+ taberr_inst = data.ll_pyexcclass2exc(pyobjectptr(TabError))
classdef = a.bookkeeper.getclassdef(StandardError) # most precise class seen
- assert keyerr_inst.typeptr == t.rtyper.class_reprs[classdef].getvtable()
+ assert taberr_inst.typeptr == t.rtyper.class_reprs[classdef].getvtable()
myerr_inst = data.ll_pyexcclass2exc(pyobjectptr(MyException))
assert myerr_inst.typeptr == t.rtyper.class_reprs[None].getvtable()
Modified: pypy/dist/pypy/rpython/test/test_rbuiltin.py
==============================================================================
--- pypy/dist/pypy/rpython/test/test_rbuiltin.py (original)
+++ pypy/dist/pypy/rpython/test/test_rbuiltin.py Sat Sep 17 18:14:12 2005
@@ -199,6 +199,35 @@
res = interpret(f, [])
assert res is True
+def test_isinstance():
+ class A(object):
+ pass
+ class B(A):
+ pass
+ class C(A):
+ pass
+ def f(x, y):
+ if x == 1:
+ a = A()
+ elif x == 2:
+ a = B()
+ else:
+ a = C()
+ if y == 1:
+ res = isinstance(a, A)
+ cls = A
+ elif y == 2:
+ res = isinstance(a, B)
+ cls = B
+ else:
+ res = isinstance(a, C)
+ cls = C
+ return int(res) + 2 * isinstance(a, cls)
+ for x in [1, 2, 3]:
+ for y in [1, 2, 3]:
+ res = interpret(f, [x, y])
+ assert res == isinstance([A(), B(), C()][x-1], [A, B, C][y-1]) * 3
+
def test_isinstance_list():
def f(i):
if i == 0:
More information about the Pypy-commit
mailing list