From 2a670037382af5cd6a656ab8f49daf3fbe061095 Mon Sep 17 00:00:00 2001 From: sobolevn Date: Tue, 3 Nov 2026 11:23:27 +0300 Subject: [PATCH 1/2] [3.14] gh-161233: Fix `TypeError` when `timer=None` was passed to `cProfile.Profile` (GH-161234) (cherry picked from commit e9c9a339035c9b96a5ebca8337a13140725ecf2a) Co-authored-by: sobolevn --- Lib/test/test_cprofile.py | 14 ++ ...-11-03-10-33-33.gh-issue-161233._9VrfL.rst | 2 + Modules/_lsprof.c | 4 + Modules/config_bootstrap.c | 122 ++++++++++++++++++ 4 files changed, 142 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2026-11-03-10-33-33.gh-issue-161233._9VrfL.rst create mode 100644 Modules/config_bootstrap.c diff --git a/Lib/test/test_cprofile.py b/Lib/test/test_cprofile.py index 5230348c0eb68f7..656143a399a7ff7 100644 --- a/Lib/test/test_cprofile.py +++ b/Lib/test/test_cprofile.py @@ -105,6 +105,20 @@ def timer(): profiler.disable() profiler.clear() + def test_external_timer_is_none(self): + # gh-161233 + def work(): + pass + + for kwargs in ({}, {'timer': None}): + with self.subTest(kwargs=kwargs): + profiler = cProfile.Profile(**kwargs) + profiler.enable() + with support.catch_unraisable_exception() as cm: + work() + self.assertIsNone(cm.unraisable) + profiler.disable() + def test_profile_enable_disable(self): prof = self.profilerclass() # Make sure we clean ourselves up if the test fails for some reason. diff --git a/Misc/NEWS.d/next/Library/2026-11-03-10-33-33.gh-issue-161233._9VrfL.rst b/Misc/NEWS.d/next/Library/2026-11-03-10-33-33.gh-issue-161233._9VrfL.rst new file mode 100644 index 000000000000000..96e9f5e39df3ec1 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-11-03-10-33-33.gh-issue-161233._9VrfL.rst @@ -0,0 +1,2 @@ +Fix unraisable :exc:`TypeError` when ``None`` was passed as a *timer* to +:class:`cProfile.Profile `. diff --git a/Modules/_lsprof.c b/Modules/_lsprof.c index 237919e889ca0c8..a157d808d7bd198 100644 --- a/Modules/_lsprof.c +++ b/Modules/_lsprof.c @@ -92,6 +92,7 @@ _lsprof_get_state(PyObject *module) static PyTime_t CallExternalTimer(ProfilerObject *pObj) { + assert(pObj->externalTimer != NULL && pObj->externalTimer != Py_None); PyObject *o = NULL; // External timer can do arbitrary things so we need a flag to prevent @@ -1021,6 +1022,9 @@ profiler_init_impl(ProfilerObject *self, PyObject *timer, double timeunit, if (setSubcalls(self, subcalls) < 0 || setBuiltins(self, builtins) < 0) { return -1; } + if (timer == Py_None) { + timer = NULL; + } self->externalTimerUnit = timeunit; Py_XSETREF(self->externalTimer, Py_XNewRef(timer)); self->tool_id = PY_MONITORING_PROFILER_ID; diff --git a/Modules/config_bootstrap.c b/Modules/config_bootstrap.c new file mode 100644 index 000000000000000..3bee44089cfafb8 --- /dev/null +++ b/Modules/config_bootstrap.c @@ -0,0 +1,122 @@ +/* Generated automatically from ./Modules/config.c.in by makesetup. */ +/* Module configuration */ + +/* !!! !!! !!! This file is edited by the makesetup script !!! !!! !!! */ + +/* This file contains the table of built-in modules. + See create_builtin() in import.c. */ + +#include "Python.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +extern PyObject* PyInit_atexit(void); +extern PyObject* PyInit_faulthandler(void); +extern PyObject* PyInit_posix(void); +extern PyObject* PyInit__signal(void); +extern PyObject* PyInit__tracemalloc(void); +extern PyObject* PyInit__suggestions(void); +extern PyObject* PyInit__datetime(void); +extern PyObject* PyInit__codecs(void); +extern PyObject* PyInit__collections(void); +extern PyObject* PyInit_errno(void); +extern PyObject* PyInit__io(void); +extern PyObject* PyInit_itertools(void); +extern PyObject* PyInit__sre(void); +extern PyObject* PyInit__sysconfig(void); +extern PyObject* PyInit__thread(void); +extern PyObject* PyInit_time(void); +extern PyObject* PyInit__types(void); +extern PyObject* PyInit__typing(void); +extern PyObject* PyInit__weakref(void); +extern PyObject* PyInit__abc(void); +extern PyObject* PyInit__functools(void); +extern PyObject* PyInit__locale(void); +extern PyObject* PyInit__opcode(void); +extern PyObject* PyInit__operator(void); +extern PyObject* PyInit__stat(void); +extern PyObject* PyInit__symtable(void); +extern PyObject* PyInit_pwd(void); + +/* -- ADDMODULE MARKER 1 -- */ + +extern PyObject* PyMarshal_Init(void); +extern PyObject* PyInit__imp(void); +extern PyObject* PyInit_gc(void); +extern PyObject* PyInit__ast(void); +extern PyObject* PyInit__tokenize(void); +extern PyObject* PyInit__contextvars(void); +extern PyObject* _PyWarnings_Init(void); +extern PyObject* PyInit__string(void); + +struct _inittab _PyImport_Inittab[] = { + + {"atexit", PyInit_atexit}, + {"faulthandler", PyInit_faulthandler}, + {"posix", PyInit_posix}, + {"_signal", PyInit__signal}, + {"_tracemalloc", PyInit__tracemalloc}, + {"_suggestions", PyInit__suggestions}, + {"_datetime", PyInit__datetime}, + {"_codecs", PyInit__codecs}, + {"_collections", PyInit__collections}, + {"errno", PyInit_errno}, + {"_io", PyInit__io}, + {"itertools", PyInit_itertools}, + {"_sre", PyInit__sre}, + {"_sysconfig", PyInit__sysconfig}, + {"_thread", PyInit__thread}, + {"time", PyInit_time}, + {"_types", PyInit__types}, + {"_typing", PyInit__typing}, + {"_weakref", PyInit__weakref}, + {"_abc", PyInit__abc}, + {"_functools", PyInit__functools}, + {"_locale", PyInit__locale}, + {"_opcode", PyInit__opcode}, + {"_operator", PyInit__operator}, + {"_stat", PyInit__stat}, + {"_symtable", PyInit__symtable}, + {"pwd", PyInit_pwd}, + +/* -- ADDMODULE MARKER 2 -- */ + + /* This module lives in marshal.c */ + {"marshal", PyMarshal_Init}, + + /* This lives in import.c */ + {"_imp", PyInit__imp}, + + /* This lives in Python/Python-ast.c */ + {"_ast", PyInit__ast}, + + /* This lives in Python/Python-tokenize.c */ + {"_tokenize", PyInit__tokenize}, + + /* These entries are here for sys.builtin_module_names */ + {"builtins", NULL}, + {"sys", NULL}, + + /* This lives in gcmodule.c */ + {"gc", PyInit_gc}, + + /* This lives in Python/_contextvars.c */ + {"_contextvars", PyInit__contextvars}, + + /* This lives in _warnings.c */ + {"_warnings", _PyWarnings_Init}, + + /* This lives in Objects/unicodeobject.c */ + {"_string", PyInit__string}, + + /* Sentinel */ + {0, 0} +}; + + +#ifdef __cplusplus +} +#endif From a714c004522767e2bfb9e1c8959151d12e78327e Mon Sep 17 00:00:00 2001 From: sobolevn Date: Tue, 3 Nov 2026 11:37:17 +0300 Subject: [PATCH 2/2] Delete Modules/config_bootstrap.c --- Modules/config_bootstrap.c | 122 ------------------------------------- 1 file changed, 122 deletions(-) delete mode 100644 Modules/config_bootstrap.c diff --git a/Modules/config_bootstrap.c b/Modules/config_bootstrap.c deleted file mode 100644 index 3bee44089cfafb8..000000000000000 --- a/Modules/config_bootstrap.c +++ /dev/null @@ -1,122 +0,0 @@ -/* Generated automatically from ./Modules/config.c.in by makesetup. */ -/* Module configuration */ - -/* !!! !!! !!! This file is edited by the makesetup script !!! !!! !!! */ - -/* This file contains the table of built-in modules. - See create_builtin() in import.c. */ - -#include "Python.h" - -#ifdef __cplusplus -extern "C" { -#endif - - -extern PyObject* PyInit_atexit(void); -extern PyObject* PyInit_faulthandler(void); -extern PyObject* PyInit_posix(void); -extern PyObject* PyInit__signal(void); -extern PyObject* PyInit__tracemalloc(void); -extern PyObject* PyInit__suggestions(void); -extern PyObject* PyInit__datetime(void); -extern PyObject* PyInit__codecs(void); -extern PyObject* PyInit__collections(void); -extern PyObject* PyInit_errno(void); -extern PyObject* PyInit__io(void); -extern PyObject* PyInit_itertools(void); -extern PyObject* PyInit__sre(void); -extern PyObject* PyInit__sysconfig(void); -extern PyObject* PyInit__thread(void); -extern PyObject* PyInit_time(void); -extern PyObject* PyInit__types(void); -extern PyObject* PyInit__typing(void); -extern PyObject* PyInit__weakref(void); -extern PyObject* PyInit__abc(void); -extern PyObject* PyInit__functools(void); -extern PyObject* PyInit__locale(void); -extern PyObject* PyInit__opcode(void); -extern PyObject* PyInit__operator(void); -extern PyObject* PyInit__stat(void); -extern PyObject* PyInit__symtable(void); -extern PyObject* PyInit_pwd(void); - -/* -- ADDMODULE MARKER 1 -- */ - -extern PyObject* PyMarshal_Init(void); -extern PyObject* PyInit__imp(void); -extern PyObject* PyInit_gc(void); -extern PyObject* PyInit__ast(void); -extern PyObject* PyInit__tokenize(void); -extern PyObject* PyInit__contextvars(void); -extern PyObject* _PyWarnings_Init(void); -extern PyObject* PyInit__string(void); - -struct _inittab _PyImport_Inittab[] = { - - {"atexit", PyInit_atexit}, - {"faulthandler", PyInit_faulthandler}, - {"posix", PyInit_posix}, - {"_signal", PyInit__signal}, - {"_tracemalloc", PyInit__tracemalloc}, - {"_suggestions", PyInit__suggestions}, - {"_datetime", PyInit__datetime}, - {"_codecs", PyInit__codecs}, - {"_collections", PyInit__collections}, - {"errno", PyInit_errno}, - {"_io", PyInit__io}, - {"itertools", PyInit_itertools}, - {"_sre", PyInit__sre}, - {"_sysconfig", PyInit__sysconfig}, - {"_thread", PyInit__thread}, - {"time", PyInit_time}, - {"_types", PyInit__types}, - {"_typing", PyInit__typing}, - {"_weakref", PyInit__weakref}, - {"_abc", PyInit__abc}, - {"_functools", PyInit__functools}, - {"_locale", PyInit__locale}, - {"_opcode", PyInit__opcode}, - {"_operator", PyInit__operator}, - {"_stat", PyInit__stat}, - {"_symtable", PyInit__symtable}, - {"pwd", PyInit_pwd}, - -/* -- ADDMODULE MARKER 2 -- */ - - /* This module lives in marshal.c */ - {"marshal", PyMarshal_Init}, - - /* This lives in import.c */ - {"_imp", PyInit__imp}, - - /* This lives in Python/Python-ast.c */ - {"_ast", PyInit__ast}, - - /* This lives in Python/Python-tokenize.c */ - {"_tokenize", PyInit__tokenize}, - - /* These entries are here for sys.builtin_module_names */ - {"builtins", NULL}, - {"sys", NULL}, - - /* This lives in gcmodule.c */ - {"gc", PyInit_gc}, - - /* This lives in Python/_contextvars.c */ - {"_contextvars", PyInit__contextvars}, - - /* This lives in _warnings.c */ - {"_warnings", _PyWarnings_Init}, - - /* This lives in Objects/unicodeobject.c */ - {"_string", PyInit__string}, - - /* Sentinel */ - {0, 0} -}; - - -#ifdef __cplusplus -} -#endif