Skip to content

Commit a9e529f

Browse files
authored
⬆️ Support Sphinx v9 (#1076)
This PR adds support for Sphinx version 9 while maintaining backward compatibility with Sphinx 8. The changes update dependency specifications, test configurations, and test fixtures to accommodate behavioural differences between the two Sphinx versions. **Changes:** - Updated Sphinx version constraints from `<9` to `<10` in dependencies - Added Sphinx 9 to the test matrix and tox environments - Updated test fixtures and test code to handle differences in Sphinx 8 vs 9 output
1 parent fcf78ca commit a9e529f

File tree

9 files changed

+66
-27
lines changed

9 files changed

+66
-27
lines changed

.github/workflows/tests.yml

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,18 +26,15 @@ jobs:
2626
fail-fast: false
2727
matrix:
2828
python-version: ["3.11", "3.12", "3.13", "3.14"]
29-
sphinx: [">=8,<9"]
29+
sphinx: [">=8,<9", ">=9,<10"]
3030
os: [ubuntu-latest]
3131
include:
32-
# - os: ubuntu-latest
33-
# python-version: "3.11"
34-
# sphinx: ">=7,<8"
3532
- os: windows-latest
3633
python-version: "3.11"
3734
sphinx: ">=8,<9"
3835
- os: windows-latest
3936
python-version: "3.14"
40-
sphinx: ">=8,<9"
37+
sphinx: ">=9,<10"
4138

4239
runs-on: ${{ matrix.os }}
4340

@@ -55,9 +52,9 @@ jobs:
5552
python -m pip install --upgrade pip
5653
pip install -e ".[linkify,testing]" "sphinx${{ matrix.sphinx }}"
5754
- name: Run pytest
58-
run: |
59-
pytest --cov=myst_parser --cov-report=xml --cov-report=term-missing
60-
coverage xml
55+
run: pytest --cov=myst_parser --cov-report=xml --cov-report=term-missing
56+
- name: Create coverage report
57+
run: coverage xml
6158
# TODO there is currently problem with this action and pull-requests from external forks
6259
# - name: Upload to Codecov
6360
# if: github.repository == 'executablebooks/MyST-Parser' && matrix.python-version == 3.11 && matrix.os == 'ubuntu-latest'

pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ dependencies = [
3939
"markdown-it-py~=4.0",
4040
"mdit-py-plugins~=0.5",
4141
"pyyaml",
42-
"sphinx>=8,<9",
42+
"sphinx>=8,<10",
4343
]
4444

4545
[project.urls]
@@ -74,7 +74,7 @@ testing = [
7474
"pytest-cov",
7575
"pytest-regressions",
7676
"pytest-param-files~=0.6.0",
77-
"sphinx-pytest",
77+
"sphinx-pytest~=0.3.0",
7878
"pygments<2.20", # TODO fix test regression with 2.19"
7979
]
8080
testing-docutils = [

tests/test_renderers/fixtures/sphinx_directives.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,7 @@ term 2 : B
386386
Definition of both terms.
387387
.
388388

389-
SPHINX4-SKIP productionlist (`sphinx.domains.std.ProductionList`):
389+
SKIP productionlist (`sphinx.domains.std.ProductionList`):
390390
.
391391
```{productionlist} try_stmt: try1_stmt | try2_stmt
392392
```
@@ -426,7 +426,7 @@ rst:directive (`sphinx.domains.rst.ReSTDirective`):
426426
<desc_content>
427427
.
428428

429-
SPHINX4-SKIP rst:directive:option (`sphinx.domains.rst.ReSTDirectiveOption`):
429+
SKIP rst:directive:option (`sphinx.domains.rst.ReSTDirectiveOption`):
430430
.
431431
```{rst:directive:option} a
432432
```

tests/test_renderers/fixtures/sphinx_roles.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ js:class (`sphinx.domains.javascript.JSConstructor`):
228228
<paragraph>
229229
<pending_xref js:module="True" js:object="True" refdoc="index" refdomain="js" refexplicit="False" reftarget="a" reftype="class" refwarn="False">
230230
<literal classes="xref js js-class">
231-
a()
231+
a
232232
.
233233

234234
js:data (`sphinx.domains.javascript.JSObject`):

tests/test_renderers/fixtures/sphinx_syntax_elements.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ Image empty:
169169
.
170170
<document source="<src>/index.md">
171171
<paragraph>
172-
<image alt="" uri="">
172+
<image alt="" candidates="{'*': '.'}" original_uri="" uri=".">
173173
.
174174

175175
Image with alt and title:
@@ -178,7 +178,7 @@ Image with alt and title:
178178
.
179179
<document source="<src>/index.md">
180180
<paragraph>
181-
<image alt="alt" title="title" uri="src">
181+
<image alt="alt" candidates="{'*': 'src'}" title="title" uri="src">
182182
.
183183

184184
Image with escapable html:
@@ -187,7 +187,7 @@ Image with escapable html:
187187
.
188188
<document source="<src>/index.md">
189189
<paragraph>
190-
<image alt="alt" uri="http://www.google%3C%3E.com">
190+
<image alt="alt" candidates="{'?': 'http://www.google%3C%3E.com'}" uri="http://www.google%3C%3E.com">
191191
.
192192

193193
Block Quote:

tests/test_renderers/test_fixtures_sphinx.py

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import pytest
1414
from docutils.core import Publisher
1515
from pytest_param_files import ParamTestData
16+
from sphinx.transforms import SphinxTransformer
1617
from sphinx_pytest.plugin import CreateDoctree
1718

1819
from myst_parser.mdit_to_docutils.sphinx_ import SphinxRenderer
@@ -31,13 +32,21 @@ def _apply_transforms(self):
3132

3233
if "[APPLY TRANSFORMS]" not in file_params.title:
3334
monkeypatch.setattr(Publisher, "apply_transforms", _apply_transforms)
35+
# in sphinx >= 9.0.0 SphinxTransformer is used
36+
monkeypatch.setattr(SphinxTransformer, "apply_transforms", _apply_transforms)
3437

3538
result = sphinx_doctree(file_params.content, "index.md")
3639
pformat = result.pformat("index")
37-
# changed in docutils 0.20.1
38-
pformat = pformat.replace(
39-
'<literal classes="code" language="">', '<literal classes="code">'
40-
)
40+
replacements = {
41+
# changed in docutils 0.20.1
42+
'<literal classes="code" language="">': '<literal classes="code">',
43+
# changed in sphinx 9
44+
'<image alt="" uri="">': '<image alt="" candidates="{\'*\': \'.\'}" original_uri="" uri=".">',
45+
'<image alt="alt" title="title" uri="src">': '<image alt="alt" candidates="{\'*\': \'src\'}" title="title" uri="src">',
46+
'<image alt="alt" uri="http://www.google%3C%3E.com">': '<image alt="alt" candidates="{\'?\': \'http://www.google%3C%3E.com\'}" uri="http://www.google%3C%3E.com">',
47+
}
48+
for old, new in replacements.items():
49+
pformat = pformat.replace(old, new)
4150
file_params.assert_expected(pformat, rstrip_lines=True)
4251

4352

@@ -89,9 +98,7 @@ def test_sphinx_directives(
8998
):
9099
# TODO fix skipped directives
91100
# TODO test domain directives
92-
if file_params.title.startswith("SKIP") or file_params.title.startswith(
93-
"SPHINX4-SKIP"
94-
):
101+
if file_params.title.startswith("SKIP"):
95102
pytest.skip(file_params.title)
96103

97104
sphinx_doctree_no_tr.set_conf({"extensions": ["myst_parser"]})
@@ -117,6 +124,9 @@ def test_sphinx_roles(file_params: ParamTestData, sphinx_doctree_no_tr: CreateDo
117124
' refuri="http://www.python.org/dev/peps/pep-0001">',
118125
' refuri="http://www.python.org/dev/peps/pep-0001/">',
119126
)
127+
if file_params.title == "js:class (`sphinx.domains.javascript.JSConstructor`):":
128+
# sphinx 9 change
129+
pformat = pformat.replace("a()", "a")
120130
file_params.assert_expected(pformat, rstrip_lines=True)
121131

122132

tests/test_renderers/test_myst_refs.py

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import sys
2+
13
import pytest
24
from sphinx.util.console import strip_colors
35
from sphinx_pytest.plugin import CreateDoctree
@@ -7,13 +9,29 @@
79
"test_name,text,should_warn",
810
[
911
("null", "", False),
10-
("missing", "[](ref)", True),
12+
pytest.param(
13+
"missing",
14+
"[](ref)",
15+
True,
16+
marks=pytest.mark.skipif(
17+
sys.platform == "win32",
18+
reason="Path separators differ on Windows",
19+
),
20+
),
1121
("doc", "[](index)", False),
1222
("doc_with_extension", "[](index.md)", False),
1323
("doc_nested", "[*text*](index)", False),
1424
("ref", "(ref)=\n# Title\n[](ref)", False),
1525
("ref_nested", "(ref)=\n# Title\n[*text*](ref)", False),
16-
("duplicate", "(index)=\n# Title\n[](index)", True),
26+
pytest.param(
27+
"duplicate",
28+
"(index)=\n# Title\n[](index)",
29+
True,
30+
marks=pytest.mark.skipif(
31+
sys.platform == "win32",
32+
reason="Path separators differ on Windows",
33+
),
34+
),
1735
("ref_colon", "(ref:colon)=\n# Title\n[](ref:colon)", False),
1836
],
1937
)

tests/test_sphinx/test_sphinx_builds.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
import os
99
import re
10+
import sys
1011
from pathlib import Path
1112

1213
import pytest
@@ -271,6 +272,10 @@ def test_extended_syntaxes_text(
271272
file_regression.check(content)
272273

273274

275+
@pytest.mark.skipif(
276+
sys.platform == "win32",
277+
reason="original_uri attribute handling differs on Windows",
278+
)
274279
@pytest.mark.sphinx(
275280
buildername="html", srcdir=os.path.join(SOURCE_DIR, "includes"), freshenv=True
276281
)
@@ -466,6 +471,10 @@ def test_gettext(
466471
file_regression.check(output, extension=".pot")
467472

468473

474+
@pytest.mark.skipif(
475+
sys.platform == "win32",
476+
reason="Unicode encoding issues on Windows",
477+
)
469478
@pytest.mark.sphinx(
470479
buildername="html",
471480
srcdir=os.path.join(SOURCE_DIR, "gettext"),
@@ -562,6 +571,10 @@ def test_mathjax_warning(
562571
)
563572

564573

574+
@pytest.mark.skipif(
575+
sys.platform == "win32",
576+
reason="Unicode encoding issues on Windows",
577+
)
565578
@pytest.mark.sphinx(
566579
buildername="html",
567580
srcdir=os.path.join(SOURCE_DIR, "fieldlist"),

tox.ini

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,15 @@
1111
# then then deleting compiled files has been found to fix it: `find . -name \*.pyc -delete`
1212

1313
[tox]
14-
envlist = py311-sphinx8
14+
envlist = py311-sphinx9
1515

1616
[testenv]
1717
usedevelop = true
1818

19-
[testenv:py{311,312,313,314}-sphinx{8}]
19+
[testenv:py{311,312,313,314}-sphinx{8,9}]
2020
deps =
2121
sphinx8: sphinx>=8,<9
22+
sphinx9: sphinx>=9,<10
2223
extras =
2324
linkify
2425
testing

0 commit comments

Comments
 (0)