Skip to content

Commit bc4f23e

Browse files
Copilotmwouts
andauthored
Fix AttributeError when raw cell contains non-dict YAML content (#1451)
* Add test notebook to reproduce issue with invalid YAML in raw cell * Fix AttributeError when raw cell contains non-dict YAML content * Add an example notebook with complex YAML-like content Co-authored-by: mwouts <[email protected]> Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: Marc Wouts <[email protected]>
1 parent e2ae352 commit bc4f23e

21 files changed

+379
-4
lines changed

src/jupytext/header.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -330,9 +330,12 @@ def metadata_and_cell_to_metadata(nb, fmt, unsupported_keys=None):
330330
except (yaml.parser.ParserError, yaml.scanner.ScannerError):
331331
logging.warning("[jupytext] failed to parse YAML in raw cell")
332332
else:
333-
nb.cells = nb.cells[1:]
334-
if "root_level_metadata_filter" not in fmt and default_root_level_metadata_filter(fmt) == "all":
335-
metadata.setdefault("jupytext", {})["root_level_metadata_filter"] = "-" + ",-".join(frontmatter)
336-
metadata = recursive_update(frontmatter, metadata, overwrite=False)
333+
if not isinstance(frontmatter, dict):
334+
logging.warning("[jupytext] YAML header in raw cell is not a dictionary")
335+
else:
336+
nb.cells = nb.cells[1:]
337+
if "root_level_metadata_filter" not in fmt and default_root_level_metadata_filter(fmt) == "all":
338+
metadata.setdefault("jupytext", {})["root_level_metadata_filter"] = "-" + ",-".join(frontmatter)
339+
metadata = recursive_update(frontmatter, metadata, overwrite=False)
337340
nb.metadata = metadata
338341
return nb
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "raw",
5+
"id": "b32297a4",
6+
"metadata": {},
7+
"source": [
8+
"---\n",
9+
"\n",
10+
"This is a complex paragraph\n",
11+
"that is split over multiple lines.\n",
12+
"\n",
13+
"It also includes blank lines.\n",
14+
"\n",
15+
"\n",
16+
"---"
17+
]
18+
},
19+
{
20+
"cell_type": "code",
21+
"execution_count": null,
22+
"metadata": {},
23+
"outputs": [],
24+
"id": "0b3bde0a",
25+
"source": [
26+
"print(\"Hello, World!\")"
27+
]
28+
}
29+
],
30+
"metadata": {
31+
"kernelspec": {
32+
"display_name": "Python 3",
33+
"language": "python",
34+
"name": "python3"
35+
},
36+
"language_info": {
37+
"name": "python"
38+
}
39+
},
40+
"nbformat": 4,
41+
"nbformat_minor": 5
42+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "raw",
5+
"id": "b32297a4",
6+
"metadata": {},
7+
"source": [
8+
"---\n",
9+
"Content.\n",
10+
"---"
11+
]
12+
},
13+
{
14+
"cell_type": "code",
15+
"execution_count": null,
16+
"metadata": {},
17+
"outputs": [],
18+
"id": "0b3bde0a",
19+
"source": [
20+
"print(\"Hello, World!\")"
21+
]
22+
}
23+
],
24+
"metadata": {
25+
"kernelspec": {
26+
"display_name": "Python 3",
27+
"language": "python",
28+
"name": "python3"
29+
},
30+
"language_info": {
31+
"name": "python"
32+
}
33+
},
34+
"nbformat": 4,
35+
"nbformat_minor": 5
36+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
---
2+
3+
This is a complex paragraph
4+
that is split over multiple lines.
5+
6+
It also includes blank lines.
7+
8+
9+
jupyter:
10+
kernelspec:
11+
display_name: Python 3
12+
language: python
13+
name: python3
14+
---
15+
16+
```{python}
17+
print("Hello, World!")
18+
```
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
Content.
3+
jupyter:
4+
kernelspec:
5+
display_name: Python 3
6+
language: python
7+
name: python3
8+
---
9+
10+
```{python}
11+
print("Hello, World!")
12+
```
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# ---
2+
#
3+
# This is a complex paragraph
4+
# that is split over multiple lines.
5+
#
6+
# It also includes blank lines.
7+
#
8+
#
9+
# jupyter:
10+
# kernelspec:
11+
# display_name: Python 3
12+
# language: python
13+
# name: python3
14+
# ---
15+
16+
# %%
17+
print("Hello, World!")
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# ---
2+
# Content.
3+
# jupyter:
4+
# kernelspec:
5+
# display_name: Python 3
6+
# language: python
7+
# name: python3
8+
# ---
9+
10+
# %%
11+
print("Hello, World!")
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
---
2+
3+
This is a complex paragraph
4+
that is split over multiple lines.
5+
6+
It also includes blank lines.
7+
8+
9+
jupyter:
10+
kernelspec:
11+
display_name: Python 3
12+
language: python
13+
name: python3
14+
---
15+
16+
```python
17+
print("Hello, World!")
18+
```
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
Content.
3+
jupyter:
4+
kernelspec:
5+
display_name: Python 3
6+
language: python
7+
name: python3
8+
---
9+
10+
```python
11+
print("Hello, World!")
12+
```
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
---
2+
kernelspec:
3+
display_name: Python 3
4+
language: python
5+
name: python3
6+
---
7+
8+
```{raw-cell}
9+
10+
---
11+
12+
This is a complex paragraph
13+
that is split over multiple lines.
14+
15+
It also includes blank lines.
16+
17+
18+
---
19+
```
20+
21+
```{code-cell}
22+
print("Hello, World!")
23+
```

0 commit comments

Comments
 (0)