Skip to content

Commit

Permalink
Support compatible release versions
Browse files Browse the repository at this point in the history
  • Loading branch information
srittau committed Oct 10, 2024
1 parent e8ded86 commit 84a4b39
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 8 deletions.
4 changes: 2 additions & 2 deletions stub_uploader/build_wheel.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@
`{distribution}`.
This version of `{stub_distribution}` aims to provide accurate annotations
for `{distribution}=={typeshed_version_pin}`.
for `{distribution}{typeshed_version_spec}`.
The source for this package can be found at
https://github.com/python/typeshed/tree/main/stubs/{distribution}. All fixes for
types and metadata should be contributed there.
Expand Down Expand Up @@ -381,7 +381,7 @@ def generate_long_description(
distribution=distribution,
formatted_distribution=formatted_distribution,
stub_distribution=metadata.stub_distribution,
typeshed_version_pin=metadata.version_spec,
typeshed_version_spec=metadata.version_spec,
)
)
if extra_description:
Expand Down
6 changes: 3 additions & 3 deletions stub_uploader/get_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
from typing import Any

import requests
from packaging.specifiers import SpecifierSet
from packaging.specifiers import Specifier, SpecifierSet
from packaging.version import Version
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
Expand Down Expand Up @@ -51,7 +51,7 @@ def ensure_specificity(ver: list[int], specificity: int) -> None:


def compute_stub_version(
version_spec: str, published_versions: list[Version], date: datetime.date
version_spec: Specifier, published_versions: list[Version], date: datetime.date
) -> Version:
# The most important postcondition is that the incremented version is greater than
# all published versions. This ensures that users who don't pin get the most
Expand All @@ -65,7 +65,7 @@ def compute_stub_version(
# 1.2.post3 -> 1.2.3
# This is necessary, since structured post versions (e.g. `1.2.post3.4`) are not
# supported by PEP 440.
version_base = Version(version_spec.removesuffix(".*"))
version_base = Version(version_spec.version.removesuffix(".*"))
if max_published.epoch > 0 or version_base.epoch > 0:
raise NotImplementedError("Epochs in versions are not supported")
elif version_base.is_prerelease or version_base.is_devrelease:
Expand Down
8 changes: 6 additions & 2 deletions stub_uploader/metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,16 @@ def stub_distribution(self) -> str:
return distribution

@property
def version_spec(self) -> str:
def version_spec(self) -> Specifier:
# The "version" field in METADATA.toml isn't actually a version, it's more
# like a specifier, e.g. we allow it to contain wildcards.
version = self.data["version"]
assert isinstance(version, str)
return version
if version[0].isdigit():
version = f"=={version}"
spec = Specifier(version)
assert spec.operator in {"==", "~="}
return spec

@property
def _unvalidated_requires(self) -> list[Requirement]:
Expand Down
17 changes: 16 additions & 1 deletion tests/test_unit.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from typing import Any

import pytest
from packaging.specifiers import Specifier
from packaging.version import Version

from stub_uploader.build_wheel import collect_package_data
Expand Down Expand Up @@ -44,7 +45,10 @@ def test_ensure_specificity() -> None:

def _stub_ver(ver: str, published: list[str]) -> str:
published_vers = [Version(v) for v in published]
return str(compute_stub_version(ver, published_vers, TODAY))
if ver[0].isdigit():
ver = f"=={ver}"
spec = Specifier(ver)
return str(compute_stub_version(spec, published_vers, TODAY))


def test_compute_stub_version() -> None:
Expand All @@ -53,6 +57,8 @@ def test_compute_stub_version() -> None:
assert _stub_ver("1", empty_list) == f"1.0.0.{TODAY_V}"
assert _stub_ver("1.2", empty_list) == f"1.2.0.{TODAY_V}"
assert _stub_ver("1.2.post3", empty_list) == f"1.2.3.{TODAY_V}"
assert _stub_ver("~=1.2", empty_list) == f"1.2.0.{TODAY_V}"
assert _stub_ver("~=1.2.3", empty_list) == f"1.2.3.{TODAY_V}"

# published greater than version spec
assert _stub_ver("1.1", ["1.2"]) == f"1.2.0.{TODAY_V}"
Expand All @@ -62,6 +68,8 @@ def test_compute_stub_version() -> None:
assert _stub_ver("1.4.40", ["1.4.50"]) == f"1.4.50.{TODAY_V}"
assert _stub_ver("1.4.0.40", ["1.4.0.50"]) == f"1.4.0.50.{TODAY_V}"
assert _stub_ver("1.2.post3", ["1.2.3.4"]) == f"1.2.3.{TODAY_V}"
assert _stub_ver("~=1.2", ["1.3.0.4"]) == f"1.3.0.{TODAY_V}"
assert _stub_ver("~=1.2.3", ["1.2.4.40"]) == f"1.2.4.{TODAY_V}"

# published less than version spec
assert _stub_ver("1.2", ["1.1.0.4"]) == f"1.2.0.{TODAY_V}"
Expand All @@ -73,13 +81,16 @@ def test_compute_stub_version() -> None:
assert _stub_ver("1.2.3.4", ["1.1.0.17"]) == f"1.2.3.4.{TODAY_V}"
assert _stub_ver("1.2.post3", ["1.1.0.17"]) == f"1.2.3.{TODAY_V}"
assert _stub_ver("1.2.3", ["1.1.0.21000101"]) == f"1.2.3.{TODAY_V}"
assert _stub_ver("~=1.2", ["1.1.0.40"]) == f"1.2.0.{TODAY_V}"
assert _stub_ver("~=1.2.3", ["1.2.2.40"]) == f"1.2.3.{TODAY_V}"

# published equals version spec
assert _stub_ver("1.1", ["1.1"]) == f"1.1.0.{TODAY_V}"
assert _stub_ver("1.1", ["1.1.0.19991204"]) == f"1.1.0.{TODAY_V}"
assert _stub_ver("1.1", ["1.1.3.19991204"]) == f"1.1.3.{TODAY_V}"
assert _stub_ver("1.2.3.4", ["1.2.3.4.19991204"]) == f"1.2.3.4.{TODAY_V}"
assert _stub_ver("1.2.3.4.5", ["1.2.3.4.5"]) == f"1.2.3.4.5.{TODAY_V}"
assert _stub_ver("~=1.2.3", ["1.2.3.40"]) == f"1.2.3.{TODAY_V}"

# test with multiple published versions
assert (
Expand All @@ -95,6 +106,10 @@ def test_compute_stub_version() -> None:
_stub_ver("1.2.*", [f"1.1.0.{TODAY_V}", f"1.1.0.{TOMORROW_V}"])
== f"1.2.0.{TODAY_V}"
)
assert (
_stub_ver("~=1.2.3", [f"1.2.3.{TODAY_V}", f"1.2.3.{TOMORROW_V}"])
== f"1.2.3.{IN_TWO_DAYS_V}"
)


def test_collect_package_data() -> None:
Expand Down

0 comments on commit 84a4b39

Please sign in to comment.