Skip to content

Commit 2aa8157

Browse files
authored
Merge pull request #16 from xcube-dev/pont-14-handle-magic
Make parameter extraction more robust and ignore magic
2 parents 5f8af15 + 889e2b7 commit 2aa8157

File tree

3 files changed

+109
-12
lines changed

3 files changed

+109
-12
lines changed

CHANGES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
* Improve automated parameter extraction (#9)
44
* Handle notebooks without parameters (#11)
55
* Handle non-code cells (#12)
6+
* Ignore magic commands in input notebooks (#14)
67

78
## Changes in 0.1.0
89

test/data/paramtest.ipynb

Lines changed: 89 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
"id": "325a90ed-c291-4277-9c0f-99c5543ac218",
3838
"metadata": {
3939
"editable": true,
40-
"raw_mimetype": "",
40+
"raw_mimetype": "text/asciidoc",
4141
"slideshow": {
4242
"slide_type": ""
4343
},
@@ -47,6 +47,94 @@
4747
"This is a raw cell."
4848
]
4949
},
50+
{
51+
"cell_type": "markdown",
52+
"id": "beb2ee7b-e984-4613-ba37-a486c40527f6",
53+
"metadata": {
54+
"editable": true,
55+
"slideshow": {
56+
"slide_type": ""
57+
},
58+
"tags": []
59+
},
60+
"source": [
61+
"Below are some magic commands, to make sure that these are handled during\n",
62+
"parameter extraction and conversion."
63+
]
64+
},
65+
{
66+
"cell_type": "code",
67+
"execution_count": 3,
68+
"id": "d6b05d5c-87a7-4002-b7b1-aead36c08482",
69+
"metadata": {
70+
"editable": true,
71+
"slideshow": {
72+
"slide_type": ""
73+
},
74+
"tags": []
75+
},
76+
"outputs": [
77+
{
78+
"data": {
79+
"text/html": [
80+
"<h3>Hi!</h3>\n"
81+
],
82+
"text/plain": [
83+
"<IPython.core.display.HTML object>"
84+
]
85+
},
86+
"metadata": {},
87+
"output_type": "display_data"
88+
}
89+
],
90+
"source": [
91+
"%%html\n",
92+
"<h3>Hi!</h3>"
93+
]
94+
},
95+
{
96+
"cell_type": "code",
97+
"execution_count": 4,
98+
"id": "eef41e77-30e5-4138-ad27-810b31161194",
99+
"metadata": {
100+
"editable": true,
101+
"slideshow": {
102+
"slide_type": ""
103+
},
104+
"tags": []
105+
},
106+
"outputs": [
107+
{
108+
"data": {
109+
"text/plain": [
110+
"[]"
111+
]
112+
},
113+
"execution_count": 4,
114+
"metadata": {},
115+
"output_type": "execute_result"
116+
}
117+
],
118+
"source": [
119+
"%dirs"
120+
]
121+
},
122+
{
123+
"cell_type": "markdown",
124+
"id": "567258c5-847f-4d6a-be80-9d69991df102",
125+
"metadata": {
126+
"editable": true,
127+
"slideshow": {
128+
"slide_type": ""
129+
},
130+
"tags": []
131+
},
132+
"source": [
133+
"Now the parameter cell! In a real notebook this should ideally come as early as possible,\n",
134+
"but in this test notebook we add some \"tricky\" cells before it to make sure that xcetool\n",
135+
"can deal with them."
136+
]
137+
},
50138
{
51139
"cell_type": "code",
52140
"execution_count": null,

xcengine/core.py

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,8 @@
22
# Permissions are hereby granted under the terms of the MIT License:
33
# https://opensource.org/licenses/MIT.
44

5-
import functools
65
import io
76
import json
8-
import operator
97
import os
108
import shutil
119
import sys
@@ -55,6 +53,10 @@ def convert_notebook_to_script(
5553
exporter = nbconvert.PythonExporter()
5654
(body, resources) = exporter.from_notebook_node(self.notebook)
5755
with open(output_dir / "user_code.py", "w") as fh:
56+
fh.write(
57+
"import unittest.mock\n"
58+
"get_ipython = unittest.mock.MagicMock\n"
59+
)
5860
fh.write(body)
5961
parent_dir = pathlib.Path(__file__).parent
6062
shutil.copy2(parent_dir / "wrapper.py", output_dir / "execute.py")
@@ -73,17 +75,23 @@ def process_params_cell(self) -> None:
7375
params_cell_index = i
7476
break
7577
if params_cell_index is not None:
76-
setup_code = "\n".join(
77-
map(
78-
operator.attrgetter("source"),
79-
filter(
80-
lambda c: c.cell_type == "code",
81-
self.notebook.cells[:params_cell_index],
82-
),
83-
)
78+
setup_node = nbformat.from_dict(self.notebook)
79+
setup_node.cells = setup_node.cells[:params_cell_index]
80+
exporter = nbconvert.PythonExporter()
81+
(setup_code, _) = exporter.from_notebook_node(setup_node)
82+
# Mock out the get_ipython function in case there are any
83+
# IPython magic commands in the notebook. This effectively
84+
# turns them into no-ops
85+
setup_code = (
86+
"import unittest.mock\n"
87+
"get_ipython = unittest.mock.MagicMock\n"
88+
+ setup_code
8489
)
90+
params_node = nbformat.from_dict(self.notebook)
91+
params_node.cells = [params_node.cells[params_cell_index]]
92+
(params_code, _) = exporter.from_notebook_node(params_node)
8593
self.nb_params = NotebookParameters.from_code(
86-
self.notebook.cells[params_cell_index].source,
94+
params_code,
8795
setup_code=setup_code,
8896
)
8997
self.notebook.cells.insert(

0 commit comments

Comments
 (0)