coveragepy
coveragepy copied to clipboard
pytest and multiprocessing: CoverageException: Can't combine line data with arc dat
Originally reported by Samuel Colvin (Bitbucket: samuelcolvin, GitHub: samuelcolvin)
I'm getting CoverageException: Can't combine line data with arc dat
when using coverage with the pytest-cov pytest extension. I think this is similar to #399, but that issue is closed.
Example failure on travis: https://travis-ci.org/samuelcolvin/arq/builds/148541711
The test causing problems is using click's CliRunner
, code here. The CLI command that's testing starts another process (using multiprocessing.Process
) to run the worker which is what's causing the problem, if you prevent the worker process being started the exception doesn't occur.
I tried changing the concurrency
mode but it made no difference.
To reproduce: clone, pip install -e . && pip install -r tests/requirements.txt
, py.test --cov=arq
.
relevant bits of pip freeze
:
click==6.6
coverage==4.2
pytest==2.9.2
pytest-cov==2.3.0
Let me know if you need anymore information.
- Bitbucket: https://bitbucket.org/ned/coveragepy/issue/512
Original comment by Miguel Sánchez de León Peque (Bitbucket: Peque, GitHub: Peque)
@ionelmc Thanks. That helped and it currently finishes the report. However, the source
and omit
parameters are ignored.
Have not figured out why. Here is the repo/branch: https://github.com/Peque/osbrain/tree/coverage
Original comment by Ionel Cristian Mărieș (Bitbucket: ionelmc, GitHub: ionelmc)
Maybe you need to tell pytest-cov what is the coverage config file (eg --cov-config=setup.cfg
).
Original comment by Miguel Sánchez de León Peque (Bitbucket: Peque, GitHub: Peque)
I think I may have hit this issue too.
Builds used to pass without any problems, but when moving the configuration from .coveragerc
to setup.cfg
(https://github.com/Peque/osbrain/commit/f9eb8c65c5f0e16618b6602786e74eaff9e46a4a), it fails (https://travis-ci.org/Peque/osbrain/builds/237146025?utm_source=github_status&utm_medium=notification).
Original comment by Loic Dachary (Bitbucket: dachary, GitHub: dachary)
The following patch retries with the coverage: prefix if a non default file was specified and nothing was read from it. There could be a cleaner way to do the same and I'm willing to work on it if you think it is worth implementing. To be fully backward compatible it should only retry with the coverage: prefix in the case where a file was provided and nothing was read from it because it serves no useful purpose. Unless there is a valid use case for --rcfile=/dev/null ?
#!diff
diff -r [24aff3d7bfd5 (bb)](https://bitbucket.org/ned/coveragepy/commits/24aff3d7bfd5) coverage/config.py
--- a/coverage/config.py Mon Dec 12 08:26:18 2016 +0100
+++ b/coverage/config.py Thu Dec 15 10:35:14 2016 +0100
@@ -151,6 +151,7 @@
# Metadata about the config.
self.attempted_config_files = []
self.config_files = []
+ self.any_set = False
# Defaults for [run]
self.branch = False
@@ -223,12 +224,11 @@
self.config_files.extend(files_read)
- any_set = False
try:
for option_spec in self.CONFIG_FILE_OPTIONS:
was_set = self._set_attr_from_config_option(cp, *option_spec)
if was_set:
- any_set = True
+ self.any_set = True
except ValueError as err:
raise CoverageException("Couldn't read config file %s: %s" % (filename, err))
@@ -253,18 +253,18 @@
if cp.has_section('paths'):
for option in cp.options('paths'):
self.paths[option] = cp.getlist('paths', option)
- any_set = True
+ self.any_set = True
# plugins can have options
for plugin in self.plugins:
if cp.has_section(plugin):
self.plugin_options[plugin] = cp.get_section(plugin)
- any_set = True
+ self.any_set = True
# Was this file used as a config file? If no prefix, then it was used.
# If a prefix, then it was only used if we found some settings in it.
if section_prefix:
- return any_set
+ return self.any_set
else:
return True
@@ -422,9 +422,12 @@
config_read = config.from_file(fname, section_prefix=prefix)
is_config_file = fname == config_file
- if not config_read and is_config_file and specified_file:
- raise CoverageException("Couldn't read '%s' as a config file" % fname)
-
+ if is_config_file and specified_file:
+ if not config_read:
+ raise CoverageException("Couldn't read '%s' as a config file" % fname)
+ if not config.any_set:
+ config_read = config.from_file(fname, section_prefix="coverage:")
+
if config_read:
break
Original comment by Ionel Cristian Mărieș (Bitbucket: ionelmc, GitHub: ionelmc)
I don't see how it's relevant. pytest-cov doesn't read the file, it will only pass the absolute path (if it exists).
The sections are named differently ("[run]" vs "[coverage:run]"). If you specify setup.cfg as the file, coverage.py will try to read the "[run]" section and won't find it. It only looks for "[coverage:run]" when it is reading setup.cfg because it couldn't find .coveragerc.
Of course, this behavior could change, but that's the way the code is now.
Original comment by Ionel Cristian Mărieș (Bitbucket: ionelmc, GitHub: ionelmc)
What do you mean, "discovered implicitly"?
@ionelmc it isn't enough to tell coverage.py to use setup.cfg. It won't be read properly unless it is discovered implicitly.
Original comment by Ionel Cristian Mărieș (Bitbucket: ionelmc, GitHub: ionelmc)
pytest-cov could have an improvement to use setup.cfg if .coveragerc don't exist (same as coverage, but with pytest-cov's correct handling of relatiev paths). Open a bug report if you want it.
Original comment by Samuel Colvin (Bitbucket: samuelcolvin, GitHub: samuelcolvin)
Ned, thanks so much for the help. I've switched to using .coveragerc
and that seems to have fixed it.
Perhaps a comment in the docs saying that using setup.cfg
is not always the same as using .coveragerc
would be useful?
I've come to some different conclusions that Ionel did, though he was very helpful in getting me going with debugging with his aspectlib.
The problem here is the Process spawned by test_repeat_worker_close. It doesn't find the same configuration file that the rest of the tests do. Specifying --cov-config=setup.cfg
doesn't help, because coverage.py only reads that file properly when it is read implicitly, not explicitly (that could be the subject of another bug report).
I think this is a combination of the direct use of Process, which perhaps coverage.py hasn't patched enough, and having settings in the implicitly-read setup.cfg file.
One simple solution is to move your coverage.py settings into a .coveragerc file. If you do that, things work.
Original comment by Ionel Cristian Mărieș (Bitbucket: ionelmc, GitHub: ionelmc)
I've taken a look at this as well, my opinion is that a combination of configuration, subprocess use and cwd changes cause the problem. That's why you get the data file saved without arcs (branch=False).
There are thee ways to deal with this:
- Specify
--cov-config=setup.cfg
(pytest-cov will absolutize it beforetmpworkdir
is used). Alternatively, you could use a.coveragerc
(pytest-cov absolutize that if it exists). - Fix the test to not use subprocesses. Afaik the test spawns a suprocess that sigterms the parent. This makes no sense to me - you can do that with no subprocess at all. Eg:
signal.kill(os.getpid(), signal.SIGTERM)
or even a thread. - Stop changing current working directory (
tmpworkdir
fixture).
There is no bug in either coverage or pytest-cov here.
Also, note that concurrency = multiprocessing
is completely un-necessary if you use pytest-cov (it completely manages coverage measurements in subprocesses for you).
Original comment by Samuel Colvin (Bitbucket: samuelcolvin, GitHub: samuelcolvin)
Sorry about that, on ubuntu redis runs as a service so is always there. I've dusted off my mac and tried to run the code however brew seems to be broken so I can't install python3.5.
As far as I know it should be as simple:
-
brew install redis
-
redis-server
, leave the terminal with redis running - in another terminal in the
arq
directorygit fetch && git checkout coverage-broken
(I've added a test on that branch which breaks coverage), see here. - run
py.test
all tests should pass - run
py.test --cov=arq
you should getCoverageException
as on travis.
@samuelcolvin I'm willing to try reproducing this, but I need explicit instructions, or I'll wander in the redis-wilderness for a while. What should I do on my Mac to get things to pass? Do you think the test failures are preventing the coverage failure?
Original comment by Samuel Colvin (Bitbucket: samuelcolvin, GitHub: samuelcolvin)
looks like you don't have redis installed.
I tried running your scenario, and did not get the error you describe. The full output is here: https://gist.github.com/nedbat/a482ea69fa509de5e0a7c3da8f378e4b
The test run ends with:
tests/test_worker.py ✓✓✓✓✓✓✓✓✓✓✓ 100% ██████████
---------- coverage: platform darwin, python 3.5.2-final-0 -----------
Name Stmts Miss Branch BrPart Cover
---------------------------------------------------
arq/__init__.py 4 0 0 0 100%
arq/cli.py 15 0 0 0 100%
arq/logs.py 18 1 2 1 90%
arq/main.py 85 1 22 1 98%
arq/testing.py 164 6 34 0 97%
arq/utils.py 53 2 12 1 95%
arq/version.py 2 0 0 0 100%
arq/worker.py 245 31 54 4 88%
---------------------------------------------------
TOTAL 586 41 124 7 93%
Results (4.23s):
29 passed
11 failed
- /usr/local/pythonz/pythons/CPython-3.5.2/lib/python3.5/asyncio/base_events.py:704: OSError: Multiple exceptions: [Errno 61] Connect call failed ('127.0.0.1', 6379), [Errno 61] Connect call failed ('::1', 6379), [Errno 61] Connect call failed ('fe80::1%lo0', 6379, 0, 1)
- /usr/local/pythonz/pythons/CPython-3.5.2/lib/python3.5/asyncio/base_events.py:704: OSError: Multiple exceptions: [Errno 61] Connect call failed ('127.0.0.1', 6379), [Errno 61] Connect call failed ('::1', 6379), [Errno 61] Connect call failed ('fe80::1%lo0', 6379, 0, 1)
- /Users/ned/foo/arq/tests/test_main.py:137: assert None
- /usr/local/pythonz/pythons/CPython-3.5.2/lib/python3.5/asyncio/base_events.py:704: OSError: Multiple exceptions: [Errno 61] Connect call failed ('127.0.0.1', 6379), [Errno 61] Connect call failed ('::1', 6379), [Errno 61] Connect call failed ('fe80::1%lo0', 6379, 0, 1)
- /usr/local/pythonz/pythons/CPython-3.5.2/lib/python3.5/asyncio/base_events.py:704: OSError: Multiple exceptions: [Errno 61] Connect call failed ('127.0.0.1', 6379), [Errno 61] Connect call failed ('::1', 6379), [Errno 61] Connect call failed ('fe80::1%lo0', 6379, 0, 1)
- /usr/local/pythonz/pythons/CPython-3.5.2/lib/python3.5/asyncio/base_events.py:704: OSError: Multiple exceptions: [Errno 61] Connect call failed ('127.0.0.1', 6379), [Errno 61] Connect call failed ('::1', 6379), [Errno 61] Connect call failed ('fe80::1%lo0', 6379, 0, 1)
- /usr/local/pythonz/pythons/CPython-3.5.2/lib/python3.5/asyncio/base_events.py:704: OSError: Multiple exceptions: [Errno 61] Connect call failed ('127.0.0.1', 6379), [Errno 61] Connect call failed ('::1', 6379), [Errno 61] Connect call failed ('fe80::1%lo0', 6379, 0, 1)
- /usr/local/pythonz/pythons/CPython-3.5.2/lib/python3.5/asyncio/base_events.py:704: OSError: Multiple exceptions: [Errno 61] Connect call failed ('127.0.0.1', 6379), [Errno 61] Connect call failed ('::1', 6379), [Errno 61] Connect call failed ('fe80::1%lo0', 6379, 0, 1)
- /usr/local/pythonz/pythons/CPython-3.5.2/lib/python3.5/asyncio/base_events.py:704: OSError: Multiple exceptions: [Errno 61] Connect call failed ('127.0.0.1', 6379), [Errno 61] Connect call failed ('::1', 6379), [Errno 61] Connect call failed ('fe80::1%lo0', 6379, 0, 1)
- /usr/local/pythonz/pythons/CPython-3.5.2/lib/python3.5/asyncio/base_events.py:704: OSError: Multiple exceptions: [Errno 61] Connect call failed ('127.0.0.1', 6379), [Errno 61] Connect call failed ('::1', 6379), [Errno 61] Connect call failed ('fe80::1%lo0', 6379, 0, 1)
- /usr/local/pythonz/pythons/CPython-3.5.2/lib/python3.5/asyncio/base_events.py:704: OSError: Multiple exceptions: [Errno 61] Connect call failed ('127.0.0.1', 6379), [Errno 61] Connect call failed ('::1', 6379), [Errno 61] Connect call failed ('fe80::1%lo0', 6379, 0, 1)
I'm not sure what caused my test failures, but I wouldn't think they are significant in this case.
Original comment by Samuel Colvin (Bitbucket: samuelcolvin, GitHub: samuelcolvin)
Same error with hg clone ... setup.py install
I'm afraid:
...
INTERNALERROR> File "/home/samuel/code/arq/env/lib/python3.5/site-packages/pytest_cov/engine.py", line 150, in finish
INTERNALERROR> self.cov.combine()
INTERNALERROR> File "/home/samuel/code/arq/env/lib/python3.5/site-packages/coverage-4.2.1a0-py3.5-linux-x86_64.egg/coverage/control.py", line 822, in combine
INTERNALERROR> self.data_files.combine_parallel_data(self.data, aliases=aliases, data_paths=data_paths)
INTERNALERROR> File "/home/samuel/code/arq/env/lib/python3.5/site-packages/coverage-4.2.1a0-py3.5-linux-x86_64.egg/coverage/data.py", line 716, in combine_parallel_data
INTERNALERROR> data.update(new_data, aliases=aliases)
INTERNALERROR> File "/home/samuel/code/arq/env/lib/python3.5/site-packages/coverage-4.2.1a0-py3.5-linux-x86_64.egg/coverage/data.py", line 481, in update
INTERNALERROR> raise CoverageException("Can't combine line data with arc data")
INTERNALERROR> coverage.misc.CoverageException: Can't combine line data with arc data
@samuelcolvin Sorry, I haven't started digging into this. It does sounds a lot like the fix I put in 4.2, so I will have to look at it soon. Have you tried it with the tip of coverage.py?
Original comment by Samuel Colvin (Bitbucket: samuelcolvin, GitHub: samuelcolvin)
Any update on this? I'm currently having to choose between coverage and running some tests.
One simple solution is to move your coverage.py settings into a .coveragerc file. If you do that, things work.
My project uses a .coveragerc
file and coverage reporting still fails with this error what seems like 1 in 3 runs.
@joshfriend can you give us specific instructions to reproduce what you are seeing, even if it's cloning your full project?
Feel free to re-open if you get more information.
Thanks for the reminder, sorry I was not able to give a full project example (it's proprietary). I may still be able to extract a shareable example from it though someday.
The only insight I have is that we use testing.postgresql
to create temporary postgres database instances for integration testing. This may introduce subprocesses to the tests, but I didn't think of that initially because the code being tested doesn't use subprocesses. In CI we attach a postgres docker container instead of using the testing.postgresql
package, which is probably why tests never fail with this coverage exception in CI.
@joshfriend Thanks for still trying. One way to get more information is to run with coverage debugging. You can add this to your configuration file:
[run]
debug = process, pid, dataio, dataop
The debug output will go to stderr, but you can redirect it to a file with the COVERAGE_DEBUG_FILE environment variable (odd that it can't be set from the configuration file...).
You will get a lot of information. Let's see what it says.
I don't see anything weird in this debug log, but this is from a test session that ended with the Can't combine arc data with line data
failure:
41553.9654: cwd is now '/Users/jfriend/proj-dir'
41553.9654: New process: executable: '/Users/jfriend/proj-dir/.venv/bin/python'
41553.9654: New process: cmd: ['/Users/jfriend/proj-dir/.venv/bin/pytest', 'tests', '--random-order', 'tests', '-W', 'ignore::cryptography.utils.CryptographyDeprecationWarning', '-W', 'ignore::DeprecationWarning', '--random-order-seed=278164', '--cov=cirrus', '--cov-config', '.coveragerc', '--cov-report', 'html', '--cov-report', 'xml', '--junitxml=junit_report.xml']
41553.9654: New process: pid: 41553, parent pid: 41523
41553.9654: Erasing data file '/Users/jfriend/proj-dir/.coverage'
41553.9654: Setting context: None
41553.9654: Adding arcs: 73 files, 4760 arcs total
41553.9654: Erasing data file '/Users/jfriend/proj-dir/.coverage.MacBook-Pro.skynet.41553.515875'
41553.9654: Opening data file '/Users/jfriend/proj-dir/.coverage.MacBook-Pro.skynet.41553.515875'
41553.9654: Initing data file '/Users/jfriend/proj-dir/.coverage.MacBook-Pro.skynet.41553.515875'
41553.9654: Adding file tracers: 0 files
41553.9654: Touching ['...snip...']
41553.9654: Opening data file '/Users/jfriend/proj-dir/.coverage'
41553.9654: Combining data file '/Users/jfriend/proj-dir/.coverage.MacBook-Pro.skynet.41553.515875'
41553.9654: Opening data file '/Users/jfriend/proj-dir/.coverage.MacBook-Pro.skynet.41553.515875'
41553.9654: Updating with data from '/Users/jfriend/proj-dir/.coverage.MacBook-Pro.skynet.41553.515875'
41553.9654: atexit: pid: 41553, instance: <coverage.control.Coverage object at 0x109f50460>
For full context:
- Coverage 6.3 (also tried 6.3.1)
- Python 3.8.5
- macOS 12.1
- I have an M1 mac, but the python binary is built with x86_64 architecture, and I've had this error plenty of times on my intel mac as well.
- I've tried a native arm64 python3.10.2 as well, still got the error
.coveragerc
file:
[run]
branch = true
relative_files = true
debug = process, pid, dataio, dataop
omit =
*/env/*
*/test/*
log_lint_plugin.py
[report]
fail_under = 100
exclude_lines =
def __repr__
def __str__
def __unicode__
pragma: no cover
Thanks. Does this include the "dataop" setting, and is it the full log (other than "...snip...")? I've added another debug message to coverage master, if you could run it again with dataop.
Yes, dataop
was included, and thats a full output to the file I specified with COVERAGE_DEBUG_FILE
. What's inside snip
is just a list of all the python files in my project.
I updated to coverage @ cf712c6 and almost immediately had one failing test run. The log output looked identical to before, though so far I have only had one CoverageException
failure, so I'm not 100% confident in the logs below. I'll include them anyways and keep trying. Unfortunately, when I'm actively looking for things to fail, it seems to happen far less frequently 😆
27174.f71d: cwd is now '/Users/jfriend/proj-dir'
27174.f71d: New process: executable: '/Users/jfriend/proj-dir/.venv/bin/python'
27174.f71d: New process: cmd: ['/Users/jfriend/proj-dir/.venv/bin/pytest', 'tests', '--random-order', 'tests', '--cov=cirrus', '--cov-config', '.coveragerc', '--cov-report', 'html', '--cov-report', 'xml', '--junitxml=junit_report.xml']
27174.f71d: New process: pid: 27174, parent pid: 27006
27174.f71d: Erasing data file '/Users/jfriend/proj-dir/.coverage'
27174.f71d: Setting context: None
27174.f71d: Adding arcs: 72 files, 4698 arcs total
27174.f71d: Erasing data file '/Users/jfriend/proj-dir/.coverage.MacBook-Pro.skynet.27174.812723'
27174.f71d: Opening data file '/Users/jfriend/proj-dir/.coverage.MacBook-Pro.skynet.27174.812723'
27174.f71d: Initing data file '/Users/jfriend/proj-dir/.coverage.MacBook-Pro.skynet.27174.812723'
27174.f71d: Adding file tracers: 0 files
27174.f71d: Touching ['...snip...']
27174.f71d: Opening data file '/Users/jfriend/proj-dir/.coverage'
27174.f71d: Combining data file '/Users/jfriend/proj-dir/.coverage.MacBook-Pro.skynet.27174.812723'
27174.f71d: Opening data file '/Users/jfriend/proj-dir/.coverage.MacBook-Pro.skynet.27174.812723'
27174.f71d: Updating with data from '/Users/jfriend/proj-dir/.coverage.MacBook-Pro.skynet.27174.812723'
27174.f71d: atexit: pid: 27174, instance: <coverage.control.Coverage object at 0x10acda490>
Also, I'm not sure if this is expected, but when debug is printed to stderr instead of a file, an exception is thrown at the end:
Exception ignored in atexit callback: <bound method Coverage._atexit of <coverage.control.Coverage object at 0x105a06470>>
Traceback (most recent call last):
File "/Users/jfriend/proj-dir/.venv/lib/python3.10/site-packages/coverage/control.py", line 600, in _atexit
self._debug.write(f"{event}: pid: {os.getpid()}, instance: {self!r}")
File "/Users/jfriend/proj-dir/.venv/lib/python3.10/site-packages/coverage/debug.py", line 74, in write
self.output.write(msg+"\n")
File "/Users/jfriend/proj-dir/.venv/lib/python3.10/site-packages/coverage/debug.py", line 319, in write
self.outfile.write(filter_text(text, self.filters))
ValueError: I/O operation on closed file.
Just ran into this bug and worked around it with --cov-config=.coveragerc
. Symptomology is similar to @joshfriend above, but my project uses pyproject.toml
and expected coverage.py to find its configuration there in multiprocess Processes
.
Unfortunately, those subprocesses were not reading the toml file, and were generating data in arc instead of line (or vice-versa, I can't remember...), thus the error. I had to copy my config out of the pyproject.toml
file into .coveragerc
and use the --cov-config
option with pytest-cov to force reading of it in all subprocesses.
Prior to the patch, there was some weirdness with collectors on Windows.
Tests would always show this kind of noise:
tests/test_hough.py::test_form_pdf
self._collectors:
<Collector at 0x25409186df0: CTracer>
_find_and_load : <frozen importlib._bootstrap>:1007
_find_and_load_unlocked : <frozen importlib._bootstrap>:986
_load_unlocked : <frozen importlib._bootstrap>:680
exec_module : <frozen importlib._bootstrap_external>:850
_call_with_frames_removed : <frozen importlib._bootstrap>:228
<module> : C:\Python39\lib\site.py:589
main : C:\Python39\lib\site.py:576
addsitepackages : C:\Python39\lib\site.py:359
addsitedir : C:\Python39\lib\site.py:208
addpackage : C:\Python39\lib\site.py:169
<module> : <string>:1
<module> : <string>:4
init : C:\Users\Joan\AppData\Local\pypoetry\Cache\virtualenvs\hough-Va69xgWd-py3.9\lib\site-packages\pytest_cov\embed.py:52
start : C:\Users\Joan\AppData\Local\pypoetry\Cache\virtualenvs\hough-Va69xgWd-py3.9\lib\site-packages\coverage\control.py:575
_init_for_start : C:\Users\Joan\AppData\Local\pypoetry\Cache\virtualenvs\hough-Va69xgWd-py3.9\lib\site-packages\coverage\control.py:483
__init__ : C:\Users\Joan\AppData\Local\pypoetry\Cache\virtualenvs\hough-Va69xgWd-py3.9\lib\site-packages\coverage\collector.py:114
<Collector at 0x2540924e190: CTracer>
<module> : <string>:1
spawn_main : C:\Python39\lib\multiprocessing\spawn.py:116
_main : C:\Python39\lib\multiprocessing\spawn.py:129
_bootstrap : C:\Users\Joan\AppData\Local\pypoetry\Cache\virtualenvs\hough-Va69xgWd-py3.9\lib\site-packages\coverage\multiproc.py:32
start : C:\Users\Joan\AppData\Local\pypoetry\Cache\virtualenvs\hough-Va69xgWd-py3.9\lib\site-packages\coverage\control.py:575
_init_for_start : C:\Users\Joan\AppData\Local\pypoetry\Cache\virtualenvs\hough-Va69xgWd-py3.9\lib\site-packages\coverage\control.py:483
__init__ : C:\Users\Joan\AppData\Local\pypoetry\Cache\virtualenvs\hough-Va69xgWd-py3.9\lib\site-packages\coverage\collector.py:114
Analysis: 0%| | 0/1 [00:00<?, ?pg/s]self._collectors:
<Collector at 0x26014147df0: CTracer>
_find_and_load : <frozen importlib._bootstrap>:1007
_find_and_load_unlocked : <frozen importlib._bootstrap>:986
_load_unlocked : <frozen importlib._bootstrap>:680
exec_module : <frozen importlib._bootstrap_external>:850
_call_with_frames_removed : <frozen importlib._bootstrap>:228
<module> : C:\Python39\lib\site.py:589
main : C:\Python39\lib\site.py:576
addsitepackages : C:\Python39\lib\site.py:359
addsitedir : C:\Python39\lib\site.py:208
addpackage : C:\Python39\lib\site.py:169
<module> : <string>:1
<module> : <string>:4
init : C:\Users\Joan\AppData\Local\pypoetry\Cache\virtualenvs\hough-Va69xgWd-py3.9\lib\site-packages\pytest_cov\embed.py:52
start : C:\Users\Joan\AppData\Local\pypoetry\Cache\virtualenvs\hough-Va69xgWd-py3.9\lib\site-packages\coverage\control.py:575
_init_for_start : C:\Users\Joan\AppData\Local\pypoetry\Cache\virtualenvs\hough-Va69xgWd-py3.9\lib\site-packages\coverage\control.py:483
__init__ : C:\Users\Joan\AppData\Local\pypoetry\Cache\virtualenvs\hough-Va69xgWd-py3.9\lib\site-packages\coverage\collector.py:114
<Collector at 0x26077a9d0a0: CTracer>
<module> : <string>:1
spawn_main : C:\Python39\lib\multiprocessing\spawn.py:116
_main : C:\Python39\lib\multiprocessing\spawn.py:129
_bootstrap : C:\Users\Joan\AppData\Local\pypoetry\Cache\virtualenvs\hough-Va69xgWd-py3.9\lib\site-packages\coverage\multiproc.py:32
start : C:\Users\Joan\AppData\Local\pypoetry\Cache\virtualenvs\hough-Va69xgWd-py3.9\lib\site-packages\coverage\control.py:575
_init_for_start : C:\Users\Joan\AppData\Local\pypoetry\Cache\virtualenvs\hough-Va69xgWd-py3.9\lib\site-packages\coverage\control.py:483
__init__ : C:\Users\Joan\AppData\Local\pypoetry\Cache\virtualenvs\hough-Va69xgWd-py3.9\lib\site-packages\coverage\collector.py:114
self._collectors:
<Collector at 0x13aaad36df0: CTracer>
_find_and_load : <frozen importlib._bootstrap>:1007
_find_and_load_unlocked : <frozen importlib._bootstrap>:986
_load_unlocked : <frozen importlib._bootstrap>:680
exec_module : <frozen importlib._bootstrap_external>:850
_call_with_frames_removed : <frozen importlib._bootstrap>:228
<module> : C:\Python39\lib\site.py:589
main : C:\Python39\lib\site.py:576
addsitepackages : C:\Python39\lib\site.py:359
addsitedir : C:\Python39\lib\site.py:208
addpackage : C:\Python39\lib\site.py:169
<module> : <string>:1
<module> : <string>:4
init : C:\Users\Joan\AppData\Local\pypoetry\Cache\virtualenvs\hough-Va69xgWd-py3.9\lib\site-packages\pytest_cov\embed.py:52
start : C:\Users\Joan\AppData\Local\pypoetry\Cache\virtualenvs\hough-Va69xgWd-py3.9\lib\site-packages\coverage\control.py:575
_init_for_start : C:\Users\Joan\AppData\Local\pypoetry\Cache\virtualenvs\hough-Va69xgWd-py3.9\lib\site-packages\coverage\control.py:483
__init__ : C:\Users\Joan\AppData\Local\pypoetry\Cache\virtualenvs\hough-Va69xgWd-py3.9\lib\site-packages\coverage\collector.py:114
...
but only on Windows. Go figure.
Hope this detail helps track down the bug.
I get this error when I use branch = true
. @wohali @joshfriend can you confirm this with your repo?
I do use branch = true
, I posted my entire coveragerc in an earlier comment: https://github.com/nedbat/coveragepy/issues/512#issuecomment-1030099482
My question is: does turning off branch = true
fix the crash in your repo?
The issue is not able to be replicated reliably in my projects, so unfortunately I could not tell you
I get this error when I use
branch = true
. @wohali @joshfriend can you confirm this with your repo?
Yes, I use branch = true
. As I understand it this changes the format of the file, as I mentioned above, so the results cannot be combined with runs that don't include that. Something to do with multiprocess runs and the toml
file not being included caused the mixed format issue for me.
Just ran into this bug and worked around it with
--cov-config=.coveragerc
. Symptomology is similar to @joshfriend above, but my project usespyproject.toml
and expected coverage.py to find its configuration there in multiprocessProcesses
.
We also use pyproject.toml for our coverage configuration, and wanted to mention that I both encountered and was (seemingly) able to work around this issue by explicitly specifying --cov-config=pyproject.toml
as an argument when invoking pytest
. Explicitly passing the path of the config file seemed to be sufficient without also extracting it out into .coveragerc
format.
I have been using explicit --cov-config=path/to/.coveragerc
the entire time as my projects use a git submodule to share the coverage/linter/etc configs across projects.
I have not changed anything about my coverage setup other than to update coverage.py as new versions come out periodically, and I rarely see this issue anymore. It used to happen quite frequently, but recently is so infrequent that I can't try anything to debug it, but it is also not annoying anymore so I stopped trying.
We also use pyproject.toml for our coverage configuration, and wanted to mention that I both encountered and was (seemingly) able to work around this issue by explicitly specifying
--cov-config=pyproject.toml
as an argument when invokingpytest
. Explicitly passing the path of the config file seemed to be sufficient without also extracting it out into.coveragerc
format.
Tried this and it didn't work -- is your project multiprocess as well?
Tried this and it didn't work -- is your project multiprocess as well?
Hmm, our project itself doesn't use multiprocessing so I suppose the scenario is slightly different, but we do use pytest-xdist to distribute test cases across cores, which seems to be the cause of the error in our case.
Original comment by Ionel Cristian Mărieș (Bitbucket: ionelmc, GitHub: ionelmc)
I've taken a look at this as well, my opinion is that a combination of configuration, subprocess use and cwd changes cause the problem. That's why you get the data file saved without arcs (branch=False).
There are thee ways to deal with this:
* Specify `--cov-config=setup.cfg` (pytest-cov will absolutize it before `tmpworkdir` is used). Alternatively, you could use a `.coveragerc` (pytest-cov absolutize that if it exists). * Fix the test to not use subprocesses. Afaik the test spawns a suprocess that sigterms the parent. This makes no sense to me - you can do that with no subprocess at all. Eg: `signal.kill(os.getpid(), signal.SIGTERM)` or even a thread. * Stop changing current working directory (`tmpworkdir` fixture).
There is no bug in either coverage or pytest-cov here.
Also, note that
concurrency = multiprocessing
is completely un-necessary if you use pytest-cov (it completely manages coverage measurements in subprocesses for you).
Specifying --cov-config=setup.cfg as an addopted parameter in my setup.cfg solved the issue for me. Thanks!
Here are a few keywords on my setting so others might find this solution:
I use hydra config manager (which changes the current directory), and have a subprocess called thanks to sh.python(command)
. In addition, I use the tmp_dir fixture.