Skip to content

Commit 4c9ea09

Browse files
authored
bpo-38787: Add PyCFunction_CheckExact() macro for exact type checks (GH-20024)
… now that we allow subtypes of PyCFunction. Also add PyCMethod_CheckExact() and PyCMethod_Check() for checks against the PyCMethod subtype.
1 parent 5650e76 commit 4c9ea09

File tree

5 files changed

+10
-4
lines changed

5 files changed

+10
-4
lines changed

Include/cpython/methodobject.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44

55
PyAPI_DATA(PyTypeObject) PyCMethod_Type;
66

7+
#define PyCMethod_CheckExact(op) Py_IS_TYPE(op, &PyCMethod_Type)
8+
#define PyCMethod_Check(op) PyObject_TypeCheck(op, &PyCMethod_Type)
9+
710
/* Macros for direct access to these values. Type checks are *not*
811
done, so use with care. */
912
#define PyCFunction_GET_FUNCTION(func) \

Include/methodobject.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ extern "C" {
1313

1414
PyAPI_DATA(PyTypeObject) PyCFunction_Type;
1515

16-
#define PyCFunction_Check(op) (Py_IS_TYPE(op, &PyCFunction_Type) || (PyType_IsSubtype(Py_TYPE(op), &PyCFunction_Type)))
16+
#define PyCFunction_CheckExact(op) Py_IS_TYPE(op, &PyCFunction_Type)
17+
#define PyCFunction_Check(op) PyObject_TypeCheck(op, &PyCFunction_Type)
1718

1819
typedef PyObject *(*PyCFunction)(PyObject *, PyObject *);
1920
typedef PyObject *(*_PyCFunctionFast) (PyObject *, PyObject *const *, Py_ssize_t);
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Add PyCFunction_CheckExact() macro for exact type checks now that we allow subtypes of PyCFunction,
2+
as well as PyCMethod_CheckExact() and PyCMethod_Check() for the new PyCMethod subtype.

Objects/abstract.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -900,7 +900,7 @@ binary_op(PyObject *v, PyObject *w, const int op_slot, const char *op_name)
900900
Py_DECREF(result);
901901

902902
if (op_slot == NB_SLOT(nb_rshift) &&
903-
PyCFunction_Check(v) &&
903+
PyCFunction_CheckExact(v) &&
904904
strcmp(((PyCFunctionObject *)v)->m_ml->ml_name, "print") == 0)
905905
{
906906
PyErr_Format(PyExc_TypeError,

Python/ceval.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5054,7 +5054,7 @@ trace_call_function(PyThreadState *tstate,
50545054
PyObject *kwnames)
50555055
{
50565056
PyObject *x;
5057-
if (PyCFunction_Check(func)) {
5057+
if (PyCFunction_CheckExact(func) || PyCMethod_CheckExact(func)) {
50585058
C_TRACE(x, PyObject_Vectorcall(func, args, nargs, kwnames));
50595059
return x;
50605060
}
@@ -5115,7 +5115,7 @@ do_call_core(PyThreadState *tstate, PyObject *func, PyObject *callargs, PyObject
51155115
{
51165116
PyObject *result;
51175117

5118-
if (PyCFunction_Check(func)) {
5118+
if (PyCFunction_CheckExact(func) || PyCMethod_CheckExact(func)) {
51195119
C_TRACE(result, PyObject_Call(func, callargs, kwdict));
51205120
return result;
51215121
}

0 commit comments

Comments
 (0)