summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--coverage/config.py3
-rw-r--r--coverage/tomlconfig.py47
-rw-r--r--tests/test_config.py34
3 files changed, 62 insertions, 22 deletions
diff --git a/coverage/config.py b/coverage/config.py
index ca3de3bd..62f281ad 100644
--- a/coverage/config.py
+++ b/coverage/config.py
@@ -260,9 +260,6 @@ class CoverageConfig(object):
"""
_, ext = os.path.splitext(filename)
if ext == '.toml':
- from coverage.optional import toml
- if toml is None:
- return False
cp = TomlConfigParser(our_file)
else:
cp = HandyConfigParser(our_file)
diff --git a/coverage/tomlconfig.py b/coverage/tomlconfig.py
index 33647309..f5978820 100644
--- a/coverage/tomlconfig.py
+++ b/coverage/tomlconfig.py
@@ -25,34 +25,43 @@ class TomlConfigParser:
# pylint: disable=missing-function-docstring
def __init__(self, our_file):
+ self.our_file = our_file
self.getters = [lambda obj: obj['tool']['coverage']]
- if our_file:
+ if self.our_file:
self.getters.append(lambda obj: obj)
self._data = []
def read(self, filenames):
+ # RawConfigParser takes a filename or list of filenames, but we only
+ # ever call this with a single filename.
+ assert isinstance(filenames, path_types)
+ filename = filenames
+ if env.PYVERSION >= (3, 6):
+ filename = os.fspath(filename)
+
from coverage.optional import toml
if toml is None:
- raise RuntimeError('toml module is not installed.')
-
- if isinstance(filenames, path_types):
- filenames = [filenames]
- read_ok = []
- for filename in filenames:
- try:
- with io.open(filename, encoding='utf-8') as fp:
- toml_data = fp.read()
- toml_data = substitute_variables(toml_data, os.environ)
+ if self.our_file:
+ raise CoverageException("Can't read {!r} without TOML support".format(filename))
+
+ try:
+ with io.open(filename, encoding='utf-8') as fp:
+ toml_data = fp.read()
+ toml_data = substitute_variables(toml_data, os.environ)
+ if toml:
+ try:
self._data.append(toml.loads(toml_data))
- except IOError:
- continue
- except toml.TomlDecodeError as err:
- raise TomlDecodeError(*err.args)
- if env.PYVERSION >= (3, 6):
- filename = os.fspath(filename)
- read_ok.append(filename)
- return read_ok
+ except toml.TomlDecodeError as err:
+ raise TomlDecodeError(*err.args)
+ elif re.search(r"^\[tool\.coverage\.", toml_data, flags=re.MULTILINE):
+ # Looks like they meant to read TOML, but we can't.
+ raise CoverageException("Can't read {!r} without TOML support".format(filename))
+ else:
+ return []
+ except IOError:
+ return []
+ return [filename]
def has_option(self, section, option):
for data in self._data:
diff --git a/tests/test_config.py b/tests/test_config.py
index 3bd2fd2b..74ff5f00 100644
--- a/tests/test_config.py
+++ b/tests/test_config.py
@@ -8,6 +8,7 @@ import mock
import coverage
from coverage.misc import CoverageException
+import coverage.optional
from tests.coveragetest import CoverageTest, UsingModulesMixin
@@ -651,3 +652,36 @@ class ConfigFileTest(UsingModulesMixin, CoverageTest):
self.assertFalse(cov.config.timid)
self.assertFalse(cov.config.branch)
self.assertEqual(cov.config.data_file, ".coverage")
+
+ def test_no_toml_installed_explicit_toml(self):
+ # Can't specify a toml config file if toml isn't installed.
+ with coverage.optional.without('toml'):
+ msg = "Can't read 'cov.toml' without TOML support"
+ with self.assertRaisesRegex(CoverageException, msg):
+ coverage.Coverage(config_file="cov.toml")
+
+ def test_no_toml_installed_pyproject_toml(self):
+ # Can't have coverage config in pyproject.toml without toml installed.
+ self.make_file("pyproject.toml", """\
+ # A toml file!
+ [tool.coverage.run]
+ xyzzy = 17
+ """)
+ with coverage.optional.without('toml'):
+ msg = "Can't read 'pyproject.toml' without TOML support"
+ with self.assertRaisesRegex(CoverageException, msg):
+ coverage.Coverage()
+
+ def test_no_toml_installed_pyproject_no_coverage(self):
+ # It's ok to have non-coverage pyproject.toml without toml installed.
+ self.make_file("pyproject.toml", """\
+ # A toml file!
+ [tool.something]
+ xyzzy = 17
+ """)
+ with coverage.optional.without('toml'):
+ cov = coverage.Coverage()
+ # We get default settings:
+ self.assertFalse(cov.config.timid)
+ self.assertFalse(cov.config.branch)
+ self.assertEqual(cov.config.data_file, ".coverage")