Skip to content

Commit 533ffb5

Browse files
dimblebyradoering
authored andcommitted
normalize source distribution names
1 parent f5b45de commit 533ffb5

File tree

8 files changed

+71
-23
lines changed

8 files changed

+71
-23
lines changed

src/poetry/core/masonry/builders/sdist.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
from poetry.core.masonry.builders.builder import Builder
2020
from poetry.core.masonry.builders.builder import BuildIncludeFile
21+
from poetry.core.masonry.utils.helpers import distribution_name
2122

2223

2324
if TYPE_CHECKING:
@@ -65,7 +66,8 @@ def build(
6566
if not target_dir.exists():
6667
target_dir.mkdir(parents=True)
6768

68-
target = target_dir / f"{self._package.pretty_name}-{self._meta.version}.tar.gz"
69+
name = distribution_name(self._package.name)
70+
target = target_dir / f"{name}-{self._meta.version}.tar.gz"
6971
gz = GzipFile(target.as_posix(), mode="wb", mtime=0)
7072
tar = tarfile.TarFile(
7173
target.as_posix(), mode="w", fileobj=gz, format=tarfile.PAX_FORMAT

src/poetry/core/masonry/builders/wheel.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,14 @@
2424
from poetry.core.constraints.version import parse_constraint
2525
from poetry.core.masonry.builders.builder import Builder
2626
from poetry.core.masonry.builders.sdist import SdistBuilder
27-
from poetry.core.masonry.utils.helpers import escape_name
27+
from poetry.core.masonry.utils.helpers import distribution_name
2828
from poetry.core.masonry.utils.helpers import normalize_file_permissions
2929
from poetry.core.masonry.utils.package_include import PackageInclude
3030

3131

3232
if TYPE_CHECKING:
33+
from packaging.utils import NormalizedName
34+
3335
from poetry.core.poetry import Poetry
3436

3537
wheel_file_template = """\
@@ -280,7 +282,7 @@ def wheel_data_folder(self) -> str:
280282

281283
@property
282284
def wheel_filename(self) -> str:
283-
name = escape_name(self._package.pretty_name)
285+
name = distribution_name(self._package.name)
284286
version = self._meta.version
285287
return f"{name}-{version}-{self.tag}.whl"
286288

@@ -289,9 +291,8 @@ def supports_python2(self) -> bool:
289291
parse_constraint(">=2.0.0 <3.0.0")
290292
)
291293

292-
def dist_info_name(self, distribution: str, version: str) -> str:
293-
escaped_name = escape_name(distribution)
294-
294+
def dist_info_name(self, name: NormalizedName, version: str) -> str:
295+
escaped_name = distribution_name(name)
295296
return f"{escaped_name}-{version}.dist-info"
296297

297298
@property

src/poetry/core/masonry/utils/helpers.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,17 @@
33
import re
44
import warnings
55

6+
from typing import TYPE_CHECKING
7+
from typing import NewType
8+
from typing import cast
9+
10+
11+
if TYPE_CHECKING:
12+
from packaging.utils import NormalizedName
13+
14+
15+
DistributionName = NewType("DistributionName", str)
16+
617

718
def normalize_file_permissions(st_mode: int) -> int:
819
"""
@@ -39,4 +50,34 @@ def escape_name(name: str) -> str:
3950
Escaped wheel name as specified in https://packaging.python.org/en/latest/specifications/binary-distribution-format/#escaping-and-unicode.
4051
This function should only be used for the generation of artifact names, and not to normalize or filter existing artifact names.
4152
"""
53+
warnings.warn(
54+
"escape_name() is deprecated. Use packaging.utils.canonicalize_name() and"
55+
" distribution_name() instead.",
56+
DeprecationWarning,
57+
stacklevel=2,
58+
)
4259
return re.sub(r"[-_.]+", "_", name, flags=re.UNICODE).lower()
60+
61+
62+
def distribution_name(name: NormalizedName) -> DistributionName:
63+
"""
64+
A normalized name, but with "-" replaced by "_". This is used in various places:
65+
66+
https://packaging.python.org/en/latest/specifications/binary-distribution-format/#escaping-and-unicode
67+
68+
In distribution names ... This is equivalent to PEP 503 normalisation followed by
69+
replacing - with _.
70+
71+
https://packaging.python.org/en/latest/specifications/source-distribution-format/#source-distribution-file-name
72+
73+
... {name} is normalised according to the same rules as for binary distributions
74+
75+
https://packaging.python.org/en/latest/specifications/recording-installed-packages/#the-dist-info-directory
76+
77+
This directory is named as {name}-{version}.dist-info, with name and version fields
78+
corresponding to Core metadata specifications. Both fields must be normalized
79+
(see PEP 503 and PEP 440 for the definition of normalization for each field
80+
respectively), and replace dash (-) characters with underscore (_) characters ...
81+
"""
82+
distribution_name = name.replace("-", "_")
83+
return cast(DistributionName, distribution_name)

tests/fixtures/simple_project/dist/simple-project-1.2.3.tar.gz renamed to tests/fixtures/simple_project/dist/simple_project-1.2.3.tar.gz

File renamed without changes.

tests/integration/test_pep517.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ def test_pep517_build_sdist(
4848
outdir=str(temporary_directory),
4949
distributions=["sdist"],
5050
)
51-
distributions = list(temporary_directory.glob("poetry-core-*.tar.gz"))
51+
distributions = list(temporary_directory.glob("poetry_core-*.tar.gz"))
5252
assert len(distributions) == 1
5353

5454

tests/masonry/builders/test_complete.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -427,7 +427,7 @@ def test_module_src() -> None:
427427
builder = Builder(Factory().create_poetry(module_path))
428428
builder.build(fmt="all")
429429

430-
sdist = module_path / "dist" / "module-src-0.1.tar.gz"
430+
sdist = module_path / "dist" / "module_src-0.1.tar.gz"
431431

432432
assert sdist.exists()
433433

@@ -451,7 +451,7 @@ def test_package_src() -> None:
451451
builder = Builder(Factory().create_poetry(module_path))
452452
builder.build(fmt="all")
453453

454-
sdist = module_path / "dist" / "package-src-0.1.tar.gz"
454+
sdist = module_path / "dist" / "package_src-0.1.tar.gz"
455455

456456
assert sdist.exists()
457457

@@ -476,7 +476,7 @@ def test_split_source() -> None:
476476
builder = Builder(Factory().create_poetry(module_path))
477477
builder.build(fmt="all")
478478

479-
sdist = module_path / "dist" / "split-source-0.1.tar.gz"
479+
sdist = module_path / "dist" / "split_source-0.1.tar.gz"
480480

481481
assert sdist.exists()
482482

@@ -522,7 +522,7 @@ def test_package_with_include(mocker: MockerFixture) -> None:
522522
builder = Builder(Factory().create_poetry(module_path))
523523
builder.build(fmt="all")
524524

525-
sdist = fixtures_dir / "with-include" / "dist" / "with-include-1.2.3.tar.gz"
525+
sdist = fixtures_dir / "with-include" / "dist" / "with_include-1.2.3.tar.gz"
526526

527527
assert sdist.exists()
528528

@@ -589,7 +589,7 @@ def test_respect_format_for_explicit_included_files() -> None:
589589
builder = Builder(Factory().create_poetry(module_path))
590590
builder.build(fmt="all")
591591

592-
sdist = module_path / "dist" / "exclude-whl-include-sdist-0.1.0.tar.gz"
592+
sdist = module_path / "dist" / "exclude_whl_include_sdist-0.1.0.tar.gz"
593593

594594
assert sdist.exists()
595595

tests/masonry/builders/test_sdist.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ def test_package() -> None:
255255
builder = SdistBuilder(poetry)
256256
builder.build()
257257

258-
sdist = fixtures_dir / "complete" / "dist" / "my-package-1.2.3.tar.gz"
258+
sdist = fixtures_dir / "complete" / "dist" / "my_package-1.2.3.tar.gz"
259259

260260
assert sdist.exists()
261261

@@ -272,7 +272,7 @@ def test_sdist_reproducibility() -> None:
272272
builder = SdistBuilder(poetry)
273273
builder.build()
274274

275-
sdist = fixtures_dir / "complete" / "dist" / "my-package-1.2.3.tar.gz"
275+
sdist = fixtures_dir / "complete" / "dist" / "my_package-1.2.3.tar.gz"
276276

277277
assert sdist.exists()
278278

@@ -388,7 +388,7 @@ def test_with_src_module_file() -> None:
388388

389389
builder.build()
390390

391-
sdist = fixtures_dir / "source_file" / "dist" / "module-src-0.1.tar.gz"
391+
sdist = fixtures_dir / "source_file" / "dist" / "module_src-0.1.tar.gz"
392392

393393
assert sdist.exists()
394394

@@ -413,7 +413,7 @@ def test_with_src_module_dir() -> None:
413413

414414
builder.build()
415415

416-
sdist = fixtures_dir / "source_package" / "dist" / "package-src-0.1.tar.gz"
416+
sdist = fixtures_dir / "source_package" / "dist" / "package_src-0.1.tar.gz"
417417

418418
assert sdist.exists()
419419

@@ -465,7 +465,7 @@ def get_ignored_files(self, folder: Path | None = None) -> list[str]:
465465
builder.build()
466466

467467
sdist = (
468-
fixtures_dir / "default_with_excluded_data" / "dist" / "my-package-1.2.3.tar.gz"
468+
fixtures_dir / "default_with_excluded_data" / "dist" / "my_package-1.2.3.tar.gz"
469469
)
470470

471471
assert sdist.exists()
@@ -499,7 +499,7 @@ def test_src_excluded_nested_data() -> None:
499499
builder = SdistBuilder(poetry)
500500
builder.build()
501501

502-
sdist = module_path / "dist" / "my-package-1.2.3.tar.gz"
502+
sdist = module_path / "dist" / "my_package-1.2.3.tar.gz"
503503

504504
assert sdist.exists()
505505

@@ -554,7 +554,7 @@ def test_includes() -> None:
554554

555555
builder.build()
556556

557-
sdist = fixtures_dir / "with-include" / "dist" / "with-include-1.2.3.tar.gz"
557+
sdist = fixtures_dir / "with-include" / "dist" / "with_include-1.2.3.tar.gz"
558558

559559
assert sdist.exists()
560560

@@ -574,7 +574,7 @@ def test_includes_with_inline_table() -> None:
574574
fixtures_dir
575575
/ "with_include_inline_table"
576576
/ "dist"
577-
/ "with-include-1.2.3.tar.gz"
577+
/ "with_include-1.2.3.tar.gz"
578578
)
579579

580580
assert sdist.exists()
@@ -608,7 +608,7 @@ def test_sdist_package_pep_561_stub_only() -> None:
608608
builder = SdistBuilder(poetry)
609609
builder.build()
610610

611-
sdist = root / "dist" / "pep-561-stubs-0.1.tar.gz"
611+
sdist = root / "dist" / "pep_561_stubs-0.1.tar.gz"
612612

613613
assert sdist.exists()
614614

@@ -626,7 +626,7 @@ def test_sdist_disable_setup_py() -> None:
626626
builder = SdistBuilder(poetry)
627627
builder.build()
628628

629-
sdist = module_path / "dist" / "my-package-1.2.3.tar.gz"
629+
sdist = module_path / "dist" / "my_package-1.2.3.tar.gz"
630630

631631
assert sdist.exists()
632632

tests/masonry/utils/test_helpers.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
from __future__ import annotations
22

3+
import warnings
4+
35
import pytest
46

57
from poetry.core.masonry.utils.helpers import escape_name
@@ -16,4 +18,6 @@
1618
],
1719
)
1820
def test_escape_name(name: str, expected: str) -> None:
19-
assert escape_name(name) == expected
21+
with warnings.catch_warnings():
22+
warnings.simplefilter("ignore")
23+
assert escape_name(name) == expected

0 commit comments

Comments
 (0)