summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephen Finucane <stephen@that.guru>2016-11-18 14:47:35 +0000
committerStephen Finucane <stephen@that.guru>2016-11-18 14:47:35 +0000
commit6cf9adfcf0ed8d909242462f2289002856670487 (patch)
tree54fe6fd2b1111f9efd542348faeb7370b8df6c60
parentda70bedd80b0c8ffe317fbe32f05f5bb51495b48 (diff)
downloadpython-coveragepy-6cf9adfcf0ed8d909242462f2289002856670487.tar.gz
Read options from tox.iniissue-519
If coveragerc does not exist, setup.cfg does not exist or does not contain any coverage-related metadata, and no custom config file is provided, fall back to tox.ini. The syntax of tox.ini files is the same as that expected of setup.cfg files, namely: [coverage:{section}] Fixes: #519
-rw-r--r--CHANGES.rst5
-rw-r--r--coverage/control.py22
-rw-r--r--tests/test_config.py77
3 files changed, 78 insertions, 26 deletions
diff --git a/CHANGES.rst b/CHANGES.rst
index 1ff0dbb..e19085d 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -53,11 +53,16 @@ Unreleased
- Support PyPy3 5.2 alpha 1.
+- Options are now also read from a tox.ini file, if any. Like setup.py,
+ sections are prefixed with "coverage:", so the ``[run]`` options will be read
+ from ``[coverage:run]`` section of tox.ini. Finishes `issue 519`_.
+
.. _issue 412: https://bitbucket.org/ned/coveragepy/issues/412/coverage-combine-should-error-if-no
.. _issue 505: https://bitbucket.org/ned/coveragepy/issues/505/use-canonical-filename-for-debounce
.. _issue 510: https://bitbucket.org/ned/coveragepy/issues/510/erase-still-needed-in-42
.. _issue 511: https://bitbucket.org/ned/coveragepy/issues/511/version-42-coverage-combine-empties
.. _issue 516: https://bitbucket.org/ned/coveragepy/issues/516/running-coverage-combine-twice-deletes-all
+.. _issue 519: https://bitbucket.org/ned/coveragepy/issues/519/coverage-run-sections-in-toxini-or-as
.. _issue 525: https://bitbucket.org/ned/coveragepy/issues/525/coverage-combine-when-not-in-parallel-mode
.. _issue 529: https://bitbucket.org/ned/coveragepy/issues/529/encoding-marker-may-only-appear-on-the
.. _issue 530: https://bitbucket.org/ned/coveragepy/issues/530/deprecationwarning-you-passed-a-bytestring
diff --git a/coverage/control.py b/coverage/control.py
index d920337..e658ef1 100644
--- a/coverage/control.py
+++ b/coverage/control.py
@@ -134,10 +134,8 @@ class Coverage(object):
# 1: defaults:
self.config = CoverageConfig()
- # 2: from the rcfile, .coveragerc or setup.cfg file:
+ # 2: from the rcfile, .coveragerc, .tox or setup.cfg file:
if config_file:
- # pylint: disable=redefined-variable-type
- did_read_rc = False
# Some API users were specifying ".coveragerc" to mean the same as
# True, so make it so.
if config_file == ".coveragerc":
@@ -147,14 +145,22 @@ class Coverage(object):
config_file = ".coveragerc"
self.config_file = config_file
- did_read_rc = self.config.from_file(config_file)
+ for fname, prefix in [(config_file, ""),
+ ("setup.cfg", "coverage:"),
+ ("tox.ini", "coverage:")]:
+ config_read = self.config.from_file(fname,
+ section_prefix=prefix)
+ print('config read?')
+ print(config_read)
+ is_config_file = fname == config_file
- if not did_read_rc:
- if specified_file:
+ if not config_read and is_config_file and specified_file:
raise CoverageException(
- "Couldn't read '%s' as a config file" % config_file
+ "Couldn't read '%s' as a config file" % fname
)
- self.config.from_file("setup.cfg", section_prefix="coverage:")
+
+ if config_read:
+ break
# 3: from environment variables:
env_data_file = os.environ.get('COVERAGE_FILE')
diff --git a/tests/test_config.py b/tests/test_config.py
index 1c980b8..b45b89b 100644
--- a/tests/test_config.py
+++ b/tests/test_config.py
@@ -211,13 +211,15 @@ class ConfigTest(CoverageTest):
_ = coverage.Coverage()
def test_unknown_option_in_other_ini_file(self):
- self.make_file("setup.cfg", """\
- [coverage:run]
- huh = what?
- """)
- msg = r"Unrecognized option '\[coverage:run\] huh=' in config file setup.cfg"
- with self.assertRaisesRegex(CoverageException, msg):
- _ = coverage.Coverage()
+ for fname in ["setup.cfg", "tox.ini"]:
+ self.make_file(fname, """\
+ [coverage:run]
+ huh = what?
+ """)
+ msg = (r"Unrecognized option '\[coverage:run\] huh=' in config "
+ r"file %s" % fname)
+ with self.assertRaisesRegex(CoverageException, msg):
+ _ = coverage.Coverage()
class ConfigFileTest(CoverageTest):
@@ -304,6 +306,18 @@ class ConfigFileTest(CoverageTest):
examples/
"""
+ # Just some sample tox.ini text from the docs.
+ TOX_INI = """\
+ [tox]
+ envlist = py{26,27,33,34,35}-{c,py}tracer
+ skip_missing_interpreters = True
+
+ [testenv]
+ commands =
+ # Create tests/zipmods.zip, install the egg1 egg
+ python igor.py zip_mods install_egg
+ """
+
def assert_config_settings_are_correct(self, cov):
"""Check that `cov` has all the settings from LOTSA_SETTINGS."""
self.assertTrue(cov.config.timid)
@@ -349,29 +363,44 @@ class ConfigFileTest(CoverageTest):
cov = coverage.Coverage()
self.assert_config_settings_are_correct(cov)
- def test_config_file_settings_in_setupcfg(self):
+ def _test_config_file_settings_in_x(self, fname, contents):
# Configuration will be read from setup.cfg from sections prefixed with
# "coverage:"
nested = self.LOTSA_SETTINGS.format(section="coverage:")
- self.make_file("setup.cfg", nested + "\n" + self.SETUP_CFG)
+ fname = self.make_file(fname, nested + "\n" + contents)
cov = coverage.Coverage()
self.assert_config_settings_are_correct(cov)
- def test_config_file_settings_in_setupcfg_if_coveragerc_specified(self):
- # Configuration will be read from setup.cfg from sections prefixed with
- # "coverage:", even if the API said to read from a (non-existent)
- # .coveragerc file.
+ def test_config_file_settings_in_setupcfg(self):
+ self._test_config_file_settings_in_x("setup.cfg", self.SETUP_CFG)
+
+ def test_config_file_settings_in_toxini(self):
+ self._test_config_file_settings_in_x("tox.ini", self.TOX_INI)
+
+ def _test_config_file_settings_in_x_if_coveragerc_specified(self, fname,
+ contents):
+ # Configuration will be read from a non-".coveragerc" file from
+ # sections prefixed with "coverage:", even if the API said to read from
+ # a (non-existent) .coveragerc file.
nested = self.LOTSA_SETTINGS.format(section="coverage:")
- self.make_file("setup.cfg", nested + "\n" + self.SETUP_CFG)
+ self.make_file(fname, nested + "\n" + contents)
cov = coverage.Coverage(config_file=".coveragerc")
self.assert_config_settings_are_correct(cov)
- def test_setupcfg_only_if_not_coveragerc(self):
+ def test_config_file_settings_in_setupcfg_if_coveragerc_specified(self):
+ self._test_config_file_settings_in_x_if_coveragerc_specified(
+ "setup.cfg", self.SETUP_CFG)
+
+ def test_config_file_settings_in_tox_if_coveragerc_specified(self):
+ self._test_config_file_settings_in_x_if_coveragerc_specified(
+ "tox.ini", self.TOX_INI)
+
+ def _test_x_only_if_not_coveragerc(self, fname):
self.make_file(".coveragerc", """\
[run]
include = foo
""")
- self.make_file("setup.cfg", """\
+ self.make_file(fname, """\
[coverage:run]
omit = bar
branch = true
@@ -381,8 +410,14 @@ class ConfigFileTest(CoverageTest):
self.assertEqual(cov.config.omit, None)
self.assertEqual(cov.config.branch, False)
- def test_setupcfg_only_if_prefixed(self):
- self.make_file("setup.cfg", """\
+ def test_setupcfg_only_if_not_coveragerc(self):
+ self._test_x_only_if_not_coveragerc("setup.cfg")
+
+ def test_toxini_only_if_not_coveragerc(self):
+ self._test_x_only_if_not_coveragerc("tox.ini")
+
+ def _test_x_only_if_prefixed(self, fname):
+ self.make_file(fname, """\
[run]
omit = bar
branch = true
@@ -391,6 +426,12 @@ class ConfigFileTest(CoverageTest):
self.assertEqual(cov.config.omit, None)
self.assertEqual(cov.config.branch, False)
+ def test_setupcfg_only_if_prefixed(self):
+ self._test_x_only_if_prefixed("setup.cfg")
+
+ def test_toxini_only_if_prefixed(self):
+ self._test_x_only_if_prefixed("tox.ini")
+
def test_non_ascii(self):
self.make_file(".coveragerc", """\
[report]