Skip to content

Commit cbac235

Browse files
authored
Populate notebook metadata when exporting with %notebook magic (#14955)
Fixes #14954
2 parents c694662 + dadac0d commit cbac235

File tree

2 files changed

+49
-1
lines changed

2 files changed

+49
-1
lines changed

IPython/core/magics/basic.py

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from logging import error
55
import io
66
import os
7+
import platform
78
from pprint import pformat
89
import sys
910
from warnings import warn
@@ -603,10 +604,44 @@ def notebook(self, s):
603604
)
604605
cells.append(cell)
605606

606-
nb = v4.new_notebook(cells=cells)
607+
kernel_language_info = self._get_kernel_language_info()
608+
609+
nb = v4.new_notebook(
610+
cells=cells,
611+
metadata={
612+
"kernelspec": {
613+
"display_name": "Python 3 (ipykernel)",
614+
"language": "python",
615+
"name": "python3",
616+
},
617+
"language_info": kernel_language_info
618+
or {
619+
"codemirror_mode": {
620+
"name": "ipython",
621+
"version": sys.version_info[0],
622+
},
623+
"file_extension": ".py",
624+
"mimetype": "text/x-python",
625+
"name": "python",
626+
"nbconvert_exporter": "python",
627+
"pygments_lexer": "ipython3",
628+
"version": platform.python_version(),
629+
},
630+
},
631+
)
607632
with io.open(outfname, "w", encoding="utf-8") as f:
608633
write(nb, f, version=4)
609634

635+
def _get_kernel_language_info(self) -> dict | None:
636+
"""Get language info from kernel, useful when used in Jupyter Console where kernels exist."""
637+
if not hasattr(self.shell, "kernel"):
638+
return
639+
if not hasattr(self.shell.kernel, "language_info"):
640+
return
641+
if not isinstance(self.shell.kernel.language_info, dict):
642+
return
643+
return self.shell.kernel.language_info
644+
610645
@magics_class
611646
class AsyncMagics(BasicMagics):
612647

tests/test_magic.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33

44
import gc
55
import io
6+
import json
67
import os
8+
import platform
79
import re
810
import shlex
911
import signal
@@ -962,6 +964,17 @@ def test_notebook_export_json():
962964
with TemporaryDirectory() as td:
963965
outfile = os.path.join(td, "nb.ipynb")
964966
_ip.run_line_magic("notebook", "%s" % outfile)
967+
with open(outfile) as f:
968+
exported = json.load(f)
969+
970+
# check metadata
971+
language_info = exported["metadata"]["language_info"]
972+
assert language_info["name"] == "python"
973+
assert language_info["file_extension"] == ".py"
974+
assert language_info["version"] == platform.python_version()
975+
976+
kernelspec = exported["metadata"]["kernelspec"]
977+
assert kernelspec["language"] == "python"
965978

966979

967980
def test_notebook_export_json_with_output():

0 commit comments

Comments
 (0)