Skip to content

Commit

Permalink
Give warnings about not being able to parse TOML files if toml isn't …
Browse files Browse the repository at this point in the history
…installed
  • Loading branch information
nedbat committed Nov 4, 2019
1 parent 9c04f2d commit df744f8
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 22 deletions.
3 changes: 0 additions & 3 deletions coverage/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -260,9 +260,6 @@ def from_file(self, filename, our_file):
"""
_, 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)
Expand Down
47 changes: 28 additions & 19 deletions coverage/tomlconfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
34 changes: 34 additions & 0 deletions tests/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import coverage
from coverage.misc import CoverageException
import coverage.optional

from tests.coveragetest import CoverageTest, UsingModulesMixin

Expand Down Expand Up @@ -651,3 +652,36 @@ def test_nocoveragerc_file_when_specified(self):
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")

0 comments on commit df744f8

Please sign in to comment.