Skip to content

Commit 72d29ea

Browse files
authored
gh-146615: Fix crash in __get__() for METH_METHOD descriptors with invalid type argument (GH-146634)
1 parent 70d1b08 commit 72d29ea

File tree

3 files changed

+26
-1
lines changed

3 files changed

+26
-1
lines changed

Lib/test/test_descr.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1803,6 +1803,28 @@ class SubSpam(spam.spamlist): pass
18031803
spam_cm.__get__(None, list)
18041804
self.assertEqual(str(cm.exception), expected_errmsg)
18051805

1806+
@support.cpython_only
1807+
def test_method_get_meth_method_invalid_type(self):
1808+
# gh-146615: method_get() for METH_METHOD descriptors used to pass
1809+
# Py_TYPE(type)->tp_name as the %V fallback instead of the separate
1810+
# %s argument, causing a missing argument for %s and a crash.
1811+
# Verify the error message is correct when __get__() is called with a
1812+
# non-type as the second argument.
1813+
#
1814+
# METH_METHOD|METH_FASTCALL|METH_KEYWORDS is the only flag combination
1815+
# that enters the affected branch in method_get().
1816+
import io
1817+
1818+
obj = io.StringIO()
1819+
descr = io.TextIOBase.read
1820+
1821+
with self.assertRaises(TypeError) as cm:
1822+
descr.__get__(obj, "not_a_type")
1823+
self.assertEqual(
1824+
str(cm.exception),
1825+
"descriptor 'read' needs a type, not 'str', as arg 2",
1826+
)
1827+
18061828
def test_staticmethods(self):
18071829
# Testing static methods...
18081830
class C(object):
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fix a crash in :meth:`~object.__get__` for :c:expr:`METH_METHOD` descriptors
2+
when an invalid (non-type) object is passed as the second argument.
3+
Patch by Steven Sun.

Objects/descrobject.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ method_get(PyObject *self, PyObject *obj, PyObject *type)
150150
} else {
151151
PyErr_Format(PyExc_TypeError,
152152
"descriptor '%V' needs a type, not '%s', as arg 2",
153-
descr_name((PyDescrObject *)descr),
153+
descr_name((PyDescrObject *)descr), "?",
154154
Py_TYPE(type)->tp_name);
155155
return NULL;
156156
}

0 commit comments

Comments
 (0)