[pypy-svn] r75686 - in pypy/branch/fast-forward/pypy: module/__builtin__ module/__builtin__/test objspace objspace/std objspace/test
benjamin at codespeak.net
benjamin at codespeak.net
Wed Jun 30 17:13:09 CEST 2010
Author: benjamin
Date: Wed Jun 30 17:13:07 2010
New Revision: 75686
Modified:
pypy/branch/fast-forward/pypy/module/__builtin__/abstractinst.py
pypy/branch/fast-forward/pypy/module/__builtin__/test/test_abstractinst.py
pypy/branch/fast-forward/pypy/objspace/descroperation.py
pypy/branch/fast-forward/pypy/objspace/std/objspace.py
pypy/branch/fast-forward/pypy/objspace/test/test_descroperation.py
Log:
new plan: disable isinstance() and issubtype() overriding by user classes by default
Modified: pypy/branch/fast-forward/pypy/module/__builtin__/abstractinst.py
==============================================================================
--- pypy/branch/fast-forward/pypy/module/__builtin__/abstractinst.py (original)
+++ pypy/branch/fast-forward/pypy/module/__builtin__/abstractinst.py Wed Jun 30 17:13:07 2010
@@ -45,12 +45,20 @@
return space.type(w_obj)
@jit.unroll_safe
-def abstract_isinstance_w(space, w_obj, w_klass_or_tuple):
+def abstract_isinstance_w(space, w_obj, w_klass_or_tuple, allow_override=False):
"""Implementation for the full 'isinstance(obj, klass_or_tuple)'."""
+ # -- case (anything, tuple)
+ # XXX it might be risky that the JIT sees this
+ if space.is_true(space.isinstance(w_klass_or_tuple, space.w_tuple)):
+ for w_klass in space.fixedview(w_klass_or_tuple):
+ if abstract_isinstance_w(space, w_obj, w_klass, allow_override):
+ return True
+ return False
+
# -- case (anything, type)
try:
- w_result = space.isinstance(w_obj, w_klass_or_tuple)
+ w_result = space.isinstance(w_obj, w_klass_or_tuple, allow_override)
except OperationError, e: # if w_klass_or_tuple was not a type, ignore it
if not e.match(space, space.w_TypeError):
raise # propagate other errors
@@ -64,7 +72,8 @@
w_pretendtype = space.getattr(w_obj, space.wrap('__class__'))
if space.is_w(w_pretendtype, space.type(w_obj)):
return False # common case: obj.__class__ is type(obj)
- w_result = space.issubtype(w_pretendtype, w_klass_or_tuple)
+ w_result = space.issubtype(w_pretendtype, w_klass_or_tuple,
+ allow_override)
except OperationError, e:
if e.async(space):
raise
@@ -78,13 +87,6 @@
oldstyleinst = space.interpclass_w(w_obj)
if isinstance(oldstyleinst, W_InstanceObject):
return oldstyleinst.w_class.is_subclass_of(oldstyleclass)
- # -- case (anything, tuple)
- # XXX it might be risky that the JIT sees this
- if space.is_true(space.isinstance(w_klass_or_tuple, space.w_tuple)):
- for w_klass in space.fixedview(w_klass_or_tuple):
- if abstract_isinstance_w(space, w_obj, w_klass):
- return True
- return False
return _abstract_isinstance_w_helper(space, w_obj, w_klass_or_tuple)
@jit.dont_look_inside
@@ -118,12 +120,21 @@
@jit.unroll_safe
-def abstract_issubclass_w(space, w_derived, w_klass_or_tuple):
+def abstract_issubclass_w(space, w_derived, w_klass_or_tuple,
+ allow_override=False):
"""Implementation for the full 'issubclass(derived, klass_or_tuple)'."""
+ # -- case (class-like-object, tuple-of-classes)
+ # XXX it might be risky that the JIT sees this
+ if space.is_true(space.isinstance(w_klass_or_tuple, space.w_tuple)):
+ for w_klass in space.fixedview(w_klass_or_tuple):
+ if abstract_issubclass_w(space, w_derived, w_klass, allow_override):
+ return True
+ return False
+
# -- case (type, type)
try:
- w_result = space.issubtype(w_derived, w_klass_or_tuple)
+ w_result = space.issubtype(w_derived, w_klass_or_tuple, allow_override)
except OperationError, e: # if one of the args was not a type, ignore it
if not e.match(space, space.w_TypeError):
raise # propagate other errors
@@ -140,14 +151,6 @@
check_class(space, w_derived, "issubclass() arg 1 must be a class")
# from here on, we are sure that w_derived is a class-like object
- # -- case (class-like-object, tuple-of-classes)
- # XXX it might be risky that the JIT sees this
- if space.is_true(space.isinstance(w_klass_or_tuple, space.w_tuple)):
- for w_klass in space.fixedview(w_klass_or_tuple):
- if abstract_issubclass_w(space, w_derived, w_klass):
- return True
- return False
-
# -- case (class-like-object, abstract-class)
check_class(space, w_klass_or_tuple,
"issubclass() arg 2 must be a class, type,"
@@ -193,13 +196,15 @@
"""Check whether a class 'cls' is a subclass (i.e., a derived class) of
another class. When using a tuple as the second argument, check whether
'cls' is a subclass of any of the classes listed in the tuple."""
- return space.wrap(abstract_issubclass_w(space, w_cls, w_klass_or_tuple))
+ result = abstract_issubclass_w(space, w_cls, w_klass_or_tuple, True)
+ return space.wrap(result)
def isinstance(space, w_obj, w_klass_or_tuple):
"""Check whether an object is an instance of a class (or of a subclass
thereof). When using a tuple as the second argument, check whether 'obj'
is an instance of any of the classes listed in the tuple."""
- return space.wrap(abstract_isinstance_w(space, w_obj, w_klass_or_tuple))
+ result = abstract_isinstance_w(space, w_obj, w_klass_or_tuple, True)
+ return space.wrap(result)
# avoid namespace pollution
app_issubclass = issubclass; del issubclass
Modified: pypy/branch/fast-forward/pypy/module/__builtin__/test/test_abstractinst.py
==============================================================================
--- pypy/branch/fast-forward/pypy/module/__builtin__/test/test_abstractinst.py (original)
+++ pypy/branch/fast-forward/pypy/module/__builtin__/test/test_abstractinst.py Wed Jun 30 17:13:07 2010
@@ -182,3 +182,23 @@
assert not issubclass(BSub1, BSub2)
assert not issubclass(MyInst, BSub1)
assert not issubclass(BSub1, MyInst)
+
+ def test_overriding(self):
+ class ABC(type):
+
+ def __instancecheck__(cls, inst):
+ """Implement isinstance(inst, cls)."""
+ return any(cls.__subclasscheck__(c)
+ for c in set([type(inst), inst.__class__]))
+
+ def __subclasscheck__(cls, sub):
+ """Implement issubclass(sub, cls)."""
+ candidates = cls.__dict__.get("__subclass__", set()) | set([cls])
+ return any(c in candidates for c in sub.mro())
+ class Integer:
+
+ __metaclass__ = ABC
+
+ __subclass__ = set([int])
+ assert issubclass(int, Integer)
+ assert issubclass(int, (Integer,))
Modified: pypy/branch/fast-forward/pypy/objspace/descroperation.py
==============================================================================
--- pypy/branch/fast-forward/pypy/objspace/descroperation.py (original)
+++ pypy/branch/fast-forward/pypy/objspace/descroperation.py Wed Jun 30 17:13:07 2010
@@ -465,18 +465,21 @@
space.wrap("coercion should return None or 2-tuple"))
return w_res
- def issubtype(space, w_sub, w_type):
- w_check = space.lookup(w_type, "__subclasscheck__")
- if w_check is None:
- raise OperationError(space.w_TypeError,
- space.wrap("issubclass not supported here"))
- return space.get_and_call_function(w_check, w_type, w_sub)
-
- def isinstance(space, w_inst, w_type):
- w_check = space.lookup(w_type, "__instancecheck__")
- if w_check is not None:
- return space.get_and_call_function(w_check, w_type, w_inst)
- return space.issubtype(space.type(w_inst), w_type)
+ def issubtype(space, w_sub, w_type, allow_override=False):
+ if allow_override:
+ w_check = space.lookup(w_type, "__subclasscheck__")
+ if w_check is None:
+ raise OperationError(space.w_TypeError,
+ space.wrap("issubclass not supported here"))
+ return space.get_and_call_function(w_check, w_type, w_sub)
+ return space._type_issubtype(w_sub, w_type)
+
+ def isinstance(space, w_inst, w_type, allow_override=False):
+ if allow_override:
+ w_check = space.lookup(w_type, "__instancecheck__")
+ if w_check is not None:
+ return space.get_and_call_function(w_check, w_type, w_inst)
+ return space.issubtype(space.type(w_inst), w_type, allow_override)
Modified: pypy/branch/fast-forward/pypy/objspace/std/objspace.py
==============================================================================
--- pypy/branch/fast-forward/pypy/objspace/std/objspace.py (original)
+++ pypy/branch/fast-forward/pypy/objspace/std/objspace.py Wed Jun 30 17:13:07 2010
@@ -508,3 +508,8 @@
def raise_key_error(self, w_key):
e = self.call_function(self.w_KeyError, w_key)
raise OperationError(self.w_KeyError, e)
+
+ def _type_issubtype(self, w_sub, w_type):
+ if isinstance(w_sub, W_TypeObject) and isinstance(w_type, W_TypeObject):
+ return self.wrap(w_sub.issubtype(w_type))
+ raise OperationError(self.w_TypeError, self.wrap("need type objects"))
Modified: pypy/branch/fast-forward/pypy/objspace/test/test_descroperation.py
==============================================================================
--- pypy/branch/fast-forward/pypy/objspace/test/test_descroperation.py (original)
+++ pypy/branch/fast-forward/pypy/objspace/test/test_descroperation.py Wed Jun 30 17:13:07 2010
@@ -13,6 +13,22 @@
space.call_method(l, 'append', space.w_False)
assert space.nonzero(l) is space.w_True
+ def test_isinstance_and_issubtype_ignore_special(self):
+ space = self.space
+ w_tup = space.appexec((), """():
+ class Meta(type):
+ def __subclasscheck__(mcls, cls):
+ return False
+ class Base:
+ __metaclass__ = Meta
+ class Sub(Base):
+ pass
+ return Base, Sub""")
+ w_base, w_sub = space.unpackiterable(w_tup)
+ assert space.is_true(space.issubtype(w_sub, w_base))
+ w_inst = space.call_function(w_sub)
+ assert space.isinstance_w(w_inst, w_base)
+
class AppTest_Descroperation:
OPTIONS = {}
More information about the Pypy-commit
mailing list