mirror of https://github.com/python/cpython
Merged revisions 72690 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk ........ r72690 | benjamin.peterson | 2009-05-16 16:44:25 -0500 (Sat, 16 May 2009) | 1 line properly lookup __instancecheck__ and __subclasscheck__ ........
This commit is contained in:
parent
188789d8f4
commit
88fe5f9776
|
@ -1556,16 +1556,25 @@ order (MRO) for bases """
|
|||
return 0
|
||||
def stop(self):
|
||||
raise StopIteration
|
||||
def return_true(self, thing=None):
|
||||
return True
|
||||
def do_isinstance(obj):
|
||||
return isinstance(int, obj)
|
||||
def do_issubclass(obj):
|
||||
return issubclass(int, obj)
|
||||
|
||||
# It would be nice to have every special method tested here, but I'm
|
||||
# only listing the ones I can remember outside of typeobject.c, since it
|
||||
# does it right.
|
||||
specials = [
|
||||
("__bytes__", bytes, hello, {}),
|
||||
("__reversed__", reversed, empty_seq, {}),
|
||||
("__length_hint__", list, zero,
|
||||
("__bytes__", bytes, hello, set(), {}),
|
||||
("__reversed__", reversed, empty_seq, set(), {}),
|
||||
("__length_hint__", list, zero, set(),
|
||||
{"__iter__" : iden, "__next__" : stop}),
|
||||
("__sizeof__", sys.getsizeof, zero, {}),
|
||||
("__sizeof__", sys.getsizeof, zero, set(), {}),
|
||||
("__instancecheck__", do_isinstance, return_true, set(), {}),
|
||||
("__subclasscheck__", do_issubclass, return_true,
|
||||
set(("__bases__",)), {}),
|
||||
# These two fail because the compiler generates LOAD_ATTR to look
|
||||
# them up. We'd have to add a new opcode to fix this, and it's
|
||||
# probably not worth it.
|
||||
|
@ -1577,7 +1586,9 @@ order (MRO) for bases """
|
|||
def __getattr__(self, attr, test=self):
|
||||
test.fail("__getattr__ called with {0}".format(attr))
|
||||
def __getattribute__(self, attr, test=self):
|
||||
test.fail("__getattribute__ called with {0}".format(attr))
|
||||
if attr not in ok:
|
||||
test.fail("__getattribute__ called with {0}".format(attr))
|
||||
return object.__getattribute__(attr)
|
||||
class SpecialDescr(object):
|
||||
def __init__(self, impl):
|
||||
self.impl = impl
|
||||
|
@ -1586,7 +1597,7 @@ order (MRO) for bases """
|
|||
return self.impl.__get__(obj, owner)
|
||||
|
||||
|
||||
for name, runner, meth_impl, env in specials:
|
||||
for name, runner, meth_impl, ok, env in specials:
|
||||
class X(Checker):
|
||||
pass
|
||||
for attr, obj in env.items():
|
||||
|
|
|
@ -2574,14 +2574,8 @@ PyObject_IsInstance(PyObject *inst, PyObject *cls)
|
|||
Py_LeaveRecursiveCall();
|
||||
return r;
|
||||
}
|
||||
if (name == NULL) {
|
||||
name = PyUnicode_InternFromString("__instancecheck__");
|
||||
if (name == NULL)
|
||||
return -1;
|
||||
}
|
||||
checker = PyObject_GetAttr(cls, name);
|
||||
if (checker == NULL && PyErr_Occurred())
|
||||
PyErr_Clear();
|
||||
|
||||
checker = _PyObject_LookupSpecial(cls, "__instancecheck__", &name);
|
||||
if (checker != NULL) {
|
||||
PyObject *res;
|
||||
int ok = -1;
|
||||
|
@ -2644,14 +2638,8 @@ PyObject_IsSubclass(PyObject *derived, PyObject *cls)
|
|||
Py_LeaveRecursiveCall();
|
||||
return r;
|
||||
}
|
||||
if (name == NULL) {
|
||||
name = PyUnicode_InternFromString("__subclasscheck__");
|
||||
if (name == NULL)
|
||||
return -1;
|
||||
}
|
||||
PyErr_Fetch(&t, &v, &tb);
|
||||
checker = PyObject_GetAttr(cls, name);
|
||||
PyErr_Restore(t, v, tb);
|
||||
|
||||
checker = _PyObject_LookupSpecial(cls, "__subclasscheck__", &name);
|
||||
if (checker != NULL) {
|
||||
PyObject *res;
|
||||
int ok = -1;
|
||||
|
|
|
@ -598,14 +598,6 @@ type___instancecheck__(PyObject *type, PyObject *inst)
|
|||
}
|
||||
|
||||
|
||||
static PyObject *
|
||||
type_get_instancecheck(PyObject *type, void *context)
|
||||
{
|
||||
static PyMethodDef ml = {"__instancecheck__",
|
||||
type___instancecheck__, METH_O };
|
||||
return PyCFunction_New(&ml, type);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
type___subclasscheck__(PyObject *type, PyObject *inst)
|
||||
{
|
||||
|
@ -619,13 +611,6 @@ type___subclasscheck__(PyObject *type, PyObject *inst)
|
|||
}
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
type_get_subclasscheck(PyObject *type, void *context)
|
||||
{
|
||||
static PyMethodDef ml = {"__subclasscheck__",
|
||||
type___subclasscheck__, METH_O };
|
||||
return PyCFunction_New(&ml, type);
|
||||
}
|
||||
|
||||
static PyGetSetDef type_getsets[] = {
|
||||
{"__name__", (getter)type_name, (setter)type_set_name, NULL},
|
||||
|
@ -635,8 +620,6 @@ static PyGetSetDef type_getsets[] = {
|
|||
(setter)type_set_abstractmethods, NULL},
|
||||
{"__dict__", (getter)type_dict, NULL, NULL},
|
||||
{"__doc__", (getter)type_get_doc, NULL, NULL},
|
||||
{"__instancecheck__", (getter)type_get_instancecheck, NULL, NULL},
|
||||
{"__subclasscheck__", (getter)type_get_subclasscheck, NULL, NULL},
|
||||
{0}
|
||||
};
|
||||
|
||||
|
@ -2518,6 +2501,10 @@ static PyMethodDef type_methods[] = {
|
|||
METH_VARARGS | METH_KEYWORDS | METH_CLASS,
|
||||
PyDoc_STR("__prepare__() -> dict\n"
|
||||
"used to create the namespace for the class statement")},
|
||||
{"__instancecheck__", type___instancecheck__, METH_O,
|
||||
PyDoc_STR("__instancecheck__() -> check if an object is an instance")},
|
||||
{"__subclasscheck__", type___subclasscheck__, METH_O,
|
||||
PyDoc_STR("__subclasschck__ -> check if an class is a subclass")},
|
||||
{0}
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue