1313import build_docs
1414
1515logger = logging .getLogger (__name__ )
16+ VERSIONS = build_docs .parse_versions_from_devguide ()
17+ LANGUAGES = build_docs .parse_languages_from_config ()
1618
1719
1820def parse_args ():
@@ -24,102 +26,107 @@ def parse_args():
2426 return parser .parse_args ()
2527
2628
27- def remote_by_url (repo : git .Repo , url_pattern : str ) :
29+ def find_upstream_remote_name (repo : git .Repo ) -> str :
2830 """Find a remote of repo matching the regex url_pattern."""
2931 for remote in repo .remotes :
3032 for url in remote .urls :
31- if re . search ( url_pattern , url ) :
32- return remote
33+ if "github.com/python" in url :
34+ return f" { remote . name } /"
3335
3436
3537def find_sphinx_spec (text : str ):
3638 if found := re .search (
37- """sphinx[=<>~]{1,2}[0-9.]{3,}|needs_sphinx = [0-9.'"]*""" , text , flags = re .I
39+ """sphinx[=<>~]{1,2}[0-9.]{3,}|needs_sphinx = [0-9.'"]*""" ,
40+ text ,
41+ flags = re .IGNORECASE ,
3842 ):
3943 return found .group (0 ).replace (" " , "" )
4044 return "ø"
4145
4246
43- def find_sphinx_in_file (repo : git .Repo , branch , filename ):
44- upstream = remote_by_url (repo , "github.com.python" ).name
45- # Just in case you don't use origin/:
46- branch = branch .replace ("origin/" , upstream + "/" )
47- try :
48- return find_sphinx_spec (repo .git .show (f"{ branch } :{ filename } " ))
49- except git .exc .GitCommandError :
50- return "ø"
47+ def find_sphinx_in_files (repo : git .Repo , branch_or_tag , filenames ):
48+ upstream = find_upstream_remote_name (repo )
49+ # Just in case you don't use upstream/:
50+ branch_or_tag = branch_or_tag .replace ("upstream/" , upstream )
51+ specs = []
52+ for filename in filenames :
53+ try :
54+ blob = repo .git .show (f"{ branch_or_tag } :{ filename } " )
55+ except git .exc .GitCommandError :
56+ specs .append ("ø" )
57+ else :
58+ specs .append (find_sphinx_spec (blob ))
59+ return specs
5160
5261
5362CONF_FILES = {
5463 "travis" : ".travis.yml" ,
55- "azure" : ".azure-pipelines/docs-steps.yml" ,
5664 "requirements.txt" : "Doc/requirements.txt" ,
5765 "conf.py" : "Doc/conf.py" ,
5866}
5967
6068
61- def search_sphinx_versions_in_cpython (repo : git .Repo ):
62- repo .git .fetch ("https://github.com/python/cpython" )
63- table = []
64- for version in sorted (build_docs .VERSIONS ):
65- table .append (
66- [
67- version .name ,
68- * [
69- find_sphinx_in_file (repo , version .branch_or_tag , filename )
70- for filename in CONF_FILES .values ()
71- ],
72- ]
73- )
74- print (tabulate (table , headers = ["version" , * CONF_FILES .keys ()], tablefmt = "rst" ))
69+ def branch_or_tag_for (version ):
70+ if version .status == "EOL" :
71+ return f"tags/{ version .branch_or_tag } "
72+ return f"upstream/{ version .branch_or_tag } "
7573
7674
77- async def get_version_in_prod (language , version ):
78- url = f"https://docs.python.org/{ language } /{ version } /" .replace ("/en/" , "/" )
75+ def search_sphinx_versions_in_cpython (repo : git .Repo ):
76+ repo .git .fetch ("https://github.com/python/cpython" )
77+ filenames = CONF_FILES .values ()
78+ table = [
79+ [
80+ version .name ,
81+ * find_sphinx_in_files (repo , branch_or_tag_for (version ), filenames ),
82+ ]
83+ for version in VERSIONS
84+ ]
85+ headers = ["version" , * CONF_FILES .keys ()]
86+ print (tabulate (table , headers = headers , tablefmt = "rst" , disable_numparse = True ))
87+
88+
89+ async def get_version_in_prod (language : str , version : str ) -> str :
90+ if language == "en" :
91+ url = f"https://docs.python.org/{ version } /"
92+ else :
93+ url = f"https://docs.python.org/{ language } /{ version } /"
7994 async with httpx .AsyncClient () as client :
8095 try :
81- response = await client .get (url , timeout = 10 )
96+ response = await client .get (url , timeout = 5 )
8297 except httpx .ConnectTimeout :
8398 return "(timeout)"
84- text = response .text .encode ("ASCII" , errors = "ignore" ).decode ("ASCII" )
99+ # Python 2.6--3.7: sphinx.pocoo.org
100+ # from Python 3.8: www.sphinx-doc.org
85101 if created_using := re .search (
86- r"(?:sphinx.pocoo.org|www.sphinx-doc.org).*?([0-9.]+[0-9])" , text , flags = re . M
102+ r"(?:sphinx.pocoo.org|www.sphinx-doc.org).*?([0-9.]+[0-9])" , response . text
87103 ):
88104 return created_using .group (1 )
89105 return "ø"
90106
91107
92108async def which_sphinx_is_used_in_production ():
93- table = []
94- for version in sorted (build_docs .VERSIONS ):
95- table .append (
96- [
97- version .name ,
98- * await asyncio .gather (
99- * [
100- get_version_in_prod (language .tag , version .name )
101- for language in build_docs .LANGUAGES
102- ]
103- ),
104- ]
105- )
106- print (
107- tabulate (
108- table ,
109- disable_numparse = True ,
110- headers = [
111- "version" ,
112- * [language .tag for language in sorted (build_docs .LANGUAGES )],
113- ],
114- tablefmt = "rst" ,
115- )
116- )
109+ table = [
110+ [
111+ version .name ,
112+ * await asyncio .gather (
113+ * [
114+ get_version_in_prod (language .tag , version .name )
115+ for language in LANGUAGES
116+ ]
117+ ),
118+ ]
119+ for version in VERSIONS
120+ ]
121+ headers = ["version" , * [language .tag for language in LANGUAGES ]]
122+ print (tabulate (table , headers = headers , tablefmt = "rst" , disable_numparse = True ))
117123
118124
119125def main ():
120126 logging .basicConfig (level = logging .INFO )
121127 logging .getLogger ("charset_normalizer" ).setLevel (logging .WARNING )
122128 logging .getLogger ("asyncio" ).setLevel (logging .WARNING )
129+ logging .getLogger ("httpx" ).setLevel (logging .WARNING )
123130 args = parse_args ()
124131 repo = git .Repo (args .cpython_clone )
125132 print ("Sphinx configuration in various branches:" , end = "\n \n " )
0 commit comments