Skip to content

Commit 80bfea7

Browse files
graingerthukkin
andauthored
Support TOML v1.0.0 syntax in pyproject.toml (#1186)
* Support TOML v1.0.0 syntax in `pyproject.toml` fixes #1180 Co-authored-by: Taneli Hukkinen <[email protected]> * fix toml meta test * use pytest.mark.parametrize to narrow test failure * Update tests/test_config.py Co-authored-by: Taneli Hukkinen <[email protected]> Co-authored-by: Taneli Hukkinen <[email protected]>
1 parent 8cb3215 commit 80bfea7

File tree

5 files changed

+37
-40
lines changed

5 files changed

+37
-40
lines changed

coverage/tomlconfig.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@
1212

1313
# TOML support is an install-time extra option.
1414
try:
15-
import toml
15+
import tomli
1616
except ImportError: # pragma: not covered
17-
toml = None
17+
tomli = None
1818

1919

2020
class TomlDecodeError(Exception):
@@ -44,12 +44,12 @@ def read(self, filenames):
4444
toml_text = fp.read()
4545
except OSError:
4646
return []
47-
if toml:
47+
if tomli is not None:
4848
toml_text = substitute_variables(toml_text, os.environ)
4949
try:
50-
self.data = toml.loads(toml_text)
51-
except toml.TomlDecodeError as err:
52-
raise TomlDecodeError(*err.args)
50+
self.data = tomli.loads(toml_text)
51+
except tomli.TOMLDecodeError as err:
52+
raise TomlDecodeError(str(err))
5353
return [filename]
5454
else:
5555
has_toml = re.search(r"^\[tool\.coverage\.", toml_text, flags=re.MULTILINE)

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ def better_set_verbosity(v):
107107

108108
extras_require={
109109
# Enable pyproject.toml support.
110-
'toml': ['toml'],
110+
'toml': ['tomli'],
111111
},
112112

113113
# We need to get HTML assets from our htmlfiles directory.

tests/helpers.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ def without_module(using_module, missing_module_name):
242242
Use this in a test function to make an optional module unavailable during
243243
the test::
244244
245-
with without_module(product.something, 'toml'):
245+
with without_module(product.something, 'tomli'):
246246
use_toml_somehow()
247247
248248
Arguments:

tests/test_config.py

Lines changed: 25 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -186,31 +186,28 @@ def test_parse_errors(self):
186186
with pytest.raises(CoverageException, match=msg):
187187
coverage.Coverage()
188188

189-
def test_toml_parse_errors(self):
189+
@pytest.mark.parametrize("bad_config,msg", [
190+
("[tool.coverage.run]\ntimid = \"maybe?\"\n", r"maybe[?]"),
191+
("[tool.coverage.run\n", None),
192+
('[tool.coverage.report]\nexclude_lines = ["foo("]\n',
193+
r"Invalid \[tool.coverage.report\].exclude_lines value u?'foo\(': "
194+
r"(unbalanced parenthesis|missing \))"),
195+
('[tool.coverage.report]\npartial_branches = ["foo["]\n',
196+
r"Invalid \[tool.coverage.report\].partial_branches value u?'foo\[': "
197+
r"(unexpected end of regular expression|unterminated character set)"),
198+
('[tool.coverage.report]\npartial_branches_always = ["foo***"]\n',
199+
r"Invalid \[tool.coverage.report\].partial_branches_always value "
200+
r"u?'foo\*\*\*': "
201+
r"multiple repeat"),
202+
('[tool.coverage.run]\nconcurrency="foo"', "not a list"),
203+
("[tool.coverage.report]\nprecision=1.23", "not an integer"),
204+
('[tool.coverage.report]\nfail_under="s"', "not a float"),
205+
])
206+
def test_toml_parse_errors(self, bad_config, msg):
190207
# Im-parsable values raise CoverageException, with details.
191-
bad_configs_and_msgs = [
192-
("[tool.coverage.run]\ntimid = \"maybe?\"\n", r"maybe[?]"),
193-
("[tool.coverage.run\n", r"Key group"),
194-
('[tool.coverage.report]\nexclude_lines = ["foo("]\n',
195-
r"Invalid \[tool.coverage.report\].exclude_lines value u?'foo\(': "
196-
r"(unbalanced parenthesis|missing \))"),
197-
('[tool.coverage.report]\npartial_branches = ["foo["]\n',
198-
r"Invalid \[tool.coverage.report\].partial_branches value u?'foo\[': "
199-
r"(unexpected end of regular expression|unterminated character set)"),
200-
('[tool.coverage.report]\npartial_branches_always = ["foo***"]\n',
201-
r"Invalid \[tool.coverage.report\].partial_branches_always value "
202-
r"u?'foo\*\*\*': "
203-
r"multiple repeat"),
204-
('[tool.coverage.run]\nconcurrency="foo"', "not a list"),
205-
("[tool.coverage.report]\nprecision=1.23", "not an integer"),
206-
('[tool.coverage.report]\nfail_under="s"', "not a float"),
207-
]
208-
209-
for bad_config, msg in bad_configs_and_msgs:
210-
print("Trying %r" % bad_config)
211-
self.make_file("pyproject.toml", bad_config)
212-
with pytest.raises(CoverageException, match=msg):
213-
coverage.Coverage()
208+
self.make_file("pyproject.toml", bad_config)
209+
with pytest.raises(CoverageException, match=msg):
210+
coverage.Coverage()
214211

215212
def test_environment_vars_in_config(self):
216213
# Config files can have $envvars in them.
@@ -715,15 +712,15 @@ def test_note_is_obsolete(self):
715712

716713
def test_no_toml_installed_no_toml(self):
717714
# Can't read a toml file that doesn't exist.
718-
with without_module(coverage.tomlconfig, 'toml'):
715+
with without_module(coverage.tomlconfig, 'tomli'):
719716
msg = "Couldn't read 'cov.toml' as a config file"
720717
with pytest.raises(CoverageException, match=msg):
721718
coverage.Coverage(config_file="cov.toml")
722719

723720
def test_no_toml_installed_explicit_toml(self):
724721
# Can't specify a toml config file if toml isn't installed.
725722
self.make_file("cov.toml", "# A toml file!")
726-
with without_module(coverage.tomlconfig, 'toml'):
723+
with without_module(coverage.tomlconfig, 'tomli'):
727724
msg = "Can't read 'cov.toml' without TOML support"
728725
with pytest.raises(CoverageException, match=msg):
729726
coverage.Coverage(config_file="cov.toml")
@@ -735,7 +732,7 @@ def test_no_toml_installed_pyproject_toml(self):
735732
[tool.coverage.run]
736733
xyzzy = 17
737734
""")
738-
with without_module(coverage.tomlconfig, 'toml'):
735+
with without_module(coverage.tomlconfig, 'tomli'):
739736
msg = "Can't read 'pyproject.toml' without TOML support"
740737
with pytest.raises(CoverageException, match=msg):
741738
coverage.Coverage()
@@ -747,7 +744,7 @@ def test_no_toml_installed_pyproject_no_coverage(self):
747744
[tool.something]
748745
xyzzy = 17
749746
""")
750-
with without_module(coverage.tomlconfig, 'toml'):
747+
with without_module(coverage.tomlconfig, 'tomli'):
751748
cov = coverage.Coverage()
752749
# We get default settings:
753750
assert not cov.config.timid

tests/test_testing.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -347,10 +347,10 @@ def _same_python_executable(e1, e2):
347347

348348

349349
def test_without_module():
350-
toml1 = tomlconfig.toml
351-
with without_module(tomlconfig, 'toml'):
352-
toml2 = tomlconfig.toml
353-
toml3 = tomlconfig.toml
350+
toml1 = tomlconfig.tomli
351+
with without_module(tomlconfig, 'tomli'):
352+
toml2 = tomlconfig.tomli
353+
toml3 = tomlconfig.tomli
354354

355355
assert toml1 is toml3 is not None
356356
assert toml2 is None

0 commit comments

Comments
 (0)