Skip to content

Commit 23b228e

Browse files
committed
Convert Version to a dataclass
1 parent 8c8b000 commit 23b228e

File tree

1 file changed

+22
-25
lines changed

1 file changed

+22
-25
lines changed

build_docs.py

+22-25
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@
5858
import sys
5959
from bisect import bisect_left as bisect
6060
from contextlib import contextmanager, suppress
61-
from functools import total_ordering
6261
from pathlib import Path
6362
from string import Template
6463
from time import perf_counter, sleep
@@ -103,11 +102,23 @@ def __reversed__(self) -> Iterator[Version]:
103102

104103
@classmethod
105104
def from_json(cls, data: dict) -> Versions:
106-
versions = sorted(
107-
[Version.from_json(name, release) for name, release in data.items()],
108-
key=Version.as_tuple,
109-
)
110-
return cls(versions)
105+
"""Load versions from the devguide's JSON representation."""
106+
permitted = ", ".join(sorted(Version.STATUSES | Version.SYNONYMS.keys()))
107+
108+
versions = []
109+
for name, release in data.items():
110+
branch = release["branch"]
111+
status = release["status"]
112+
status = Version.SYNONYMS.get(status, status)
113+
if status not in Version.STATUSES:
114+
msg = (
115+
f"Saw invalid version status {status!r}, "
116+
f"expected to be one of {permitted}."
117+
)
118+
raise ValueError(msg)
119+
versions.append(Version(name=name, branch_or_tag=branch, status=status))
120+
121+
return cls(sorted(versions, key=Version.as_tuple))
111122

112123
def filter(self, branches: Sequence[str] = ()) -> Sequence[Version]:
113124
"""Filter the given versions.
@@ -143,10 +154,14 @@ def setup_indexsidebar(self, current: Version, dest_path: Path) -> None:
143154
dest_path.write_text(rendered_template, encoding="UTF-8")
144155

145156

146-
@total_ordering
157+
@dataclasses.dataclass(frozen=True, kw_only=True, slots=True)
147158
class Version:
148159
"""Represents a CPython version and its documentation build dependencies."""
149160

161+
name: str
162+
branch_or_tag: str | None
163+
status: str
164+
150165
STATUSES = {"EOL", "security-fixes", "stable", "pre-release", "in development"}
151166

152167
# Those synonyms map branch status vocabulary found in the devguide
@@ -159,19 +174,6 @@ class Version:
159174
"prerelease": "pre-release",
160175
}
161176

162-
def __init__(
163-
self, name: str, *, status: str, branch_or_tag: str | None = None
164-
) -> None:
165-
status = self.SYNONYMS.get(status, status)
166-
if status not in self.STATUSES:
167-
raise ValueError(
168-
"Version status expected to be one of: "
169-
f"{', '.join(self.STATUSES | set(self.SYNONYMS.keys()))}, got {status!r}."
170-
)
171-
self.name = name
172-
self.branch_or_tag = branch_or_tag
173-
self.status = status
174-
175177
def __repr__(self) -> str:
176178
return f"Version({self.name})"
177179

@@ -181,11 +183,6 @@ def __eq__(self, other: Version) -> bool:
181183
def __gt__(self, other: Version) -> bool:
182184
return self.as_tuple() > other.as_tuple()
183185

184-
@classmethod
185-
def from_json(cls, name: str, values: dict) -> Version:
186-
"""Loads a version from devguide's json representation."""
187-
return cls(name, status=values["status"], branch_or_tag=values["branch"])
188-
189186
@property
190187
def requirements(self) -> list[str]:
191188
"""Generate the right requirements for this version.

0 commit comments

Comments
 (0)