diff options
author | Victor Stinner <victor.stinner@haypocalc.com> | 2011-05-01 21:43:37 (GMT) |
---|---|---|
committer | Victor Stinner <victor.stinner@haypocalc.com> | 2011-05-01 21:43:37 (GMT) |
commit | e363ec10578d7c378998a2170fb7babe3cfb6586 (patch) | |
tree | 1164473d6ece233ded4d00f5e52e3f7607b94245 | |
parent | 12b8fcfc45373ba48961866289809a004fcd5c14 (diff) | |
download | cpython-e363ec10578d7c378998a2170fb7babe3cfb6586.zip cpython-e363ec10578d7c378998a2170fb7babe3cfb6586.tar.gz cpython-e363ec10578d7c378998a2170fb7babe3cfb6586.tar.bz2 |
(Merge 3.1) Issue #9756: When calling a method descriptor or a slot wrapper
descriptor, the check of the object type doesn't read the __class__ attribute
anymore. Fix a crash if a class override its __class__ attribute (e.g. a proxy
of the str type).
-rw-r--r-- | Lib/test/test_descr.py | 16 | ||||
-rw-r--r-- | Misc/NEWS | 5 | ||||
-rw-r--r-- | Objects/descrobject.c | 9 |
3 files changed, 27 insertions, 3 deletions
diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py index b5e86fb..1fe0de5 100644 --- a/Lib/test/test_descr.py +++ b/Lib/test/test_descr.py @@ -4564,6 +4564,22 @@ order (MRO) for bases """ with self.assertRaises(AttributeError): del X.__abstractmethods__ + def test_proxy_call(self): + class FakeStr(object): + __class__ = str + + fake_str = FakeStr() + # isinstance() reads __class__ on new style classes + self.assertTrue(isinstance(fake_str, str)) + + # call a method descriptor + with self.assertRaises(TypeError): + str.split(fake_str) + + # call a slot wrapper descriptor + with self.assertRaises(TypeError): + str.__add__(fake_str, "abc") + class DictProxyTests(unittest.TestCase): def setUp(self): @@ -9,6 +9,11 @@ What's New in Python 2.7.2? Core and Builtins ----------------- +- Issue #9756: When calling a method descriptor or a slot wrapper descriptor, + the check of the object type doesn't read the __class__ attribute anymore. + Fix a crash if a class override its __class__ attribute (e.g. a proxy of the + str type). + - Issue #10517: After fork(), reinitialize the TLS used by the PyGILState_* APIs, to avoid a crash with the pthread implementation in RHEL 5. Patch by Charles-François Natali. diff --git a/Objects/descrobject.c b/Objects/descrobject.c index 9d735a2..135b6d2 100644 --- a/Objects/descrobject.c +++ b/Objects/descrobject.c @@ -224,7 +224,8 @@ methoddescr_call(PyMethodDescrObject *descr, PyObject *args, PyObject *kwds) return NULL; } self = PyTuple_GET_ITEM(args, 0); - if (!PyObject_IsInstance(self, (PyObject *)(descr->d_type))) { + if (!_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self), + (PyObject *)(descr->d_type))) { PyErr_Format(PyExc_TypeError, "descriptor '%.200s' " "requires a '%.100s' object " @@ -282,7 +283,8 @@ wrapperdescr_call(PyWrapperDescrObject *descr, PyObject *args, PyObject *kwds) return NULL; } self = PyTuple_GET_ITEM(args, 0); - if (!PyObject_IsInstance(self, (PyObject *)(descr->d_type))) { + if (!_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self), + (PyObject *)(descr->d_type))) { PyErr_Format(PyExc_TypeError, "descriptor '%.200s' " "requires a '%.100s' object " @@ -1046,7 +1048,8 @@ PyWrapper_New(PyObject *d, PyObject *self) assert(PyObject_TypeCheck(d, &PyWrapperDescr_Type)); descr = (PyWrapperDescrObject *)d; - assert(PyObject_IsInstance(self, (PyObject *)(descr->d_type))); + assert(_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self), + (PyObject *)(descr->d_type))); wp = PyObject_GC_New(wrapperobject, &wrappertype); if (wp != NULL) { |