diff --git a/Lib/profiling/tracing/__init__.py b/Lib/profiling/tracing/__init__.py index bd3cbf299aab3b9..6423e8c9f4e93d8 100644 --- a/Lib/profiling/tracing/__init__.py +++ b/Lib/profiling/tracing/__init__.py @@ -197,7 +197,10 @@ def main(): # in the module's namespace. globs = module.__dict__ globs.update({ - '__spec__': spec, + # See gh-140729, set None to __spec__ according + # to the documentation, + # https://docs.python.org/3/reference/import.html#module-specs + '__spec__': None, '__file__': spec.origin, '__name__': spec.name, '__package__': None, diff --git a/Lib/test/test_profiling/test_tracing_profiler.py b/Lib/test/test_profiling/test_tracing_profiler.py index 3668e24e073ce4d..3ef33d1abb91408 100644 --- a/Lib/test/test_profiling/test_tracing_profiler.py +++ b/Lib/test/test_profiling/test_tracing_profiler.py @@ -1,5 +1,4 @@ """Test suite for the cProfile module.""" - import sys import unittest @@ -192,6 +191,31 @@ class Foo: f.close() assert_python_ok('-m', "cProfile", f.name) + def test_process_run_pickle(self): + # gh-140729: test use Process in cProfile. + val = 10 + with tempfile.NamedTemporaryFile("w+", delete_on_close=False) as f: + f.write(textwrap.dedent( + f'''\ + import multiprocessing + + def worker(x): + print(__name__) + exit(x ** 2) + + if __name__ == "__main__": + multiprocessing.set_start_method("spawn") + p = multiprocessing.Process(target=worker, args=({val},)) + p.start() + p.join() + print("p.exitcode =", p.exitcode) + ''')) + f.close() + _, out, err = assert_python_ok('-m', "cProfile", f.name) + self.assertIn(b"__mp_main__", out) + self.assertIn(bytes(f"exitcode = {val**2}", encoding='utf8'), out) + self.assertNotIn(b"Can't pickle", err) + def main(): if '-r' not in sys.argv: diff --git a/Misc/NEWS.d/next/Library/2026-02-11-16-47-27.gh-issue-140729.2uTPQp.rst b/Misc/NEWS.d/next/Library/2026-02-11-16-47-27.gh-issue-140729.2uTPQp.rst new file mode 100644 index 000000000000000..efe0efda798978b --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-02-11-16-47-27.gh-issue-140729.2uTPQp.rst @@ -0,0 +1 @@ +Fix pickling error in the ``cProfile`` module when using :class:`multiprocessing.Process` in script, which can not be properly pickled and executed.