From a59daf64b16e192454336f912a3b0c2c0c566b18 Mon Sep 17 00:00:00 2001 From: Tian Gao Date: Thu, 13 Apr 2023 23:12:20 -0700 Subject: [PATCH 1/6] Use pep669 APIs for cprofile --- Lib/test/test_cprofile.py | 11 +- Modules/_lsprof.c | 271 ++++++++++++++++++++++++++++---------- 2 files changed, 209 insertions(+), 73 deletions(-) diff --git a/Lib/test/test_cprofile.py b/Lib/test/test_cprofile.py index 98648528bc81f2..e95c01426527f0 100644 --- a/Lib/test/test_cprofile.py +++ b/Lib/test/test_cprofile.py @@ -25,7 +25,6 @@ def test_bad_counter_during_dealloc(self): with support.catch_unraisable_exception() as cm: obj = _lsprof.Profiler(lambda: int) obj.enable() - obj = _lsprof.Profiler(1) obj.disable() obj.clear() @@ -37,10 +36,11 @@ def test_profile_enable_disable(self): self.addCleanup(prof.disable) prof.enable() - self.assertIs(sys.getprofile(), prof) + self.assertEqual( + sys.monitoring.get_tool(sys.monitoring.PROFILER_ID), "cProfile") prof.disable() - self.assertIs(sys.getprofile(), None) + self.assertIs(sys.monitoring.get_tool(sys.monitoring.PROFILER_ID), None) def test_profile_as_context_manager(self): prof = self.profilerclass() @@ -53,10 +53,11 @@ def test_profile_as_context_manager(self): # profile should be set as the global profiler inside the # with-block - self.assertIs(sys.getprofile(), prof) + self.assertEqual( + sys.monitoring.get_tool(sys.monitoring.PROFILER_ID), "cProfile") # profile shouldn't be set once we leave the with-block. - self.assertIs(sys.getprofile(), None) + self.assertIs(sys.monitoring.get_tool(sys.monitoring.PROFILER_ID), None) class TestCommandLine(unittest.TestCase): def test_sort(self): diff --git a/Modules/_lsprof.c b/Modules/_lsprof.c index 83d034ae7eed78..ba63dc8655315f 100644 --- a/Modules/_lsprof.c +++ b/Modules/_lsprof.c @@ -49,6 +49,8 @@ typedef struct { int flags; PyObject *externalTimer; double externalTimerUnit; + int tool_id; + PyObject* missing; } ProfilerObject; #define POF_ENABLED 0x001 @@ -399,64 +401,6 @@ ptrace_leave_call(PyObject *self, void *key) pObj->freelistProfilerContext = pContext; } -static int -profiler_callback(PyObject *self, PyFrameObject *frame, int what, - PyObject *arg) -{ - switch (what) { - - /* the 'frame' of a called function is about to start its execution */ - case PyTrace_CALL: - { - PyCodeObject *code = PyFrame_GetCode(frame); - ptrace_enter_call(self, (void *)code, (PyObject *)code); - Py_DECREF(code); - break; - } - - /* the 'frame' of a called function is about to finish - (either normally or with an exception) */ - case PyTrace_RETURN: - { - PyCodeObject *code = PyFrame_GetCode(frame); - ptrace_leave_call(self, (void *)code); - Py_DECREF(code); - break; - } - - /* case PyTrace_EXCEPTION: - If the exception results in the function exiting, a - PyTrace_RETURN event will be generated, so we don't need to - handle it. */ - - /* the Python function 'frame' is issuing a call to the built-in - function 'arg' */ - case PyTrace_C_CALL: - if ((((ProfilerObject *)self)->flags & POF_BUILTINS) - && PyCFunction_Check(arg)) { - ptrace_enter_call(self, - ((PyCFunctionObject *)arg)->m_ml, - arg); - } - break; - - /* the call to the built-in function 'arg' is returning into its - caller 'frame' */ - case PyTrace_C_RETURN: /* ...normally */ - case PyTrace_C_EXCEPTION: /* ...with an exception set */ - if ((((ProfilerObject *)self)->flags & POF_BUILTINS) - && PyCFunction_Check(arg)) { - ptrace_leave_call(self, - ((PyCFunctionObject *)arg)->m_ml); - } - break; - - default: - break; - } - return 0; -} - static int pending_exception(ProfilerObject *pObj) { @@ -650,6 +594,84 @@ setBuiltins(ProfilerObject *pObj, int nvalue) return 0; } +PyObject* pystart_callback(ProfilerObject* self, PyObject *const *args, Py_ssize_t size) +{ + PyObject* code = args[0]; + ptrace_enter_call((PyObject*)self, (void *)code, (PyObject *)code); + + Py_RETURN_NONE; +} + +PyObject* pyreturn_callback(ProfilerObject* self, PyObject *const *args, Py_ssize_t size) +{ + PyObject* code = args[0]; + ptrace_leave_call((PyObject*)self, (void *)code); + + Py_RETURN_NONE; +} + +PyObject* get_cfunc_from_callable(PyObject* callable, PyObject* self_arg, PyObject* missing) +{ + // return a new reference + if (PyCFunction_Check(callable)) { + Py_INCREF(callable); + return (PyObject*)((PyCFunctionObject *)callable); + } + if (Py_TYPE(callable) == &PyMethodDescr_Type) { + /* For backwards compatibility need to + * convert to builtin method */ + + /* If no arg, skip */ + if (self_arg == missing) { + Py_RETURN_NONE; + } + PyObject *meth = Py_TYPE(callable)->tp_descr_get( + callable, self_arg, (PyObject*)Py_TYPE(self_arg)); + if (meth == NULL) { + return NULL; + } + if (PyCFunction_Check(meth)) { + return (PyObject*)((PyCFunctionObject *)meth); + } + } + return NULL; +} + +PyObject* ccall_callback(ProfilerObject* self, PyObject *const *args, Py_ssize_t size) +{ + if (self->flags & POF_BUILTINS) { + PyObject* callable = args[2]; + PyObject* self_arg = args[3]; + + PyObject* cfunc = get_cfunc_from_callable(callable, self_arg, self->missing); + + if (cfunc) { + ptrace_enter_call((PyObject*)self, + ((PyCFunctionObject *)cfunc)->m_ml, + cfunc); + Py_DECREF(cfunc); + } + } + Py_RETURN_NONE; +} + +PyObject* creturn_callback(ProfilerObject* self, PyObject *const *args, Py_ssize_t size) +{ + if (self->flags & POF_BUILTINS) { + PyObject* callable = args[2]; + PyObject* self_arg = args[3]; + + PyObject* cfunc = get_cfunc_from_callable(callable, self_arg, self->missing); + + if (cfunc) { + ptrace_leave_call((PyObject*)self, + ((PyCFunctionObject *)cfunc)->m_ml); + Py_DECREF(cfunc); + } + } + Py_RETURN_NONE; +} + PyDoc_STRVAR(enable_doc, "\ enable(subcalls=True, builtins=True)\n\ \n\ @@ -666,6 +688,7 @@ profiler_enable(ProfilerObject *self, PyObject *args, PyObject *kwds) int subcalls = -1; int builtins = -1; static char *kwlist[] = {"subcalls", "builtins", 0}; + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|pp:enable", kwlist, &subcalls, &builtins)) return NULL; @@ -673,11 +696,82 @@ profiler_enable(ProfilerObject *self, PyObject *args, PyObject *kwds) return NULL; } - PyThreadState *tstate = _PyThreadState_GET(); - if (_PyEval_SetProfile(tstate, profiler_callback, (PyObject*)self) < 0) { + PyObject* monitoring = _PyImport_GetModuleAttrString("sys", "monitoring"); + if (!monitoring) { + return NULL; + } + + if (PyObject_CallMethod(monitoring, "use_tool_id", "is", self->tool_id, "cProfile") == NULL) { + Py_DECREF(monitoring); + return NULL; + } + + PyObject* self_pystart_callback = PyObject_GetAttrString((PyObject*)self, "_pystart_callback"); + PyObject* self_pyreturn_callback = PyObject_GetAttrString((PyObject*)self, "_pyreturn_callback"); + PyObject* self_ccall_callback = PyObject_GetAttrString((PyObject*)self, "_ccall_callback"); + PyObject* self_creturn_callback = PyObject_GetAttrString((PyObject*)self, "_creturn_callback"); + + if (!self_pystart_callback || !self_pyreturn_callback || !self_ccall_callback || !self_creturn_callback) { + Py_XDECREF(self_pystart_callback); + Py_XDECREF(self_pyreturn_callback); + Py_XDECREF(self_ccall_callback); + Py_XDECREF(self_creturn_callback); + Py_DECREF(monitoring); + return NULL; + } + + Py_XDECREF(PyObject_CallMethod(monitoring, "register_callback", "iiO", self->tool_id, + (1 << PY_MONITORING_EVENT_PY_START), + self_pystart_callback)); + + Py_XDECREF(PyObject_CallMethod(monitoring, "register_callback", "iiO", self->tool_id, + (1 << PY_MONITORING_EVENT_PY_RESUME), + self_pystart_callback)); + + Py_XDECREF(PyObject_CallMethod(monitoring, "register_callback", "iiO", self->tool_id, + (1 << PY_MONITORING_EVENT_PY_RETURN), + self_pyreturn_callback)); + + Py_XDECREF(PyObject_CallMethod(monitoring, "register_callback", "iiO", self->tool_id, + (1 << PY_MONITORING_EVENT_PY_YIELD), + self_pyreturn_callback)); + + Py_XDECREF(PyObject_CallMethod(monitoring, "register_callback", "iiO", self->tool_id, + (1 << PY_MONITORING_EVENT_PY_UNWIND), + self_pyreturn_callback)); + + Py_XDECREF(PyObject_CallMethod(monitoring, "register_callback", "iiO", self->tool_id, + (1 << PY_MONITORING_EVENT_CALL), + self_ccall_callback)); + + Py_XDECREF(PyObject_CallMethod(monitoring, "register_callback", "iiO", self->tool_id, + (1 << PY_MONITORING_EVENT_C_RETURN), + self_creturn_callback)); + + Py_XDECREF(PyObject_CallMethod(monitoring, "register_callback", "iiO", self->tool_id, + (1 << PY_MONITORING_EVENT_C_RAISE), + self_creturn_callback)); + + Py_DECREF(self_pystart_callback); + Py_DECREF(self_pyreturn_callback); + Py_DECREF(self_ccall_callback); + Py_DECREF(self_creturn_callback); + + if (!PyObject_CallMethod(monitoring, "set_events", "ii", self->tool_id, + (1 << PY_MONITORING_EVENT_PY_START) + | (1 << PY_MONITORING_EVENT_PY_RESUME) + | (1 << PY_MONITORING_EVENT_PY_RETURN) + | (1 << PY_MONITORING_EVENT_PY_YIELD) + | (1 << PY_MONITORING_EVENT_PY_UNWIND) + | (1 << PY_MONITORING_EVENT_CALL) + | (1 << PY_MONITORING_EVENT_C_RETURN) + | (1 << PY_MONITORING_EVENT_C_RAISE))) { + Py_DECREF(monitoring); return NULL; } + Py_DECREF(monitoring); + self->flags |= POF_ENABLED; Py_RETURN_NONE; } @@ -707,13 +801,34 @@ Stop collecting profiling information.\n\ static PyObject* profiler_disable(ProfilerObject *self, PyObject* noarg) { - PyThreadState *tstate = _PyThreadState_GET(); - if (_PyEval_SetProfile(tstate, NULL, NULL) < 0) { - return NULL; + if (self->flags & POF_ENABLED) { + PyObject* result = NULL; + PyObject* monitoring = _PyImport_GetModuleAttrString("sys", "monitoring"); + + if (!monitoring) { + return NULL; + } + + result = PyObject_CallMethod(monitoring, "set_events", "ii", self->tool_id, 0); + if (!result) { + Py_DECREF(monitoring); + return NULL; + } + Py_DECREF(result); + + result = PyObject_CallMethod(monitoring, "free_tool_id", "i", self->tool_id); + if (!result) { + Py_DECREF(monitoring); + return NULL; + } + Py_DECREF(result); + + Py_DECREF(monitoring); + + self->flags &= ~POF_ENABLED; + flush_unmatched(self); } - self->flags &= ~POF_ENABLED; - flush_unmatched(self); if (pending_exception(self)) { return NULL; } @@ -778,17 +893,37 @@ profiler_init(ProfilerObject *pObj, PyObject *args, PyObject *kw) return -1; pObj->externalTimerUnit = timeunit; Py_XSETREF(pObj->externalTimer, Py_XNewRef(timer)); + pObj->tool_id = PY_MONITORING_PROFILER_ID; + + PyObject* monitoring = _PyImport_GetModuleAttrString("sys", "monitoring"); + if (!monitoring) { + return -1; + } + pObj->missing = PyObject_GetAttrString(monitoring, "MISSING"); + if (!pObj->missing) { + Py_DECREF(monitoring); + return -1; + } + Py_DECREF(monitoring); return 0; } static PyMethodDef profiler_methods[] = { _LSPROF_PROFILER_GETSTATS_METHODDEF - {"enable", _PyCFunction_CAST(profiler_enable), + {"enable", _PyCFunction_CAST(profiler_enable), METH_VARARGS | METH_KEYWORDS, enable_doc}, - {"disable", (PyCFunction)profiler_disable, + {"disable", (PyCFunction)profiler_disable, METH_NOARGS, disable_doc}, - {"clear", (PyCFunction)profiler_clear, + {"clear", (PyCFunction)profiler_clear, METH_NOARGS, clear_doc}, + {"_pystart_callback", _PyCFunction_CAST(pystart_callback), + METH_FASTCALL, NULL}, + {"_pyreturn_callback", _PyCFunction_CAST(pyreturn_callback), + METH_FASTCALL, NULL}, + {"_ccall_callback", _PyCFunction_CAST(ccall_callback), + METH_FASTCALL, NULL}, + {"_creturn_callback", _PyCFunction_CAST(creturn_callback), + METH_FASTCALL, NULL}, {NULL, NULL} }; From 82946faf7abb26b737f09d5958f1477f5f8062b4 Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Fri, 14 Apr 2023 06:32:55 +0000 Subject: [PATCH 2/6] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20blu?= =?UTF-8?q?rb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../next/Library/2023-04-14-06-32-54.gh-issue-103533.n_AfcS.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Library/2023-04-14-06-32-54.gh-issue-103533.n_AfcS.rst diff --git a/Misc/NEWS.d/next/Library/2023-04-14-06-32-54.gh-issue-103533.n_AfcS.rst b/Misc/NEWS.d/next/Library/2023-04-14-06-32-54.gh-issue-103533.n_AfcS.rst new file mode 100644 index 00000000000000..1008ea076c71a0 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-04-14-06-32-54.gh-issue-103533.n_AfcS.rst @@ -0,0 +1 @@ +Update :mod:`cProfile` to use PEP 669 API From 3c88fd14b24fa786c0a1c5179ead92720eb41324 Mon Sep 17 00:00:00 2001 From: Tian Gao Date: Sat, 15 Apr 2023 17:44:47 -0700 Subject: [PATCH 3/6] Clean up code. Report ValueError when another tool is trying to use the profiler tool id --- Lib/test/test_cprofile.py | 8 ++++ Modules/_lsprof.c | 99 ++++++++++++++++----------------------- 2 files changed, 49 insertions(+), 58 deletions(-) diff --git a/Lib/test/test_cprofile.py b/Lib/test/test_cprofile.py index e95c01426527f0..484b8f8e3a365c 100644 --- a/Lib/test/test_cprofile.py +++ b/Lib/test/test_cprofile.py @@ -59,6 +59,14 @@ def test_profile_as_context_manager(self): # profile shouldn't be set once we leave the with-block. self.assertIs(sys.monitoring.get_tool(sys.monitoring.PROFILER_ID), None) + def test_second_profiler(self): + pr = self.profilerclass() + pr2 = self.profilerclass() + pr.enable() + self.assertRaises(ValueError, pr2.enable) + pr.disable() + + class TestCommandLine(unittest.TestCase): def test_sort(self): rc, out, err = assert_python_failure('-m', 'cProfile', '-s', 'demo') diff --git a/Modules/_lsprof.c b/Modules/_lsprof.c index ba63dc8655315f..b10bbd4d167ed8 100644 --- a/Modules/_lsprof.c +++ b/Modules/_lsprof.c @@ -672,6 +672,23 @@ PyObject* creturn_callback(ProfilerObject* self, PyObject *const *args, Py_ssize Py_RETURN_NONE; } +typedef struct { + int event; + const char* callback_method; +} CallbackTableEntry; + +static CallbackTableEntry callback_table[] = { + {PY_MONITORING_EVENT_PY_START, "_pystart_callback"}, + {PY_MONITORING_EVENT_PY_RESUME, "_pystart_callback"}, + {PY_MONITORING_EVENT_PY_RETURN, "_pyreturn_callback"}, + {PY_MONITORING_EVENT_PY_YIELD, "_pyreturn_callback"}, + {PY_MONITORING_EVENT_PY_UNWIND, "_pyreturn_callback"}, + {PY_MONITORING_EVENT_CALL, "_ccall_callback"}, + {PY_MONITORING_EVENT_C_RETURN, "_creturn_callback"}, + {PY_MONITORING_EVENT_C_RAISE, "_creturn_callback"}, + {0, NULL} +}; + PyDoc_STRVAR(enable_doc, "\ enable(subcalls=True, builtins=True)\n\ \n\ @@ -688,6 +705,7 @@ profiler_enable(ProfilerObject *self, PyObject *args, PyObject *kwds) int subcalls = -1; int builtins = -1; static char *kwlist[] = {"subcalls", "builtins", 0}; + int all_events = 0; if (!PyArg_ParseTupleAndKeywords(args, kwds, "|pp:enable", kwlist, &subcalls, &builtins)) @@ -702,70 +720,25 @@ profiler_enable(ProfilerObject *self, PyObject *args, PyObject *kwds) } if (PyObject_CallMethod(monitoring, "use_tool_id", "is", self->tool_id, "cProfile") == NULL) { + PyErr_Format(PyExc_ValueError, "Another profiling tool is already active"); Py_DECREF(monitoring); return NULL; } - PyObject* self_pystart_callback = PyObject_GetAttrString((PyObject*)self, "_pystart_callback"); - PyObject* self_pyreturn_callback = PyObject_GetAttrString((PyObject*)self, "_pyreturn_callback"); - PyObject* self_ccall_callback = PyObject_GetAttrString((PyObject*)self, "_ccall_callback"); - PyObject* self_creturn_callback = PyObject_GetAttrString((PyObject*)self, "_creturn_callback"); - - if (!self_pystart_callback || !self_pyreturn_callback || !self_ccall_callback || !self_creturn_callback) { - Py_XDECREF(self_pystart_callback); - Py_XDECREF(self_pyreturn_callback); - Py_XDECREF(self_ccall_callback); - Py_XDECREF(self_creturn_callback); - Py_DECREF(monitoring); - return NULL; + for (int i = 0; callback_table[i].callback_method; i++) { + PyObject* callback = PyObject_GetAttrString((PyObject*)self, callback_table[i].callback_method); + if (!callback) { + Py_DECREF(monitoring); + return NULL; + } + Py_XDECREF(PyObject_CallMethod(monitoring, "register_callback", "iiO", self->tool_id, + (1 << callback_table[i].event), + callback)); + Py_DECREF(callback); + all_events |= (1 << callback_table[i].event); } - Py_XDECREF(PyObject_CallMethod(monitoring, "register_callback", "iiO", self->tool_id, - (1 << PY_MONITORING_EVENT_PY_START), - self_pystart_callback)); - - Py_XDECREF(PyObject_CallMethod(monitoring, "register_callback", "iiO", self->tool_id, - (1 << PY_MONITORING_EVENT_PY_RESUME), - self_pystart_callback)); - - Py_XDECREF(PyObject_CallMethod(monitoring, "register_callback", "iiO", self->tool_id, - (1 << PY_MONITORING_EVENT_PY_RETURN), - self_pyreturn_callback)); - - Py_XDECREF(PyObject_CallMethod(monitoring, "register_callback", "iiO", self->tool_id, - (1 << PY_MONITORING_EVENT_PY_YIELD), - self_pyreturn_callback)); - - Py_XDECREF(PyObject_CallMethod(monitoring, "register_callback", "iiO", self->tool_id, - (1 << PY_MONITORING_EVENT_PY_UNWIND), - self_pyreturn_callback)); - - Py_XDECREF(PyObject_CallMethod(monitoring, "register_callback", "iiO", self->tool_id, - (1 << PY_MONITORING_EVENT_CALL), - self_ccall_callback)); - - Py_XDECREF(PyObject_CallMethod(monitoring, "register_callback", "iiO", self->tool_id, - (1 << PY_MONITORING_EVENT_C_RETURN), - self_creturn_callback)); - - Py_XDECREF(PyObject_CallMethod(monitoring, "register_callback", "iiO", self->tool_id, - (1 << PY_MONITORING_EVENT_C_RAISE), - self_creturn_callback)); - - Py_DECREF(self_pystart_callback); - Py_DECREF(self_pyreturn_callback); - Py_DECREF(self_ccall_callback); - Py_DECREF(self_creturn_callback); - - if (!PyObject_CallMethod(monitoring, "set_events", "ii", self->tool_id, - (1 << PY_MONITORING_EVENT_PY_START) - | (1 << PY_MONITORING_EVENT_PY_RESUME) - | (1 << PY_MONITORING_EVENT_PY_RETURN) - | (1 << PY_MONITORING_EVENT_PY_YIELD) - | (1 << PY_MONITORING_EVENT_PY_UNWIND) - | (1 << PY_MONITORING_EVENT_CALL) - | (1 << PY_MONITORING_EVENT_C_RETURN) - | (1 << PY_MONITORING_EVENT_C_RAISE))) { + if (!PyObject_CallMethod(monitoring, "set_events", "ii", self->tool_id, all_events)) { Py_DECREF(monitoring); return NULL; } @@ -809,6 +782,16 @@ profiler_disable(ProfilerObject *self, PyObject* noarg) return NULL; } + for (int i = 0; callback_table[i].callback_method; i++) { + result = PyObject_CallMethod(monitoring, "register_callback", "iiO", self->tool_id, + (1 << callback_table[i].event), Py_None); + if (!result) { + Py_DECREF(monitoring); + return NULL; + } + Py_DECREF(result); + } + result = PyObject_CallMethod(monitoring, "set_events", "ii", self->tool_id, 0); if (!result) { Py_DECREF(monitoring); From 2c9bed406464ad1a5cb4be66fcd13d0102e6d9f9 Mon Sep 17 00:00:00 2001 From: Tian Gao Date: Sat, 15 Apr 2023 20:05:38 -0700 Subject: [PATCH 4/6] Make the callback table const --- Modules/_lsprof.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/_lsprof.c b/Modules/_lsprof.c index b10bbd4d167ed8..0b0dc6d18326e1 100644 --- a/Modules/_lsprof.c +++ b/Modules/_lsprof.c @@ -677,7 +677,7 @@ typedef struct { const char* callback_method; } CallbackTableEntry; -static CallbackTableEntry callback_table[] = { +static const CallbackTableEntry callback_table[] = { {PY_MONITORING_EVENT_PY_START, "_pystart_callback"}, {PY_MONITORING_EVENT_PY_RESUME, "_pystart_callback"}, {PY_MONITORING_EVENT_PY_RETURN, "_pyreturn_callback"}, From 20f46637937dd35d1abfcf744cd442e0fe49fb62 Mon Sep 17 00:00:00 2001 From: Tian Gao Date: Wed, 19 Apr 2023 18:22:00 -0700 Subject: [PATCH 5/6] Make global check happy --- Modules/_lsprof.c | 6 ++---- Tools/c-analyzer/cpython/ignored.tsv | 1 + 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/Modules/_lsprof.c b/Modules/_lsprof.c index 0b0dc6d18326e1..804b9aa4add102 100644 --- a/Modules/_lsprof.c +++ b/Modules/_lsprof.c @@ -672,12 +672,10 @@ PyObject* creturn_callback(ProfilerObject* self, PyObject *const *args, Py_ssize Py_RETURN_NONE; } -typedef struct { +static const struct { int event; const char* callback_method; -} CallbackTableEntry; - -static const CallbackTableEntry callback_table[] = { +} callback_table[] = { {PY_MONITORING_EVENT_PY_START, "_pystart_callback"}, {PY_MONITORING_EVENT_PY_RESUME, "_pystart_callback"}, {PY_MONITORING_EVENT_PY_RETURN, "_pyreturn_callback"}, diff --git a/Tools/c-analyzer/cpython/ignored.tsv b/Tools/c-analyzer/cpython/ignored.tsv index a8ba88efc732fb..1c394e5f2139cf 100644 --- a/Tools/c-analyzer/cpython/ignored.tsv +++ b/Tools/c-analyzer/cpython/ignored.tsv @@ -216,6 +216,7 @@ Modules/_io/_iomodule.c - static_types - Modules/_io/textio.c - encodefuncs - Modules/_io/winconsoleio.c - _PyWindowsConsoleIO_Type - Modules/_localemodule.c - langinfo_constants - +Modules/_lsprof.c - callback_table - Modules/_pickle.c - READ_WHOLE_LINE - Modules/_sqlite/module.c - error_codes - Modules/_sre/sre.c pattern_repr flag_names - From b7b719d75e1e3546d7521ec4e109945589a67f92 Mon Sep 17 00:00:00 2001 From: Tian Gao Date: Thu, 4 May 2023 10:58:49 -0700 Subject: [PATCH 6/6] Fixed return None to NULL --- Modules/_lsprof.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/_lsprof.c b/Modules/_lsprof.c index 804b9aa4add102..a7ce328cb5307a 100644 --- a/Modules/_lsprof.c +++ b/Modules/_lsprof.c @@ -623,7 +623,7 @@ PyObject* get_cfunc_from_callable(PyObject* callable, PyObject* self_arg, PyObje /* If no arg, skip */ if (self_arg == missing) { - Py_RETURN_NONE; + return NULL; } PyObject *meth = Py_TYPE(callable)->tp_descr_get( callable, self_arg, (PyObject*)Py_TYPE(self_arg));