File: max_versions.py

package info (click to toggle)
pdm 2.20.1%2Bds1-2
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 2,988 kB
  • sloc: python: 24,413; javascript: 34; makefile: 11
file content (59 lines) | stat: -rw-r--r-- 2,206 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
from __future__ import annotations

import json
from html.parser import HTMLParser
from pathlib import Path

import httpx

PROJECT_DIR = Path(__file__).parent.parent


class PythonVersionParser(HTMLParser):
    def __init__(self, *, convert_charrefs: bool = True) -> None:
        super().__init__(convert_charrefs=convert_charrefs)
        self._parsing_release_number_span = False
        self._parsing_release_number_a = False
        self.parsed_python_versions: list[str] = []

    def handle_starttag(self, tag: str, attrs: list[tuple[str, str]]) -> None:
        if tag == "span" and any("release-number" in value for key, value in attrs if key == "class"):
            self._parsing_release_number_span = True
            return

        if self._parsing_release_number_span and tag == "a":
            self._parsing_release_number_a = True

    def handle_endtag(self, tag: str) -> None:
        if self._parsing_release_number_span and tag == "span":
            self._parsing_release_number_span = False

        if self._parsing_release_number_a and tag == "a":
            self._parsing_release_number_a = False

    def handle_data(self, data: str) -> None:
        if self._parsing_release_number_a:
            self.parsed_python_versions.append(data[7:])


def dump_python_version_module(dest_file) -> None:
    resp = httpx.get("https://python.org/downloads/", follow_redirects=True)
    resp_text = resp.text
    parser = PythonVersionParser()
    parser.feed(resp_text)
    python_versions = sorted(parser.parsed_python_versions)
    max_versions: dict[str, int] = {}
    for version in python_versions:
        major, minor, patch = version.split(".")
        major_minor = f"{major}.{minor}"
        if major not in max_versions or max_versions[major] < int(minor):
            max_versions[major] = int(minor)
        if major_minor not in max_versions or max_versions[major_minor] < int(patch):
            max_versions[major_minor] = int(patch)
    with open(dest_file, "w") as f:
        json.dump(max_versions, f, sort_keys=True, indent=4)
        f.write("\n")


if __name__ == "__main__":
    dump_python_version_module(PROJECT_DIR / "src/pdm/models/python_max_versions.json")