Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 477ba91

Browse files
committed
don't segfault on deleting __abstractmethods__ #10892
1 parent 5e8dada commit 477ba91

3 files changed

Lines changed: 19 additions & 3 deletions

File tree

Lib/test/test_descr.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4224,12 +4224,16 @@ def __getattribute__(self, name):
42244224

42254225
self.assertRaises(AttributeError, getattr, EvilGetattribute(), "attr")
42264226

4227-
def test_type_has_no_abstractmethods(self):
4227+
def test_abstractmethods(self):
42284228
# type pretends not to have __abstractmethods__.
42294229
self.assertRaises(AttributeError, getattr, type, "__abstractmethods__")
42304230
class meta(type):
42314231
pass
42324232
self.assertRaises(AttributeError, getattr, meta, "__abstractmethods__")
4233+
class X(object):
4234+
pass
4235+
with self.assertRaises(AttributeError):
4236+
del X.__abstractmethods__
42334237

42344238

42354239
class DictProxyTests(unittest.TestCase):

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ What's New in Python 3.2 Release Candidate 1
88
Core and Builtins
99
-----------------
1010

11+
- Issue #10892: Don't segfault when trying to delete __abstractmethods__ from a
12+
class.
13+
1114
- Issue #8020: Avoid a crash where the small objects allocator would read
1215
non-Python managed memory while it is being modified by another thread.
1316
Patch by Matt Bandy.

Objects/typeobject.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -340,8 +340,17 @@ type_set_abstractmethods(PyTypeObject *type, PyObject *value, void *context)
340340
abc.ABCMeta.__new__, so this function doesn't do anything
341341
special to update subclasses.
342342
*/
343-
int res = PyDict_SetItemString(type->tp_dict,
344-
"__abstractmethods__", value);
343+
int res;
344+
if (value != NULL) {
345+
res = PyDict_SetItemString(type->tp_dict, "__abstractmethods__", value);
346+
}
347+
else {
348+
res = PyDict_DelItemString(type->tp_dict, "__abstractmethods__");
349+
if (res && PyErr_ExceptionMatches(PyExc_KeyError)) {
350+
PyErr_Format(PyExc_AttributeError, "__abstractmethods__", value);
351+
return -1;
352+
}
353+
}
345354
if (res == 0) {
346355
PyType_Modified(type);
347356
if (value && PyObject_IsTrue(value)) {

0 commit comments

Comments
 (0)