Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't normalize or escape versions #469

Merged
merged 3 commits into from
Sep 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/poetry/core/masonry/builders/sdist.py
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ def build_setup(self) -> bytes:
return SETUP.format(
before="\n".join(before),
name=str(self._meta.name),
version=str(self._meta.version),
version=self._meta.version,
description=str(self._meta.summary),
long_description=str(self._meta.description),
author=str(self._meta.author),
Expand Down
6 changes: 2 additions & 4 deletions src/poetry/core/masonry/builders/wheel.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
from poetry.core.masonry.builders.builder import Builder
from poetry.core.masonry.builders.sdist import SdistBuilder
from poetry.core.masonry.utils.helpers import escape_name
from poetry.core.masonry.utils.helpers import escape_version
from poetry.core.masonry.utils.helpers import normalize_file_permissions
from poetry.core.masonry.utils.package_include import PackageInclude
from poetry.core.semver.helpers import parse_constraint
Expand Down Expand Up @@ -282,7 +281,7 @@ def wheel_data_folder(self) -> str:
@property
def wheel_filename(self) -> str:
name = escape_name(self._package.pretty_name)
version = escape_version(self._meta.version)
version = self._meta.version
return f"{name}-{version}-{self.tag}.whl"

def supports_python2(self) -> bool:
Expand All @@ -292,9 +291,8 @@ def supports_python2(self) -> bool:

def dist_info_name(self, distribution: str, version: str) -> str:
escaped_name = escape_name(distribution)
escaped_version = escape_version(version)

return f"{escaped_name}-{escaped_version}.dist-info"
return f"{escaped_name}-{version}.dist-info"

@property
def tag(self) -> str:
Expand Down
3 changes: 1 addition & 2 deletions src/poetry/core/masonry/metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,12 @@ class Metadata:
def from_package(cls, package: Package) -> Metadata:
from packaging.utils import canonicalize_name

from poetry.core.utils.helpers import normalize_version
from poetry.core.version.helpers import format_python_constraint

meta = cls()

meta.name = canonicalize_name(package.name)
meta.version = normalize_version(package.version.text)
meta.version = package.version.to_string()
meta.summary = package.description
if package.readmes:
descriptions = []
Expand Down
6 changes: 6 additions & 0 deletions src/poetry/core/masonry/utils/helpers.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from __future__ import annotations

import re
import warnings


def normalize_file_permissions(st_mode: int) -> int:
Expand All @@ -25,6 +26,11 @@ def escape_version(version: str) -> str:
the escaping specification in :pep:`427#escaping-and-unicode`
because this conflicts with :pep:`440#local-version-identifiers`.
"""
warnings.warn(
"escape_version() is deprecated. Use Version.parse().to_string() instead.",
DeprecationWarning,
stacklevel=2,
)
return re.sub(r"[^\w\d.+]+", "_", version, flags=re.UNICODE)


Expand Down
6 changes: 6 additions & 0 deletions src/poetry/core/utils/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import stat
import tempfile
import unicodedata
import warnings

from contextlib import contextmanager
from pathlib import Path
Expand All @@ -25,6 +26,11 @@ def module_name(name: str) -> str:


def normalize_version(version: str) -> str:
warnings.warn(
"normalize_version() is deprecated. Use Version.parse().to_string() instead.",
DeprecationWarning,
stacklevel=2,
)
return PEP440Version.parse(version).to_string()


Expand Down
2 changes: 2 additions & 0 deletions tests/masonry/builders/fixtures/epoch/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Epoch
=====
3 changes: 3 additions & 0 deletions tests/masonry/builders/fixtures/epoch/epoch.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
"""Example module"""

__version__ = "1!2.0"
12 changes: 12 additions & 0 deletions tests/masonry/builders/fixtures/epoch/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[tool.poetry]
name = "epoch"
version = "1!2.0"
description = "Some description."
authors = [
"Sébastien Eustace <sebastien@eustace.io>"
]
license = "MIT"

readme = "README.rst"

homepage = "https://python-poetry.org/"
12 changes: 12 additions & 0 deletions tests/masonry/builders/test_wheel.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,18 @@ def test_wheel_prerelease() -> None:
assert whl.exists()


def test_wheel_epoch() -> None:
module_path = fixtures_dir / "epoch"
WheelBuilder.make(Factory().create_poetry(module_path))

whl = module_path / "dist" / "epoch-1!2.0-py2.py3-none-any.whl"

assert whl.exists()

with zipfile.ZipFile(str(whl)) as z:
assert "epoch-1!2.0.dist-info/METADATA" in z.namelist()


def test_wheel_excluded_data() -> None:
module_path = fixtures_dir / "default_with_excluded_data_toml"
WheelBuilder.make(Factory().create_poetry(module_path))
Expand Down
18 changes: 0 additions & 18 deletions tests/masonry/utils/test_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,6 @@
import pytest

from poetry.core.masonry.utils.helpers import escape_name
from poetry.core.masonry.utils.helpers import escape_version


@pytest.mark.parametrize(
"version,expected",
[
("1.2.3", "1.2.3"),
("1.2.3_1", "1.2.3_1"),
("1.2.3-1", "1.2.3_1"),
("1.2.3-1", "1.2.3_1"),
("2022.2", "2022.2"),
("12.20.12-----451---14-1-4-41", "12.20.12_451_14_1_4_41"),
("1.0b2.dev1", "1.0b2.dev1"),
("1.0+abc.7", "1.0+abc.7"),
],
)
def test_escape_version(version: str, expected: str) -> None:
assert escape_version(version) == expected


@pytest.mark.parametrize(
Expand Down
70 changes: 70 additions & 0 deletions tests/semver/test_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -288,3 +288,73 @@ def test_difference() -> None:
assert (
v.difference(VersionRange(Version.parse("1.4.0"), Version.parse("3.0.0"))) == v
)


@pytest.mark.parametrize(
"version,normalized_version",
[
( # already normalized version
"1!2.3.4.5.6a7.post8.dev9+local1.123.abc",
"1!2.3.4.5.6a7.post8.dev9+local1.123.abc",
),
# PEP 440 Normalization
# Case sensitivity
("1.1RC1", "1.1rc1"),
# Integer Normalization
("00", "0"),
("09000", "9000"),
("1.0+foo0100", "1.0+foo0100"),
# Pre-release separators
("1.1.a1", "1.1a1"),
("1.1-a1", "1.1a1"),
("1.1_a1", "1.1a1"),
("1.1a.1", "1.1a1"),
("1.1a-1", "1.1a1"),
("1.1a_1", "1.1a1"),
# Pre-release spelling
("1.1alpha1", "1.1a1"),
("1.1beta2", "1.1b2"),
("1.1c3", "1.1rc3"),
("1.1pre4", "1.1rc4"),
("1.1preview5", "1.1rc5"),
# Implicit pre-release number
("1.2a", "1.2a0"),
# Post release separators
("1.2.post2", "1.2.post2"),
("1.2-post2", "1.2.post2"),
("1.2_post2", "1.2.post2"),
("1.2post.2", "1.2.post2"),
("1.2post-2", "1.2.post2"),
("1.2post_2", "1.2.post2"),
# Post release spelling
("1.0-r4", "1.0.post4"),
("1.0-rev4", "1.0.post4"),
# Implicit post release number
("1.2.post", "1.2.post0"),
# Implicit post releases
("1.0-1", "1.0.post1"),
# Development release separators
("1.2.dev2", "1.2.dev2"),
("1.2-dev2", "1.2.dev2"),
("1.2_dev2", "1.2.dev2"),
("1.2dev.2", "1.2.dev2"),
("1.2dev-2", "1.2.dev2"),
("1.2dev_2", "1.2.dev2"),
# Implicit development release number
("1.2.dev", "1.2.dev0"),
# Local version segments
("1.0+ubuntu-1", "1.0+ubuntu.1"),
("1.0+ubuntu_1", "1.0+ubuntu.1"),
# Preceding v character
("v1.0", "1.0"),
# Leading and Trailing Whitespace
(" 1.0 ", "1.0"),
("\t1.0\t", "1.0"),
("\n1.0\n", "1.0"),
("\r\n1.0\r\n", "1.0"),
("\f1.0\f", "1.0"),
("\v1.0\v", "1.0"),
],
)
def test_to_string_normalizes(version: str, normalized_version: str) -> None:
assert Version.parse(version).to_string() == normalized_version
71 changes: 0 additions & 71 deletions tests/utils/test_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,82 +8,11 @@
import pytest

from poetry.core.utils.helpers import combine_unicode
from poetry.core.utils.helpers import normalize_version
from poetry.core.utils.helpers import parse_requires
from poetry.core.utils.helpers import readme_content_type
from poetry.core.utils.helpers import temporary_directory


@pytest.mark.parametrize(
"version,normalized_version",
[
( # already normalized version
"1!2.3.4.5.6a7.post8.dev9+local1.123.abc",
"1!2.3.4.5.6a7.post8.dev9+local1.123.abc",
),
# PEP 440 Normalization
# Case sensitivity
("1.1RC1", "1.1rc1"),
# Integer Normalization
("00", "0"),
("09000", "9000"),
("1.0+foo0100", "1.0+foo0100"),
# Pre-release separators
("1.1.a1", "1.1a1"),
("1.1-a1", "1.1a1"),
("1.1_a1", "1.1a1"),
("1.1a.1", "1.1a1"),
("1.1a-1", "1.1a1"),
("1.1a_1", "1.1a1"),
# Pre-release spelling
("1.1alpha1", "1.1a1"),
("1.1beta2", "1.1b2"),
("1.1c3", "1.1rc3"),
("1.1pre4", "1.1rc4"),
("1.1preview5", "1.1rc5"),
# Implicit pre-release number
("1.2a", "1.2a0"),
# Post release separators
("1.2.post2", "1.2.post2"),
("1.2-post2", "1.2.post2"),
("1.2_post2", "1.2.post2"),
("1.2post.2", "1.2.post2"),
("1.2post-2", "1.2.post2"),
("1.2post_2", "1.2.post2"),
# Post release spelling
("1.0-r4", "1.0.post4"),
("1.0-rev4", "1.0.post4"),
# Implicit post release number
("1.2.post", "1.2.post0"),
# Implicit post releases
("1.0-1", "1.0.post1"),
# Development release separators
("1.2.dev2", "1.2.dev2"),
("1.2-dev2", "1.2.dev2"),
("1.2_dev2", "1.2.dev2"),
("1.2dev.2", "1.2.dev2"),
("1.2dev-2", "1.2.dev2"),
("1.2dev_2", "1.2.dev2"),
# Implicit development release number
("1.2.dev", "1.2.dev0"),
# Local version segments
("1.0+ubuntu-1", "1.0+ubuntu.1"),
("1.0+ubuntu_1", "1.0+ubuntu.1"),
# Preceding v character
("v1.0", "1.0"),
# Leading and Trailing Whitespace
(" 1.0 ", "1.0"),
("\t1.0\t", "1.0"),
("\n1.0\n", "1.0"),
("\r\n1.0\r\n", "1.0"),
("\f1.0\f", "1.0"),
("\v1.0\v", "1.0"),
],
)
def test_normalize_version(version: str, normalized_version: str) -> None:
assert normalize_version(version) == normalized_version


def test_parse_requires() -> None:
requires = """\
jsonschema>=2.6.0.0,<3.0.0.0
Expand Down