|
10 | 10 | from enum import Enum |
11 | 11 | from textwrap import dedent |
12 | 12 | from statistics import mean |
| 13 | +from typing import Type |
| 14 | + |
13 | 15 | import pandas as pd |
| 16 | +from IPython.core.magic import Magics |
14 | 17 | from ipykernel.ipkernel import IPythonKernel |
15 | 18 | from itables import show |
16 | 19 |
|
17 | | -from jumper.context import kernel_context |
| 20 | +from jumper.context import kernel_context, KernelMode |
18 | 21 | from jumper.userpersistence import PersHelper, scorep_script_name |
19 | 22 | from jumper.userpersistence import magics_cleanup |
20 | 23 | import importlib |
21 | | -from jumper.perfdatahandler import PerformanceDataHandler |
22 | | -import jumper.visualization as perfvis |
| 24 | +from magic_extension.magic import KernelMagics |
23 | 25 |
|
24 | 26 | # import jumper.multinode_monitor.slurm_monitor as slurm_monitor |
25 | 27 |
|
|
30 | 32 | subprocess_dump = "subprocess_dump.pkl" |
31 | 33 |
|
32 | 34 |
|
33 | | -# kernel modes |
34 | | -class KernelMode(Enum): |
35 | | - DEFAULT = (0, "default") |
36 | | - MULTICELL = (1, "multicell") |
37 | | - WRITEFILE = (2, "writefile") |
38 | | - |
39 | | - def __str__(self): |
40 | | - return self.value[1] |
41 | | - |
42 | | - |
43 | 35 | class JumperKernel(IPythonKernel): |
44 | 36 | implementation = "Python and Score-P" |
45 | 37 | implementation_version = "1.0" |
@@ -953,8 +945,16 @@ async def do_execute( |
953 | 945 | self.get_perfdata_index(-1, metrics[1:]), nmetrics) |
954 | 946 | return self.standard_reply() |
955 | 947 | """ |
956 | | - |
957 | | - if code.startswith("%%display_code_for_index"): |
| 948 | + if self.is_magic_code(code, KernelMagics): |
| 949 | + return await super().do_execute( |
| 950 | + code, |
| 951 | + silent, |
| 952 | + store_history, |
| 953 | + user_expressions, |
| 954 | + allow_stdin, |
| 955 | + cell_id=cell_id, |
| 956 | + ) |
| 957 | + elif code.startswith("%%display_code_for_index"): |
958 | 958 | if len(code.split(" ")) == 1: |
959 | 959 | self.cell_output( |
960 | 960 | "No index specified. Use: %%display_code_for_index index", |
@@ -1179,6 +1179,44 @@ async def do_execute( |
1179 | 1179 | explicit_scorep=False, |
1180 | 1180 | ) |
1181 | 1181 |
|
| 1182 | + def is_magic_code( |
| 1183 | + self, |
| 1184 | + code: str, |
| 1185 | + magic_class: Type[Magics] |
| 1186 | + ) -> bool: |
| 1187 | + """ |
| 1188 | + Determines whether the given code starts with a cell or line magic |
| 1189 | + defined in the specified magic class. |
| 1190 | +
|
| 1191 | + Args: |
| 1192 | + code (str): The source code of the cell. |
| 1193 | + magic_class (Type[Magics]): The magic class to filter against (e.g. JumperMagics). |
| 1194 | +
|
| 1195 | + Returns: |
| 1196 | + bool: True if the code starts with a magic defined in the given class, False otherwise. |
| 1197 | + """ |
| 1198 | + code = code.strip() |
| 1199 | + if not code: |
| 1200 | + return False |
| 1201 | + |
| 1202 | + first_token = code.split(maxsplit=1)[0] |
| 1203 | + |
| 1204 | + mm = self.shell.magics_manager |
| 1205 | + target_magics = set() |
| 1206 | + |
| 1207 | + # Collect magic names, which are registered in "magic_class" |
| 1208 | + for magic_type in ('cell', 'line'): |
| 1209 | + for name, func in mm.magics[magic_type].items(): |
| 1210 | + if getattr(func, '__self__', None).__class__ == magic_class: |
| 1211 | + target_magics.add((magic_type, name)) |
| 1212 | + |
| 1213 | + if first_token.startswith("%%"): |
| 1214 | + return ('cell', first_token[2:]) in target_magics |
| 1215 | + elif first_token.startswith("%"): |
| 1216 | + return ('line', first_token[1:]) in target_magics |
| 1217 | + |
| 1218 | + return False |
| 1219 | + |
1182 | 1220 | def do_shutdown(self, restart): |
1183 | 1221 | self.pershelper.postprocess() |
1184 | 1222 | return super().do_shutdown(restart) |
|
0 commit comments