Skip to content

Commit 529ef0d

Browse files
committed
[stubsabot] Move obsolete data into ts_utils.metadata
Inspired: python#14401 (comment)
1 parent 82e2e9c commit 529ef0d

File tree

2 files changed

+27
-27
lines changed

2 files changed

+27
-27
lines changed

lib/ts_utils/metadata.py

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
from __future__ import annotations
77

8+
import datetime
89
import functools
910
import re
1011
import urllib.parse
@@ -18,6 +19,7 @@
1819
import tomlkit
1920
from packaging.requirements import Requirement
2021
from packaging.specifiers import Specifier
22+
from tomlkit.items import String
2123

2224
from .paths import PYPROJECT_PATH, STUBS_PATH, distribution_path
2325

@@ -140,6 +142,13 @@ def read_stubtest_settings(distribution: str) -> StubtestSettings:
140142
)
141143

142144

145+
@final
146+
@dataclass(frozen=True)
147+
class ObsoleteMetadata:
148+
since_version: Annotated[str, "A string representing a specific version"]
149+
since_date: Annotated[datetime.date, "A date when the package became obsolete"]
150+
151+
143152
@final
144153
@dataclass(frozen=True)
145154
class StubMetadata:
@@ -154,7 +163,7 @@ class StubMetadata:
154163
extra_description: str | None
155164
stub_distribution: Annotated[str, "The name under which the distribution is uploaded to PyPI"]
156165
upstream_repository: Annotated[str, "The URL of the upstream repository"] | None
157-
obsolete_since: Annotated[str, "A string representing a specific version"] | None
166+
obsolete: Annotated[ObsoleteMetadata, "Metadata indicating when the stubs package became obsolete"] | None
158167
no_longer_updated: bool
159168
uploaded_to_pypi: Annotated[bool, "Whether or not a distribution is uploaded to PyPI"]
160169
partial_stub: Annotated[bool, "Whether this is a partial type stub package as per PEP 561."]
@@ -163,7 +172,7 @@ class StubMetadata:
163172

164173
@property
165174
def is_obsolete(self) -> bool:
166-
return self.obsolete_since is not None
175+
return self.obsolete is not None
167176

168177

169178
_KNOWN_METADATA_FIELDS: Final = frozenset(
@@ -269,7 +278,14 @@ def read_metadata(distribution: str) -> StubMetadata:
269278
assert num_url_path_parts == 2, bad_github_url_msg
270279

271280
obsolete_since: object = data.get("obsolete_since")
272-
assert isinstance(obsolete_since, (str, type(None)))
281+
assert isinstance(obsolete_since, (String, type(None)))
282+
if obsolete_since:
283+
comment = obsolete_since.trivia.comment
284+
since_date_string = comment.removeprefix("# Released on ")
285+
since_date = datetime.date.fromisoformat(since_date_string)
286+
obsolete = ObsoleteMetadata(since_version=obsolete_since, since_date=since_date)
287+
else:
288+
obsolete = None
273289
no_longer_updated: object = data.get("no_longer_updated", False)
274290
assert type(no_longer_updated) is bool
275291
uploaded_to_pypi: object = data.get("upload", True)
@@ -308,7 +324,7 @@ def read_metadata(distribution: str) -> StubMetadata:
308324
extra_description=extra_description,
309325
stub_distribution=stub_distribution,
310326
upstream_repository=upstream_repository,
311-
obsolete_since=obsolete_since,
327+
obsolete=obsolete,
312328
no_longer_updated=no_longer_updated,
313329
uploaded_to_pypi=uploaded_to_pypi,
314330
partial_stub=partial_stub,

scripts/stubsabot.py

Lines changed: 7 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,8 @@
3131
import tomlkit
3232
from packaging.specifiers import Specifier
3333
from termcolor import colored
34-
from tomlkit.items import String
3534

36-
from ts_utils.metadata import NoSuchStubError, StubMetadata, metadata_path, read_metadata, update_metadata
35+
from ts_utils.metadata import ObsoleteMetadata, StubMetadata, read_metadata, update_metadata
3736
from ts_utils.paths import PYRIGHT_CONFIG, STUBS_PATH, distribution_path
3837

3938
TYPESHED_OWNER = "python"
@@ -506,27 +505,9 @@ def _add_months(date: datetime.date, months: int) -> datetime.date:
506505
return datetime.date(year, month, day)
507506

508507

509-
def obsolete_more_than_6_months(distribution: str) -> bool:
510-
try:
511-
with metadata_path(distribution).open("rb") as file:
512-
data = tomlkit.load(file)
513-
except FileNotFoundError:
514-
raise NoSuchStubError(f"Typeshed has no stubs for {distribution!r}!") from None
515-
516-
obsolete_since = data["obsolete_since"]
517-
if not obsolete_since:
518-
return False
519-
520-
assert type(obsolete_since) is String
521-
comment: str | None = obsolete_since.trivia.comment
522-
if not comment:
523-
return False
524-
525-
release_date_string = comment.removeprefix("# Released on ")
526-
release_date = datetime.date.fromisoformat(release_date_string)
527-
remove_date = _add_months(release_date, POLICY_MONTHS_DELTA)
508+
def obsolete_more_than_n_months(since_date: datetime.date) -> bool:
509+
remove_date = _add_months(since_date, POLICY_MONTHS_DELTA)
528510
today = datetime.datetime.now(tz=datetime.timezone.utc).date()
529-
530511
return remove_date >= today
531512

532513

@@ -564,7 +545,10 @@ async def has_no_longer_updated_release(release_to_download: PypiReleaseDownload
564545
async def determine_action(distribution: str, session: aiohttp.ClientSession) -> Update | NoUpdate | Obsolete | Remove:
565546
stub_info = read_metadata(distribution)
566547
if stub_info.is_obsolete:
567-
if obsolete_more_than_6_months(stub_info.distribution):
548+
assert type(stub_info.obsolete) is ObsoleteMetadata
549+
since_date = stub_info.obsolete.since_date
550+
551+
if obsolete_more_than_n_months(since_date):
568552
pypi_info = await fetch_pypi_info(f"types-{stub_info.distribution}", session)
569553
latest_release = pypi_info.get_latest_release()
570554
links = {

0 commit comments

Comments
 (0)