Skip to content

Commit

Permalink
Allow dash-separated module name in pyproject.toml (#4566)
Browse files Browse the repository at this point in the history
  • Loading branch information
abravalheri authored Aug 14, 2024
2 parents 57379cd + 0aac59e commit 8bd9308
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 33 deletions.
6 changes: 2 additions & 4 deletions setuptools/config/_validate_pyproject/error_reporting.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import typing
from contextlib import contextmanager
from textwrap import indent, wrap
from typing import Any, Dict, Generator, Iterator, List, Optional, Sequence, Union, cast
from typing import Any, Dict, Generator, Iterator, List, Optional, Sequence, Union

from .fastjsonschema_exceptions import JsonSchemaValueException

Expand Down Expand Up @@ -316,9 +316,7 @@ def _label(self, path: Sequence[str]) -> str:
def _value(self, value: Any, path: Sequence[str]) -> str:
if path[-1] == "type" and not self._is_property(path):
type_ = self._jargon(value)
return (
f"[{', '.join(type_)}]" if isinstance(value, list) else cast(str, type_)
)
return f"[{', '.join(type_)}]" if isinstance(type_, list) else type_
return repr(value)

def _inline_attrs(self, schema: dict, path: Sequence[str]) -> Iterator[str]:
Expand Down
48 changes: 24 additions & 24 deletions setuptools/config/_validate_pyproject/fastjsonschema_validations.py

Large diffs are not rendered by default.

23 changes: 22 additions & 1 deletion setuptools/config/_validate_pyproject/formats.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,9 @@ def pep508_identifier(name: str) -> bool:
from packaging import requirements as _req
except ImportError: # pragma: no cover
# let's try setuptools vendored version
from setuptools._vendor.packaging import requirements as _req # type: ignore
from setuptools._vendor.packaging import ( # type: ignore[no-redef]
requirements as _req,
)

def pep508(value: str) -> bool:
"""See :ref:`PyPA's dependency specifiers <pypa:dependency-specifiers>`
Expand Down Expand Up @@ -289,6 +291,25 @@ def python_module_name(value: str) -> bool:
return python_qualified_identifier(value)


def python_module_name_relaxed(value: str) -> bool:
"""Similar to :obj:`python_module_name`, but relaxed to also accept
dash characters (``-``) and cover special cases like ``pip-run``.
It is recommended, however, that beginners avoid dash characters,
as they require advanced knowledge about Python internals.
The following are disallowed:
* names starting/ending in dashes,
* names ending in ``-stubs`` (potentially collide with :obj:`pep561_stub_name`).
"""
if value.startswith("-") or value.endswith("-"):
return False
if value.endswith("-stubs"):
return False # Avoid collision with PEP 561
return python_module_name(value.replace("-", "_"))


def python_entrypoint_group(value: str) -> bool:
"""See ``Data model > group`` in the :ref:`PyPA's entry-points specification
<pypa:entry-points>`.
Expand Down
6 changes: 3 additions & 3 deletions setuptools/config/setuptools.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -148,14 +148,14 @@
},
"namespace-packages": {
"type": "array",
"items": {"type": "string", "format": "python-module-name"},
"items": {"type": "string", "format": "python-module-name-relaxed"},
"$comment": "https://setuptools.pypa.io/en/latest/userguide/package_discovery.html",
"description": "**DEPRECATED**: use implicit namespaces instead (:pep:`420`)."
},
"py-modules": {
"description": "Modules that setuptools will manipulate",
"type": "array",
"items": {"type": "string", "format": "python-module-name"},
"items": {"type": "string", "format": "python-module-name-relaxed"},
"$comment": "TODO: clarify the relationship with ``packages``"
},
"data-files": {
Expand Down Expand Up @@ -250,7 +250,7 @@
"description": "Valid package name (importable or :pep:`561`).",
"type": "string",
"anyOf": [
{"type": "string", "format": "python-module-name"},
{"type": "string", "format": "python-module-name-relaxed"},
{"type": "string", "format": "pep561-stub-name"}
]
},
Expand Down
27 changes: 27 additions & 0 deletions setuptools/tests/config/test_apply_pyprojecttoml.py
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,33 @@ def test_default_patterns(self, tmp_path):
assert set(dist.metadata.license_files) == {*license_files, "LICENSE.txt"}


class TestPyModules:
# https://github.com/pypa/setuptools/issues/4316

def dist(self, name):
toml_config = f"""
[project]
name = "test"
version = "42.0"
[tool.setuptools]
py-modules = [{name!r}]
"""
pyproject = Path("pyproject.toml")
pyproject.write_text(cleandoc(toml_config), encoding="utf-8")
return pyprojecttoml.apply_configuration(Distribution({}), pyproject)

@pytest.mark.parametrize("module", ["pip-run", "abc-d.λ-xyz-e"])
def test_valid_module_name(self, tmp_path, monkeypatch, module):
monkeypatch.chdir(tmp_path)
assert module in self.dist(module).py_modules

@pytest.mark.parametrize("module", ["pip run", "-pip-run", "pip-run-stubs"])
def test_invalid_module_name(self, tmp_path, monkeypatch, module):
monkeypatch.chdir(tmp_path)
with pytest.raises(ValueError, match="py-modules"):
self.dist(module).py_modules


class TestDeprecatedFields:
def test_namespace_packages(self, tmp_path):
pyproject = tmp_path / "pyproject.toml"
Expand Down
2 changes: 1 addition & 1 deletion tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ commands =
[testenv:generate-validation-code]
skip_install = True
deps =
validate-pyproject[all]==0.18
validate-pyproject[all]==0.19
commands =
python -m tools.generate_validation_code

Expand Down

0 comments on commit 8bd9308

Please sign in to comment.