From da8c5565d1f89ecfa6c5581ed8dd12a446fceebf Mon Sep 17 00:00:00 2001 From: Prithviraj Chaudhuri Date: Sat, 3 Oct 2026 01:07:26 -0400 Subject: [PATCH 1/4] Added importer support to profiling --- Lib/profile.py | 36 +++++++++++++++-------- Lib/profiling/tracing/__init__.py | 49 ++++++++++++++++++------------- 2 files changed, 52 insertions(+), 33 deletions(-) diff --git a/Lib/profile.py b/Lib/profile.py index 304284da4211632..eb4923c17049950 100644 --- a/Lib/profile.py +++ b/Lib/profile.py @@ -23,8 +23,6 @@ # governing permissions and limitations under the License. -import importlib.machinery -import io import sys import time import marshal @@ -562,7 +560,9 @@ def f(m, f1=f1): def main(): import os + import runpy from optparse import OptionParser + from pkgutil import get_importer usage = "profile.py [-o output_file_path] [-s sort] [-m module | scriptfile] [arg] ..." parser = OptionParser(usage=usage) @@ -589,7 +589,6 @@ def main(): if len(args) > 0: if options.module: - import runpy code = "run_module(modname, run_name='__main__')" globs = { 'run_module': runpy.run_module, @@ -597,17 +596,28 @@ def main(): } else: progname = args[0] + importer = get_importer(progname) sys.path.insert(0, os.path.dirname(progname)) - with io.open_code(progname) as fp: - code = compile(fp.read(), progname, 'exec') - spec = importlib.machinery.ModuleSpec(name='__main__', loader=None, - origin=progname) - globs = { - '__spec__': spec, - '__file__': spec.origin, - '__name__': spec.name, - '__package__': None, - } + + if importer is not None: + code = "run_module_as_main('__main__', alter_argv=False)" + globs = { + "run_module_as_main": runpy._run_module_as_main, + } + else: + import io + import importlib.machinery + + with io.open_code(progname) as fp: + code = compile(fp.read(), progname, 'exec') + spec = importlib.machinery.ModuleSpec(name='__main__', loader=None, + origin=progname) + globs = { + '__spec__': spec, + '__file__': spec.origin, + '__name__': spec.name, + '__package__': None, + } try: runctx(code, globs, None, options.outfile, options.sort) except BrokenPipeError as exc: diff --git a/Lib/profiling/tracing/__init__.py b/Lib/profiling/tracing/__init__.py index 165665304e05a40..78adb38968272c7 100644 --- a/Lib/profiling/tracing/__init__.py +++ b/Lib/profiling/tracing/__init__.py @@ -150,6 +150,7 @@ def main(): import runpy import pstats from optparse import OptionParser + from pkgutil import get_importer usage = "cProfile.py [-o output_file_path] [-s sort] [-m module | scriptfile] [arg] ..." parser = OptionParser(usage=usage) parser.allow_interspersed_args = False @@ -183,27 +184,35 @@ def main(): } else: progname = args[0] + importer = get_importer(progname) sys.path.insert(0, os.path.dirname(progname)) - with io.open_code(progname) as fp: - code = compile(fp.read(), progname, 'exec', module='__main__') - spec = importlib.machinery.ModuleSpec(name='__main__', loader=None, - origin=progname) - 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({ - # Set __spec__ to None so the profiled program behaves like a - # script run directly (gh-140729). - '__spec__': None, - '__file__': spec.origin, - '__name__': spec.name, - '__package__': None, - }) + + if importer is not None: + code = "run_module_as_main('__main__', alter_argv=False)" + globs = { + "run_module_as_main": runpy._run_module_as_main, + } + else: + with io.open_code(progname) as fp: + code = compile(fp.read(), progname, 'exec', module='__main__') + spec = importlib.machinery.ModuleSpec(name='__main__', loader=None, + origin=progname) + 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({ + # Set __spec__ to None so the profiled program behaves like a + # script run directly (gh-140729). + '__spec__': None, + '__file__': spec.origin, + '__name__': spec.name, + '__package__': None, + }) try: runctx(code, globs, None, options.outfile, options.sort) From dfdfaec9fcc100e02d0d48c81ca4b80996e9ec16 Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Sun, 4 Oct 2026 04:29:49 +0000 Subject: [PATCH 2/4] =?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/C_API/2026-10-04-04-29-47.gh-issue-100961.hwdNxK.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/C_API/2026-10-04-04-29-47.gh-issue-100961.hwdNxK.rst diff --git a/Misc/NEWS.d/next/C_API/2026-10-04-04-29-47.gh-issue-100961.hwdNxK.rst b/Misc/NEWS.d/next/C_API/2026-10-04-04-29-47.gh-issue-100961.hwdNxK.rst new file mode 100644 index 000000000000000..f18018162b68a07 --- /dev/null +++ b/Misc/NEWS.d/next/C_API/2026-10-04-04-29-47.gh-issue-100961.hwdNxK.rst @@ -0,0 +1 @@ +Added logic to evaluate importers when running Profile and cProfile, then use _run_module_as_main to run the target script. From bac9c7e53731fd0066be1e2385c5cb7019a9b64b Mon Sep 17 00:00:00 2001 From: Prithviraj Chaudhuri Date: Sun, 4 Oct 2026 00:46:55 -0400 Subject: [PATCH 3/4] Updated blurb --- .../next/C_API/2026-10-04-04-29-47.gh-issue-100961.hwdNxK.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/Misc/NEWS.d/next/C_API/2026-10-04-04-29-47.gh-issue-100961.hwdNxK.rst b/Misc/NEWS.d/next/C_API/2026-10-04-04-29-47.gh-issue-100961.hwdNxK.rst index f18018162b68a07..6ee1a157ce7b9fc 100644 --- a/Misc/NEWS.d/next/C_API/2026-10-04-04-29-47.gh-issue-100961.hwdNxK.rst +++ b/Misc/NEWS.d/next/C_API/2026-10-04-04-29-47.gh-issue-100961.hwdNxK.rst @@ -1 +1,2 @@ Added logic to evaluate importers when running Profile and cProfile, then use _run_module_as_main to run the target script. +If importer is not none then the target script is run using _run_module_as_main. From fd6cf1aa9b35e809c9a31d44aea977e2c41b7993 Mon Sep 17 00:00:00 2001 From: Prithviraj Chaudhuri Date: Sun, 4 Oct 2026 01:54:55 -0400 Subject: [PATCH 4/4] Retrigger CI