Visitar URL original
fix: read config files that start with a UTF-8 byte order mark (#2388) · coveragepy/coveragepy@33a1cd3 · GitHub
Skip to content

Commit 33a1cd3

Browse files
fix: read config files that start with a UTF-8 byte order mark (#2388)
* fix: read config files that start with a UTF-8 byte order mark * news fragment --------- Co-authored-by: Ned Batchelder <ned@nedbatchelder.com>
1 parent e504e56 commit 33a1cd3

4 files changed

Lines changed: 27 additions & 2 deletions

File tree

‎coverage/config.py‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,8 @@ def read( # type: ignore[override]
5656
encoding_unused: str | None = None,
5757
) -> list[str]:
5858
"""Read a file name as UTF-8 configuration data."""
59-
return super().read(filenames, encoding="utf-8")
59+
# utf-8-sig also accepts a file that starts with a byte order mark.
60+
return super().read(filenames, encoding="utf-8-sig")
6061

6162
def real_section(self, section: str) -> str | None:
6263
"""Get the actual name of a section."""

‎coverage/tomlconfig.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ def read(self, filenames: Iterable[str]) -> list[str]:
4141
filename = os.fspath(filenames)
4242

4343
try:
44-
with open(filename, encoding="utf-8") as fp:
44+
with open(filename, encoding="utf-8-sig") as fp:
4545
toml_text = fp.read()
4646
except OSError:
4747
return []
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
- Fix: a configuration file (``.coveragerc``, ``setup.cfg``, ``tox.ini`` or
2+
``pyproject.toml``) saved with a UTF-8 byte order mark couldn't be read.
3+
Now a leading BOM is ignored. `pull 2388`_.
4+
5+
.. _pull 2388: https://github.com/coveragepy/coveragepy/pull/2388

‎tests/test_config.py‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,25 @@ def test_config_file(self) -> None:
5757
assert not cov.config.branch
5858
assert cov.config.data_file == ".hello_kitty.data"
5959

60+
@pytest.mark.parametrize(
61+
"filename, section",
62+
[
63+
(".coveragerc", "run"),
64+
("setup.cfg", "coverage:run"),
65+
("tox.ini", "coverage:run"),
66+
("pyproject.toml", "tool.coverage.run"),
67+
],
68+
)
69+
def test_config_file_with_bom(self, filename: str, section: str) -> None:
70+
# Editors on Windows can save files as "UTF-8 with BOM".
71+
value = "true" if filename.endswith(".toml") else "True"
72+
self.make_file(
73+
filename,
74+
bytes=f"\ufeff[{section}]\ntimid = {value}\n".encode("utf-8"),
75+
)
76+
cov = coverage.Coverage()
77+
assert cov.config.timid
78+
6079
@pytest.mark.parametrize("file_class", FilePathClasses)
6180
def test_named_config_file(self, file_class: FilePathType) -> None:
6281
# You can name the config file what you like.

0 commit comments

Comments
 (0)