Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
165 commits
Select commit Hold shift + click to select a range
91f6979
Moved kernprof pre-import code to another module
TTsangSC Mar 25, 2026
4e8cc67
Removed redundant check in kernprof
TTsangSC Mar 25, 2026
9a5a0bc
Move code between kernprof & `~.curated_profiling`
TTsangSC Mar 26, 2026
607d7a3
New subpackage for profiling child processes
TTsangSC Mar 28, 2026
6cf8dee
WIP: set up child-proc profiling via import sys
TTsangSC Mar 28, 2026
7fa12c0
WIP: `multiprocessing` patches
TTsangSC Mar 28, 2026
e3675d9
Child-process stat gathering; cache refactoring
TTsangSC Mar 28, 2026
1c7681a
WIP: kernprof now sets up child-proc profiling
TTsangSC Mar 29, 2026
41eb3b3
Debugging support in `kernprof`
TTsangSC Apr 1, 2026
9bedb2d
Cleanup prioritization and more debug messages
TTsangSC Apr 6, 2026
2d5ffa5
Try to keep one cache per process
TTsangSC Apr 7, 2026
f3f1418
Renamed submodule
TTsangSC Apr 7, 2026
cf00675
WIP: pass along more data
TTsangSC Apr 7, 2026
3119f0a
WIP: fix profiling for forked processes
TTsangSC Apr 8, 2026
12a2ae0
Cleanup: `[...].multiprocessing_patches`
TTsangSC Apr 8, 2026
10d208b
Removed `import_machinery`
TTsangSC Apr 8, 2026
4b6bb38
Fixed stat-aggregation bug
TTsangSC Apr 8, 2026
ab1f921
More forked-process fixes
TTsangSC Apr 8, 2026
ee3f439
Streamlined debug output in `_child_process_profiling`
TTsangSC Apr 8, 2026
78c1533
WIP: refactoring `tests/test_child_procs.py`
TTsangSC Apr 9, 2026
73ac303
Test local funcs in the profiled script
TTsangSC Apr 9, 2026
44c4eb0
Consolidated tests
TTsangSC Apr 9, 2026
5c5556a
Added tests for our `multiprocessing` patches
TTsangSC Apr 11, 2026
ddb211c
WIP: flesh out the child-proc tests more
TTsangSC Apr 12, 2026
b4d28a2
WIP: test when the parallelly-run func fails
TTsangSC Apr 12, 2026
d1947fd
More debug output, flexible `multiprocessing` patching
TTsangSC Apr 13, 2026
f1da2db
Fix attribute-cleanup logic in `multiprocessing_patches.apply()`
TTsangSC Apr 13, 2026
843f410
WIP: let child processes fully clean up before terminating them
TTsangSC Apr 13, 2026
46b7d37
Clean up `~~.multiprocessing_patches`
TTsangSC Apr 13, 2026
519dbd5
Fix `tests/test_child_procs.py`
TTsangSC Apr 13, 2026
e7410e2
Test for non-`multiprocessing` child processes
TTsangSC Apr 13, 2026
de70525
Unify tempfile creation
TTsangSC Apr 14, 2026
a3cfa2f
Failsafe: timeout the lock-file waiting
TTsangSC Apr 14, 2026
5abf4e2
Added check in tests for .pth-file cleanup
TTsangSC Apr 14, 2026
0837d7c
Fix kernprof docstring
TTsangSC Apr 14, 2026
7b4eefa
Shuffled code inside `~._child_process_profiling`
TTsangSC Apr 14, 2026
48e8239
Fix `subprocess.run()` wrapper in tests
TTsangSC Apr 14, 2026
c256fa0
CHANGELOG and help-text update
TTsangSC Apr 14, 2026
4088eb3
Typing fixes
TTsangSC Apr 15, 2026
fa5b4a8
Cache refactoring + logging improvement
TTsangSC Apr 16, 2026
d6e99b3
Factor out common utils
TTsangSC Apr 16, 2026
9363e5e
Refactored `LineProfilingCache` logging
TTsangSC Apr 16, 2026
248dc0f
WIP: write combined debug logs for debugging
TTsangSC Apr 16, 2026
e6d8b8c
Compatibility fix
TTsangSC Apr 16, 2026
108fc33
Compat fix (test)
TTsangSC Apr 16, 2026
093b6e9
Better handling of `multiprocessing`
TTsangSC Apr 17, 2026
c864fa0
Cache the active config
TTsangSC Apr 18, 2026
8cf8ffb
Move config for `multiprocessing_patches`
TTsangSC Apr 18, 2026
d7ee4c9
Streamlined profiler installation
TTsangSC Apr 18, 2026
8fe9bcf
WIP: boost test coverage
TTsangSC Apr 18, 2026
82ed140
Minor refactoring
TTsangSC Apr 18, 2026
acd48b3
More in-process unit tests for `test_child_procs`
TTsangSC Apr 18, 2026
e91719d
WIP debug the new unit tests
TTsangSC Apr 19, 2026
d0dfd8a
Restart the fork-server process after each session
TTsangSC Apr 20, 2026
565c306
Simplify `multiprocessing_patches`
TTsangSC Apr 20, 2026
492a5a1
iMisc. test fixes
TTsangSC Apr 20, 2026
b820e50
Fix thread profiling + refactoring
TTsangSC Apr 21, 2026
a5447e7
Partial rollback of `threading` fix
TTsangSC Apr 22, 2026
575f32c
Fix forkserver profiling in newer Pythons
TTsangSC Apr 22, 2026
6778564
Fix test on Windows
TTsangSC Apr 22, 2026
577e85b
Added `conftest.py`
TTsangSC Apr 25, 2026
fd34eda
Test for `@pytest.mark.retry`
TTsangSC Apr 25, 2026
0ca2af2
Check retried fixture teardown order
TTsangSC Apr 26, 2026
532b0df
Update `test_child_procs.py`
TTsangSC Apr 26, 2026
251f60e
Test fixes
TTsangSC Apr 26, 2026
466a05e
WIP: improve coverage
TTsangSC Apr 26, 2026
f74674d
WIP: refactor cleanup functionalities
TTsangSC Apr 26, 2026
8450358
Move files around
TTsangSC Apr 26, 2026
9b052ce
Patch `threading` with `CuratedProfilerContext`
TTsangSC Apr 26, 2026
09d4e18
Continue migration
TTsangSC Apr 26, 2026
e906f6b
Finish migration
TTsangSC Apr 26, 2026
e02d897
Tweak config layout
TTsangSC Apr 27, 2026
bdbb683
WIP: increase test coverage
TTsangSC Apr 27, 2026
2c875ee
Updated test code path for coverage
TTsangSC Apr 27, 2026
f0e1743
Fixed test pollution
TTsangSC Apr 28, 2026
ec6c6e8
Bugfix + SIGTERM handling
TTsangSC Apr 28, 2026
04e3b8d
Fix signal handling
TTsangSC Apr 29, 2026
f88577d
Fix for profiler cleanup
TTsangSC Apr 29, 2026
bf58640
Fix test failing corner case
TTsangSC Apr 29, 2026
e05d570
Streamlined tests
TTsangSC May 1, 2026
09fb005
Update `line_profiler.line_profiler.LineStats`
TTsangSC May 4, 2026
c1a2b0e
Various cleanup
TTsangSC May 4, 2026
b0df028
Curb stray warnings for profiling outfiles
TTsangSC May 4, 2026
e9255b7
WIP: migrate .pth-related code
TTsangSC May 4, 2026
8d862bf
Finish .pth code migration
TTsangSC May 4, 2026
b037c11
Fixes for cache management
TTsangSC May 4, 2026
e1c4085
Refactor `multiprocessing_patches`
TTsangSC May 4, 2026
0263b0e
WIP: refactor flaky tests
TTsangSC May 5, 2026
0364071
Fixup signal handling and child bootstrapping
TTsangSC May 6, 2026
e69894a
Fix stats file detection in `test_apply_mp_patches_*`
TTsangSC May 6, 2026
7943588
Moved code for formatting calls
TTsangSC May 6, 2026
ea01812
Refactored call formatting
TTsangSC May 6, 2026
c1b35e0
Extended `@pytest.mark.retry`
TTsangSC May 6, 2026
5a25d66
Reworked `multiprocessing_patches`
TTsangSC May 7, 2026
cd87aea
Fix: `getattr_static`
TTsangSC May 7, 2026
7ad0a70
WIP: test update
TTsangSC May 7, 2026
0e98933
Reworked `multiprocessing_patches`... again
TTsangSC May 8, 2026
51ee622
Retry tests for consistency instead of leniency
TTsangSC May 11, 2026
0cf7989
Better debugging output
TTsangSC May 12, 2026
39e91c1
Reworked `multiprocessing.pool` patch
TTsangSC May 12, 2026
d1db7ba
Fix signal-handling edge cases
TTsangSC May 13, 2026
1edc9d7
Partial rollback of 4a22dba
TTsangSC May 13, 2026
e1aa599
Updated tests
TTsangSC May 13, 2026
7b32f9a
Fix `tests/test_retry_tests.py`
TTsangSC May 13, 2026
1994419
More robust PID management
TTsangSC May 15, 2026
815de73
Updated tests
TTsangSC May 15, 2026
22cf3fe
Timeout for `test_apply_mp_patches_*()`
TTsangSC May 16, 2026
f14001e
PID-tracking fix
TTsangSC May 16, 2026
98f8b31
Minor test fixes
TTsangSC May 18, 2026
3dfe818
Unreg. `atexit` hook in `multiprocessing` procs
TTsangSC May 18, 2026
de5583d
More defensive error handling
TTsangSC May 18, 2026
fdf8fdd
Added timeouts to CI job stages
TTsangSC May 21, 2026
0663a58
Test-timeout fixes
TTsangSC May 22, 2026
e8b127c
Recover more output on subprocess failure
TTsangSC May 25, 2026
5c1cf82
WIP: try harder to debug the flaky tests
TTsangSC May 26, 2026
45b995a
Minor global-state fixes
TTsangSC May 29, 2026
5e985fe
Fix unclean cache state
TTsangSC Jun 8, 2026
ce54d65
Updated warning handling in tests
TTsangSC Jun 8, 2026
2e05bbf
Better handling of error cases
TTsangSC Jun 9, 2026
6a8ffb8
Fix `sys.argv` pollution in `kernprof`
TTsangSC Jun 9, 2026
e41fbef
Small fix: `~._child_process_profiling` debug logs
TTsangSC Jun 9, 2026
dd1462a
Tweaked warning reporting in `test_child_procs.py`
TTsangSC Jun 10, 2026
f7a48ed
Misc. fixes for the session cache
TTsangSC Jun 12, 2026
0198a48
Fix conditional skip in `test_child_procs.py`
TTsangSC Jun 12, 2026
2507acc
Various fixes
TTsangSC Jun 13, 2026
36164b8
Streamlined `multiprocessing_patches`
TTsangSC Jun 13, 2026
b3f05e3
WIP: prioritization of `multiprocessing_patches`
TTsangSC Jun 14, 2026
1dd05ba
WIP: make `multiprocessing_patches` a subpackage
TTsangSC Jun 15, 2026
d1b69bc
Migrate `multiprocessing_patches/__init__.py`
TTsangSC Jun 15, 2026
bb5fcfe
Refactored child-process setup
TTsangSC Jun 16, 2026
52b43e5
Minor fixes
TTsangSC Jun 25, 2026
e7e605f
Removed signal handling
TTsangSC Jun 25, 2026
7b5952f
Always track pool-worker PIDs
TTsangSC Jun 26, 2026
96d1f52
No longer using `@pytest.mark.retry`
TTsangSC Jun 26, 2026
7f35b11
Updated `ty` config
TTsangSC Jun 26, 2026
5ca8d3e
Debug info on assertions
TTsangSC Jun 27, 2026
499d8e8
Fix for worker-process PID tracking
TTsangSC Jun 27, 2026
3d27ede
Stop intefering with worker-process termination
TTsangSC Jun 27, 2026
72f4fe9
WIP: break down the test_child_procs tests
TTsangSC Jun 27, 2026
1ba227c
Break `test_child_procs` down
TTsangSC Jun 29, 2026
eb59171
Fix `multiprocessing` profiling patch conflict
TTsangSC Jun 29, 2026
de85fad
WIP: separate tests for the `process` patch
TTsangSC Jun 29, 2026
92263ab
WIP: test script for `Process`-based parallelism
TTsangSC Jun 29, 2026
85f17c8
New tests for `Process`-based parallelism
TTsangSC Jun 29, 2026
ad70668
Minor fixes for `test_child_procs` tests
TTsangSC Jun 30, 2026
7737fbb
No longer isolating a test in a timed thread
TTsangSC Jul 2, 2026
dcc8905
Removed polling stuff entirely
TTsangSC Jul 2, 2026
c818cc3
Fix `@add_timeout` doctest which leaked a thread
TTsangSC Jul 2, 2026
e2dd751
Fix doctest for `Worker` wrapper around MP procs
TTsangSC Jul 6, 2026
14e9ee7
Lint and misc. fixes
TTsangSC Jul 6, 2026
d8dfcd9
Log failing cleanups as warnings
TTsangSC Jul 6, 2026
c3b72a9
Fix `LineStats.from_files()` warning messages
TTsangSC Jul 6, 2026
f6894f4
.pth-file-related fixes
TTsangSC Jul 8, 2026
841976a
Fix double-counting of pre-fork stats in forked children (PR431-1)
Erotemic Jul 5, 2026
2176893
Make the pool result protocol tolerate unpatched workers (PR431-2)
Erotemic Jul 5, 2026
d771ada
Refactor the pool-working protocol
TTsangSC Jul 10, 2026
c28cc15
Ditch the entry-point system for multiproc patches
TTsangSC Jul 10, 2026
c902c29
Assertion + end-of-process management fixes
TTsangSC Jul 10, 2026
ac28767
Reduce per-multiproc-task IO overhead
TTsangSC Jul 10, 2026
e7152a6
`kernprof.py::_manage_profiler` cleanup
TTsangSC Jul 11, 2026
4c4d2c5
WIP: various `test_child_procs` fixes
TTsangSC Jul 11, 2026
1476d5a
More test fixes + `kernprof` fixes in forking code
TTsangSC Jul 11, 2026
ee21829
Test more edge cases
TTsangSC Jul 11, 2026
60c9f72
WIP: debug `test_unwritable_purelib_path()`
TTsangSC Jul 13, 2026
a723476
Fix (?) process-table retrieval on Windows
TTsangSC Jul 13, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ jobs:
- name: Test full loose sdist
env:
COVERAGE_CORE: ctrace
timeout-minutes: 10
run: |-
pwd
ls -al
Expand Down Expand Up @@ -154,6 +155,7 @@ jobs:
CIBW_ARCHS_LINUX: ${{ matrix.arch }}
PYTHONUTF8: '1'
VSCMD_ARG_TGT_ARCH: ''
timeout-minutes: 60
- name: Show built files
shell: bash
run: ls -la wheelhouse
Expand Down Expand Up @@ -426,6 +428,7 @@ jobs:
env:
CI_PYTHON_VERSION: py${{ matrix.python-version }}
COVERAGE_CORE: ctrace
timeout-minutes: 10
run: |-
echo "Creating test sandbox directory"
export WORKSPACE_DNAME="testdir_${CI_PYTHON_VERSION}_${GITHUB_RUN_ID}_${RUNNER_OS}"
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ Changes
is available (#427)
* FIX: Bytecodes of profiled functions now always labeled to prevent
confusion with non-profiled "twins" (#425)
* FEAT: Experimental support for profiling child processes with
``kernprof --prof-child-procs`` (#431)


5.0.2
Expand Down
79 changes: 79 additions & 0 deletions _line_profiler_hooks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
"""
Additional hooks installed by :py:mod:`line_profiler`.

Notes:
- This file and its content should be considered an implementation
detail of :py:mod:`line_profiler`; currently we just use this to
set up shop in a child Python process, and extend profiling to
therein.

- This current implementation writes temporary .pth files to the
site-packages directory, which are executed for all Python
processes referring to the same ``lib/``. However, only processes
originating from a parent which set the requisite environment
variables will execute to the profiling code.

- Said .pth file always import this module; hence, this file is kept
intentionally lean and separate from the main
:py:mod:`line_profiler` package to reduce overhead; e.g.
imports in this file are deferred to being as late as possible.

- Inspired by similar code in :py:mod:`coverage.control` and
:py:mod:`pytest_autoprofile.startup_hook`.
"""
import os


__all__ = ('load_pth_hook',)

INHERITED_PID_ENV_VARNAME = (
'LINE_PROFILER_PROFILE_CHILD_PROCESSES_CACHE_PID'
)


def load_pth_hook(ppid: int) -> None:
"""
Function imported and called by the written .pth file; to reduce
overhead, we immediately return if ``ppid`` doesn't match
:env:`LINE_PROFILER_PROFILE_CHILD_PROCESSES_CACHE_PID`.
"""
try:
env_ppid = int(os.environ[INHERITED_PID_ENV_VARNAME])
except (KeyError, ValueError):
return
if env_ppid != ppid:
return
# Note: .pth files may be double-loaded in a virtual environment
# (see https://stackoverflow.com/questions/58807569), so work around
# that;
# also see similar check in `coverage.control.process_startup()`
if getattr(load_pth_hook, 'called', False):
return

# If we're here, we're most probably in a descendent process of a
# profiled Python process, so we can be more liberal with the
# imports without worrying about overhead
import warnings
from line_profiler._diagnostics import log
from line_profiler._child_process_profiling.cache import LineProfilingCache

try:
cache = LineProfilingCache.load()
cache._setup_in_child_process(True, 'pth')
except Exception as e: # nocover
# A child which has the profiling environment but cannot set
# up profiling is an abnormal condition the user asked to know
# about, so always warn (but still let the process run
# unprofiled)
msg = (
f'line_profiler child-process profiling setup failed in '
f'PID {os.getpid()} ({type(e).__name__}: {e}); '
f'this process runs unprofiled'
)
# Write log before issuing the warning, in case the warning is
# promoted to an exception
log.warning(msg)
warnings.warn(msg)
load_pth_hook.called = True # type: ignore
else:
cache.patch(load_pth_hook, 'called', True)
Loading
Loading