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()
|