https://github.com/python/cpython/commit/c7a7aa9a57c25ef2666f7dbf62edab882747af6b
commit: c7a7aa9a57c25ef2666f7dbf62edab882747af6b
branch: main
author: Aneesh Durg <aneeshdur...@gmail.com>
committer: gaogaotiantian <gaogaotiant...@hotmail.com>
date: 2025-04-24T14:41:01-04:00
summary:

gh-132737: Support profiling modules that require __main___ (#132738)

files:
A 
Misc/NEWS.d/next/Core_and_Builtins/2025-04-19-18-07-34.gh-issue-132737.9mW1il.rst
M Lib/cProfile.py
M Lib/test/test_cprofile.py

diff --git a/Lib/cProfile.py b/Lib/cProfile.py
index e7c868b8d55543..770d26f79628fe 100644
--- a/Lib/cProfile.py
+++ b/Lib/cProfile.py
@@ -6,6 +6,7 @@
 
 import _lsprof
 import importlib.machinery
+import importlib.util
 import io
 import profile as _pyprofile
 
@@ -173,13 +174,22 @@ def main():
                 code = compile(fp.read(), progname, 'exec')
             spec = importlib.machinery.ModuleSpec(name='__main__', loader=None,
                                                   origin=progname)
-            globs = {
+            module = importlib.util.module_from_spec(spec)
+            # Set __main__ so that importing __main__ in the profiled code will
+            # return the same namespace that the code is executing under.
+            sys.modules['__main__'] = module
+            # Ensure that we're using the same __dict__ instance as the module
+            # for the global variables so that updates to globals are reflected
+            # in the module's namespace.
+            globs = module.__dict__
+            globs.update({
                 '__spec__': spec,
                 '__file__': spec.origin,
                 '__name__': spec.name,
                 '__package__': None,
                 '__cached__': None,
-            }
+            })
+
         try:
             runctx(code, globs, None, options.outfile, options.sort)
         except BrokenPipeError as exc:
diff --git a/Lib/test/test_cprofile.py b/Lib/test/test_cprofile.py
index b46edf66bf09f8..192c8eab26ebff 100644
--- a/Lib/test/test_cprofile.py
+++ b/Lib/test/test_cprofile.py
@@ -5,8 +5,10 @@
 
 # rip off all interesting stuff from test_profile
 import cProfile
+import tempfile
+import textwrap
 from test.test_profile import ProfileTest, regenerate_expected_output
-from test.support.script_helper import assert_python_failure
+from test.support.script_helper import assert_python_failure, assert_python_ok
 from test import support
 
 
@@ -154,6 +156,19 @@ def test_sort(self):
         self.assertGreater(rc, 0)
         self.assertIn(b"option -s: invalid choice: 'demo'", err)
 
+    def test_profile_script_importing_main(self):
+        """Check that scripts that reference __main__ see their own namespace
+        when being profiled."""
+        with tempfile.NamedTemporaryFile("w+", delete_on_close=False) as f:
+            f.write(textwrap.dedent("""\
+                class Foo:
+                    pass
+                import __main__
+                assert Foo == __main__.Foo
+                """))
+            f.close()
+            assert_python_ok('-m', "cProfile", f.name)
+
 
 def main():
     if '-r' not in sys.argv:
diff --git 
a/Misc/NEWS.d/next/Core_and_Builtins/2025-04-19-18-07-34.gh-issue-132737.9mW1il.rst
 
b/Misc/NEWS.d/next/Core_and_Builtins/2025-04-19-18-07-34.gh-issue-132737.9mW1il.rst
new file mode 100644
index 00000000000000..0f01091782529d
--- /dev/null
+++ 
b/Misc/NEWS.d/next/Core_and_Builtins/2025-04-19-18-07-34.gh-issue-132737.9mW1il.rst
@@ -0,0 +1 @@
+Support profiling code that requires ``__main__``, such as :mod:`pickle`.

_______________________________________________
Python-checkins mailing list -- python-checkins@python.org
To unsubscribe send an email to python-checkins-le...@python.org
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: arch...@mail-archive.com

Reply via email to