-
Notifications
You must be signed in to change notification settings - Fork 76
/
python_releases.py
66 lines (49 loc) · 1.8 KB
/
python_releases.py
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
60
61
62
63
64
65
66
"""Get the latest Python release which is online."""
import urllib.request
import re
from html.parser import HTMLParser
import gzip
class PythonVersionParser(HTMLParser):
"""Specialized HTMLParser to get Python version number."""
def __init__(self):
super().__init__()
self.versions = set()
self.found_version = False
def handle_starttag(self, tag, attrs):
"""Look for the right tag and store result in an attribute."""
if tag == "a":
for attr in attrs:
if attr[0] == "href" and "/downloads/release/python-" in attr[1]:
self.found_version = True
return
def handle_data(self, data):
"""Extract Python version from entry."""
if self.found_version:
self.found_version = False
match = re.search(r"Python (\d+)\.(\d+)\.(\d+)?", data)
if match:
major = int(match.group(1))
minor = int(match.group(2))
bugfix = int(match.group(3))
self.versions.add((major, minor, bugfix))
def versions():
"""Get all Python release versions."""
req = urllib.request.Request("https://www.python.org/downloads/")
req.add_header("Accept-Encoding", "gzip")
with urllib.request.urlopen(req) as response:
raw = response.read()
if response.info().get("Content-Encoding") == "gzip":
raw = gzip.decompress(raw)
html = raw.decode("utf-8")
parser = PythonVersionParser()
parser.feed(html)
return parser.versions
def latest():
"""Return version of latest Python release."""
return max(versions())
def main():
"""Print all discovered release versions."""
for x in sorted(versions()):
print(x)
if __name__ == "__main__":
main()