instance, as long as x.__class__ is X or a subclass thereof.
Did a little cleanup of PyObject_IsInstance() too.
def meth_class_get():
# Full coverage of descrobject.c::classmethod_get()
- if verbose: print "Testing __get__ method of METH_CLASS C methods..."
+ if verbose:
+ print "Testing __get__ method of METH_CLASS C methods..."
# Baseline
arg = [1, 2, 3]
res = {1: None, 2: None, 3: None}
else:
raise TestFailed, "shouldn't have allowed descr.__get__(None, int)"
+def isinst_isclass():
+ if verbose:
+ print "Testing proxy isinstance() and isclass()..."
+ class Proxy(object):
+ def __init__(self, obj):
+ self.__obj = obj
+ def __getattribute__(self, name):
+ if name.startswith("_Proxy__"):
+ return object.__getattribute__(self, name)
+ else:
+ return getattr(self.__obj, name)
+ # Test with a classic class
+ class C:
+ pass
+ a = C()
+ pa = Proxy(a)
+ verify(isinstance(a, C)) # Baseline
+ verify(isinstance(pa, C)) # Test
+ # Test with a new-style class
+ class C(object):
+ pass
+ a = C()
+ pa = Proxy(a)
+ verify(isinstance(a, C)) # Baseline
+ verify(isinstance(pa, C)) # Test
+
def test_main():
do_this_first()
subclass_right_op()
dict_type_with_metaclass()
meth_class_get()
+ isinst_isclass()
if verbose: print "All OK"
Core and builtins
-----------------
+- isinstance(x, X): if X is a new-style class, this is now equivalent
+ to issubclass(type(x), X) or issubclass(x.__class__, X). Previously
+ only type(x) was tested. (For classic classes this was already the
+ case.)
+
- compile(), eval() and the exec statement now fully support source code
passed as unicode strings.
static PyObject *__class__ = NULL;
int retval = 0;
+ if (__class__ == NULL) {
+ __class__ = PyString_FromString("__class__");
+ if (__class__ == NULL)
+ return -1;
+ }
+
if (PyClass_Check(cls) && PyInstance_Check(inst)) {
PyObject *inclass =
(PyObject*)((PyInstanceObject*)inst)->in_class;
}
else if (PyType_Check(cls)) {
retval = PyObject_TypeCheck(inst, (PyTypeObject *)cls);
+ if (retval == 0) {
+ PyObject *c = PyObject_GetAttr(inst, __class__);
+ if (c == NULL) {
+ PyErr_Clear();
+ }
+ else {
+ if (c != inst->ob_type && PyType_Check(c))
+ retval = PyType_IsSubtype(
+ (PyTypeObject *)c,
+ (PyTypeObject *)cls);
+ Py_DECREF(c);
+ }
+ }
}
else if (PyTuple_Check(cls)) {
/* Not a general sequence -- that opens up the road to
if (retval != 0)
break;
}
- return retval;
}
else {
if (!check_class(cls,
"isinstance() arg 2 must be a class, type,"
" or tuple of classes and types"))
return -1;
- if (__class__ == NULL) {
- __class__ = PyString_FromString("__class__");
- if (__class__ == NULL)
- return -1;
- }
icls = PyObject_GetAttr(inst, __class__);
if (icls == NULL) {
PyErr_Clear();