Refactor Jupyter magic handling (#2545)
This commit is contained in:
parent
62ed5389fc
commit
26970742b7
@ -39,18 +39,18 @@
|
|||||||
)
|
)
|
||||||
NON_PYTHON_CELL_MAGICS = frozenset(
|
NON_PYTHON_CELL_MAGICS = frozenset(
|
||||||
(
|
(
|
||||||
"%%bash",
|
"bash",
|
||||||
"%%html",
|
"html",
|
||||||
"%%javascript",
|
"javascript",
|
||||||
"%%js",
|
"js",
|
||||||
"%%latex",
|
"latex",
|
||||||
"%%markdown",
|
"markdown",
|
||||||
"%%perl",
|
"perl",
|
||||||
"%%ruby",
|
"ruby",
|
||||||
"%%script",
|
"script",
|
||||||
"%%sh",
|
"sh",
|
||||||
"%%svg",
|
"svg",
|
||||||
"%%writefile",
|
"writefile",
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
TOKEN_HEX = secrets.token_hex
|
TOKEN_HEX = secrets.token_hex
|
||||||
@ -230,10 +230,11 @@ def replace_cell_magics(src: str) -> Tuple[str, List[Replacement]]:
|
|||||||
cell_magic_finder.visit(tree)
|
cell_magic_finder.visit(tree)
|
||||||
if cell_magic_finder.cell_magic is None:
|
if cell_magic_finder.cell_magic is None:
|
||||||
return src, replacements
|
return src, replacements
|
||||||
if cell_magic_finder.cell_magic.header.split()[0] in NON_PYTHON_CELL_MAGICS:
|
if cell_magic_finder.cell_magic.name in NON_PYTHON_CELL_MAGICS:
|
||||||
raise NothingChanged
|
raise NothingChanged
|
||||||
mask = get_token(src, cell_magic_finder.cell_magic.header)
|
header = cell_magic_finder.cell_magic.header
|
||||||
replacements.append(Replacement(mask=mask, src=cell_magic_finder.cell_magic.header))
|
mask = get_token(src, header)
|
||||||
|
replacements.append(Replacement(mask=mask, src=header))
|
||||||
return f"{mask}\n{cell_magic_finder.cell_magic.body}", replacements
|
return f"{mask}\n{cell_magic_finder.cell_magic.body}", replacements
|
||||||
|
|
||||||
|
|
||||||
@ -311,11 +312,26 @@ def _is_ipython_magic(node: ast.expr) -> TypeGuard[ast.Attribute]:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _get_str_args(args: List[ast.expr]) -> List[str]:
|
||||||
|
str_args = []
|
||||||
|
for arg in args:
|
||||||
|
assert isinstance(arg, ast.Str)
|
||||||
|
str_args.append(arg.s)
|
||||||
|
return str_args
|
||||||
|
|
||||||
|
|
||||||
@dataclasses.dataclass(frozen=True)
|
@dataclasses.dataclass(frozen=True)
|
||||||
class CellMagic:
|
class CellMagic:
|
||||||
header: str
|
name: str
|
||||||
|
params: Optional[str]
|
||||||
body: str
|
body: str
|
||||||
|
|
||||||
|
@property
|
||||||
|
def header(self) -> str:
|
||||||
|
if self.params:
|
||||||
|
return f"%%{self.name} {self.params}"
|
||||||
|
return f"%%{self.name}"
|
||||||
|
|
||||||
|
|
||||||
@dataclasses.dataclass
|
@dataclasses.dataclass
|
||||||
class CellMagicFinder(ast.NodeVisitor):
|
class CellMagicFinder(ast.NodeVisitor):
|
||||||
@ -345,14 +361,8 @@ def visit_Expr(self, node: ast.Expr) -> None:
|
|||||||
and _is_ipython_magic(node.value.func)
|
and _is_ipython_magic(node.value.func)
|
||||||
and node.value.func.attr == "run_cell_magic"
|
and node.value.func.attr == "run_cell_magic"
|
||||||
):
|
):
|
||||||
args = []
|
args = _get_str_args(node.value.args)
|
||||||
for arg in node.value.args:
|
self.cell_magic = CellMagic(name=args[0], params=args[1], body=args[2])
|
||||||
assert isinstance(arg, ast.Str)
|
|
||||||
args.append(arg.s)
|
|
||||||
header = f"%%{args[0]}"
|
|
||||||
if args[1]:
|
|
||||||
header += f" {args[1]}"
|
|
||||||
self.cell_magic = CellMagic(header=header, body=args[2])
|
|
||||||
self.generic_visit(node)
|
self.generic_visit(node)
|
||||||
|
|
||||||
|
|
||||||
@ -404,12 +414,8 @@ def visit_Assign(self, node: ast.Assign) -> None:
|
|||||||
and _is_ipython_magic(node.value.func)
|
and _is_ipython_magic(node.value.func)
|
||||||
and node.value.func.attr == "getoutput"
|
and node.value.func.attr == "getoutput"
|
||||||
):
|
):
|
||||||
args = []
|
(arg,) = _get_str_args(node.value.args)
|
||||||
for arg in node.value.args:
|
src = f"!{arg}"
|
||||||
assert isinstance(arg, ast.Str)
|
|
||||||
args.append(arg.s)
|
|
||||||
assert args
|
|
||||||
src = f"!{args[0]}"
|
|
||||||
self.magics[node.value.lineno].append(
|
self.magics[node.value.lineno].append(
|
||||||
OffsetAndMagic(node.value.col_offset, src)
|
OffsetAndMagic(node.value.col_offset, src)
|
||||||
)
|
)
|
||||||
@ -435,11 +441,7 @@ def visit_Expr(self, node: ast.Expr) -> None:
|
|||||||
and we look for instances of any of the latter.
|
and we look for instances of any of the latter.
|
||||||
"""
|
"""
|
||||||
if isinstance(node.value, ast.Call) and _is_ipython_magic(node.value.func):
|
if isinstance(node.value, ast.Call) and _is_ipython_magic(node.value.func):
|
||||||
args = []
|
args = _get_str_args(node.value.args)
|
||||||
for arg in node.value.args:
|
|
||||||
assert isinstance(arg, ast.Str)
|
|
||||||
args.append(arg.s)
|
|
||||||
assert args
|
|
||||||
if node.value.func.attr == "run_line_magic":
|
if node.value.func.attr == "run_line_magic":
|
||||||
if args[0] == "pinfo":
|
if args[0] == "pinfo":
|
||||||
src = f"?{args[1]}"
|
src = f"?{args[1]}"
|
||||||
|
Loading…
Reference in New Issue
Block a user