Skip to content

Commit 2e91dd8

Browse files
authored
⬆️ Drop Sphinx 3, add Sphinx 5 (#579)
1 parent 3c45b7e commit 2e91dd8

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+343
-1891
lines changed

.github/workflows/tests.yml

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,16 +26,15 @@ jobs:
2626
fail-fast: false
2727
matrix:
2828
python-version: ["3.7", "3.8", "3.9", "3.10"]
29-
sphinx: [">=4,<5"]
29+
sphinx: [">=5,<6"]
3030
os: [ubuntu-latest]
3131
include:
32-
# fails because of: https://github.com/sphinx-doc/sphinx/issues/10291
33-
# - os: ubuntu-latest
34-
# python-version: "3.8"
35-
# sphinx: ">=3,<4"
36-
- os: windows-latest
37-
python-version: "3.8"
38-
sphinx: ">=4,<5"
32+
- os: ubuntu-latest
33+
python-version: "3.8"
34+
sphinx: ">=4,<5"
35+
- os: windows-latest
36+
python-version: "3.8"
37+
sphinx: ">=4,<5"
3938

4039
runs-on: ${{ matrix.os }}
4140

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ repos:
5050
- id: mypy
5151
args: [--config-file=pyproject.toml]
5252
additional_dependencies:
53-
- sphinx~=4.1
53+
- sphinx~=5.0
5454
- markdown-it-py>=1.0.0,<3.0.0
5555
- mdit-py-plugins~=0.3.0
5656
files: >

myst_parser/_compat.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
"""Helpers for cross compatibility across dependency versions."""
2+
from typing import Callable, Iterable
3+
4+
from docutils.nodes import Element
5+
6+
7+
def findall(node: Element) -> Callable[..., Iterable[Element]]:
8+
"""Iterate through"""
9+
# findall replaces traverse in docutils v0.18
10+
# note a difference is that findall is an iterator
11+
return getattr(node, "findall", node.traverse)

myst_parser/mdit_to_docutils/base.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
from markdown_it.token import Token
3333
from markdown_it.tree import SyntaxTreeNode
3434

35+
from myst_parser._compat import findall
3536
from myst_parser.config.main import MdParserConfig
3637
from myst_parser.mocking import (
3738
MockIncludeDirective,
@@ -41,7 +42,7 @@
4142
MockState,
4243
MockStateMachine,
4344
)
44-
from ..parsers.directives import DirectiveParsingError, parse_directive_text
45+
from myst_parser.parsers.directives import DirectiveParsingError, parse_directive_text
4546
from .html_to_nodes import html_to_nodes
4647
from .utils import is_external_url
4748

@@ -260,7 +261,7 @@ def _render_finalise(self) -> None:
260261
# those from the initial markdown parse
261262
# instead we gather them from a walk of the created document
262263
foot_refs = OrderedDict()
263-
for refnode in self.document.traverse(nodes.footnote_reference):
264+
for refnode in findall(self.document)(nodes.footnote_reference):
264265
if refnode["refname"] not in foot_refs:
265266
foot_refs[refnode["refname"]] = True
266267

@@ -447,7 +448,7 @@ def render_inline(self, token: SyntaxTreeNode) -> None:
447448
self.render_children(token)
448449

449450
def render_text(self, token: SyntaxTreeNode) -> None:
450-
self.current_node.append(nodes.Text(token.content, token.content))
451+
self.current_node.append(nodes.Text(token.content))
451452

452453
def render_bullet_list(self, token: SyntaxTreeNode) -> None:
453454
list_node = nodes.bullet_list()
@@ -888,7 +889,7 @@ def dict_to_fm_field_list(
888889

889890
field_node = nodes.field()
890891
field_node.source = value
891-
field_node += nodes.field_name(key, "", nodes.Text(key, key))
892+
field_node += nodes.field_name(key, "", nodes.Text(key))
892893
field_node += nodes.field_body(value, *[body])
893894
field_list += field_node
894895

myst_parser/sphinx_ext/myst_refs.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
from sphinx.util import docname_join, logging
1717
from sphinx.util.nodes import clean_astext, make_refnode
1818

19+
from myst_parser._compat import findall
20+
1921
try:
2022
from sphinx.errors import NoUri
2123
except ImportError:
@@ -35,7 +37,7 @@ class MystReferenceResolver(ReferencesResolver):
3537

3638
def run(self, **kwargs: Any) -> None:
3739
self.document: document
38-
for node in self.document.traverse(addnodes.pending_xref):
40+
for node in findall(self.document)(addnodes.pending_xref):
3941
if node["reftype"] != "myst":
4042
continue
4143

pyproject.toml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,12 @@ keywords = [
3434
]
3535
requires-python = ">=3.7"
3636
dependencies = [
37-
"docutils>=0.15,<0.18",
37+
"docutils>=0.15,<0.19",
3838
"jinja2", # required for substitutions, but let sphinx choose version
3939
"markdown-it-py>=1.0.0,<3.0.0",
4040
"mdit-py-plugins~=0.3.0",
4141
"pyyaml",
42-
"sphinx>=3.1,<5",
42+
"sphinx>=4,<6",
4343
"typing-extensions",
4444
]
4545

@@ -63,7 +63,6 @@ rtd = [
6363
testing = [
6464
"beautifulsoup4",
6565
"coverage[toml]",
66-
"docutils~=0.17.0", # this version changes some HTML tags
6766
"pytest>=6,<7",
6867
"pytest-cov",
6968
"pytest-regressions",

tests/test_renderers/fixtures/sphinx_directives.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ default-domain (`sphinx.directives.DefaultDomain`):
1414
<document source="<src>/index.md">
1515
.
1616

17-
SPHINX4 object (`sphinx.directives.ObjectDescription`):
17+
object (`sphinx.directives.ObjectDescription`):
1818
.
1919
```{object} something
2020
```
@@ -161,7 +161,7 @@ acks (`sphinx.directives.other.Acks`):
161161
name
162162
.
163163

164-
SPHINX4 hlist (`sphinx.directives.other.HList`):
164+
hlist (`sphinx.directives.other.HList`):
165165
.
166166
```{hlist}
167167
@@ -386,18 +386,18 @@ term 2 : B
386386
Definition of both terms.
387387
.
388388

389-
SPHINX3 productionlist (`sphinx.domains.std.ProductionList`):
389+
SPHINX4-SKIP productionlist (`sphinx.domains.std.ProductionList`):
390390
.
391391
```{productionlist} try_stmt: try1_stmt | try2_stmt
392392
```
393393
.
394394
<document source="<src>/index.md">
395395
<productionlist>
396-
<production ids="grammar-token-try_stmt grammar-token-try-stmt" tokenname="try_stmt" xml:space="preserve">
396+
<production ids="grammar-token-try_stmt" tokenname="try_stmt" xml:space="preserve">
397397
try1_stmt | try2_stmt
398398
.
399399

400-
SPHINX4 cmdoption (`sphinx.domains.std.Cmdoption`):
400+
cmdoption (`sphinx.domains.std.Cmdoption`):
401401
.
402402
```{cmdoption} a
403403
```
@@ -412,7 +412,7 @@ SPHINX4 cmdoption (`sphinx.domains.std.Cmdoption`):
412412
<desc_content>
413413
.
414414

415-
SPHINX4 rst:directive (`sphinx.domains.rst.ReSTDirective`):
415+
rst:directive (`sphinx.domains.rst.ReSTDirective`):
416416
.
417417
```{rst:directive} a
418418
```
@@ -426,15 +426,15 @@ SPHINX4 rst:directive (`sphinx.domains.rst.ReSTDirective`):
426426
<desc_content>
427427
.
428428

429-
SPHINX4 rst:directive:option (`sphinx.domains.rst.ReSTDirectiveOption`):
429+
SPHINX4-SKIP rst:directive:option (`sphinx.domains.rst.ReSTDirectiveOption`):
430430
.
431431
```{rst:directive:option} a
432432
```
433433
.
434434
<document source="<src>/index.md">
435435
<index entries="('single',\ ':a:\ (directive\ option)',\ 'directive-option-a',\ '',\ 'A')">
436436
<desc classes="rst directive:option" desctype="directive:option" domain="rst" noindex="False" objtype="directive:option">
437-
<desc_signature classes="sig sig-object" ids="directive-option-a directive:option--a">
437+
<desc_signature classes="sig sig-object" ids="directive-option-a">
438438
<desc_name classes="sig-name descname" xml:space="preserve">
439439
:a:
440440
<desc_content>

tests/test_renderers/test_fixtures_sphinx.py

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
from pathlib import Path
1010

1111
import pytest
12-
import sphinx
1312
from sphinx_pytest.plugin import CreateDoctree
1413

1514
from myst_parser.mdit_to_docutils.sphinx_ import SphinxRenderer
@@ -42,11 +41,9 @@ def test_directive_options(file_params, sphinx_doctree_no_tr: CreateDoctree):
4241
def test_sphinx_directives(file_params, sphinx_doctree_no_tr: CreateDoctree):
4342
# TODO fix skipped directives
4443
# TODO test domain directives
45-
if file_params.title.startswith("SKIP"):
46-
pytest.skip(file_params.title)
47-
elif file_params.title.startswith("SPHINX3") and sphinx.version_info[0] < 3:
48-
pytest.skip(file_params.title)
49-
elif file_params.title.startswith("SPHINX4") and sphinx.version_info[0] < 4:
44+
if file_params.title.startswith("SKIP") or file_params.title.startswith(
45+
"SPHINX4-SKIP"
46+
):
5047
pytest.skip(file_params.title)
5148

5249
sphinx_doctree_no_tr.set_conf({"extensions": ["myst_parser"]})
@@ -63,8 +60,6 @@ def test_sphinx_directives(file_params, sphinx_doctree_no_tr: CreateDoctree):
6360
def test_sphinx_roles(file_params, sphinx_doctree_no_tr: CreateDoctree):
6461
if file_params.title.startswith("SKIP"):
6562
pytest.skip(file_params.title)
66-
elif file_params.title.startswith("SPHINX4") and sphinx.version_info[0] < 4:
67-
pytest.skip(file_params.title)
6863

6964
sphinx_doctree_no_tr.set_conf({"extensions": ["myst_parser"]})
7065
pformat = sphinx_doctree_no_tr(file_params.content, "index.md").pformat("index")

tests/test_sphinx/conftest.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ def test_basic(app, status, warning, get_sphinx_app_output):
3939
from bs4 import BeautifulSoup
4040
from sphinx.testing.path import path
4141

42+
from myst_parser._compat import findall
43+
4244
SOURCE_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), "sourcedirs"))
4345

4446

@@ -109,7 +111,7 @@ def read(
109111
extension = regress_ext
110112

111113
# convert absolute filenames
112-
for node in doctree.traverse(
114+
for node in findall(doctree)(
113115
lambda n: "source" in n and not isinstance(n, str)
114116
):
115117
node["source"] = pathlib.Path(node["source"]).name

tests/test_sphinx/test_sphinx_builds.py

Lines changed: 21 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -37,19 +37,19 @@ def test_basic(
3737
warnings = warning.getvalue().strip()
3838
assert warnings == ""
3939

40-
get_sphinx_app_doctree(
41-
app,
42-
docname="content",
43-
regress=True,
44-
regress_ext=f".sphinx{sphinx.version_info[0]}.xml",
45-
)
46-
get_sphinx_app_doctree(
47-
app,
48-
docname="content",
49-
resolve=True,
50-
regress=True,
51-
regress_ext=f".sphinx{sphinx.version_info[0]}.xml",
52-
)
40+
try:
41+
get_sphinx_app_doctree(
42+
app,
43+
docname="content",
44+
regress=True,
45+
)
46+
finally:
47+
get_sphinx_app_doctree(
48+
app,
49+
docname="content",
50+
resolve=True,
51+
regress=True,
52+
)
5353
get_sphinx_app_output(
5454
app,
5555
filename="content.html",
@@ -104,7 +104,7 @@ def test_references(
104104
app,
105105
filename="index.html",
106106
regress_html=True,
107-
regress_ext=f".sphinx{sphinx.version_info[0]}.html",
107+
replace={"Permalink to this headline": "Permalink to this heading"},
108108
)
109109

110110

@@ -154,7 +154,7 @@ def test_references_singlehtml(
154154
filename="index.html",
155155
buildername="singlehtml",
156156
regress_html=True,
157-
regress_ext=f".sphinx{sphinx.version_info[0]}.html",
157+
replace={"Permalink to this headline": "Permalink to this heading"},
158158
)
159159

160160

@@ -185,7 +185,7 @@ def test_heading_slug_func(
185185
app,
186186
filename="index.html",
187187
regress_html=True,
188-
regress_ext=f".sphinx{sphinx.version_info[0]}.html",
188+
replace={"Permalink to this headline": "Permalink to this heading"},
189189
)
190190

191191

@@ -216,14 +216,13 @@ def test_extended_syntaxes(
216216
app,
217217
docname="index",
218218
regress=True,
219-
regress_ext=f".sphinx{sphinx.version_info[0]}.xml",
220219
)
221220
finally:
222221
get_sphinx_app_output(
223222
app,
224223
filename="index.html",
225224
regress_html=True,
226-
regress_ext=f".sphinx{sphinx.version_info[0]}.html",
225+
replace={"Permalink to this headline": "Permalink to this heading"},
227226
)
228227

229228

@@ -249,7 +248,6 @@ def test_includes(
249248
app,
250249
docname="index",
251250
regress=True,
252-
regress_ext=f".sphinx{sphinx.version_info[0]}.xml",
253251
# fix for Windows CI
254252
replace={
255253
r"subfolder\example2.jpg": "subfolder/example2.jpg",
@@ -262,8 +260,8 @@ def test_includes(
262260
app,
263261
filename="index.html",
264262
regress_html=True,
265-
regress_ext=f".sphinx{sphinx.version_info[0]}.html",
266263
replace={
264+
"Permalink to this headline": "Permalink to this heading",
267265
r"'subfolder\\example2'": "'subfolder/example2'",
268266
r'uri="subfolder\\example2"': 'uri="subfolder/example2"',
269267
"_images/example21.jpg": "_images/example2.jpg",
@@ -354,7 +352,7 @@ def test_commonmark_only(
354352
app,
355353
filename="index.html",
356354
regress_html=True,
357-
regress_ext=f".sphinx{sphinx.version_info[0]}.html",
355+
replace={"Permalink to this headline": "Permalink to this heading"},
358356
)
359357

360358

@@ -407,7 +405,7 @@ def test_gettext(
407405
output = re.sub(r"POT-Creation-Date: [0-9: +-]+", "POT-Creation-Date: ", output)
408406
output = re.sub(r"Copyright \(C\) [0-9]{4}", "Copyright (C) XXXX", output)
409407

410-
file_regression.check(output, extension=f".sphinx{sphinx.version_info[0]}.pot")
408+
file_regression.check(output, extension=".pot")
411409

412410

413411
@pytest.mark.sphinx(
@@ -434,15 +432,13 @@ def test_gettext_html(
434432
app,
435433
docname="index",
436434
regress=True,
437-
regress_ext=f".sphinx{sphinx.version_info[0]}.xml",
438435
)
439436
finally:
440437
get_sphinx_app_doctree(
441438
app,
442439
docname="index",
443440
resolve=True,
444441
regress=True,
445-
regress_ext=f".sphinx{sphinx.version_info[0]}.xml",
446442
)
447443
get_sphinx_app_output(
448444
app,
@@ -483,7 +479,7 @@ def test_gettext_additional_targets(
483479
output = re.sub(r"POT-Creation-Date: [0-9: +-]+", "POT-Creation-Date: ", output)
484480
output = re.sub(r"Copyright \(C\) [0-9]{4}", "Copyright (C) XXXX", output)
485481

486-
file_regression.check(output, extension=f".sphinx{sphinx.version_info[0]}.pot")
482+
file_regression.check(output, extension=".pot")
487483

488484

489485
@pytest.mark.sphinx(
@@ -530,7 +526,6 @@ def test_fieldlist_extension(
530526
app,
531527
docname="index",
532528
regress=True,
533-
regress_ext=f".sphinx{sphinx.version_info[0]}.xml",
534529
# changed in:
535530
# https://www.sphinx-doc.org/en/master/changes.html#release-4-4-0-released-jan-17-2022
536531
replace={

0 commit comments

Comments
 (0)