@@ -1670,14 +1670,13 @@ too_many_positional(PyThreadState *tstate, PyCodeObject *co,
16701670
16711671static int
16721672suggest_missing_self (PyFunctionObject * func , PyCodeObject * co ,
1673- _PyStackRef const * args , Py_ssize_t argcount )
1673+ PyObject * first_argument , Py_ssize_t argcount )
16741674{
16751675 /* Missing self shows up as exactly one extra positional argument. */
16761676 if ((co -> co_argcount + 1 ) != argcount ) {
16771677 return 0 ;
16781678 }
16791679
1680- PyObject * first_argument = PyStackRef_AsPyObjectBorrow (args [0 ]);
16811680 if (first_argument == NULL || PyType_Check (first_argument )) {
16821681 // When first arg is NULL, it's not really about self
16831682 // If its a type object, then its a classmethod.
@@ -1791,6 +1790,15 @@ initialize_locals(PyThreadState *tstate, PyFunctionObject *func,
17911790 kwdict = NULL ;
17921791 }
17931792
1793+ /* Pin the first argument for the "missing self" hint: the surplus
1794+ argument cleanup below may close args[0] before the hint is computed.
1795+ The pin is only needed when the "too many positional arguments"
1796+ error is about to be raised. */
1797+ PyObject * first_argument = NULL ;
1798+ if (argcount > co -> co_argcount && !(co -> co_flags & CO_VARARGS )) {
1799+ first_argument = Py_NewRef (PyStackRef_AsPyObjectBorrow (args [0 ]));
1800+ }
1801+
17941802 /* Copy all positional arguments into local variables */
17951803 Py_ssize_t j , n ;
17961804 if (argcount > co -> co_argcount ) {
@@ -1935,7 +1943,7 @@ initialize_locals(PyThreadState *tstate, PyFunctionObject *func,
19351943
19361944 /* Check the number of positional arguments */
19371945 if ((argcount > co -> co_argcount ) && !(co -> co_flags & CO_VARARGS )) {
1938- int missing_self_hint = suggest_missing_self (func , co , args , argcount );
1946+ int missing_self_hint = suggest_missing_self (func , co , first_argument , argcount );
19391947 too_many_positional (tstate , co , argcount , func -> func_defaults , localsplus ,
19401948 func -> func_qualname , missing_self_hint );
19411949 goto fail_post_args ;
@@ -1996,6 +2004,7 @@ initialize_locals(PyThreadState *tstate, PyFunctionObject *func,
19962004 goto fail_post_args ;
19972005 }
19982006 }
2007+ Py_XDECREF (first_argument );
19992008 return 0 ;
20002009
20012010fail_pre_positional :
@@ -2012,6 +2021,7 @@ initialize_locals(PyThreadState *tstate, PyFunctionObject *func,
20122021 }
20132022 /* fall through */
20142023fail_post_args :
2024+ Py_XDECREF (first_argument );
20152025 return -1 ;
20162026}
20172027
0 commit comments