Skip to content

Commit

Permalink
Swap in tomllib/tomli for toml. (#340)
Browse files Browse the repository at this point in the history
* Swap tomllib for toml.

Fixes #339 -- the toml package does not support heterogenous arrays,
which are now allowed in the toml spec. This commit swaps in tomllib
from the standard library for Python >= 3.11 and its backport tomli for
older versions.

---------

Co-authored-by: Jendrik Seipp <[email protected]>
  • Loading branch information
sacsar and jendrikseipp authored Nov 24, 2023
1 parent b6fae71 commit 072c3bb
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 9 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ vulture.egg-info/
.pytest_cache/
.tox/
.venv/
.vscode/
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# next (unreleased)
* Switch to tomllib/tomli to support heterogeneous arrays (Sebastian Csar, #340).

# 2.10 (2023-10-06)

* Drop support for Python 3.7 (Jendrik Seipp, #323).
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ def find_version(*parts):
"Programming Language :: Python :: Implementation :: PyPy",
"Topic :: Software Development :: Quality Assurance",
],
install_requires=["toml"],
install_requires=["tomli >= 1.1.0; python_version < '3.11'"],
entry_points={"console_scripts": ["vulture = vulture.core:main"]},
python_requires=">=3.8",
packages=setuptools.find_packages(exclude=["tests"]),
Expand Down
56 changes: 51 additions & 5 deletions tests/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
Unit tests for config file and CLI argument parsing.
"""

from io import StringIO
from io import BytesIO
from textwrap import dedent

import pytest
Expand All @@ -17,6 +17,13 @@
)


def get_toml_bytes(toml_str: str) -> BytesIO:
"""
Wrap a string in BytesIO to play the role of the incoming config stream.
"""
return BytesIO(bytes(toml_str, "utf-8"))


def test_cli_args():
"""
Ensure that CLI arguments are converted to a config object.
Expand Down Expand Up @@ -62,9 +69,48 @@ def test_toml_config():
sort_by_size=True,
verbose=True,
)
data = StringIO(
data = get_toml_bytes(
dedent(
"""\
[tool.vulture]
exclude = ["file*.py", "dir/"]
ignore_decorators = ["deco1", "deco2"]
ignore_names = ["name1", "name2"]
make_whitelist = true
min_confidence = 10
sort_by_size = true
verbose = true
paths = ["path1", "path2"]
"""
)
)
result = _parse_toml(data)
assert isinstance(result, dict)
assert result == expected


def test_toml_config_with_heterogenous_array():
"""
Ensure parsing of TOML files results in a valid config object, even if some
other part of the file contains an array of mixed types.
"""
expected = dict(
paths=["path1", "path2"],
exclude=["file*.py", "dir/"],
ignore_decorators=["deco1", "deco2"],
ignore_names=["name1", "name2"],
make_whitelist=True,
min_confidence=10,
sort_by_size=True,
verbose=True,
)
data = get_toml_bytes(
dedent(
"""\
[tool.foo]
# comment for good measure
problem_array = [{a = 1}, [2,3,4], "foo"]
[tool.vulture]
exclude = ["file*.py", "dir/"]
ignore_decorators = ["deco1", "deco2"]
Expand All @@ -87,7 +133,7 @@ def test_config_merging():
If we have both CLI args and a ``pyproject.toml`` file, the CLI args should
have precedence.
"""
toml = StringIO(
toml = get_toml_bytes(
dedent(
"""\
[tool.vulture]
Expand Down Expand Up @@ -131,7 +177,7 @@ def test_config_merging_missing():
If we have set a boolean value in the TOML file, but not on the CLI, we
want the TOML value to be taken.
"""
toml = StringIO(
toml = get_toml_bytes(
dedent(
"""\
[tool.vulture]
Expand All @@ -153,7 +199,7 @@ def test_config_merging_toml_paths_only():
If we have paths in the TOML but not on the CLI, the TOML paths should be
used.
"""
toml = StringIO(
toml = get_toml_bytes(
dedent(
"""\
[tool.vulture]
Expand Down
9 changes: 6 additions & 3 deletions vulture/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
import argparse
import pathlib

import toml
try:
import tomllib
except ModuleNotFoundError:
import tomli as tomllib

from .version import __version__

Expand Down Expand Up @@ -76,7 +79,7 @@ def _parse_toml(infile):
verbose = true
paths = ["path1", "path2"]
"""
data = toml.load(infile)
data = tomllib.load(infile)
settings = data.get("tool", {}).get("vulture", {})
_check_input_config(settings)
return settings
Expand Down Expand Up @@ -194,7 +197,7 @@ def make_config(argv=None, tomlfile=None):
else:
toml_path = pathlib.Path("pyproject.toml").resolve()
if toml_path.is_file():
with open(toml_path) as fconfig:
with open(toml_path, "rb") as fconfig:
config = _parse_toml(fconfig)
detected_toml_path = str(toml_path)
else:
Expand Down

0 comments on commit 072c3bb

Please sign in to comment.