Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/IPython/core/magic.py: 28%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

375 statements  

1from __future__ import annotations 

2 

3"""Magic functions for InteractiveShell.""" 

4 

5# ----------------------------------------------------------------------------- 

6# Copyright (C) 2001 Janko Hauser <jhauser@zscout.de> and 

7# Copyright (C) 2001 Fernando Perez <fperez@colorado.edu> 

8# Copyright (C) 2008 The IPython Development Team 

9 

10# Distributed under the terms of the BSD License. The full license is in 

11# the file COPYING, distributed as part of this software. 

12# ----------------------------------------------------------------------------- 

13 

14import os 

15import re 

16import sys 

17from getopt import getopt, GetoptError 

18 

19from traitlets.config.configurable import Configurable 

20from .error import UsageError 

21from .inputtransformer2 import ESC_MAGIC, ESC_MAGIC2 

22from ..utils.ipstruct import Struct 

23from ..utils.text import dedent 

24from traitlets import Bool, Dict, Instance, observe 

25 

26import typing as t 

27from typing import Any, Literal, TypeVar, overload 

28from collections.abc import Callable 

29 

30if t.TYPE_CHECKING: 

31 from types import FrameType 

32 

33 from IPython.core.interactiveshell import InteractiveShell 

34 

35_F = TypeVar("_F", bound=Callable[..., Any]) 

36_MagicKind = Literal["line", "cell"] 

37_MagicSpec = Literal["line", "cell", "line_cell"] 

38 

39 

40# ----------------------------------------------------------------------------- 

41# Globals 

42# ----------------------------------------------------------------------------- 

43 

44# A dict we'll use for each class that has magics, used as temporary storage to 

45# pass information between the @line/cell_magic method decorators and the 

46# @magics_class class decorator, because the method decorators have no 

47# access to the class when they run. See for more details: 

48# http://stackoverflow.com/questions/2366713/can-a-python-decorator-of-an-instance-method-access-the-class 

49 

50magics: dict[str, dict[str, str]] = dict(line={}, cell={}) 

51 

52magic_kinds: tuple[_MagicKind, ...] = ("line", "cell") 

53magic_spec: tuple[_MagicSpec, ...] = ("line", "cell", "line_cell") 

54magic_escapes: dict[_MagicKind, str] = dict(line=ESC_MAGIC, cell=ESC_MAGIC2) 

55 

56# Regexes used by Magics.format_latex, compiled once at import time. 

57# Characters that need to be escaped for latex: 

58_LATEX_ESCAPE_RE = re.compile(r"(%|_|\$|#|&)", re.MULTILINE) 

59# Magic command names as headers: 

60_LATEX_CMD_NAME_RE = re.compile(r"^(%s.*?):" % ESC_MAGIC, re.MULTILINE) 

61# Magic commands 

62_LATEX_CMD_RE = re.compile(r"(?P<cmd>%s.+?\b)(?!\}\}:)" % ESC_MAGIC, re.MULTILINE) 

63# Paragraph continue 

64_LATEX_PAR_RE = re.compile(r"\\$", re.MULTILINE) 

65# The "\n" symbol 

66_LATEX_NEWLINE_RE = re.compile(r"\\n") 

67 

68# ----------------------------------------------------------------------------- 

69# Utility classes and functions 

70# ----------------------------------------------------------------------------- 

71 

72 

73class Bunch: 

74 pass 

75 

76 

77def compress_dhist(dh: list[str]) -> list[str]: 

78 """Compress a directory history into a new one with at most 20 entries. 

79 

80 Return a new list made from the first and last 10 elements of dhist after 

81 removal of duplicates. 

82 """ 

83 head, tail = dh[:-10], dh[-10:] 

84 

85 newhead: list[str] = [] 

86 done: set[str] = set() 

87 for h in head: 

88 if h in done: 

89 continue 

90 newhead.append(h) 

91 done.add(h) 

92 

93 return newhead + tail 

94 

95 

96def needs_local_scope(func: _F) -> _F: 

97 """Decorator to mark magic functions which need to local scope to run.""" 

98 func.needs_local_scope = True # type: ignore[attr-defined] 

99 return func 

100 

101 

102# ----------------------------------------------------------------------------- 

103# Class and method decorators for registering magics 

104# ----------------------------------------------------------------------------- 

105 

106 

107_T = TypeVar("_T", bound=type["Magics"]) 

108 

109 

110def magics_class(cls: _T) -> _T: 

111 """Class decorator for all subclasses of the main Magics class. 

112 

113 Any class that subclasses Magics *must* also apply this decorator, to 

114 ensure that all the methods that have been decorated as line/cell magics 

115 get correctly registered in the class instance. This is necessary because 

116 when method decorators run, the class does not exist yet, so they 

117 temporarily store their information into a module global. Application of 

118 this class decorator copies that global data to the class instance and 

119 clears the global. 

120 

121 Obviously, this mechanism is not thread-safe, which means that the 

122 *creation* of subclasses of Magic should only be done in a single-thread 

123 context. Instantiation of the classes has no restrictions. Given that 

124 these classes are typically created at IPython startup time and before user 

125 application code becomes active, in practice this should not pose any 

126 problems. 

127 """ 

128 cls.registered = True 

129 cls.magics = dict(line=magics["line"], cell=magics["cell"]) 

130 magics["line"] = {} 

131 magics["cell"] = {} 

132 return cls 

133 

134 

135def record_magic( 

136 dct: dict[str, dict[str, Any]], 

137 magic_kind: _MagicSpec, 

138 magic_name: str, 

139 func: Any, 

140) -> None: 

141 """Utility function to store a function as a magic of a specific kind. 

142 

143 Parameters 

144 ---------- 

145 dct : dict 

146 A dictionary with 'line' and 'cell' subdicts. 

147 magic_kind : str 

148 Kind of magic to be stored. 

149 magic_name : str 

150 Key to store the magic as. 

151 func : function 

152 Callable object to store. 

153 """ 

154 if magic_kind == "line_cell": 

155 dct["line"][magic_name] = dct["cell"][magic_name] = func 

156 else: 

157 dct[magic_kind][magic_name] = func 

158 

159 

160def validate_type(magic_kind: str) -> None: 

161 """Ensure that the given magic_kind is valid. 

162 

163 Check that the given magic_kind is one of the accepted spec types (stored 

164 in the global `magic_spec`), raise ValueError otherwise. 

165 """ 

166 if magic_kind not in magic_spec: 

167 raise ValueError( 

168 "magic_kind must be one of %s, %s given" % magic_kinds, magic_kind 

169 ) 

170 

171 

172# The docstrings for the decorator below will be fairly similar for the two 

173# types (method and function), so we generate them here once and reuse the 

174# templates below. 

175_docstring_template = """Decorate the given {0} as {1} magic. 

176 

177The decorator can be used with or without arguments, as follows. 

178 

179i) without arguments: it will create a {1} magic named as the {0} being 

180decorated:: 

181 

182 @deco 

183 def foo(...) 

184 

185will create a {1} magic named `foo`. 

186 

187ii) with one string argument: which will be used as the actual name of the 

188resulting magic:: 

189 

190 @deco('bar') 

191 def foo(...) 

192 

193will create a {1} magic named `bar`. 

194 

195To register a class magic use ``Interactiveshell.register_magic(class or instance)``. 

196""" 

197 

198# These two are decorator factories. While they are conceptually very similar, 

199# there are enough differences in the details that it's simpler to have them 

200# written as completely standalone functions rather than trying to share code 

201# and make a single one with convoluted logic. 

202 

203 

204def _method_magic_marker( 

205 magic_kind: _MagicSpec, 

206) -> Callable[[_F | str], _F | Callable[[_F], _F]]: 

207 """Decorator factory for methods in Magics subclasses.""" 

208 

209 validate_type(magic_kind) 

210 

211 # This is a closure to capture the magic_kind. We could also use a class, 

212 # but it's overkill for just that one bit of state. 

213 def magic_deco(arg: _F | str) -> _F | Callable[[_F], _F]: 

214 retval: _F | Callable[[_F], _F] 

215 if callable(arg): 

216 # "Naked" decorator call (just @foo, no args) 

217 func = arg 

218 name = func.__name__ 

219 retval = arg 

220 record_magic(magics, magic_kind, name, name) 

221 elif isinstance(arg, str): 

222 # Decorator called with arguments (@foo('bar')) 

223 name = arg 

224 

225 def mark(func: _F, *a: Any, **kw: Any) -> _F: 

226 record_magic(magics, magic_kind, name, func.__name__) 

227 return func 

228 

229 retval = mark 

230 else: 

231 raise TypeError("Decorator can only be called with string or function") 

232 return retval 

233 

234 # Ensure the resulting decorator has a usable docstring 

235 magic_deco.__doc__ = _docstring_template.format("method", magic_kind) 

236 return magic_deco 

237 

238 

239def _function_magic_marker( 

240 magic_kind: _MagicSpec, 

241) -> Callable[[_F | str], _F | Callable[[_F], _F]]: 

242 """Decorator factory for standalone functions.""" 

243 validate_type(magic_kind) 

244 

245 # This is a closure to capture the magic_kind. We could also use a class, 

246 # but it's overkill for just that one bit of state. 

247 def magic_deco(arg: _F | str) -> _F | Callable[[_F], _F]: 

248 # Find get_ipython() in the caller's namespace 

249 caller: FrameType = sys._getframe(1) 

250 get_ipython: Callable[[], InteractiveShell] | None = None 

251 for ns in ["f_locals", "f_globals", "f_builtins"]: 

252 get_ipython = getattr(caller, ns).get("get_ipython") 

253 if get_ipython is not None: 

254 break 

255 else: 

256 raise NameError( 

257 "Decorator can only run in context where `get_ipython` exists" 

258 ) 

259 

260 ip: InteractiveShell = get_ipython() 

261 

262 retval: _F | Callable[[_F], _F] 

263 if callable(arg): 

264 # "Naked" decorator call (just @foo, no args) 

265 func = arg 

266 name = func.__name__ 

267 ip.register_magic_function(func, magic_kind, name) # type: ignore[arg-type] 

268 retval = arg 

269 elif isinstance(arg, str): 

270 # Decorator called with arguments (@foo('bar')) 

271 name = arg 

272 

273 def mark(func: _F, *a: Any, **kw: Any) -> _F: 

274 ip.register_magic_function(func, magic_kind, name) # type: ignore[arg-type] 

275 return func 

276 

277 retval = mark 

278 else: 

279 raise TypeError("Decorator can only be called with string or function") 

280 return retval 

281 

282 # Ensure the resulting decorator has a usable docstring 

283 ds = _docstring_template.format("function", magic_kind) 

284 

285 ds += dedent( 

286 """ 

287 Note: this decorator can only be used in a context where IPython is already 

288 active, so that the `get_ipython()` call succeeds. You can therefore use 

289 it in your startup files loaded after IPython initializes, but *not* in the 

290 IPython configuration file itself, which is executed before IPython is 

291 fully up and running. Any file located in the `startup` subdirectory of 

292 your configuration profile will be OK in this sense. 

293 """ 

294 ) 

295 

296 magic_deco.__doc__ = ds 

297 return magic_deco 

298 

299 

300MAGIC_NO_VAR_EXPAND_ATTR = "_ipython_magic_no_var_expand" 

301MAGIC_OUTPUT_CAN_BE_SILENCED = "_ipython_magic_output_can_be_silenced" 

302 

303 

304def no_var_expand(magic_func: _F) -> _F: 

305 """Mark a magic function as not needing variable expansion 

306 

307 By default, IPython interprets `{a}` or `$a` in the line passed to magics 

308 as variables that should be interpolated from the interactive namespace 

309 before passing the line to the magic function. 

310 This is not always desirable, e.g. when the magic executes Python code 

311 (%timeit, %time, etc.). 

312 Decorate magics with `@no_var_expand` to opt-out of variable expansion. 

313 

314 .. versionadded:: 7.3 

315 """ 

316 setattr(magic_func, MAGIC_NO_VAR_EXPAND_ATTR, True) 

317 return magic_func 

318 

319 

320def output_can_be_silenced(magic_func: _F) -> _F: 

321 """Mark a magic function so its output may be silenced. 

322 

323 The output is silenced if the Python code used as a parameter of 

324 the magic ends in a semicolon, not counting a Python comment that can 

325 follow it. 

326 """ 

327 setattr(magic_func, MAGIC_OUTPUT_CAN_BE_SILENCED, True) 

328 return magic_func 

329 

330 

331# Create the actual decorators for public use 

332 

333# These three are used to decorate methods in class definitions 

334line_magic = _method_magic_marker("line") 

335cell_magic = _method_magic_marker("cell") 

336line_cell_magic = _method_magic_marker("line_cell") 

337 

338# These three decorate standalone functions and perform the decoration 

339# immediately. They can only run where get_ipython() works 

340register_line_magic = _function_magic_marker("line") 

341register_cell_magic = _function_magic_marker("cell") 

342register_line_cell_magic = _function_magic_marker("line_cell") 

343 

344# ----------------------------------------------------------------------------- 

345# Core Magic classes 

346# ----------------------------------------------------------------------------- 

347 

348 

349class LazyMagic: 

350 """Stands in the magics table for a magic that is not imported yet. 

351 

352 Listing and completing magics only look at names, so they stay cheap; 

353 using one -- calling it, or reading any attribute of it, as pyflyby does 

354 with ``magics["line"]["prun"].__self__`` -- resolves through 

355 :meth:`MagicsManager.find`, which imports and registers the real thing. 

356 """ 

357 

358 def __init__( 

359 self, 

360 manager: MagicsManager, 

361 spec: str, 

362 magic_kind: _MagicKind, 

363 magic_name: str, 

364 ) -> None: 

365 self.spec = spec 

366 self._manager = manager 

367 self._kind = magic_kind 

368 self._name = magic_name 

369 

370 def _resolve(self) -> Callable[..., Any]: 

371 fn = self._manager.find(self._kind, self._name) 

372 if fn is None: 

373 raise UsageError( 

374 f"Magic `{magic_escapes[self._kind]}{self._name}` not found." 

375 ) 

376 return fn 

377 

378 def __call__(self, *args: Any, **kwargs: Any) -> Any: 

379 return self._resolve()(*args, **kwargs) 

380 

381 def __getattr__(self, name: str) -> Any: 

382 return getattr(self._resolve(), name) 

383 

384 def __repr__(self) -> str: 

385 return f"<unloaded magic {self._name} from {self.spec}>" 

386 

387 

388class _MagicsRegistry(dict[str, Any]): 

389 """``MagicsManager.registry``, which loads a lazy class on a miss. 

390 

391 ``registry["ExecutionMagics"]`` is a legitimate way to reach a magics 

392 instance, and may now be the first thing that needs the class. 

393 """ 

394 

395 def __init__(self, manager: MagicsManager) -> None: 

396 super().__init__() 

397 self._manager = manager 

398 

399 def __missing__(self, key: str) -> Any: 

400 for magic_name, magic_kind, spec in self._manager._lazy_declarations(): 

401 if spec.endswith(":" + key): 

402 self._manager.load_lazy(magic_name, magic_kind) 

403 # A matching spec declared once per kind 

404 # has one spec per kind, so keep going until `key` shows up. 

405 if key in self: 

406 break 

407 if key not in self: 

408 # A second miss must not loop back here. 

409 raise KeyError(key) 

410 return self[key] 

411 

412 

413class MagicsManager(Configurable): 

414 """Object that handles all magic-related functionality for IPython.""" 

415 

416 # Non-configurable class attributes 

417 

418 # A two-level dict, first keyed by magic type, then by magic function, and 

419 # holding the actual callable object as value. This is the dict used for 

420 # magic function dispatch 

421 magics = Dict() 

422 lazy_magics = Dict( 

423 help=""" 

424 Mapping from magic names to modules to load. 

425 

426 This can be used in IPython/IPykernel configuration to declare lazy magics 

427 that will only be imported/registered on first use. 

428 

429 For example:: 

430 

431 c.MagicsManager.lazy_magics = { 

432 "my_magic": "slow.to.import", 

433 "my_other_magic": "also.slow", 

434 } 

435 

436 On first invocation of `%my_magic`, `%%my_magic`, `%%my_other_magic` or 

437 `%%my_other_magic`, the corresponding module will be loaded as an ipython 

438 extensions as if you had previously done `%load_ext ipython`. 

439 

440 A value of the form ``"package.module:MagicsClass"`` is instead imported 

441 and registered directly, without going through the extension machinery. 

442 This is how IPython declares its own magics, see 

443 :mod:`IPython.core.magics._table`. 

444 

445 Magics names should be without percent(s) as magics can be both cell 

446 and line magics. 

447 

448 Lazy loading happen relatively late in execution process, and 

449 complex extensions that manipulate Python/IPython internal state or global state 

450 might not support lazy loading. 

451 """ 

452 ).tag( 

453 config=True, 

454 ) 

455 

456 # A registry of the original objects that we've been given holding magics. 

457 registry = Dict() 

458 

459 shell = Instance( 

460 "IPython.core.interactiveshell.InteractiveShellABC", allow_none=True 

461 ) 

462 

463 auto_magic = Bool( 

464 True, help="Automatically call line magics without requiring explicit % prefix" 

465 ).tag(config=True) 

466 

467 @observe("auto_magic") 

468 def _auto_magic_changed(self, change: dict[str, Any]) -> None: 

469 assert self.shell is not None 

470 self.shell.automagic = change["new"] 

471 

472 _auto_status = [ 

473 "Automagic is OFF, % prefix IS needed for line magics.", 

474 "Automagic is ON, % prefix IS NOT needed for line magics.", 

475 ] 

476 

477 user_magics = Instance("IPython.core.magics.UserMagics", allow_none=True) 

478 

479 def __init__( 

480 self, 

481 shell: InteractiveShell | None = None, 

482 config: Any = None, 

483 user_magics: Magics | None = None, 

484 **traits: Any, 

485 ) -> None: 

486 super().__init__( 

487 shell=shell, config=config, user_magics=user_magics, **traits 

488 ) 

489 self.magics = dict(line={}, cell={}) 

490 # Specs already loaded, so a class is never registered twice. 

491 self._loaded_lazy: set[str] = set() 

492 self.registry = _MagicsRegistry(self) 

493 # Let's add the user_magics to the registry for uniformity, so *all* 

494 # registered magic containers can be found there. 

495 if user_magics is not None: 

496 self.registry[user_magics.__class__.__name__] = user_magics 

497 

498 def auto_status(self) -> str: 

499 """Return descriptive string with automagic status.""" 

500 return self._auto_status[self.auto_magic] 

501 

502 def lsmagic(self) -> dict[str, dict[str, Any]]: 

503 """Return a dict of currently available magic functions. 

504 

505 The return dict has the keys 'line' and 'cell', corresponding to the 

506 two types of magics we support. Each value is a list of names. 

507 """ 

508 return self.magics 

509 

510 def lsmagic_docs( 

511 self, brief: bool = False, missing: str = "" 

512 ) -> dict[str, dict[str, str]]: 

513 """Return dict of documentation of magic functions. 

514 

515 The return dict has the keys 'line' and 'cell', corresponding to the 

516 two types of magics we support. Each value is a dict keyed by magic 

517 name whose value is the function docstring. If a docstring is 

518 unavailable, the value of `missing` is used instead. 

519 

520 If brief is True, only the first line of each docstring will be returned. 

521 """ 

522 # Everything is documented here, so everything has to be imported. 

523 self.load_all_lazy_magics() 

524 docs: dict[str, dict[str, str]] = {} 

525 for m_type in self.magics: 

526 m_docs: dict[str, str] = {} 

527 for m_name, m_func in list(self.magics[m_type].items()): 

528 if isinstance(m_func, LazyMagic): 

529 # An extension we decline to load just for a docstring. 

530 m_docs[m_name] = missing 

531 elif m_func.__doc__: 

532 if brief: 

533 m_docs[m_name] = m_func.__doc__.split("\n", 1)[0] 

534 else: 

535 m_docs[m_name] = m_func.__doc__.rstrip() 

536 else: 

537 m_docs[m_name] = missing 

538 docs[m_type] = m_docs 

539 return docs 

540 

541 def register_lazy( 

542 self, 

543 name: str, 

544 fully_qualified_name: str, 

545 magic_kind: _MagicSpec = "line_cell", 

546 ) -> None: 

547 """ 

548 Lazily register a magic, without importing what implements it. 

549 

550 The magic shows up in ``%lsmagic`` and in completion straight away; the 

551 module is only imported the first time it is looked up. 

552 

553 Parameters 

554 ---------- 

555 name : str 

556 Name of the magic you wish to register. 

557 fully_qualified_name : str 

558 Either ``"package.module"``, which is loaded as an IPython 

559 extension (and trusted to register the magic itself), or 

560 ``"package.module:MagicsClass"``, which is imported and registered 

561 directly -- how IPython declares its own magics. 

562 magic_kind : str 

563 One of 'line', 'cell' or 'line_cell' (the default, since a lazily 

564 declared magic may well be both). 

565 """ 

566 validate_type(magic_kind) 

567 self.lazy_magics[name] = fully_qualified_name 

568 kinds = magic_kinds if magic_kind == "line_cell" else (magic_kind,) 

569 for kind in kinds: 

570 existing = self.magics[kind].get(name) 

571 if existing is not None and not isinstance(existing, LazyMagic): 

572 continue 

573 self.magics[kind][name] = LazyMagic(self, fully_qualified_name, kind, name) 

574 

575 def load_lazy(self, magic_name: str, magic_kind: _MagicKind | None = None) -> None: 

576 """Import and register whatever provides `magic_name`. 

577 

578 Does nothing if `magic_name` was not declared through 

579 :meth:`register_lazy` or :attr:`lazy_magics`, or if what provides it 

580 has already been loaded. 

581 

582 When `magic_kind` is given, the placeholder for that kind decides 

583 which spec to load: a name may be declared with a different provider 

584 per kind, and the lookup must resolve the kind that was asked for, 

585 not whichever placeholder happens to be checked first. 

586 """ 

587 # `lazy_magics` is user-configurable and may have been replaced 

588 # wholesale, so prefer the spec the placeholder carries. 

589 if magic_kind is not None: 

590 fn = self.magics[magic_kind].get(magic_name) 

591 else: 

592 fn = self.magics["line"].get(magic_name) or self.magics["cell"].get( 

593 magic_name 

594 ) 

595 spec = ( 

596 fn.spec if isinstance(fn, LazyMagic) else self.lazy_magics.get(magic_name) 

597 ) 

598 if spec is None or spec in self._loaded_lazy: 

599 return 

600 module_name, sep, class_name = spec.partition(":") 

601 # Marked before loading: what we run may look a magic up itself, and 

602 # must not come back round and register twice. Unwound on failure so 

603 # a broken spec keeps raising rather than going quiet. 

604 self._loaded_lazy.add(spec) 

605 try: 

606 if sep: 

607 from importlib import import_module 

608 

609 self._register( 

610 (getattr(import_module(module_name), class_name),), 

611 lazy_spec=spec, 

612 ) 

613 else: 

614 assert self.shell is not None 

615 self.shell.run_line_magic("load_ext", spec) 

616 except Exception: 

617 self._loaded_lazy.discard(spec) 

618 raise 

619 

620 def _lazy_declarations(self) -> list[tuple[str, _MagicKind | None, str]]: 

621 """Every live lazy declaration, as ``(name, kind, spec)``. 

622 

623 The placeholders in :attr:`magics` are the source of truth, because 

624 :attr:`lazy_magics` is keyed by name alone and so keeps only the last 

625 spec for a name declared once per kind. A name declared only through 

626 the trait has no placeholder, and so no known kind. 

627 """ 

628 seen: set[tuple[str, str]] = set() 

629 declarations: list[tuple[str, _MagicKind | None, str]] = [] 

630 for kind in magic_kinds: 

631 for name, fn in list(self.magics[kind].items()): 

632 if isinstance(fn, LazyMagic) and (name, fn.spec) not in seen: 

633 seen.add((name, fn.spec)) 

634 declarations.append((name, kind, fn.spec)) 

635 for name, spec in list(self.lazy_magics.items()): 

636 if (name, spec) not in seen: 

637 seen.add((name, spec)) 

638 declarations.append((name, None, spec)) 

639 return declarations 

640 

641 def load_all_lazy_magics(self) -> None: 

642 """Import and register every magic still declared lazily. 

643 

644 Only the ``module:MagicsClass`` ones: loading an extension can run 

645 arbitrary code, so that waits for the magic to actually be used. 

646 """ 

647 for magic_name, magic_kind, spec in self._lazy_declarations(): 

648 if ":" in spec: 

649 self.load_lazy(magic_name, magic_kind) 

650 

651 def find( 

652 self, magic_kind: _MagicKind, magic_name: str 

653 ) -> Callable[..., Any] | None: 

654 """Return a registered magic, importing its implementation if needed. 

655 

656 Returns None if there is no such magic. 

657 

658 Raises 

659 ------ 

660 UsageError 

661 If `magic_name` is declared lazily for `magic_kind` but what the 

662 declaration names does not provide it. 

663 """ 

664 table = self.magics[magic_kind] 

665 fn = table.get(magic_name) 

666 if fn is None and magic_name in self.lazy_magics: 

667 # Declared straight into `lazy_magics` as configuration, so there 

668 # is no placeholder for this kind to carry the spec. 

669 self.load_lazy(magic_name, magic_kind) 

670 fn = table.get(magic_name) 

671 if isinstance(fn, LazyMagic): 

672 self.load_lazy(magic_name, magic_kind) 

673 fn = table.get(magic_name) 

674 if isinstance(fn, LazyMagic): 

675 # Declared but not delivered: the provider does not 

676 # implement this kind, and that is an error rather than a 

677 # cue to fall back to an older declaration. 

678 raise UsageError( 

679 "Magic `%s%s` is registered as lazy (%s) but loading it " 

680 "did not provide a %s implementation." 

681 % (magic_escapes[magic_kind], magic_name, fn.spec, magic_kind) 

682 ) 

683 return t.cast("Callable[..., Any] | None", fn) 

684 

685 def register(self, *magic_objects: type[Magics] | Magics) -> None: 

686 """Register one or more instances of Magics. 

687 

688 Take one or more classes or instances of classes that subclass the main 

689 `core.Magic` class, and register them with IPython to use the magic 

690 functions they provide. The registration process will then ensure that 

691 any methods that have decorated to provide line and/or cell magics will 

692 be recognized with the `%x`/`%%x` syntax as a line/cell magic 

693 respectively. 

694 

695 If classes are given, they will be instantiated with the default 

696 constructor. If your classes need a custom constructor, you should 

697 instanitate them first and pass the instance. 

698 

699 The provided arguments can be an arbitrary mix of classes and instances. 

700 

701 Parameters 

702 ---------- 

703 *magic_objects : one or more classes or instances 

704 """ 

705 self._register(magic_objects, lazy_spec=None) 

706 

707 def _register( 

708 self, 

709 magic_objects: tuple[type[Magics] | Magics, ...], 

710 lazy_spec: str | None, 

711 ) -> None: 

712 """Back end of :meth:`register`. 

713 

714 `lazy_spec` is the spec being resolved when this registration is the 

715 result of a lazy load, and None when the caller asked for it 

716 explicitly. A lazily loaded class only fills in the names it is still 

717 the declared provider of: a magic somebody registered for real -- as 

718 IPykernel does with ``%edit`` -- outranks a declaration, whichever 

719 happens to be loaded last. 

720 """ 

721 # Start by validating them to ensure they have all had their magic 

722 # methods registered at the instance level 

723 for m in magic_objects: 

724 if not m.registered: 

725 raise ValueError( 

726 "Class of magics %r was constructed without " 

727 "the @register_magics class decorator" 

728 ) 

729 if isinstance(m, type): 

730 # If we're given an uninstantiated class 

731 m = m(shell=self.shell) 

732 

733 # Now that we have an instance, we can register it and update the 

734 # table of callables 

735 self.registry[m.__class__.__name__] = m 

736 for mtype in magic_kinds: 

737 table = self.magics[mtype] 

738 for magic_name, func in m.magics[mtype].items(): 

739 if lazy_spec is not None: 

740 existing = table.get(magic_name) 

741 if existing is not None and not ( 

742 isinstance(existing, LazyMagic) 

743 and existing.spec == lazy_spec 

744 ): 

745 continue 

746 table[magic_name] = func 

747 

748 def register_function( 

749 self, 

750 func: Callable[..., Any], 

751 magic_kind: _MagicSpec = "line", 

752 magic_name: str | None = None, 

753 ) -> None: 

754 """Expose a standalone function as magic function for IPython. 

755 

756 This will create an IPython magic (line, cell or both) from a 

757 standalone function. The functions should have the following 

758 signatures: 

759 

760 * For line magics: `def f(line)` 

761 * For cell magics: `def f(line, cell)` 

762 * For a function that does both: `def f(line, cell=None)` 

763 

764 In the latter case, the function will be called with `cell==None` when 

765 invoked as `%f`, and with cell as a string when invoked as `%%f`. 

766 

767 Parameters 

768 ---------- 

769 func : callable 

770 Function to be registered as a magic. 

771 magic_kind : str 

772 Kind of magic, one of 'line', 'cell' or 'line_cell' 

773 magic_name : optional str 

774 If given, the name the magic will have in the IPython namespace. By 

775 default, the name of the function itself is used. 

776 """ 

777 

778 # Create the new method in the user_magics and register it in the 

779 # global table 

780 validate_type(magic_kind) 

781 magic_name = func.__name__ if magic_name is None else magic_name 

782 assert self.user_magics is not None 

783 setattr(self.user_magics, magic_name, func) 

784 record_magic(self.magics, magic_kind, magic_name, func) 

785 

786 def register_alias( 

787 self, 

788 alias_name: str, 

789 magic_name: str, 

790 magic_kind: _MagicKind = "line", 

791 magic_params: str | None = None, 

792 ) -> None: 

793 """Register an alias to a magic function. 

794 

795 The alias is an instance of :class:`MagicAlias`, which holds the 

796 name and kind of the magic it should call. Binding is done at 

797 call time, so if the underlying magic function is changed the alias 

798 will call the new function. 

799 

800 Parameters 

801 ---------- 

802 alias_name : str 

803 The name of the magic to be registered. 

804 magic_name : str 

805 The name of an existing magic. 

806 magic_kind : str 

807 Kind of magic, one of 'line' or 'cell' 

808 """ 

809 

810 # `validate_type` is too permissive, as it allows 'line_cell' 

811 # which we do not handle. 

812 if magic_kind not in magic_kinds: 

813 raise ValueError( 

814 "magic_kind must be one of %s, %s given" % magic_kinds, magic_kind 

815 ) 

816 

817 assert self.shell is not None 

818 assert self.user_magics is not None 

819 alias = MagicAlias(self.shell, magic_name, magic_kind, magic_params) 

820 setattr(self.user_magics, alias_name, alias) 

821 record_magic(self.magics, magic_kind, alias_name, alias) 

822 

823 

824# Key base class that provides the central functionality for magics. 

825 

826 

827class Magics(Configurable): 

828 """Base class for implementing magic functions. 

829 

830 Shell functions which can be reached as %function_name. All magic 

831 functions should accept a string, which they can parse for their own 

832 needs. This can make some functions easier to type, eg `%cd ../` 

833 vs. `%cd("../")` 

834 

835 Classes providing magic functions need to subclass this class, and they 

836 MUST: 

837 

838 - Use the method decorators `@line_magic` and `@cell_magic` to decorate 

839 individual methods as magic functions, AND 

840 

841 - Use the class decorator `@magics_class` to ensure that the magic 

842 methods are properly registered at the instance level upon instance 

843 initialization. 

844 

845 See :mod:`magic_functions` for examples of actual implementation classes. 

846 """ 

847 

848 # Dict holding all command-line options for each magic. 

849 options_table: dict[str, t.Any] = {} 

850 # Dict for the mapping of magic names to methods, set by class decorator 

851 magics: dict[str, t.Any] = {} 

852 # Flag to check that the class decorator was properly applied 

853 registered: bool = False 

854 # Instance of IPython shell 

855 shell: None | InteractiveShell = None 

856 

857 def __init__( 

858 self, shell: InteractiveShell | None = None, **kwargs: Any 

859 ) -> None: 

860 if not (self.__class__.registered): 

861 raise ValueError( 

862 "Magics subclass without registration - " 

863 "did you forget to apply @magics_class?" 

864 ) 

865 if shell is not None: 

866 if hasattr(shell, "configurables"): 

867 shell.configurables.append(self) # type: ignore[arg-type] 

868 if hasattr(shell, "config"): 

869 kwargs.setdefault("parent", shell) 

870 

871 self.shell = shell 

872 self.options_table = {} 

873 # The method decorators are run when the instance doesn't exist yet, so 

874 # they can only record the names of the methods they are supposed to 

875 # grab. Only now, that the instance exists, can we create the proper 

876 # mapping to bound methods. So we read the info off the original names 

877 # table and replace each method name by the actual bound method. 

878 # But we mustn't clobber the *class* mapping, in case of multiple instances. 

879 class_magics = self.magics 

880 self.magics = {} 

881 for mtype in magic_kinds: 

882 self.magics[mtype] = {} 

883 tab: dict[str, Any] = self.magics[mtype] 

884 cls_tab: dict[str, Any] = class_magics[mtype] 

885 for magic_name, meth_name in cls_tab.items(): 

886 if isinstance(meth_name, str): 

887 # it's a method name, grab it 

888 tab[magic_name] = getattr(self, meth_name) 

889 else: 

890 # it's the real thing 

891 tab[magic_name] = meth_name 

892 # Configurable **needs** to be initiated at the end or the config 

893 # magics get screwed up. 

894 super().__init__(**kwargs) 

895 

896 def arg_err(self, func: Callable[..., Any]) -> None: 

897 """Print docstring if incorrect arguments were passed""" 

898 from . import oinspect 

899 

900 print("Error in arguments:") 

901 print(oinspect.getdoc(func)) 

902 

903 def format_latex(self, strng: str) -> str: 

904 """Format a string for latex inclusion.""" 

905 

906 # Now build the string for output: 

907 # strng = _LATEX_CMD_NAME_RE.sub(r'\n\\texttt{\\textsl{\\large \1}}:',strng) 

908 strng = _LATEX_CMD_NAME_RE.sub(r"\n\\bigskip\n\\texttt{\\textbf{ \1}}:", strng) 

909 strng = _LATEX_CMD_RE.sub(r"\\texttt{\g<cmd>}", strng) 

910 strng = _LATEX_PAR_RE.sub(r"\\\\", strng) 

911 strng = _LATEX_ESCAPE_RE.sub(r"\\\1", strng) 

912 strng = _LATEX_NEWLINE_RE.sub(r"\\textbackslash{}n", strng) 

913 return strng 

914 

915 def parse_options( 

916 self, arg_str: str, opt_str: str, *long_opts: str, **kw: Any 

917 ) -> tuple[Any, Any]: 

918 """Parse options passed to an argument string. 

919 

920 The interface is similar to that of :func:`getopt.getopt`, but it 

921 returns a :class:`~IPython.utils.struct.Struct` with the options as keys 

922 and the stripped argument string still as a string. 

923 

924 arg_str is quoted as a true sys.argv vector by using shlex.split. 

925 This allows us to easily expand variables, glob files, quote 

926 arguments, etc. 

927 

928 Parameters 

929 ---------- 

930 arg_str : str 

931 The arguments to parse. 

932 opt_str : str 

933 The options specification. 

934 mode : str, default 'string' 

935 If given as 'list', the argument string is returned as a list (split 

936 on whitespace) instead of a string. 

937 list_all : bool, default False 

938 Put all option values in lists. Normally only options 

939 appearing more than once are put in a list. 

940 posix : bool, default True 

941 Whether to split the input line in POSIX mode or not, as per the 

942 conventions outlined in the :mod:`shlex` module from the standard 

943 library. 

944 """ 

945 

946 # inject default options at the beginning of the input line 

947 caller = sys._getframe(1).f_code.co_name 

948 arg_str = "{} {}".format(self.options_table.get(caller, ""), arg_str) 

949 

950 mode = kw.get("mode", "string") 

951 if mode not in ["string", "list"]: 

952 raise ValueError("incorrect mode given: %s" % mode) 

953 # Get options 

954 list_all = kw.get("list_all", 0) 

955 posix = kw.get("posix", os.name == "posix") 

956 strict = kw.get("strict", True) 

957 

958 preserve_non_opts = kw.get("preserve_non_opts", False) 

959 remainder_arg_str = arg_str 

960 

961 # Check if we have more than one argument to warrant extra processing: 

962 odict: dict[str, t.Any] = {} # Dictionary with options 

963 args = arg_str.split() 

964 if len(args) >= 1: 

965 from ..utils.process import arg_split 

966 # If the list of inputs only has 0 or 1 thing in it, there's no 

967 # need to look for options 

968 argv = arg_split(arg_str, posix, strict) 

969 # Do regular option processing 

970 try: 

971 opts, args = getopt(argv, opt_str, long_opts) 

972 except GetoptError as e: 

973 raise UsageError( 

974 '%s (allowed: "%s"%s)' 

975 % (e.msg, opt_str, " ".join(("",) + long_opts) if long_opts else "") 

976 ) from e 

977 for o, a in opts: 

978 if mode == "string" and preserve_non_opts: 

979 # remove option-parts from the original args-string and preserve remaining-part. 

980 # This relies on the arg_split(...) and getopt(...)'s impl spec, that the parsed options are 

981 # returned in the original order. 

982 remainder_arg_str = remainder_arg_str.replace(o, "", 1).replace( 

983 a, "", 1 

984 ) 

985 if o.startswith("--"): 

986 o = o[2:] 

987 else: 

988 o = o[1:] 

989 try: 

990 odict[o].append(a) 

991 except AttributeError: 

992 odict[o] = [odict[o], a] 

993 except KeyError: 

994 if list_all: 

995 odict[o] = [a] 

996 else: 

997 odict[o] = a 

998 

999 # Prepare opts,args for return 

1000 opts = Struct(odict) # type: ignore[assignment, no-untyped-call] 

1001 if mode == "string": 

1002 if preserve_non_opts: 

1003 args = remainder_arg_str.lstrip() # type: ignore[assignment] 

1004 else: 

1005 args = " ".join(args) # type: ignore[assignment] 

1006 

1007 return opts, args 

1008 

1009class MagicAlias: 

1010 """An alias to another magic function. 

1011 

1012 An alias is determined by its magic name and magic kind. Lookup 

1013 is done at call time, so if the underlying magic changes the alias 

1014 will call the new function. 

1015 

1016 Use the :meth:`MagicsManager.register_alias` method or the 

1017 `%alias_magic` magic function to create and register a new alias. 

1018 """ 

1019 

1020 def __init__( 

1021 self, 

1022 shell: InteractiveShell, 

1023 magic_name: str, 

1024 magic_kind: _MagicKind, 

1025 magic_params: str | None = None, 

1026 ) -> None: 

1027 self.shell = shell 

1028 self.magic_name = magic_name 

1029 self.magic_params = magic_params 

1030 self.magic_kind = magic_kind 

1031 

1032 self.pretty_target = "{}{}".format(magic_escapes[self.magic_kind], self.magic_name) 

1033 self.__doc__ = "Alias for `%s`." % self.pretty_target 

1034 

1035 self._in_call = False 

1036 

1037 def __call__(self, *args: Any, **kwargs: Any) -> Any: 

1038 """Call the magic alias.""" 

1039 fn = self.shell.find_magic(self.magic_name, self.magic_kind) # type: ignore[no-untyped-call] 

1040 if fn is None: 

1041 raise UsageError("Magic `%s` not found." % self.pretty_target) 

1042 

1043 # Protect against infinite recursion. 

1044 if self._in_call: 

1045 raise UsageError( 

1046 "Infinite recursion detected; magic aliases cannot call themselves." 

1047 ) 

1048 self._in_call = True 

1049 try: 

1050 if self.magic_params: 

1051 args_list = list(args) 

1052 args_list[0] = self.magic_params + " " + args[0] 

1053 args = tuple(args_list) 

1054 return fn(*args, **kwargs) 

1055 finally: 

1056 self._in_call = False