Skip to content

Commit 20c327a

Browse files
sunmy2019miss-islington
authored andcommitted
gh-146615: Fix crash in __get__() for METH_METHOD descriptors with invalid type argument (GH-146634)
(cherry picked from commit 72d29ea) Co-authored-by: sunmy2019 <59365878+sunmy2019@users.noreply.github.com>
1 parent c09ccd9 commit 20c327a

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
@@ -1662,6 +1662,28 @@ class SubSpam(spam.spamlist): pass
16621662
spam_cm.__get__(None, list)
16631663
self.assertEqual(str(cm.exception), expected_errmsg)
16641664

1665+
@support.cpython_only
1666+
def test_method_get_meth_method_invalid_type(self):
1667+
# gh-146615: method_get() for METH_METHOD descriptors used to pass
1668+
# Py_TYPE(type)->tp_name as the %V fallback instead of the separate
1669+
# %s argument, causing a missing argument for %s and a crash.
1670+
# Verify the error message is correct when __get__() is called with a
1671+
# non-type as the second argument.
1672+
#
1673+
# METH_METHOD|METH_FASTCALL|METH_KEYWORDS is the only flag combination
1674+
# that enters the affected branch in method_get().
1675+
import io
1676+
1677+
obj = io.StringIO()
1678+
descr = io.TextIOBase.read
1679+
1680+
with self.assertRaises(TypeError) as cm:
1681+
descr.__get__(obj, "not_a_type")
1682+
self.assertEqual(
1683+
str(cm.exception),
1684+
"descriptor 'read' needs a type, not 'str', as arg 2",
1685+
)
1686+
16651687
def test_staticmethods(self):
16661688
# Testing static methods...
16671689
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
@@ -149,7 +149,7 @@ method_get(PyObject *self, PyObject *obj, PyObject *type)
149149
} else {
150150
PyErr_Format(PyExc_TypeError,
151151
"descriptor '%V' needs a type, not '%s', as arg 2",
152-
descr_name((PyDescrObject *)descr),
152+
descr_name((PyDescrObject *)descr), "?",
153153
Py_TYPE(type)->tp_name);
154154
return NULL;
155155
}

0 commit comments

Comments
 (0)