Skip to content

Commit 72b415f

Browse files
je-cookpre-commit-ci[bot]bsipocz
authored
FIX: fix path suffix condition in core/read.py (#641)
* Fix for documents with unknown number of multiple suffixes > 1 * test * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * remove stray addition --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Brigitta Sipőcz <[email protected]>
1 parent aee9a46 commit 72b415f

8 files changed

+337
-10
lines changed

myst_nb/core/read.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ def create_nb_reader(
6868
# we check suffixes ordered by longest first, to ensure we get the "closest" match
6969
iterator = sorted(readers.items(), key=lambda x: len(x[0]), reverse=True)
7070
for suffix, (reader, reader_kwargs, commonmark_only) in iterator:
71-
if Path(path).suffix == suffix:
71+
if str(Path(path)).endswith(suffix):
7272
if isinstance(reader, str):
7373
# attempt to load the reader as an object path
7474
reader = import_object(reader)

tests/conftest.py

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,20 @@ def build_matplotlib_font_cache():
3939
FontManager()
4040

4141

42+
def _split_ext(conf, sphinx_params):
43+
if custom_formats := conf.get("nb_custom_formats"):
44+
split_files = [
45+
file.rstrip(k)
46+
for file in sphinx_params["files"]
47+
for k in custom_formats.keys()
48+
if file.endswith(k)
49+
]
50+
else:
51+
split_files = [os.path.splitext(file)[0] for file in sphinx_params["files"]]
52+
53+
return split_files[0], split_files
54+
55+
4256
@pytest.fixture()
4357
def get_test_path():
4458
def _get_test_path(name):
@@ -55,7 +69,7 @@ class SphinxFixture:
5569
def __init__(self, app, filenames):
5670
self.app = app
5771
self.env = app.env
58-
self.files = [os.path.splitext(ff) for ff in filenames]
72+
self.files = filenames
5973
self.software_versions = (
6074
f".sphinx{sphinx.version_info[0]}" # software version tracking for fixtures
6175
)
@@ -79,42 +93,42 @@ def warnings(self):
7993

8094
def invalidate_files(self):
8195
"""Invalidate the files, such that it will be flagged for a re-read."""
82-
for name, _ in self.files:
96+
for name in self.files:
8397
self.env.all_docs.pop(name)
8498

8599
def get_resolved_doctree(self, docname=None):
86100
"""Load and return the built docutils.document, after post-transforms."""
87-
docname = docname or self.files[0][0]
101+
docname = docname or self.files[0]
88102
doctree = self.env.get_and_resolve_doctree(docname, self.app.builder)
89103
doctree["source"] = docname
90104
return doctree
91105

92106
def get_doctree(self, docname=None):
93107
"""Load and return the built docutils.document."""
94-
docname = docname or self.files[0][0]
108+
docname = docname or self.files[0]
95109
doctree = self.env.get_doctree(docname)
96110
doctree["source"] = docname
97111
return doctree
98112

99113
def get_html(self, index=0):
100114
"""Return the built HTML file."""
101-
name = self.files[index][0]
115+
name = self.files[index]
102116
_path = self.app.outdir / (name + ".html")
103117
if not _path.exists():
104118
pytest.fail("html not output")
105119
return bs4.BeautifulSoup(_path.read_text(), "html.parser")
106120

107121
def get_nb(self, index=0):
108122
"""Return the output notebook (after any execution)."""
109-
name = self.files[index][0]
123+
name = self.files[index]
110124
_path = self.app.srcdir / "_build" / "jupyter_execute" / (name + ".ipynb")
111125
if not _path.exists():
112126
pytest.fail("notebook not output")
113127
return _path.read_text(encoding="utf-8")
114128

115129
def get_report_file(self, index=0):
116130
"""Return the report file for a failed execution."""
117-
name = self.files[index][0]
131+
name = self.files[index]
118132
_path = self.app.outdir / "reports" / (name + ".err.log")
119133
if not _path.exists():
120134
pytest.fail("report log not output")
@@ -153,9 +167,11 @@ def sphinx_run(sphinx_params, make_app, tmp_path):
153167
conf = sphinx_params.get("conf", {})
154168
buildername = sphinx_params.get("buildername", "html")
155169

170+
master_doc, split_files = _split_ext(conf, sphinx_params)
171+
156172
confoverrides = {
157173
"extensions": ["myst_nb"],
158-
"master_doc": os.path.splitext(sphinx_params["files"][0])[0],
174+
"master_doc": master_doc,
159175
"exclude_patterns": ["_build"],
160176
"nb_execution_show_tb": True,
161177
}
@@ -199,7 +215,7 @@ def sphinx_run(sphinx_params, make_app, tmp_path):
199215
buildername=buildername, srcdir=app_srcdir, confoverrides=confoverrides
200216
)
201217

202-
yield SphinxFixture(app, sphinx_params["files"])
218+
yield SphinxFixture(app, split_files)
203219

204220
# reset working directory
205221
os.chdir(current_dir)
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
---
2+
title: "Test chunk options in Rmd/Jupyter conversion"
3+
author: "Marc Wouts"
4+
date: "June 16, 2018"
5+
jupyter:
6+
kernelspec:
7+
display_name: Python
8+
language: python
9+
name: python3
10+
---
11+
12+
# Custom Formats
13+
14+
```{python echo=TRUE}
15+
import pandas as pd
16+
x = pd.Series({'A':1, 'B':3, 'C':2})
17+
```
18+
19+
```{python bar_plot, echo=FALSE, fig.height=5, fig.width=8}
20+
x.plot(kind='bar', title='Sample plot')
21+
```

tests/test_execute.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -365,3 +365,47 @@ def test_custom_convert_cache(sphinx_run, file_regression, check_nbs):
365365
assert data
366366
assert data["method"] == "cache"
367367
assert data["succeeded"] is True
368+
369+
370+
@pytest.mark.sphinx_params(
371+
"custom-formats2.extra.exnt",
372+
conf={
373+
"nb_execution_mode": "auto",
374+
"nb_custom_formats": {".extra.exnt": ["jupytext.reads", {"fmt": "Rmd"}]},
375+
},
376+
)
377+
def test_custom_convert_multiple_extensions_auto(
378+
sphinx_run, file_regression, check_nbs
379+
):
380+
"""The outputs should be populated."""
381+
sphinx_run.build()
382+
assert sphinx_run.warnings() == ""
383+
regress_nb_doc(file_regression, sphinx_run, check_nbs)
384+
385+
assert NbMetadataCollector.new_exec_data(sphinx_run.env)
386+
data = NbMetadataCollector.get_exec_data(sphinx_run.env, "custom-formats2")
387+
assert data
388+
assert data["method"] == "auto"
389+
assert data["succeeded"] is True
390+
391+
392+
@pytest.mark.sphinx_params(
393+
"custom-formats2.extra.exnt",
394+
conf={
395+
"nb_execution_mode": "cache",
396+
"nb_custom_formats": {".extra.exnt": ["jupytext.reads", {"fmt": "Rmd"}]},
397+
},
398+
)
399+
def test_custom_convert_multiple_extensions_cache(
400+
sphinx_run, file_regression, check_nbs
401+
):
402+
"""The outputs should be populated."""
403+
sphinx_run.build()
404+
assert sphinx_run.warnings() == ""
405+
regress_nb_doc(file_regression, sphinx_run, check_nbs)
406+
407+
assert NbMetadataCollector.new_exec_data(sphinx_run.env)
408+
data = NbMetadataCollector.get_exec_data(sphinx_run.env, "custom-formats2")
409+
assert data
410+
assert data["method"] == "cache"
411+
assert data["succeeded"] is True
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "raw",
5+
"id": "d0aefb9b",
6+
"metadata": {},
7+
"source": [
8+
"---\n",
9+
"title: \"Test chunk options in Rmd/Jupyter conversion\"\n",
10+
"author: \"Marc Wouts\"\n",
11+
"date: \"June 16, 2018\"\n",
12+
"---"
13+
]
14+
},
15+
{
16+
"cell_type": "markdown",
17+
"id": "c67b3701",
18+
"metadata": {},
19+
"source": [
20+
"# Custom Formats"
21+
]
22+
},
23+
{
24+
"cell_type": "code",
25+
"execution_count": 1,
26+
"id": "ef881a36",
27+
"metadata": {
28+
"echo": true
29+
},
30+
"outputs": [],
31+
"source": [
32+
"import pandas as pd\n",
33+
"x = pd.Series({'A':1, 'B':3, 'C':2})"
34+
]
35+
},
36+
{
37+
"cell_type": "code",
38+
"execution_count": 2,
39+
"id": "f7710843",
40+
"metadata": {
41+
"fig.height": 5,
42+
"fig.width": 8,
43+
"name": "bar_plot",
44+
"tags": [
45+
"remove_input"
46+
]
47+
},
48+
"outputs": [
49+
{
50+
"data": {
51+
"text/plain": [
52+
"<Axes: title={'center': 'Sample plot'}>"
53+
]
54+
},
55+
"execution_count": 2,
56+
"metadata": {},
57+
"output_type": "execute_result"
58+
},
59+
{
60+
"data": {
61+
"image/png": "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",
62+
"text/plain": [
63+
"<Figure size 640x480 with 1 Axes>"
64+
]
65+
},
66+
"metadata": {},
67+
"output_type": "display_data"
68+
}
69+
],
70+
"source": [
71+
"x.plot(kind='bar', title='Sample plot')"
72+
]
73+
}
74+
],
75+
"metadata": {
76+
"jupytext": {
77+
"text_representation": {
78+
"extension": ".Rmd",
79+
"format_name": "rmarkdown"
80+
}
81+
},
82+
"kernelspec": {
83+
"display_name": "Python",
84+
"language": "python",
85+
"name": "python3"
86+
},
87+
"language_info": {
88+
"codemirror_mode": {
89+
"name": "ipython",
90+
"version": 3
91+
},
92+
"file_extension": ".py",
93+
"mimetype": "text/x-python",
94+
"name": "python",
95+
"nbconvert_exporter": "python",
96+
"pygments_lexer": "ipython3",
97+
"version": "3.11.8"
98+
}
99+
},
100+
"nbformat": 4,
101+
"nbformat_minor": 5
102+
}

0 commit comments

Comments
 (0)