FIX: kernprof to always run code in sys.modules['__main__']'s namespace#423
Open
TTsangSC wants to merge 4 commits intopyutils:mainfrom
Open
FIX: kernprof to always run code in sys.modules['__main__']'s namespace#423TTsangSC wants to merge 4 commits intopyutils:mainfrom
kernprof to always run code in sys.modules['__main__']'s namespace#423TTsangSC wants to merge 4 commits intopyutils:mainfrom
Conversation
line_profiler/autoprofile/autoprofile.py::run()
- Now always creating a temporary module object for
`sys.modules['__main__']` (not only when `as_module=True`),
executing the code in its namespace and context
- Simplified internal code and dropped some imports due to the
reduced branching
kernprof.py::_main_profile()
As with `line_profiler.autoprofile.autoprofile.run()`, the code
execution now always happens in the namespace of a temporary module
object at `sys.modules['__main__']`;
this now covers cases without with `--prof-mod=...` and/or
`--line-by-line` flags
tests/test_child_procs.py
New test module (to be expanded) checking that `kernprof` doesn't
choke when running code using `multiprocessing`
- test_module
`pytest` fixture for a script/module, in which a function is
called parallel-ly with `multiprocessing.Pool.map()`
- test_multiproc_script_sanity_check()
Test that the test code works as intended with vanilla Python
- test_running_multiproc_{script,module}()
Test that the test code works as intended with `kernprof`, both
when invoked as a module and a script
TODO:
- XFailed tests for incomplete profiling results
- Actual implementation of child-process profiling
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #423 +/- ##
==========================================
+ Coverage 87.56% 89.02% +1.45%
==========================================
Files 18 20 +2
Lines 1641 2250 +609
Branches 348 473 +125
==========================================
+ Hits 1437 2003 +566
- Misses 149 184 +35
- Partials 55 63 +8
... and 4 files with indirect coverage changes Continue to review full report in Codecov by Sentry.
🚀 New features to boost your workflow:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
As discussed in #422, depending on the invocation of
kernprof, the profiled/executed code was not always consistently executed insys.modules['__main__']'s namespace. This poses issues with e.g. code usingmultiprocessing: the executed functions and data are pickled, and that in turn relies on their being reachable and retrievable via their expected locations insys.modules.Code changes
Monkey-patching
sys.modules['__main__']with an appropriate dummy module object makes sure that the executed code is run in the context and namespace of__main__. This is currently only done forline_profiler.autoprofile.autoprofile.run(..., as_module=True), which is only used whenkernprofis called with line-profiling active (-l), with profiling targets supplied (-p <...>), and executing the code as a module (-m)).The following functions are now updated so that all code paths
kernproftakes would receive the same treatment:line_profiler.autoprofile.autoprofile.run()kernprof._main_profile()Test changes
A new test module
tests/test_child_procs.pyis now added, extending upon the failing case in #422 to make sure thatkernprofcan now handle such the execution of such code:test_modulepytestfixture of a file containing test code usingmultiprocessingto parallelize some workload across child processes; can be run either as a script or a module, with customizable workload and parallelizationtest_multiproc_script_sanity_check()Checking that the test code works as expected when run with vanilla Python
test_running_multiproc_script(),test_running_multiproc_module()Checking that the execution of the test code is not affected by
kernprofin all code pathsThis test module is expected to be extended with tests where the actual profiling of child processes is tested (when we get there; maybe I can just chuck a couple in there which XFAIL at the moment?).
Other changes
In
CHANGELOG.md:5.0.1->5.0.2)Caveats
We can't currently properly profile child Python processes anyway; still, it is worthwhile to work towards that, and failing that, at the very least fix the bug so that the
kernprofdoesn't choke on random code.