Skip to content

Commit

Permalink
Add tests for dependency-groups parser
Browse files Browse the repository at this point in the history
  • Loading branch information
domdfcoding committed Feb 17, 2025
1 parent 4c54fc2 commit d1bc903
Show file tree
Hide file tree
Showing 69 changed files with 355 additions and 12 deletions.
5 changes: 5 additions & 0 deletions pyproject_parser/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,7 @@ def load(
keys = set(config.keys())

build_system_table: Optional[BuildSystemDict] = None
dependency_groups_table: Optional[DependencyGroupsDict] = None
project_table: Optional[ProjectDict] = None
tool_table: Dict[str, Dict[str, Any]] = {}

Expand Down Expand Up @@ -392,6 +393,7 @@ def dumps(
"build-system": self.build_system,
"project": self.project,
"tool": self.tool,
"dependency-groups": self.dependency_groups,
}

if toml_dict["project"] is not None:
Expand Down Expand Up @@ -495,6 +497,8 @@ def from_dict(cls: Type[_PP], d: Mapping[str, Any]) -> _PP:
for key, value in d.items():
if key == "build-system":
key = "build_system"
elif key == "dependency-groups":
key = "dependency_groups"

kwargs[key] = value

Expand All @@ -511,4 +515,5 @@ def to_dict(self) -> MutableMapping[str, Any]:
"build_system": self.build_system,
"project": self.project,
"tool": self.tool,
"dependency_groups": self.dependency_groups,
}
13 changes: 7 additions & 6 deletions pyproject_parser/parsers.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
__all__ = [
"RequiredKeysConfigParser",
"BuildSystemParser",
"DependencyGroupsParser",
"PEP621Parser",
]

Expand Down Expand Up @@ -286,13 +287,13 @@ def parse_group(config: TOML_TYPES) -> List[Union[str, Dict[str, str]]]:
if isinstance(config, list):
return config

raise BadConfigError("A group must be a list.")
raise BadConfigError("A dependency group must be an array.")

def parse( # type: ignore[override]
self,
config: Dict[str, TOML_TYPES],
set_defaults: bool = False,
) -> BuildSystemDict:
def parse(
self,
config: Dict[str, TOML_TYPES],
set_defaults: bool = False,
) -> DependencyGroupsDict:
"""
Parse the TOML configuration.
Expand Down
2 changes: 2 additions & 0 deletions pyproject_parser/type_hints.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@

__all__ = [
"BuildSystemDict",
"IncludeGroupDict",
"DependencyGroupsDict",
"Dynamic",
"ProjectDict",
"Author",
Expand Down
9 changes: 9 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from typing import Callable, Type, TypeVar, Union

# 3rd party
from dom_toml.decoder import InlineTableDict
from packaging.markers import Marker
from packaging.requirements import Requirement
from packaging.specifiers import SpecifierSet
Expand Down Expand Up @@ -46,3 +47,11 @@ def represent_readme_or_license( # noqa: MAN002
data: Union[Readme, License],
):
return dumper.represent_dict(data.to_dict())


@_representer_for(InlineTableDict)
def represent_inline_table( # noqa: MAN002
dumper: RegressionYamlDumper,
data: InlineTableDict,
):
return dumper.represent_dict(dict(data))
12 changes: 11 additions & 1 deletion tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,15 @@
from pyproject_parser.cli import ConfigTracebackHandler
from tests.test_dumping import COMPLETE_UNDERSCORE_NAME, UNORDERED

COMPLETE_DEPENDENCY_GROUPS = COMPLETE_A + """
[dependency-groups]
test = ["pytest", "coverage"]
docs = ["sphinx", "sphinx-rtd-theme"]
typing = ["mypy", "types-requests"]
typing-test = [{include-group = "typing"}, {include-group = "test"}, "useful-types"]
"""


@pytest.mark.parametrize(
"toml_string",
Expand All @@ -37,6 +46,7 @@
pytest.param(COMPLETE_PROJECT_A, id="COMPLETE_PROJECT_A"),
pytest.param(UNORDERED, id="UNORDERED"),
pytest.param(COMPLETE_UNDERSCORE_NAME, id="COMPLETE_UNDERSCORE_NAME"),
pytest.param(COMPLETE_DEPENDENCY_GROUPS, id="COMPLETE_DEPENDENCY_GROUPS"),
]
)
@pytest.mark.parametrize("show_diff", [True, False])
Expand Down Expand Up @@ -177,7 +187,7 @@ def test_check_extra_deprecation_warning(
),
pytest.param(
"[coverage]\nomit = 'demo.py'\n[flake8]\nselect = ['F401']",
"Unexpected top-level key 'coverage'. Only 'build-system', 'project' and 'tool' are allowed.",
"Unexpected top-level key 'coverage'. Only 'build-system', 'dependency-groups', 'project' and 'tool' are allowed.",
id="top-level",
),
pytest.param(
Expand Down
2 changes: 1 addition & 1 deletion tests/test_cli_/test_check_error_caught_top_level_.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
BadConfigError: Unexpected top-level key 'coverage'. Only 'build-system', 'project' and 'tool' are allowed.
BadConfigError: Unexpected top-level key 'coverage'. Only 'build-system', 'dependency-groups', 'project' and 'tool' are allowed.
Use '--traceback' to view the full traceback.
Aborted!
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Reformatting 'pyproject.toml'
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
[build-system]
requires = [ "whey",]
build-backend = "whey"

[project]
name = "whey"
version = "2021.0.0"
description = "A simple Python wheel builder for simple projects."
keywords = [ "build", "distribution", "packaging", "pep517", "pep621", "sdist", "wheel",]
dependencies = [ 'django>2.1; os_name != "nt"', 'django>2.0; os_name == "nt"', "gidgethub[httpx]>4.0.0", "httpx",]
dynamic = [ "classifiers", "requires-python",]

[[project.authors]]
name = "Dominic Davis-Foster"
email = "dominic@davis-foster.co.uk"

[project.urls]
Homepage = "https://whey.readthedocs.io/en/latest"
Documentation = "https://whey.readthedocs.io/en/latest"
"Issue Tracker" = "https://github.com/repo-helper/whey/issues"
"Source Code" = "https://github.com/repo-helper/whey"

[tool.whey]
base-classifiers = [ "Development Status :: 4 - Beta",]
python-versions = [ "3.6", "3.7", "3.8", "3.9", "3.10",]
python-implementations = [ "CPython", "PyPy",]
platforms = [ "Windows", "macOS", "Linux",]
license-key = "MIT"

[dependency-groups]
test = [ "pytest", "coverage",]
docs = [ "sphinx", "sphinx-rtd-theme",]
typing = [ "mypy", "types-requests",]
typing-test = [ { include-group = "typing" }, { include-group = "test" }, "useful-types",]
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
Reformatting 'pyproject.toml'
--- pyproject.toml (original)
+++ pyproject.toml (reformatted)
@@ -6,18 +6,13 @@
name = "whey"
version = "2021.0.0"
description = "A simple Python wheel builder for simple projects."
-keywords = [ "pep517", "pep621", "build", "sdist", "wheel", "packaging", "distribution",]
+keywords = [ "build", "distribution", "packaging", "pep517", "pep621", "sdist", "wheel",]
+dependencies = [ 'django>2.1; os_name != "nt"', 'django>2.0; os_name == "nt"', "gidgethub[httpx]>4.0.0", "httpx",]
dynamic = [ "classifiers", "requires-python",]
-dependencies = [
- "httpx",
- "gidgethub[httpx]>4.0.0",
- "django>2.1; os_name != 'nt'",
- "django>2.0; os_name == 'nt'"
-]

[[project.authors]]
+name = "Dominic Davis-Foster"
email = "dominic@davis-foster.co.uk"
-name = "Dominic Davis-Foster"

[project.urls]
Homepage = "https://whey.readthedocs.io/en/latest"
@@ -32,10 +27,9 @@
platforms = [ "Windows", "macOS", "Linux",]
license-key = "MIT"

+[dependency-groups]
+test = [ "pytest", "coverage",]
+docs = [ "sphinx", "sphinx-rtd-theme",]
+typing = [ "mypy", "types-requests",]
+typing-test = [ { include-group = "typing" }, { include-group = "test" }, "useful-types",]

-[dependency-groups]
-test = ["pytest", "coverage"]
-docs = ["sphinx", "sphinx-rtd-theme"]
-typing = ["mypy", "types-requests"]
-typing-test = [{include-group = "typing"}, {include-group = "test"}, "useful-types"]
-
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
[build-system]
requires = [ "whey",]
build-backend = "whey"

[project]
name = "whey"
version = "2021.0.0"
description = "A simple Python wheel builder for simple projects."
keywords = [ "build", "distribution", "packaging", "pep517", "pep621", "sdist", "wheel",]
dependencies = [ 'django>2.1; os_name != "nt"', 'django>2.0; os_name == "nt"', "gidgethub[httpx]>4.0.0", "httpx",]
dynamic = [ "classifiers", "requires-python",]

[[project.authors]]
name = "Dominic Davis-Foster"
email = "dominic@davis-foster.co.uk"

[project.urls]
Homepage = "https://whey.readthedocs.io/en/latest"
Documentation = "https://whey.readthedocs.io/en/latest"
"Issue Tracker" = "https://github.com/repo-helper/whey/issues"
"Source Code" = "https://github.com/repo-helper/whey"

[tool.whey]
base-classifiers = [ "Development Status :: 4 - Beta",]
python-versions = [ "3.6", "3.7", "3.8", "3.9", "3.10",]
python-implementations = [ "CPython", "PyPy",]
platforms = [ "Windows", "macOS", "Linux",]
license-key = "MIT"

[dependency-groups]
test = [ "pytest", "coverage",]
docs = [ "sphinx", "sphinx-rtd-theme",]
typing = [ "mypy", "types-requests",]
typing-test = [ { include-group = "typing" }, { include-group = "test" }, "useful-types",]
50 changes: 49 additions & 1 deletion tests/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,12 @@
from shippinglabel import normalize_keep_dot

# this package
from pyproject_parser.parsers import BuildSystemParser, PEP621Parser, RequiredKeysConfigParser
from pyproject_parser.parsers import (
BuildSystemParser,
DependencyGroupsParser,
PEP621Parser,
RequiredKeysConfigParser
)
from pyproject_parser.utils import PyProjectDeprecationWarning, _load_toml


Expand Down Expand Up @@ -555,3 +560,46 @@ class MyConfigParser(RequiredKeysConfigParser):

assert MyConfigParser().parse({}, set_defaults=True) == {"foo": "foo-default", "bar": "bar-defaults"}
assert MyConfigParser().parse({"foo": "baz"}, set_defaults=True) == {"foo": "baz", "bar": "bar-defaults"}


valid_dependency_groups_config = [
pytest.param("[dependency-groups]", id="empty"),
pytest.param('[dependency-groups]\ngroup-a = ["foo"]', id="one-group"),
pytest.param(
'[dependency-groups]\ngroup-a = ["foo"]\ngroup-b = ["foo>1.0"]\ngroup-c = ["foo<1.0"]\nall = ["foo", {include-group = "group-a"}, {include-group = "group-b"}, {include-group = "group-c"}]',
id="full-example"
),
]

bad_dependency_groups_config = [
pytest.param(
'[dependency-groups]\ngroup-a = "foo"', BadConfigError, "A dependency group must be an array"
),
]


@pytest.mark.parametrize("set_defaults", [True, False])
@pytest.mark.parametrize("toml_config", valid_dependency_groups_config)
def test_dependency_groups_parser_valid_config(
toml_config: str,
tmp_pathplus: PathPlus,
advanced_data_regression: AdvancedDataRegressionFixture,
set_defaults: bool,
):
(tmp_pathplus / "pyproject.toml").write_clean(toml_config)
config = DependencyGroupsParser().parse(
_load_toml(tmp_pathplus / "pyproject.toml")["dependency-groups"],
set_defaults=set_defaults,
)

advanced_data_regression.check(config)


@pytest.mark.parametrize("config, expects, match", bad_dependency_groups_config)
def test_dependency_groups_parser_errors(
config: str, expects: Type[Exception], match: str, tmp_pathplus: PathPlus
):
(tmp_pathplus / "pyproject.toml").write_clean(config)

with in_directory(tmp_pathplus), pytest.raises(expects, match=match):
DependencyGroupsParser().parse(_load_toml(tmp_pathplus / "pyproject.toml")["dependency-groups"])
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
all:
- foo
- include-group: group-a
- include-group: group-b
- include-group: group-c
group-a:
- foo
group-b:
- foo>1.0
group-c:
- foo<1.0
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
all:
- foo
- include-group: group-a
- include-group: group-b
- include-group: group-c
group-a:
- foo
group-b:
- foo>1.0
group-c:
- foo<1.0
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
group-a:
- foo
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
group-a:
- foo
22 changes: 19 additions & 3 deletions tests/test_pyproject_class.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,24 @@
# this package
from pyproject_parser import PyProject

COMPLETE_DEPENDENCY_GROUPS = COMPLETE_A + """
@pytest.mark.parametrize("toml_config", [*valid_pep621_config, *valid_buildsystem_config])
[dependency-groups]
test = ["pytest", "coverage"]
docs = ["sphinx", "sphinx-rtd-theme"]
typing = ["mypy", "types-requests"]
typing-test = [{include-group = "typing"}, {include-group = "test"}, "useful-types"]
"""


@pytest.mark.parametrize(
"toml_config",
[
*valid_pep621_config,
*valid_buildsystem_config,
pytest.param(COMPLETE_DEPENDENCY_GROUPS, id="complete-dependency-groups"),
]
)
def test_valid_config(
toml_config: str,
tmp_pathplus: PathPlus,
Expand Down Expand Up @@ -81,13 +97,13 @@ def test_valid_config_resolve_files(
pytest.param(
'banana = "fruit"\n[project]\nname = "food"',
BadConfigError,
"Unexpected top-level key 'banana'. Only 'build-system', 'project' and 'tool' are allowed.",
"Unexpected top-level key 'banana'. Only 'build-system', 'dependency-groups', 'project' and 'tool' are allowed.",
id="unexpected_top_level"
),
pytest.param(
"[coverage]\nomit = 'demo.py'\n[flake8]\nselect = ['F401']",
BadConfigError,
"Unexpected top-level key 'coverage'. Only 'build-system', 'project' and 'tool' are allowed.",
"Unexpected top-level key 'coverage'. Only 'build-system', 'dependency-groups', 'project' and 'tool' are allowed.",
id="top-level",
),
pytest.param(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ build_system:
build-backend: whey
requires:
- whey
dependency_groups: null
project:
authors:
- email: dominic@davis-foster.co.uk
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ build_system:
build-backend: whey
requires:
- whey
dependency_groups: null
project:
authors:
- email: dominic@davis-foster.co.uk
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
build_system: null
dependency_groups: null
project:
authors:
- email: hi@pradyunsg.me
Expand Down
Loading

0 comments on commit d1bc903

Please sign in to comment.