diff --git a/CHANGES b/CHANGES index e823bdf0c..2dbb9ae7c 100644 --- a/CHANGES +++ b/CHANGES @@ -37,6 +37,12 @@ Features added Bugs fixed ---------- +* #10498: gettext: TypeError is raised when sorting warning messages if a node + has no line number +* #10493: html theme: :rst:dir:`topic` directive is rendered incorrectly with + docutils-0.18 +* #10495: IndexError is raised for a :rst:role:`kbd` role having a separator + Testing -------- diff --git a/sphinx/builders/gettext.py b/sphinx/builders/gettext.py index 0d7d0ac11..92edcc9f2 100644 --- a/sphinx/builders/gettext.py +++ b/sphinx/builders/gettext.py @@ -53,7 +53,10 @@ class Catalog: if msg not in self.metadata: # faster lookup in hash self.messages.append(msg) self.metadata[msg] = [] - self.metadata[msg].append((origin.source, origin.line, origin.uid)) # type: ignore + line = origin.line + if line is None: + line = -1 + self.metadata[msg].append((origin.source, line, origin.uid)) # type: ignore def __iter__(self) -> Generator[Message, None, None]: for message in self.messages: diff --git a/sphinx/builders/html/transforms.py b/sphinx/builders/html/transforms.py index ea596cb4b..1ba6ba857 100644 --- a/sphinx/builders/html/transforms.py +++ b/sphinx/builders/html/transforms.py @@ -40,7 +40,9 @@ class KeyboardTransform(SphinxPostTransform): def run(self, **kwargs: Any) -> None: matcher = NodeMatcher(nodes.literal, classes=["kbd"]) - for node in self.document.findall(matcher): # type: nodes.literal + # this list must be pre-created as during iteration new nodes + # are added which match the condition in the NodeMatcher. + for node in list(self.document.findall(matcher)): # type: nodes.literal parts = self.pattern.split(node[-1].astext()) if len(parts) == 1 or self.is_multiwords_key(parts): continue diff --git a/sphinx/ext/ifconfig.py b/sphinx/ext/ifconfig.py index bffaa49ff..f0d115077 100644 --- a/sphinx/ext/ifconfig.py +++ b/sphinx/ext/ifconfig.py @@ -51,7 +51,7 @@ def process_ifconfig_nodes(app: Sphinx, doctree: nodes.document, docname: str) - ns = {confval.name: confval.value for confval in app.config} ns.update(app.config.__dict__.copy()) ns['builder'] = app.builder.name - for node in doctree.findall(ifconfig): + for node in list(doctree.findall(ifconfig)): try: res = eval(node['expr'], ns) except Exception as err: diff --git a/sphinx/themes/agogo/static/agogo.css_t b/sphinx/themes/agogo/static/agogo.css_t index 08a4db0cc..14c5e52ce 100644 --- a/sphinx/themes/agogo/static/agogo.css_t +++ b/sphinx/themes/agogo/static/agogo.css_t @@ -271,7 +271,8 @@ div.document ol { /* Sidebar */ -div.sidebar { +div.sidebar, +aside.sidebar { width: {{ theme_sidebarwidth|todim }}; {%- if theme_rightsidebar|tobool %} float: right; @@ -281,26 +282,29 @@ div.sidebar { font-size: .9em; } -div.sidebar a, div.header a { +div.sidebar a, aside.sidebar a, div.header a { text-decoration: none; } -div.sidebar a:hover, div.header a:hover { +div.sidebar a:hover, aside.sidebar a:hover, div.header a:hover { text-decoration: underline; } -div.sidebar h3 { +div.sidebar h3, +aside.sidebar h3 { color: #2e3436; text-transform: uppercase; font-size: 130%; letter-spacing: .1em; } -div.sidebar ul { +div.sidebar ul, +aside.sidebar ul { list-style-type: none; } -div.sidebar li.toctree-l1 a { +div.sidebar li.toctree-l1 a, +aside.sidebar li.toctree-l1 a { display: block; padding: 1px; border: 1px solid #dddddd; @@ -310,37 +314,44 @@ div.sidebar li.toctree-l1 a { color: #2e3436; } -div.sidebar li.toctree-l2 a { +div.sidebar li.toctree-l2 a, +aside.sidebar li.toctree-l2 a { background-color: transparent; border: none; margin-left: 1em; border-bottom: 1px solid #dddddd; } -div.sidebar li.toctree-l3 a { +div.sidebar li.toctree-l3 a, +aside.sidebar li.toctree-l3 a { background-color: transparent; border: none; margin-left: 2em; border-bottom: 1px solid #dddddd; } -div.sidebar li.toctree-l2:last-child a { +div.sidebar li.toctree-l2:last-child a, +aside.sidebar li.toctree-l2:last-child a { border-bottom: none; } -div.sidebar li.toctree-l1.current a { +div.sidebar li.toctree-l1.current a, +aside.sidebar li.toctree-l1.current a { border-right: 5px solid {{ theme_headerlinkcolor }}; } -div.sidebar li.toctree-l1.current li.toctree-l2 a { +div.sidebar li.toctree-l1.current li.toctree-l2 a, +aside.sidebar li.toctree-l1.current li.toctree-l2 a { border-right: none; } -div.sidebar input[type="text"] { +div.sidebar input[type="text"], +aside.sidebar input[type="text"] { width: 170px; } -div.sidebar input[type="submit"] { +div.sidebar input[type="submit"], +aside.sidebar input[type="submit"] { width: 30px; } diff --git a/sphinx/themes/basic/static/basic.css_t b/sphinx/themes/basic/static/basic.css_t index a05c8ba0e..9e5047afe 100644 --- a/sphinx/themes/basic/static/basic.css_t +++ b/sphinx/themes/basic/static/basic.css_t @@ -335,13 +335,13 @@ p.sidebar-title { font-weight: bold; } -div.admonition, div.topic, blockquote { +div.admonition, div.topic, aside.topic, blockquote { clear: left; } /* -- topics ---------------------------------------------------------------- */ -div.topic { +div.topic, aside.topic { border: 1px solid #ccc; padding: 7px; margin: 10px 0 10px 0; @@ -380,6 +380,7 @@ div.body p.centered { div.sidebar > :last-child, aside.sidebar > :last-child, div.topic > :last-child, +aside.topic > :last-child, div.admonition > :last-child { margin-bottom: 0; } @@ -387,6 +388,7 @@ div.admonition > :last-child { div.sidebar::after, aside.sidebar::after, div.topic::after, +aside.topic::after, div.admonition::after, blockquote::after { display: block; diff --git a/sphinx/themes/bizstyle/static/bizstyle.css_t b/sphinx/themes/bizstyle/static/bizstyle.css_t index 465734646..b5c84e0bb 100644 --- a/sphinx/themes/bizstyle/static/bizstyle.css_t +++ b/sphinx/themes/bizstyle/static/bizstyle.css_t @@ -306,7 +306,7 @@ div.quotebar { border: 1px solid #ccc; } -div.topic { +div.topic, aside.topic { background-color: #f8f8f8; } diff --git a/sphinx/themes/classic/static/classic.css_t b/sphinx/themes/classic/static/classic.css_t index 739def5cd..58b55c8bf 100644 --- a/sphinx/themes/classic/static/classic.css_t +++ b/sphinx/themes/classic/static/classic.css_t @@ -290,7 +290,7 @@ div.seealso { border: 1px solid #ff6; } -div.topic { +div.topic, aside.topic { background-color: #eee; } diff --git a/sphinx/themes/epub/static/epub.css_t b/sphinx/themes/epub/static/epub.css_t index 981baaab0..bd64a1bc8 100644 --- a/sphinx/themes/epub/static/epub.css_t +++ b/sphinx/themes/epub/static/epub.css_t @@ -230,7 +230,7 @@ p.rubric { /* -- sidebars -------------------------------------------------------------- */ -div.sidebar { +div.sidebar, aside.sidebar { margin: 0 0 0.5em 1em; border: 1px solid #ddb; padding: 7px 7px 0 7px; @@ -245,7 +245,7 @@ p.sidebar-title { /* -- topics ---------------------------------------------------------------- */ -div.topic { +div.topic, aside.topic { border: 1px solid #ccc; padding: 7px 7px 0 7px; margin: 10px 0 10px 0; diff --git a/sphinx/themes/nature/static/nature.css_t b/sphinx/themes/nature/static/nature.css_t index 28a4f64c9..f3c0d0224 100644 --- a/sphinx/themes/nature/static/nature.css_t +++ b/sphinx/themes/nature/static/nature.css_t @@ -194,7 +194,7 @@ div.seealso { border: 1px solid #ff6; } -div.topic { +div.topic, aside.topic { background-color: #eee; } diff --git a/sphinx/themes/nonav/static/nonav.css b/sphinx/themes/nonav/static/nonav.css index 98d2163a4..90c3300cf 100644 --- a/sphinx/themes/nonav/static/nonav.css +++ b/sphinx/themes/nonav/static/nonav.css @@ -219,7 +219,7 @@ p.rubric { /* -- sidebars -------------------------------------------------------------- */ -div.sidebar { +div.sidebar, aside.sidebar { margin: 0 0 0.5em 1em; border: 1px solid #ddb; padding: 7px 7px 0 7px; @@ -234,7 +234,7 @@ p.sidebar-title { /* -- topics ---------------------------------------------------------------- */ -div.topic { +div.topic, aside.topic { border: 1px solid #ccc; padding: 7px 7px 0 7px; margin: 10px 0 10px 0; diff --git a/sphinx/themes/pyramid/static/epub.css b/sphinx/themes/pyramid/static/epub.css index 165f41d5d..8606c8c8d 100644 --- a/sphinx/themes/pyramid/static/epub.css +++ b/sphinx/themes/pyramid/static/epub.css @@ -254,7 +254,7 @@ div.seealso { border: 1px solid #ff6; } -div.topic { +div.topic, aside.topic { background-color: #eee; } diff --git a/sphinx/themes/pyramid/static/pyramid.css_t b/sphinx/themes/pyramid/static/pyramid.css_t index c8c05af3b..f093ba164 100644 --- a/sphinx/themes/pyramid/static/pyramid.css_t +++ b/sphinx/themes/pyramid/static/pyramid.css_t @@ -155,7 +155,7 @@ div.sphinxsidebar .searchformwrapper { /* -- sidebars -------------------------------------------------------------- */ -div.sidebar { +div.sidebar, aside.sidebar { margin: 0 0 0.5em 1em; border: 2px solid #c6d880; background-color: #e6efc2; @@ -245,7 +245,7 @@ div.seealso { padding: 10px 20px 10px 60px; } -div.topic { +div.topic, aside.topic { background: #eeeeee; border: 2px solid #C6C9CB; padding: 10px 20px; diff --git a/sphinx/themes/sphinxdoc/static/sphinxdoc.css_t b/sphinx/themes/sphinxdoc/static/sphinxdoc.css_t index 1ff1d0291..b6de4ae6f 100644 --- a/sphinx/themes/sphinxdoc/static/sphinxdoc.css_t +++ b/sphinx/themes/sphinxdoc/static/sphinxdoc.css_t @@ -266,7 +266,7 @@ div.quotebar { border: 1px solid #ccc; } -div.topic { +div.topic, aside.topic { background-color: #f8f8f8; } diff --git a/sphinx/themes/traditional/static/traditional.css_t b/sphinx/themes/traditional/static/traditional.css_t index f98b33719..b5b05dc21 100644 --- a/sphinx/themes/traditional/static/traditional.css_t +++ b/sphinx/themes/traditional/static/traditional.css_t @@ -506,7 +506,7 @@ p.rubric { /* "Topics" */ -div.topic { +div.topic, aside.topic { background-color: #eee; border: 1px solid #ccc; padding: 0 7px 0 7px; diff --git a/tests/roots/test-ext-ifconfig/conf.py b/tests/roots/test-ext-ifconfig/conf.py index 565f6bcb3..e82ec79f2 100644 --- a/tests/roots/test-ext-ifconfig/conf.py +++ b/tests/roots/test-ext-ifconfig/conf.py @@ -7,3 +7,4 @@ confval1 = True def setup(app): app.add_config_value('confval1', False, None) app.add_config_value('confval2', False, None) + app.add_config_value('false_config', False, None) diff --git a/tests/roots/test-ext-ifconfig/index.rst b/tests/roots/test-ext-ifconfig/index.rst index ab08aabef..f7fabcc78 100644 --- a/tests/roots/test-ext-ifconfig/index.rst +++ b/tests/roots/test-ext-ifconfig/index.rst @@ -9,3 +9,13 @@ ifconfig egg +Issue 10496 regression test +=========================== + +.. ifconfig:: false_config + + `Link 1 `__ + +.. ifconfig:: false_config + + `Link 2 `__ diff --git a/tests/roots/test-transforms-post_transforms-keyboard/conf.py b/tests/roots/test-transforms-post_transforms-keyboard/conf.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/roots/test-transforms-post_transforms-keyboard/index.rst b/tests/roots/test-transforms-post_transforms-keyboard/index.rst new file mode 100644 index 000000000..21775782f --- /dev/null +++ b/tests/roots/test-transforms-post_transforms-keyboard/index.rst @@ -0,0 +1,4 @@ +Regression test for issue 10495 +=============================== + +:kbd:`spanish - inquisition` diff --git a/tests/test_transforms_post_transforms.py b/tests/test_transforms_post_transforms.py index 272d83e3a..215e6d14f 100644 --- a/tests/test_transforms_post_transforms.py +++ b/tests/test_transforms_post_transforms.py @@ -48,3 +48,12 @@ def test_missing_reference_conditional_pending_xref(app, status, warning): content = (app.outdir / 'index.html').read_text(encoding='utf8') assert 'Age' in content + + +@pytest.mark.sphinx('html', testroot='transforms-post_transforms-keyboard', + freshenv=True) +def test_keyboard_hyphen_spaces(app): + """Regression test for issue 10495, we want no crash.""" + app.build() + assert "spanish" in (app.outdir / 'index.html').read_text(encoding='utf8') + assert "inquisition" in (app.outdir / 'index.html').read_text(encoding='utf8')