Skip to content

Commit 2744240

Browse files
authored
Validate package name of sdist/wheel/editable to be installed (#33)
1 parent 1e6d619 commit 2744240

File tree

4 files changed

+32
-32
lines changed

4 files changed

+32
-32
lines changed

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ dynamic = [
3838
"version",
3939
]
4040
dependencies = [
41+
"packaging>=23.2",
4142
"tox<5,>=4.14",
4243
"uv<1,>=0.1.15",
4344
]

src/tox_uv/_installer.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from typing import TYPE_CHECKING, Any, Sequence, cast
88

99
from packaging.requirements import Requirement
10+
from packaging.utils import parse_sdist_filename, parse_wheel_filename
1011
from tox.config.of_type import ConfigDynamicDefinition
1112
from tox.config.types import Command
1213
from tox.execute.request import StdinSource
@@ -85,7 +86,8 @@ def _install_list_of_deps( # noqa: C901
8586
groups["req"].append(str(arg)) # pragma: no cover
8687
elif isinstance(arg, (WheelPackage, SdistPackage, EditablePackage)):
8788
groups["req"].extend(str(i) for i in arg.deps)
88-
name = arg.path.name.split("-")[0]
89+
parser = parse_sdist_filename if isinstance(arg, SdistPackage) else parse_wheel_filename
90+
name, *_ = parser(arg.path.name)
8991
groups["pkg"].append(f"{name}@{arg.path}")
9092
elif isinstance(arg, EditableLegacyPackage):
9193
groups["req"].extend(str(i) for i in arg.deps)

tests/demo_pkg_inline/build.py

Lines changed: 20 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,20 @@
1-
"""
2-
Please keep this file Python 2.7 compatible.
3-
See https://tox.readthedocs.io/en/rewrite/development.html#code-style-guide
4-
"""
5-
61
from __future__ import annotations
72

83
import os
4+
import re
95
import sys
106
import tarfile
117
from pathlib import Path
128
from textwrap import dedent
139
from zipfile import ZipFile
1410

15-
name = "demo_pkg_inline"
16-
pkg_name = name.replace("_", "-")
17-
11+
name = "demo-pkg-inline" if os.environ.get("WITH_DASH") else "demo_pkg_inline"
12+
name_in_artifact = re.sub(r"[^\w\d.]+", "_", name, flags=re.UNICODE) # per PEP-427
1813
version = "1.0.0"
19-
dist_info = f"{name}-{version}.dist-info"
20-
logic = f"{name}/__init__.py"
21-
plugin = f"{name}/example_plugin.py"
14+
dist_info = f"{name_in_artifact}-{version}.dist-info"
15+
module = name_in_artifact
16+
logic = f"{module}/__init__.py"
17+
plugin = f"{module}/example_plugin.py"
2218
entry_points = f"{dist_info}/entry_points.txt"
2319
metadata = f"{dist_info}/METADATA"
2420
wheel = f"{dist_info}/WHEEL"
@@ -42,37 +38,33 @@ def tox_register_tox_env(register: ToxEnvRegister) -> None:
4238
register.add_run_env(ExampleVirtualEnvRunner)
4339
""",
4440
}
41+
4542
metadata_files = {
4643
entry_points: f"""
4744
[tox]
48-
example = {name}.example_plugin""",
49-
metadata: """
45+
example = {module}.example_plugin""",
46+
metadata: f"""
5047
Metadata-Version: 2.1
51-
Name: {}
52-
Version: {}
48+
Name: {name}
49+
Version: {version}
5350
Summary: UNKNOWN
5451
Home-page: UNKNOWN
5552
Author: UNKNOWN
5653
Author-email: UNKNOWN
5754
License: UNKNOWN
58-
{}
5955
Platform: UNKNOWN
6056
6157
UNKNOWN
62-
""".format(
63-
pkg_name,
64-
version,
65-
"\n ".join(os.environ.get("METADATA_EXTRA", "").split("\n")),
66-
),
58+
""",
6759
wheel: f"""
6860
Wheel-Version: 1.0
6961
Generator: {name}-{version}
7062
Root-Is-Purelib: true
7163
Tag: py{sys.version_info[0]}-none-any
7264
""",
73-
f"{dist_info}/top_level.txt": name,
65+
f"{dist_info}/top_level.txt": module,
7466
record: f"""
75-
{name}/__init__.py,,
67+
{module}/__init__.py,,
7668
{dist_info}/METADATA,,
7769
{dist_info}/WHEEL,,
7870
{dist_info}/top_level.txt,,
@@ -86,18 +78,17 @@ def build_wheel(
8678
config_settings: dict[str, str] | None = None, # noqa: ARG001
8779
metadata_directory: str | None = None,
8880
) -> str:
89-
base_name = f"{name}-{version}-py{sys.version_info[0]}-none-any.whl"
81+
base_name = f"{name_in_artifact}-{version}-py{sys.version_info[0]}-none-any.whl"
9082
path = Path(wheel_directory) / base_name
9183
with ZipFile(str(path), "w") as zip_file_handler:
9284
for arc_name, data in content.items(): # pragma: no branch
9385
zip_file_handler.writestr(arc_name, dedent(data).strip())
9486
if metadata_directory is not None:
9587
for sub_directory, _, filenames in os.walk(metadata_directory):
9688
for filename in filenames:
97-
zip_file_handler.write(
98-
str(Path(metadata_directory) / sub_directory / filename),
99-
str(Path(sub_directory) / filename),
100-
)
89+
src = str(Path(metadata_directory) / sub_directory / filename)
90+
dest = str(Path(sub_directory) / filename)
91+
zip_file_handler.write(src, dest)
10192
else:
10293
for arc_name, data in metadata_files.items():
10394
zip_file_handler.writestr(arc_name, dedent(data).strip())
@@ -118,7 +109,7 @@ def build_editable(
118109

119110

120111
def build_sdist(sdist_directory: str, config_settings: dict[str, str] | None = None) -> str: # noqa: ARG001
121-
result = f"{name}-{version}.tar.gz" # pragma: win32 cover
112+
result = f"{name_in_artifact}-{version}.tar.gz" # pragma: win32 cover
122113
with tarfile.open(str(Path(sdist_directory) / result), "w:gz") as tar: # pragma: win32 cover
123114
root = Path(__file__).parent # pragma: win32 cover
124115
tar.add(str(root / "build.py"), "build.py") # pragma: win32 cover

tests/test_tox_uv_package.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,15 @@ def test_uv_package_use_default_from_file(tox_project: ToxProjectCreator) -> Non
2323
result.assert_success()
2424

2525

26+
@pytest.mark.parametrize("with_dash", [True, False], ids=["name_dash", "name_underscore"])
2627
@pytest.mark.parametrize("package", ["sdist", "wheel", "editable"])
27-
def test_uv_package_editable(tox_project: ToxProjectCreator, package: str, demo_pkg_inline: Path) -> None:
28-
project = tox_project({"tox.ini": f"[testenv]\npackage={package}"}, base=demo_pkg_inline)
28+
def test_uv_package_artifact(
29+
tox_project: ToxProjectCreator, package: str, demo_pkg_inline: Path, with_dash: bool
30+
) -> None:
31+
ini = f"[testenv]\npackage={package}"
32+
if with_dash:
33+
ini += "\n[testenv:.pkg]\nset_env = WITH_DASH = 1"
34+
project = tox_project({"tox.ini": ini}, base=demo_pkg_inline)
2935
result = project.run()
3036
result.assert_success()
3137

0 commit comments

Comments
 (0)