Skip to content

FIX: kernprof -m: presence of the executed module as sys.modules['__main__'] #339

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
May 4, 2025

Conversation

TTsangSC
Copy link
Contributor

Motivation

kernprof -m as it is now fails to address edge cases where the executed module is expected to be found at sys.modules['__main__']. One such cases is for the @enum.global_enum decorator, which searches sys.modules for the module whither to insert the enum instances. This causes use-cases like kernprof -m calendar to fail. Notably, a similar failure pattern is seen with even Python stdlib modules.

Changes

The key point of failure lies with how kernprof uses runpy.run_module() without the optional alter_sys argument. Since it defaults to false, the executed module is not inserted into sys.modules, and thus the aforementioned use-case fails. Hence, this PR implements the following changes:

  • CHANGELOG.rst:
    Added entry
  • kernprof.py::main():
    Now calling runpy.run_module() with alter_sys = True to maintain compatibility with code expecting the executed module to be found at sys.modules['__main__']
  • line_profiler/autoprofile/autoprofile.py::run():
    Updated implementation to do the equivalent of runpy.run_module(alter_sys=True)
  • tests/test_kernprof.py:
    • test_kernprof_m_parsing():
      • Updated implementation to expect the correct sys.argv[0] (real path to the module file)
      • Replaced tempfile.mkdtemp() with tempfile.TemporaryDirectory
    • test_kernprof_m_sys_modules():
      New test for compatibility with tools (e.g. @enum.global_enum) expecting the executed module to be found at sys.modules['__main__']

CHANGELOG.rst
    Added entry

kernprof.py::main()
    Now calling `runpy.run_module()` with `alter_sys = True` to maintain
    compatibility with code expecting the executed module to be found at
    `sys.modules['__main__']`

line_profiler/autoprofile/autoprofile.py::run()
    Updated implementation to do the equivalent of
    `runpy.run_module(alter_sys=True)`

tests/test_kernprof.py
    test_kernprof_m_parsing()
        - Updated implementation to expect the correct `sys.argv[0]`
          (real path to the module file)
        - Replaced `tempfile.mkdtemp()` with
          `tempfile.TemporaryDirectory`
    test_kernprof_m_sys_modules()
        New test for compatibility with tools (e.g. `@enum.global_enum`)
        expecting the executed module to be found at
        `sys.modules['__main__']`
@TTsangSC
Copy link
Contributor Author

TTsangSC commented Apr 29, 2025

We may want to give priority to this (over the other PRs) given that it's a fix instead of a new feature...

@Erotemic

Copy link

codecov bot commented Apr 29, 2025

Codecov Report

Attention: Patch coverage is 92.85714% with 2 lines in your changes missing coverage. Please review.

Project coverage is 63.63%. Comparing base (7f25e70) to head (53a3846).
Report is 8 commits behind head on main.

Files with missing lines Patch % Lines
line_profiler/autoprofile/autoprofile.py 92.85% 2 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #339      +/-   ##
==========================================
+ Coverage   62.30%   63.63%   +1.33%     
==========================================
  Files          13       13              
  Lines        1008     1034      +26     
  Branches      225      229       +4     
==========================================
+ Hits          628      658      +30     
+ Misses        316      315       -1     
+ Partials       64       61       -3     
Files with missing lines Coverage Δ
line_profiler/autoprofile/autoprofile.py 95.00% <92.85%> (-5.00%) ⬇️

... and 2 files with indirect coverage changes


Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 155c4c2...53a3846. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Member

@Erotemic Erotemic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall this looks great, and I had to go out of my way to find things to comment on. The only thing I think should be changed is the assert statement (unless I'm missing something and we really expect that to never happen, but it looks like a user-typo could cause that case to be hit).

line_profiler/autoprofile/autoprofile.py::run()
    - Replaced assertion with an explicitly raised `ModuleNotFoundError`
    - Streamlined logic to always call `importlib.util.find_spec()`,
      regardless of whether the module is found in `sys.modules` and
      already has a spec
@TTsangSC
Copy link
Contributor Author

TTsangSC commented May 3, 2025

Thanks for the review! Just updated the PR.

@TTsangSC
Copy link
Contributor Author

TTsangSC commented May 3, 2025

Weird, the pipeline isn't running after I pushed the changes... did we recently change workflow-triggering policies?

@TTsangSC TTsangSC requested a review from Erotemic May 4, 2025 01:51
@Erotemic
Copy link
Member

Erotemic commented May 4, 2025

I haven't changed anything. Not sure why the CI isn't running. There isn't anything about a pending workflow that needs approval. It just isn't running and I don't see an option to force it to run.

EDIT: I added a dummy commit, and it seems to run fine now. Not sure what was up. I'm unsatisfied with this hack, but at the same time I don't want to spend effort looking into it. Will keep an eye out if it happens again.

@Erotemic Erotemic merged commit 3537a50 into pyutils:main May 4, 2025
36 checks passed
@TTsangSC TTsangSC deleted the module-fix branch May 5, 2025 07:48
@TTsangSC
Copy link
Contributor Author

TTsangSC commented May 5, 2025

Cheers!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants