Skip to content

Commit 418cdfe

Browse files
authored
Merge pull request #20104 from meeseeksmachine/auto-backport-of-pr-19686-on-v3.4.x
Backport PR #19686 on branch v3.4.x (Declare sphinxext.redirect_from parallel_read_safe)
2 parents fa57933 + fe617c5 commit 418cdfe

File tree

1 file changed

+36
-5
lines changed

1 file changed

+36
-5
lines changed

doc/sphinxext/redirect_from.py

+36-5
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232

3333
from pathlib import Path
3434
from docutils.parsers.rst import Directive
35+
from sphinx.domains import Domain
3536
from sphinx.util import logging
3637

3738
logger = logging.getLogger(__name__)
@@ -48,32 +49,62 @@
4849
def setup(app):
4950
RedirectFrom.app = app
5051
app.add_directive("redirect-from", RedirectFrom)
52+
app.add_domain(RedirectFromDomain)
5153
app.connect("build-finished", _generate_redirects)
5254

55+
metadata = {'parallel_read_safe': True}
56+
return metadata
57+
58+
59+
class RedirectFromDomain(Domain):
60+
"""
61+
The sole purpose of this domain is a parallel_read_safe data store for the
62+
redirects mapping.
63+
"""
64+
name = 'redirect_from'
65+
label = 'redirect_from'
66+
67+
@property
68+
def redirects(self):
69+
"""The mapping of the redirectes."""
70+
return self.data.setdefault('redirects', {})
71+
72+
def clear_doc(self, docnames):
73+
self.redirects.clear()
74+
75+
def merge_domaindata(self, docnames, otherdata):
76+
for src, dst in otherdata['redirects'].items():
77+
if src not in self.redirects:
78+
self.redirects[src] = dst
79+
elif self.redirects[src] != dst:
80+
raise ValueError(
81+
f"Inconsistent redirections from {src} to "
82+
F"{self.redirects[src]} and {otherdata.redirects[src]}")
83+
5384

5485
class RedirectFrom(Directive):
5586
required_arguments = 1
56-
redirects = {}
5787

5888
def run(self):
5989
redirected_doc, = self.arguments
6090
env = self.app.env
6191
builder = self.app.builder
92+
domain = env.get_domain('redirect_from')
6293
current_doc = env.path2doc(self.state.document.current_source)
6394
redirected_reldoc, _ = env.relfn2path(redirected_doc, current_doc)
64-
if redirected_reldoc in self.redirects:
95+
if redirected_reldoc in domain.redirects:
6596
raise ValueError(
6697
f"{redirected_reldoc} is already noted as redirecting to "
67-
f"{self.redirects[redirected_reldoc]}")
68-
self.redirects[redirected_reldoc] = current_doc
98+
f"{domain.redirects[redirected_reldoc]}")
99+
domain.redirects[redirected_reldoc] = current_doc
69100
return []
70101

71102

72103
def _generate_redirects(app, exception):
73104
builder = app.builder
74105
if builder.name != "html" or exception:
75106
return
76-
for k, v in RedirectFrom.redirects.items():
107+
for k, v in app.env.get_domain('redirect_from').redirects.items():
77108
p = Path(app.outdir, k + builder.out_suffix)
78109
html = HTML_TEMPLATE.format(v=builder.get_relative_uri(k, v))
79110
if p.is_file():

0 commit comments

Comments
 (0)