@@ -71,10 +71,9 @@ def __init__(
7171 self ,
7272 name ,
7373 * ,
74+ status ,
7475 branch = None ,
7576 tag = None ,
76- status ,
77- sphinx_version ,
7877 sphinxopts = (),
7978 ):
8079 if status not in self .STATUSES :
@@ -88,31 +87,36 @@ def __init__(
8887 raise ValueError ("Please build a version with at least a branch or a tag." )
8988 self .branch_or_tag = branch or tag
9089 self .status = status
91- self .sphinx_version = sphinx_version
9290 self .sphinxopts = list (sphinxopts )
9391
9492 def __repr__ (self ):
9593 return f"Version({ self .name } )"
9694
9795 @property
9896 def requirements (self ):
99- """Generate the right requirements for this version, pinning breaking
100- sub-dependencies as needed.
97+ """Generate the right requirements for this version.
98+
99+ Since CPython 3.8 a Doc/requirements.txt file can be used.
100+
101+ In case the Doc/requirements.txt is absent or wrong (a
102+ sub-dependency broke), use this function to override it.
103+
104+ See https://github.com/python/cpython/issues/91294
105+ See https://github.com/python/cpython/issues/91483
106+
101107 """
102- reqs = [
103- "blurb" ,
104- "jieba" ,
105- f"sphinx=={ self .sphinx_version } " ,
108+ if self .name == "3.5" :
109+ return ["jieba" , "blurb" , "sphinx==1.8.4" , "jinja2<3.1" , "docutils<=0.17.1" ]
110+ if self .name in ("3.7" , "3.6" , "2.7" ):
111+ return ["jieba" , "blurb" , "sphinx==2.3.1" , "jinja2<3.1" , "docutils<=0.17.1" ]
112+ if self .name == ("3.8" , "3.9" ):
113+ return ["jieba" , "blurb" , "sphinx==2.4.4" , "jinja2<3.1" , "docutils<=0.17.1" ]
114+
115+ return [
116+ "jieba" , # To improve zh search.
117+ "-rrequirements.txt" ,
106118 ]
107119
108- if version_to_tuple (self .sphinx_version ) < (4 , 5 ):
109- # see https://github.com/python/cpython/issues/91294
110- reqs += ["jinja2<3.1" ]
111- if version_to_tuple (self .sphinx_version ) < (3 , 5 , 4 ):
112- # see https://github.com/python/cpython/issues/91483
113- reqs += ["docutils<=0.17.1" ]
114- return reqs
115-
116120 @property
117121 def changefreq (self ):
118122 """Estimate this version change frequency, for the sitemap."""
@@ -196,60 +200,15 @@ def __gt__(self, other):
196200#
197201# Please keep the list in reverse-order for ease of editing.
198202VERSIONS = [
199- Version (
200- "3.12" ,
201- branch = "origin/main" ,
202- status = "in development" ,
203- sphinx_version = "4.5.0" ,
204- ),
205- Version (
206- "3.11" ,
207- branch = "origin/3.11" ,
208- status = "stable" ,
209- sphinx_version = "4.5.0" ,
210- ),
211- Version (
212- "3.10" ,
213- branch = "origin/3.10" ,
214- status = "stable" ,
215- sphinx_version = "3.4.3" ,
216- ),
217- Version (
218- "3.9" ,
219- branch = "origin/3.9" ,
220- status = "security-fixes" ,
221- sphinx_version = "2.4.4" ,
222- ),
223- Version (
224- "3.8" ,
225- branch = "origin/3.8" ,
226- status = "security-fixes" ,
227- sphinx_version = "2.4.4" ,
228- ),
229- Version (
230- "3.7" ,
231- branch = "origin/3.7" ,
232- status = "security-fixes" ,
233- sphinx_version = "2.3.1" ,
234- ),
235- Version (
236- "3.6" ,
237- tag = "3.6" ,
238- status = "EOL" ,
239- sphinx_version = "2.3.1" ,
240- ),
241- Version (
242- "3.5" ,
243- tag = "3.5" ,
244- status = "EOL" ,
245- sphinx_version = "1.8.4" ,
246- ),
247- Version (
248- "2.7" ,
249- tag = "2.7" ,
250- status = "EOL" ,
251- sphinx_version = "2.3.1" ,
252- ),
203+ Version ("3.12" , branch = "origin/main" , status = "in development" ),
204+ Version ("3.11" , branch = "origin/3.11" , status = "stable" ),
205+ Version ("3.10" , branch = "origin/3.10" , status = "stable" ),
206+ Version ("3.9" , branch = "origin/3.9" , status = "security-fixes" ),
207+ Version ("3.8" , branch = "origin/3.8" , status = "security-fixes" ),
208+ Version ("3.7" , branch = "origin/3.7" , status = "security-fixes" ),
209+ Version ("3.6" , tag = "3.6" , status = "EOL" ),
210+ Version ("3.5" , tag = "3.5" , status = "EOL" ),
211+ Version ("2.7" , tag = "2.7" , status = "EOL" ),
253212]
254213
255214XELATEX_DEFAULT = (
@@ -299,13 +258,14 @@ def __gt__(self, other):
299258}
300259
301260
302- def run (cmd ) -> subprocess .CompletedProcess :
261+ def run (cmd , cwd = None ) -> subprocess .CompletedProcess :
303262 """Like subprocess.run, with logging before and after the command execution."""
304263 cmd = [str (arg ) for arg in cmd ]
305264 cmdstring = shlex .join (cmd )
306265 logging .debug ("Run: %r" , cmdstring )
307266 result = subprocess .run (
308267 cmd ,
268+ cwd = cwd ,
309269 stdin = subprocess .PIPE ,
310270 stderr = subprocess .STDOUT ,
311271 stdout = subprocess .PIPE ,
@@ -522,8 +482,7 @@ def build_sitemap(www_root: Path, group):
522482 template = jinja2 .Template (template_file .read ())
523483 sitemap_file = www_root / "sitemap.xml"
524484 sitemap_file .write_text (
525- template .render (languages = LANGUAGES , versions = VERSIONS ) + "\n " ,
526- encoding = "UTF-8"
485+ template .render (languages = LANGUAGES , versions = VERSIONS ) + "\n " , encoding = "UTF-8"
527486 )
528487 sitemap_file .chmod (0o664 )
529488 run (["chgrp" , group , sitemap_file ])
@@ -680,6 +639,9 @@ class DocBuilder(
680639 def run (self ):
681640 """Build and publish a Python doc, for a language, and a version."""
682641 try :
642+ self .clone_cpython ()
643+ if self .language .tag != "en" :
644+ self .clone_translation ()
683645 self .build_venv ()
684646 self .build ()
685647 self .copy_build_to_webroot ()
@@ -697,6 +659,28 @@ def checkout(self) -> Path:
697659 """Path to cpython git clone."""
698660 return self .build_root / "cpython"
699661
662+ def clone_translation (self ):
663+ locale_repo = f"https://github.com/python/python-docs-{ self .language .tag } .git"
664+ locale_clone_dir = (
665+ self .build_root
666+ / self .version .name
667+ / "locale"
668+ / self .language .iso639_tag
669+ / "LC_MESSAGES"
670+ )
671+ git_clone (
672+ locale_repo ,
673+ locale_clone_dir ,
674+ translation_branch (locale_repo , locale_clone_dir , self .version .name ),
675+ )
676+
677+ def clone_cpython (self ):
678+ git_clone (
679+ "https://github.com/python/cpython.git" ,
680+ self .checkout ,
681+ self .version .branch_or_tag ,
682+ )
683+
700684 def build (self ):
701685 """Build this version/language doc."""
702686 logging .info (
@@ -708,15 +692,6 @@ def build(self):
708692 sphinxopts .extend (["-q" ])
709693 if self .language .tag != "en" :
710694 locale_dirs = self .build_root / self .version .name / "locale"
711- locale_clone_dir = locale_dirs / self .language .iso639_tag / "LC_MESSAGES"
712- locale_repo = (
713- f"https://github.com/python/python-docs-{ self .language .tag } .git"
714- )
715- git_clone (
716- locale_repo ,
717- locale_clone_dir ,
718- translation_branch (locale_repo , locale_clone_dir , self .version .name ),
719- )
720695 sphinxopts .extend (
721696 (
722697 f"-D locale_dirs={ locale_dirs } " ,
@@ -726,11 +701,6 @@ def build(self):
726701 )
727702 if self .version .status == "EOL" :
728703 sphinxopts .append ("-D html_context.outdated=1" )
729- git_clone (
730- "https://github.com/python/cpython.git" ,
731- self .checkout ,
732- self .version .branch_or_tag ,
733- )
734704 maketarget = (
735705 "autobuild-"
736706 + (
@@ -780,17 +750,18 @@ def build(self):
780750 )
781751
782752 def build_venv (self ):
783- """Build a venv for the specific version.
784- This is used to pin old Sphinx versions to old cpython branches.
753+ """Build a venv for the specific Python version.
754+
755+ So we can reuse them from builds to builds, while they contain
756+ different Sphinx versions.
785757 """
786- venv_path = self .build_root / (
787- "venv-with-sphinx-" + self .version .sphinx_version
788- )
758+ venv_path = self .build_root / ("venv-" + self .version .name )
789759 run ([sys .executable , "-m" , "venv" , venv_path ])
790760 run (
791761 [venv_path / "bin" / "python" , "-m" , "pip" , "install" ]
792762 + [self .theme ]
793- + self .version .requirements
763+ + self .version .requirements ,
764+ cwd = self .checkout / "Doc" ,
794765 )
795766 run ([venv_path / "bin" / "python" , "-m" , "pip" , "freeze" , "--all" ])
796767 self .venv = venv_path
0 commit comments