Describe the bug
When writing a .pth file, coverage uses slightly invalid heuristics which will usually be correct, but become invalid in the face of things like PYTHONPATH entries or working directories (in scenarios where coverage is run with -m or in another configuration which adds the current directory to the path) with .pth files in them.
To Reproduce
How can we reproduce the problem? Please be specific. Don't link to a failing CI job. Answer the questions below:
- What version of Python are you using?: 3.13.5
- What version of coverage.py shows the problem? The output of
coverage debug sys is helpful.: 7.10.0
- What versions of what packages do you have installed? The output of
pip freeze is helpful.: N/A
- What code shows the problem? Give us a specific commit of a specific repo that we can check out. If you've already worked around the problem, please provide a commit before that fix.: N/A
- What commands should we run to reproduce the problem? Be specific. Include everything, even
git clone, pip install, and so on. Explain like we're five!
$ touch sample.pth
$ python -c 'from coverage.files import create_pth_file; create_pth_file()'
$ ls *.pth
sample.pth subcover.pth
Expected behavior
The .pth file will not be processed in this location.
Additional context
Python has specific rules for which directories will and will not honor .pth files, that are subtly distinct from the rules around which directories can import Python code. Specifically, Python will evaluate .pth files in site directories, which are enumerated by some squirrelly environment-dependent logic in site.main.
This list of processed site directories is (as far as I know) never even actually stored anywhere; but, even if it were, subtle subprocess configuration changes (for example, a parent process with user-site enabled spawning a subprocess with user-site disabled) could potentially make this configuration wrong.
There are other potential consequences in unusual configurations, such as coverage reporting in a --system-site-packages virtualenv attempting to write its .pth file into the system location. This would work for the individual test run in question, but could cause confusion if the system environment doesn't have coverage installed. The system packages location (not site-packages!) could also get picked up if something else were to write a .pth file there.
I believe the most correct API to avoid these issues is to take the first writable value in site.getsitepackages(). Most of the time this would be the same value as the existing fallback sysconfig.get_path("purelib") query; I think that using this value blindly would actually be better than attempting this heuristic, since it would be easier for users with weird setups to investigate where & when it failed.
Describe the bug
When writing a
.pthfile, coverage uses slightly invalid heuristics which will usually be correct, but become invalid in the face of things likePYTHONPATHentries or working directories (in scenarios where coverage is run with-mor in another configuration which adds the current directory to the path) with.pthfiles in them.To Reproduce
How can we reproduce the problem? Please be specific. Don't link to a failing CI job. Answer the questions below:
coverage debug sysis helpful.: 7.10.0pip freezeis helpful.: N/Agit clone,pip install, and so on. Explain like we're five!Expected behavior
The
.pthfile will not be processed in this location.Additional context
Python has specific rules for which directories will and will not honor
.pthfiles, that are subtly distinct from the rules around which directories can import Python code. Specifically, Python will evaluate.pthfiles in site directories, which are enumerated by some squirrelly environment-dependent logic insite.main.This list of processed site directories is (as far as I know) never even actually stored anywhere; but, even if it were, subtle subprocess configuration changes (for example, a parent process with user-site enabled spawning a subprocess with user-site disabled) could potentially make this configuration wrong.
There are other potential consequences in unusual configurations, such as coverage reporting in a
--system-site-packagesvirtualenv attempting to write its.pthfile into the system location. This would work for the individual test run in question, but could cause confusion if the system environment doesn't have coverage installed. The system packages location (not site-packages!) could also get picked up if something else were to write a.pthfile there.I believe the most correct API to avoid these issues is to take the first writable value in
site.getsitepackages(). Most of the time this would be the same value as the existing fallbacksysconfig.get_path("purelib")query; I think that using this value blindly would actually be better than attempting this heuristic, since it would be easier for users with weird setups to investigate where & when it failed.