1010
1111-q selects "quick build", which means to build only HTML.
1212
13- Translations are fetched from github repositories according to PEP
14- 545. `--languages` allows to select translations, like `--languages
15- en` to just build the english documents.
13+ Translations are fetched from GitHub repositories according to PEP
14+ 545. `--languages` allows selecting translations, like `--languages
15+ en` to just build the English documents.
1616
17- This script was originally created and by Georg Brandl in March
18- 2010.
17+ This script was originally created by Georg Brandl in March 2010.
1918Modified by Benjamin Peterson to do CDN cache invalidation.
2019Modified by Julien Palard to build translations.
2120
6867
6968@total_ordering
7069class Version :
71- """Represents a cpython version and its documentation builds dependencies."""
70+ """Represents a CPython version and its documentation build dependencies."""
7271
7372 STATUSES = {"EOL" , "security-fixes" , "stable" , "pre-release" , "in development" }
7473
@@ -146,7 +145,7 @@ def filter(versions, branch=None):
146145
147146 If *branch* is given, only *versions* matching *branch* are returned.
148147
149- Else all live version are returned (this mean no EOL and no
148+ Else all live versions are returned (this means no EOL and no
150149 security-fixes branches).
151150 """
152151 if branch :
@@ -155,12 +154,12 @@ def filter(versions, branch=None):
155154
156155 @staticmethod
157156 def current_stable (versions ):
158- """Find the current stable cPython version."""
157+ """Find the current stable CPython version."""
159158 return max ((v for v in versions if v .status == "stable" ), key = Version .as_tuple )
160159
161160 @staticmethod
162161 def current_dev (versions ):
163- """Find the current de cPython version."""
162+ """Find the current CPython version in development ."""
164163 return max (versions , key = Version .as_tuple )
165164
166165 @property
@@ -359,7 +358,7 @@ def locate_nearest_version(available_versions, target_version):
359358def edit (file : Path ):
360359 """Context manager to edit a file "in place", use it as:
361360
362- with edit("/etc/hosts") as i, o:
361+ with edit("/etc/hosts") as ( i, o) :
363362 for line in i:
364363 o.write(line.replace("localhoat", "localhost"))
365364 """
@@ -375,7 +374,7 @@ def edit(file: Path):
375374def setup_switchers (
376375 versions : Iterable [Version ], languages : Iterable [Language ], html_root : Path
377376):
378- """Setup cross-links between cpython versions:
377+ """Setup cross-links between CPython versions:
379378 - Cross-link various languages in a language switcher
380379 - Cross-link various versions in a version switcher
381380 """
@@ -437,7 +436,7 @@ def build_robots_txt(
437436) -> None :
438437 """Disallow crawl of EOL versions in robots.txt."""
439438 if not www_root .exists ():
440- logging .info ("Skipping robots.txt generation (www root does not even exists )." )
439+ logging .info ("Skipping robots.txt generation (www root does not even exist )." )
441440 return
442441 robots_file = www_root / "robots.txt"
443442 with open (HERE / "templates" / "robots.txt" , encoding = "UTF-8" ) as template_file :
@@ -457,7 +456,7 @@ def build_sitemap(
457456):
458457 """Build a sitemap with all live versions and translations."""
459458 if not www_root .exists ():
460- logging .info ("Skipping sitemap generation (www root does not even exists )." )
459+ logging .info ("Skipping sitemap generation (www root does not even exist )." )
461460 return
462461 with open (HERE / "templates" / "sitemap.xml" , encoding = "UTF-8" ) as template_file :
463462 template = jinja2 .Template (template_file .read ())
@@ -472,7 +471,7 @@ def build_sitemap(
472471def build_404 (www_root : Path , group ):
473472 """Build a nice 404 error page to display in case PDFs are not built yet."""
474473 if not www_root .exists ():
475- logging .info ("Skipping 404 page generation (www root does not even exists )." )
474+ logging .info ("Skipping 404 page generation (www root does not even exist )." )
476475 return
477476 not_found_file = www_root / "404.html"
478477 shutil .copyfile (HERE / "templates" / "404.html" , not_found_file )
@@ -550,7 +549,7 @@ def parse_args():
550549 )
551550 parser .add_argument (
552551 "--skip-cache-invalidation" ,
553- help = "Skip fastly cache invalidation." ,
552+ help = "Skip Fastly cache invalidation." ,
554553 action = "store_true" ,
555554 )
556555 parser .add_argument (
@@ -580,7 +579,7 @@ def parse_args():
580579 parser .add_argument (
581580 "--theme" ,
582581 default = "python-docs-theme" ,
583- help = "Python package to use for python-docs-theme: Usefull to test branches:"
582+ help = "Python package to use for python-docs-theme: Useful to test branches:"
584583 " --theme git+https://github.com/obulat/python-docs-theme@master" ,
585584 )
586585 args = parser .parse_args ()
@@ -598,7 +597,7 @@ def parse_args():
598597
599598
600599def setup_logging (log_directory : Path ):
601- """Setup logging to stderr if ran by a human, or to a file if ran from a cron."""
600+ """Setup logging to stderr if run by a human, or to a file if run from a cron."""
602601 if sys .stderr .isatty ():
603602 logging .basicConfig (
604603 format = "%(asctime)s %(levelname)s: %(message)s" , stream = sys .stderr
@@ -615,7 +614,7 @@ def setup_logging(log_directory: Path):
615614
616615@dataclass
617616class DocBuilder :
618- """Builder for a cpython version and a language."""
617+ """Builder for a CPython version and a language."""
619618
620619 version : Version
621620 versions : Iterable [Version ]
@@ -634,7 +633,7 @@ class DocBuilder:
634633 def full_build (self ):
635634 """Tell if a full build is needed.
636635
637- A full build is slow, it builds pdf, txt, epub, texinfo, and
636+ A full build is slow; it builds pdf, txt, epub, texinfo, and
638637 archives everything.
639638
640639 A partial build only builds HTML and does not archive, it's
@@ -664,7 +663,7 @@ def run(self, http: urllib3.PoolManager) -> bool:
664663
665664 @property
666665 def checkout (self ) -> Path :
667- """Path to cpython git clone."""
666+ """Path to CPython git clone."""
668667 return self .build_root / "cpython"
669668
670669 def clone_translation (self ):
@@ -687,7 +686,7 @@ def translation_repo(self):
687686
688687 @property
689688 def translation_branch (self ):
690- """Some cpython versions may be untranslated, being either too old or
689+ """Some CPython versions may be untranslated, being either too old or
691690 too new.
692691
693692 This function looks for remote branches on the given repo, and
@@ -745,7 +744,7 @@ def build(self):
745744 python = self .venv / "bin" / "python"
746745 sphinxbuild = self .venv / "bin" / "sphinx-build"
747746 blurb = self .venv / "bin" / "blurb"
748- # Disable cpython switchers, we handle them now:
747+ # Disable CPython switchers, we handle them now:
749748
750749 def is_mac ():
751750 return platform .system () == 'Darwin'
@@ -790,6 +789,7 @@ def build_venv(self):
790789 run ([sys .executable , "-m" , "venv" , venv_path ])
791790 run (
792791 [venv_path / "bin" / "python" , "-m" , "pip" , "install" , "--upgrade" ]
792+ + ["--upgrade-strategy=eager" ]
793793 + [self .theme ]
794794 + self .version .requirements ,
795795 cwd = self .checkout / "Doc" ,
@@ -955,7 +955,7 @@ def load_state(self) -> dict:
955955 return {}
956956
957957 def save_state (self , build_duration : float ):
958- """Save current cpython sha1 and current translation sha1.
958+ """Save current CPython sha1 and current translation sha1.
959959
960960 Using this we can deduce if a rebuild is needed or not.
961961 """
@@ -987,7 +987,7 @@ def symlink(
987987 http : urllib3 .PoolManager ,
988988) -> None :
989989 """Used by major_symlinks and dev_symlink to maintain symlinks."""
990- if language .tag == "en" : # english is rooted on /, no /en/
990+ if language .tag == "en" : # English is rooted on /, no /en/
991991 path = www_root
992992 else :
993993 path = www_root / language .tag
@@ -1013,7 +1013,7 @@ def major_symlinks(
10131013 skip_cache_invalidation : bool ,
10141014 http : urllib3 .PoolManager ,
10151015) -> None :
1016- """Maintains the /2/ and /3/ symlinks for each languages .
1016+ """Maintains the /2/ and /3/ symlinks for each language .
10171017
10181018 Like:
10191019 - /3/ → /3.9/
@@ -1042,7 +1042,7 @@ def dev_symlink(
10421042 skip_cache_invalidation : bool ,
10431043 http : urllib3 .PoolManager ,
10441044) -> None :
1045- """Maintains the /dev/ symlinks for each languages .
1045+ """Maintains the /dev/ symlinks for each language .
10461046
10471047 Like:
10481048 - /dev/ → /3.11/
@@ -1065,7 +1065,7 @@ def dev_symlink(
10651065def purge (http : urllib3 .PoolManager , * paths : Path | str ) -> None :
10661066 """Remove one or many paths from docs.python.org's CDN.
10671067
1068- To be used when a file change , so the CDN fetch the new one.
1068+ To be used when a file changes , so the CDN fetches the new one.
10691069 """
10701070 base = "https://docs.python.org/"
10711071 for path in paths :
@@ -1077,7 +1077,7 @@ def purge(http: urllib3.PoolManager, *paths: Path | str) -> None:
10771077def purge_path (http : urllib3 .PoolManager , www_root : Path , path : Path ) -> None :
10781078 """Recursively remove a path from docs.python.org's CDN.
10791079
1080- To be used when a directory change , so the CDN fetch the new one.
1080+ To be used when a directory changes , so the CDN fetches the new one.
10811081 """
10821082 purge (http , * [file .relative_to (www_root ) for file in path .glob ("**/*" )])
10831083 purge (http , path .relative_to (www_root ))
@@ -1118,7 +1118,9 @@ def parse_versions_from_devguide(http: urllib3.PoolManager) -> list[Version]:
11181118 "python/devguide/main/include/release-cycle.json" ,
11191119 timeout = 30 ,
11201120 ).json ()
1121- return [Version .from_json (name , release ) for name , release in releases .items ()]
1121+ versions = [Version .from_json (name , release ) for name , release in releases .items ()]
1122+ versions .sort (key = Version .as_tuple )
1123+ return versions
11221124
11231125
11241126def parse_languages_from_config ():
@@ -1164,9 +1166,9 @@ def build_docs(args) -> bool:
11641166 )
11651167 )
11661168 if sentry_sdk :
1167- with sentry_sdk .configure_scope () as scope :
1168- scope .set_tag ("version" , version .name )
1169- scope .set_tag ("language" , language .tag )
1169+ scope = sentry_sdk .get_isolation_scope ()
1170+ scope .set_tag ("version" , version .name )
1171+ scope .set_tag ("language" , language .tag )
11701172 builder = DocBuilder (
11711173 version , versions , language , languages , cpython_repo , ** vars (args )
11721174 )
0 commit comments