Skip to content

Commit

Permalink
Use abspath to rc file so that chdir doesn't bork us. #890
Browse files Browse the repository at this point in the history
  • Loading branch information
nedbat committed Dec 23, 2019
1 parent 6ba844a commit 85f5f17
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 4 deletions.
8 changes: 7 additions & 1 deletion CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,16 @@ want to know what's different in 5.0 since 4.5.x, see :ref:`whatsnew5x`.
.. Version 7.8.1 --- 2021-07-27
.. ----------------------------
Unreleased
----------

Nothing yet.
- Programs that used multiprocessing and changed directories would fail under
coverage. This is now fixed (`issue 890`_). A side effect is that debug
information about the config files read now shows absolute paths to the
files.

.. _issue 890: https://github.com/nedbat/coveragepy/issues/890


.. _changes_501:
Expand Down
5 changes: 3 additions & 2 deletions coverage/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import collections
import copy
import os
import os.path
import re

from coverage import env
Expand Down Expand Up @@ -275,7 +276,7 @@ def from_file(self, filename, our_file):
if not files_read:
return False

self.config_files_read.extend(files_read)
self.config_files_read.extend(map(os.path.abspath, files_read))

any_set = False
try:
Expand Down Expand Up @@ -323,7 +324,7 @@ def from_file(self, filename, our_file):
used = any_set

if used:
self.config_file = filename
self.config_file = os.path.abspath(filename)
with open(filename) as f:
self._config_contents = f.read()

Expand Down
3 changes: 2 additions & 1 deletion coverage/multiproc.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import multiprocessing
import multiprocessing.process
import os
import os.path
import sys
import traceback

Expand Down Expand Up @@ -85,7 +86,7 @@ def patch_multiprocessing(rcfile):

# Set the value in ProcessWithCoverage that will be pickled into the child
# process.
os.environ["COVERAGE_RCFILE"] = rcfile
os.environ["COVERAGE_RCFILE"] = os.path.abspath(rcfile)

# When spawning processes rather than forking them, we have no state in the
# new process. We sneak in there with a Stowaway: we stuff one of our own
Expand Down
19 changes: 19 additions & 0 deletions tests/test_concurrency.py
Original file line number Diff line number Diff line change
Expand Up @@ -493,6 +493,25 @@ def test_multiprocessing_bootstrap_error_handling(self):
self.assertIn("Exception during multiprocessing bootstrap init", out)
self.assertIn("Exception: Crashing because called by _bootstrap", out)

def test_bug890(self):
# chdir in multiprocessing shouldn't keep us from finding the
# .coveragerc file.
self.make_file("multi.py", """\
import multiprocessing, os, os.path
if __name__ == "__main__":
if not os.path.exists("./tmp"): os.mkdir("./tmp")
os.chdir("./tmp")
with multiprocessing.Manager():
pass
print("ok")
""")
self.make_file(".coveragerc", """\
[run]
concurrency = multiprocessing
""")
out = self.run_command("coverage run multi.py")
self.assertEqual(out.splitlines()[-1], "ok")


def test_coverage_stop_in_threads():
has_started_coverage = []
Expand Down

0 comments on commit 85f5f17

Please sign in to comment.