From 85a4281ed61554da53d1000bbaac71ca6f6d5ea2 Mon Sep 17 00:00:00 2001 From: Anderson Bravalheri Date: Wed, 18 May 2022 10:34:14 +0100 Subject: [PATCH 1/5] Use tomllib on Python >= 3.11 --- setup.cfg | 2 +- src/validate_pyproject/cli.py | 9 ++++++--- tests/helpers.py | 10 ++++++++++ tests/test_api.py | 5 +++-- tests/test_examples.py | 7 +++---- tests/test_pre_compile.py | 7 +++---- 6 files changed, 26 insertions(+), 14 deletions(-) diff --git a/setup.cfg b/setup.cfg index c32d58d..5c37119 100644 --- a/setup.cfg +++ b/setup.cfg @@ -60,7 +60,7 @@ exclude = [options.extras_require] all = - tomli>=1.2.1 + tomli>=1.2.1; python_version<"3.11" packaging>=20.4 trove-classifiers>=2021.10.20 diff --git a/src/validate_pyproject/cli.py b/src/validate_pyproject/cli.py index 74d4b75..1232c7d 100644 --- a/src/validate_pyproject/cli.py +++ b/src/validate_pyproject/cli.py @@ -32,14 +32,17 @@ T = TypeVar("T", bound=NamedTuple) -try: - from tomli import TOMLDecodeError, loads +try: # pragma: no cover + if sys.version_info[:2] >= (3, 11): + from tomllib import TOMLDecodeError, loads + else: + from tomli import TOMLDecodeError, loads except ImportError: # pragma: no cover try: from toml import TomlDecodeError as TOMLDecodeError # type: ignore from toml import loads # type: ignore except ImportError as ex: - raise ImportError("Please install a TOML parser (e.g. `tomli`)") from ex + raise ImportError("Please install `tomli` (TOML parser)") from ex _REGULAR_EXCEPTIONS = (ValidationError, TOMLDecodeError) diff --git a/tests/helpers.py b/tests/helpers.py index 5e40200..6587eeb 100644 --- a/tests/helpers.py +++ b/tests/helpers.py @@ -1,5 +1,15 @@ +import sys from pathlib import Path +if sys.version_info[:2] >= (3, 11): + import tomllib + + toml_ = tomllib +else: + import tomli + + toml_ = tomli + HERE = Path(__file__).parent EXAMPLES = HERE / "examples" INVALID = HERE / "invalid-examples" diff --git a/tests/test_api.py b/tests/test_api.py index 2de77f0..b69ec0f 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -2,11 +2,12 @@ from functools import partial, wraps import pytest -import tomli from validate_pyproject._vendor import fastjsonschema as FJS from validate_pyproject import api, errors, plugins, types +from .helpers import toml_ + PYPA_SPECS = "https://packaging.python.org/en/latest/specifications" @@ -84,7 +85,7 @@ class TestValidator: @property def valid_example(self): - return tomli.loads(self.example_toml) + return toml_.loads(self.example_toml) @property def invalid_example(self): diff --git a/tests/test_examples.py b/tests/test_examples.py index 10d9aeb..e3848e6 100644 --- a/tests/test_examples.py +++ b/tests/test_examples.py @@ -1,17 +1,16 @@ import logging import pytest -import tomli from validate_pyproject._vendor.fastjsonschema import JsonSchemaValueException from validate_pyproject import api, cli -from .helpers import EXAMPLES, INVALID, error_file, examples, invalid_examples +from .helpers import EXAMPLES, INVALID, error_file, examples, invalid_examples, toml_ @pytest.mark.parametrize("example", examples()) def test_examples_api(example): - toml_equivalent = tomli.loads((EXAMPLES / example).read_text()) + toml_equivalent = toml_.loads((EXAMPLES / example).read_text()) validator = api.Validator() return validator(toml_equivalent) is not None @@ -25,7 +24,7 @@ def test_examples_cli(example): def test_invalid_examples_api(example): example_file = INVALID / example expected_error = error_file(example_file).read_text("utf-8") - toml_equivalent = tomli.loads(example_file.read_text()) + toml_equivalent = toml_.loads(example_file.read_text()) validator = api.Validator() with pytest.raises(JsonSchemaValueException) as exc_info: validator(toml_equivalent) diff --git a/tests/test_pre_compile.py b/tests/test_pre_compile.py index 8ae4ad9..fad61f6 100644 --- a/tests/test_pre_compile.py +++ b/tests/test_pre_compile.py @@ -7,12 +7,11 @@ from pathlib import Path import pytest -import tomli from validate_pyproject._vendor.fastjsonschema import JsonSchemaValueException from validate_pyproject.pre_compile import cli, pre_compile -from .helpers import EXAMPLES, INVALID, error_file, examples, invalid_examples +from .helpers import EXAMPLES, INVALID, error_file, examples, invalid_examples, toml_ MAIN_FILE = "hello_world.py" # Let's use something different that `__init__.py` @@ -139,7 +138,7 @@ def _validate(vendored_path, toml_equivalent): @pytest.mark.parametrize("example", examples()) @pytest.mark.parametrize("pre_compiled", _PRE_COMPILED) def test_examples_api(tmp_path, pre_compiled_validate, example, pre_compiled): - toml_equivalent = tomli.loads((EXAMPLES / example).read_text()) + toml_equivalent = toml_.loads((EXAMPLES / example).read_text()) pre_compiled_path = pre_compiled(Path(tmp_path)) return pre_compiled_validate(pre_compiled_path, toml_equivalent) is not None @@ -149,7 +148,7 @@ def test_examples_api(tmp_path, pre_compiled_validate, example, pre_compiled): def test_invalid_examples_api(tmp_path, pre_compiled_validate, example, pre_compiled): example_file = INVALID / example expected_error = error_file(example_file).read_text("utf-8") - toml_equivalent = tomli.loads(example_file.read_text()) + toml_equivalent = toml_.loads(example_file.read_text()) pre_compiled_path = pre_compiled(Path(tmp_path)) with pytest.raises(JsonSchemaValueException) as exc_info: pre_compiled_validate(pre_compiled_path, toml_equivalent) From 859b8cc5db4a88314400cd3d9b1fd8e5a39eaf3e Mon Sep 17 00:00:00 2001 From: Anderson Bravalheri Date: Wed, 18 May 2022 10:42:49 +0100 Subject: [PATCH 2/5] Add test to ensure tomli is not being used on 3.11 --- tests/test_cli.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/test_cli.py b/tests/test_cli.py index 3b4e5de..c32eecc 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -1,4 +1,5 @@ import logging +import sys from pathlib import Path from uuid import uuid4 @@ -161,3 +162,10 @@ def test_multiple_files(tmp_path, capsys): captured = captured.replace(repl, "invalid file:") assert number_valid == N assert number_invalid == N + 3 + + +@pytest.mark.skipif(sys.version_info[:2] < (3, 11), reason="requires 3.11+") +def test_toml_parser(): + """Make sure Python >= 3.11 uses tomllib instead of tomli""" + func_name = cli.loads.__qualname__ + assert func_name.startswith("tomllib") From b10b6e5cc63f59f88015bbd65b8cfd091be1e587 Mon Sep 17 00:00:00 2001 From: Anderson Bravalheri Date: Wed, 18 May 2022 10:50:03 +0100 Subject: [PATCH 3/5] Update CHANGELOG --- CHANGELOG.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 094506e..e059be0 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog ========= +Version 0.9 +=========== + +- Use ``tomllib`` from the standard library in Python 3.11+, #42 + Version 0.8.1 ============= From 8754d904619346a9819141892ce41e4bc4d4c257 Mon Sep 17 00:00:00 2001 From: Anderson Bravalheri Date: Wed, 18 May 2022 10:55:38 +0100 Subject: [PATCH 4/5] Attempt to fix test for tomllib --- tests/test_cli.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/test_cli.py b/tests/test_cli.py index c32eecc..b8bc62d 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -1,3 +1,4 @@ +import inspect import logging import sys from pathlib import Path @@ -167,5 +168,5 @@ def test_multiple_files(tmp_path, capsys): @pytest.mark.skipif(sys.version_info[:2] < (3, 11), reason="requires 3.11+") def test_toml_parser(): """Make sure Python >= 3.11 uses tomllib instead of tomli""" - func_name = cli.loads.__qualname__ - assert func_name.startswith("tomllib") + module_name = inspect.getmodule(cli.loads).__name__ + assert module_name.startswith("tomllib") From 68d0c99ba4a9c5f925c4c3c1265c9a94f29ed188 Mon Sep 17 00:00:00 2001 From: Anderson Bravalheri Date: Wed, 18 May 2022 10:58:32 +0100 Subject: [PATCH 5/5] Rename test to make it more descriptive --- tests/test_cli.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_cli.py b/tests/test_cli.py index b8bc62d..3acd186 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -166,7 +166,7 @@ def test_multiple_files(tmp_path, capsys): @pytest.mark.skipif(sys.version_info[:2] < (3, 11), reason="requires 3.11+") -def test_toml_parser(): +def test_parser_is_tomllib(): """Make sure Python >= 3.11 uses tomllib instead of tomli""" module_name = inspect.getmodule(cli.loads).__name__ assert module_name.startswith("tomllib")