Skip to content

Commit 0d67ae1

Browse files
authored
Use tomllib on Python 3.11 (#1359)
Co-authored-by: hauntsaninja <>
1 parent e8973c5 commit 0d67ae1

File tree

4 files changed

+26
-18
lines changed

4 files changed

+26
-18
lines changed

coverage/tomlconfig.py

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,21 @@
66
import configparser
77
import os
88
import re
9+
import sys
910

1011
from coverage.exceptions import ConfigError
1112
from coverage.misc import import_third_party, substitute_variables
1213

13-
# TOML support is an install-time extra option. (Import typing is here because
14-
# import_third_party will unload any module that wasn't already imported.
15-
# tomli imports typing, and if we unload it, later it's imported again, and on
16-
# Python 3.6, this causes infinite recursion.)
17-
import typing # pylint: disable=unused-import, wrong-import-order
18-
tomli = import_third_party("tomli")
14+
if sys.version_info >= (3, 11):
15+
import tomllib
16+
else:
17+
# TOML support on Python 3.10 and below is an install-time extra option.
18+
# (Import typing is here because import_third_party will unload any module
19+
# that wasn't already imported. tomli imports typing, and if we unload it,
20+
# later it's imported again, and on Python 3.6, this causes infinite
21+
# recursion.)
22+
import typing # pylint: disable=unused-import, wrong-import-order
23+
tomllib = import_third_party("tomli")
1924

2025

2126
class TomlDecodeError(Exception):
@@ -45,11 +50,11 @@ def read(self, filenames):
4550
toml_text = fp.read()
4651
except OSError:
4752
return []
48-
if tomli is not None:
53+
if tomllib is not None:
4954
toml_text = substitute_variables(toml_text, os.environ)
5055
try:
51-
self.data = tomli.loads(toml_text)
52-
except tomli.TOMLDecodeError as err:
56+
self.data = tomllib.loads(toml_text)
57+
except tomllib.TOMLDecodeError as err:
5358
raise TomlDecodeError(str(err)) from err
5459
return [filename]
5560
else:

setup.py

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

109109
extras_require={
110110
# Enable pyproject.toml support.
111-
'toml': ['tomli'],
111+
'toml': ['tomli; python_version < "3.11"'],
112112
},
113113

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

tests/test_config.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
"""Test the config file handling for coverage.py"""
55

66
import math
7+
import sys
78
from collections import OrderedDict
89

910
from unittest import mock
@@ -706,27 +707,29 @@ def test_note_is_obsolete(self):
706707

707708
def test_no_toml_installed_no_toml(self):
708709
# Can't read a toml file that doesn't exist.
709-
with without_module(coverage.tomlconfig, 'tomli'):
710+
with without_module(coverage.tomlconfig, 'tomllib'):
710711
msg = "Couldn't read 'cov.toml' as a config file"
711712
with pytest.raises(ConfigError, match=msg):
712713
coverage.Coverage(config_file="cov.toml")
713714

715+
@pytest.mark.skipif(sys.version_info >= (3, 11), reason="Python 3.11 has toml in stdlib")
714716
def test_no_toml_installed_explicit_toml(self):
715717
# Can't specify a toml config file if toml isn't installed.
716718
self.make_file("cov.toml", "# A toml file!")
717-
with without_module(coverage.tomlconfig, 'tomli'):
719+
with without_module(coverage.tomlconfig, 'tomllib'):
718720
msg = "Can't read 'cov.toml' without TOML support"
719721
with pytest.raises(ConfigError, match=msg):
720722
coverage.Coverage(config_file="cov.toml")
721723

724+
@pytest.mark.skipif(sys.version_info >= (3, 11), reason="Python 3.11 has toml in stdlib")
722725
def test_no_toml_installed_pyproject_toml(self):
723726
# Can't have coverage config in pyproject.toml without toml installed.
724727
self.make_file("pyproject.toml", """\
725728
# A toml file!
726729
[tool.coverage.run]
727730
xyzzy = 17
728731
""")
729-
with without_module(coverage.tomlconfig, 'tomli'):
732+
with without_module(coverage.tomlconfig, 'tomllib'):
730733
msg = "Can't read 'pyproject.toml' without TOML support"
731734
with pytest.raises(ConfigError, match=msg):
732735
coverage.Coverage()
@@ -738,7 +741,7 @@ def test_no_toml_installed_pyproject_no_coverage(self):
738741
[tool.something]
739742
xyzzy = 17
740743
""")
741-
with without_module(coverage.tomlconfig, 'tomli'):
744+
with without_module(coverage.tomlconfig, 'tomllib'):
742745
cov = coverage.Coverage()
743746
# We get default settings:
744747
assert not cov.config.timid

tests/test_testing.py

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

358358

359359
def test_without_module():
360-
toml1 = tomlconfig.tomli
361-
with without_module(tomlconfig, 'tomli'):
362-
toml2 = tomlconfig.tomli
363-
toml3 = tomlconfig.tomli
360+
toml1 = tomlconfig.tomllib
361+
with without_module(tomlconfig, 'tomllib'):
362+
toml2 = tomlconfig.tomllib
363+
toml3 = tomlconfig.tomllib
364364

365365
assert toml1 is toml3 is not None
366366
assert toml2 is None

0 commit comments

Comments
 (0)