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

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

356 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, spec in list(self._manager.lazy_magics.items()): 

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

402 self._manager.load_lazy(magic_name) 

403 break 

404 if key not in self: 

405 # A second miss must not loop back here. 

406 raise KeyError(key) 

407 return self[key] 

408 

409 

410class MagicsManager(Configurable): 

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

412 

413 # Non-configurable class attributes 

414 

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

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

417 # magic function dispatch 

418 magics = Dict() 

419 lazy_magics = Dict( 

420 help=""" 

421 Mapping from magic names to modules to load. 

422 

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

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

425 

426 For example:: 

427 

428 c.MagicsManager.lazy_magics = { 

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

430 "my_other_magic": "also.slow", 

431 } 

432 

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

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

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

436 

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

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

439 This is how IPython declares its own magics, see 

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

441 

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

443 and line magics. 

444 

445 Lazy loading happen relatively late in execution process, and 

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

447 might not support lazy loading. 

448 """ 

449 ).tag( 

450 config=True, 

451 ) 

452 

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

454 registry = Dict() 

455 

456 shell = Instance( 

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

458 ) 

459 

460 auto_magic = Bool( 

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

462 ).tag(config=True) 

463 

464 @observe("auto_magic") 

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

466 assert self.shell is not None 

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

468 

469 _auto_status = [ 

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

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

472 ] 

473 

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

475 

476 def __init__( 

477 self, 

478 shell: InteractiveShell | None = None, 

479 config: Any = None, 

480 user_magics: Magics | None = None, 

481 **traits: Any, 

482 ) -> None: 

483 super().__init__( 

484 shell=shell, config=config, user_magics=user_magics, **traits 

485 ) 

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

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

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

489 self.registry = _MagicsRegistry(self) 

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

491 # registered magic containers can be found there. 

492 if user_magics is not None: 

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

494 

495 def auto_status(self) -> str: 

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

497 return self._auto_status[self.auto_magic] 

498 

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

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

501 

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

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

504 """ 

505 return self.magics 

506 

507 def lsmagic_docs( 

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

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

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

511 

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

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

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

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

516 

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

518 """ 

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

520 self.load_all_lazy_magics() 

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

522 for m_type in self.magics: 

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

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

525 if isinstance(m_func, LazyMagic): 

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

527 m_docs[m_name] = missing 

528 elif m_func.__doc__: 

529 if brief: 

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

531 else: 

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

533 else: 

534 m_docs[m_name] = missing 

535 docs[m_type] = m_docs 

536 return docs 

537 

538 def register_lazy( 

539 self, 

540 name: str, 

541 fully_qualified_name: str, 

542 magic_kind: _MagicSpec = "line_cell", 

543 ) -> None: 

544 """ 

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

546 

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

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

549 

550 Parameters 

551 ---------- 

552 name : str 

553 Name of the magic you wish to register. 

554 fully_qualified_name : str 

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

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

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

558 directly -- how IPython declares its own magics. 

559 magic_kind : str 

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

561 declared magic may well be both). 

562 """ 

563 validate_type(magic_kind) 

564 self.lazy_magics[name] = fully_qualified_name 

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

566 for kind in kinds: 

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

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

569 continue 

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

571 

572 def load_lazy(self, magic_name: str) -> None: 

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

574 

575 Does nothing if `magic_name` was not declared through 

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

577 has already been loaded. 

578 """ 

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

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

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

582 spec = ( 

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

584 ) 

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

586 return 

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

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

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

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

591 self._loaded_lazy.add(spec) 

592 try: 

593 if sep: 

594 from importlib import import_module 

595 

596 self._register( 

597 (getattr(import_module(module_name), class_name),), 

598 lazy_spec=spec, 

599 ) 

600 else: 

601 assert self.shell is not None 

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

603 except Exception: 

604 self._loaded_lazy.discard(spec) 

605 raise 

606 

607 def load_all_lazy_magics(self) -> None: 

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

609 

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

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

612 """ 

613 for magic_name, spec in list(self.lazy_magics.items()): 

614 if ":" in spec: 

615 self.load_lazy(magic_name) 

616 

617 def find( 

618 self, magic_kind: _MagicKind, magic_name: str 

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

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

621 

622 Returns None if there is no such magic. 

623 """ 

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

625 if isinstance(fn, LazyMagic) or (fn is None and magic_name in self.lazy_magics): 

626 self.load_lazy(magic_name) 

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

628 if isinstance(fn, LazyMagic): 

629 # Declared but not delivered; drop the stale placeholder. 

630 del self.magics[magic_kind][magic_name] 

631 fn = None 

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

633 

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

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

636 

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

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

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

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

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

642 respectively. 

643 

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

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

646 instanitate them first and pass the instance. 

647 

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

649 

650 Parameters 

651 ---------- 

652 *magic_objects : one or more classes or instances 

653 """ 

654 self._register(magic_objects, lazy_spec=None) 

655 

656 def _register( 

657 self, 

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

659 lazy_spec: str | None, 

660 ) -> None: 

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

662 

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

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

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

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

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

668 happens to be loaded last. 

669 """ 

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

671 # methods registered at the instance level 

672 for m in magic_objects: 

673 if not m.registered: 

674 raise ValueError( 

675 "Class of magics %r was constructed without " 

676 "the @register_magics class decorator" 

677 ) 

678 if isinstance(m, type): 

679 # If we're given an uninstantiated class 

680 m = m(shell=self.shell) 

681 

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

683 # table of callables 

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

685 for mtype in magic_kinds: 

686 table = self.magics[mtype] 

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

688 if lazy_spec is not None: 

689 existing = table.get(magic_name) 

690 if existing is not None and not ( 

691 isinstance(existing, LazyMagic) 

692 and existing.spec == lazy_spec 

693 ): 

694 continue 

695 table[magic_name] = func 

696 

697 def register_function( 

698 self, 

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

700 magic_kind: _MagicSpec = "line", 

701 magic_name: str | None = None, 

702 ) -> None: 

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

704 

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

706 standalone function. The functions should have the following 

707 signatures: 

708 

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

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

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

712 

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

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

715 

716 Parameters 

717 ---------- 

718 func : callable 

719 Function to be registered as a magic. 

720 magic_kind : str 

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

722 magic_name : optional str 

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

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

725 """ 

726 

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

728 # global table 

729 validate_type(magic_kind) 

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

731 assert self.user_magics is not None 

732 setattr(self.user_magics, magic_name, func) 

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

734 

735 def register_alias( 

736 self, 

737 alias_name: str, 

738 magic_name: str, 

739 magic_kind: _MagicKind = "line", 

740 magic_params: str | None = None, 

741 ) -> None: 

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

743 

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

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

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

747 will call the new function. 

748 

749 Parameters 

750 ---------- 

751 alias_name : str 

752 The name of the magic to be registered. 

753 magic_name : str 

754 The name of an existing magic. 

755 magic_kind : str 

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

757 """ 

758 

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

760 # which we do not handle. 

761 if magic_kind not in magic_kinds: 

762 raise ValueError( 

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

764 ) 

765 

766 assert self.shell is not None 

767 assert self.user_magics is not None 

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

769 setattr(self.user_magics, alias_name, alias) 

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

771 

772 

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

774 

775 

776class Magics(Configurable): 

777 """Base class for implementing magic functions. 

778 

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

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

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

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

783 

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

785 MUST: 

786 

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

788 individual methods as magic functions, AND 

789 

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

791 methods are properly registered at the instance level upon instance 

792 initialization. 

793 

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

795 """ 

796 

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

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

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

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

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

802 registered: bool = False 

803 # Instance of IPython shell 

804 shell: None | InteractiveShell = None 

805 

806 def __init__( 

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

808 ) -> None: 

809 if not (self.__class__.registered): 

810 raise ValueError( 

811 "Magics subclass without registration - " 

812 "did you forget to apply @magics_class?" 

813 ) 

814 if shell is not None: 

815 if hasattr(shell, "configurables"): 

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

817 if hasattr(shell, "config"): 

818 kwargs.setdefault("parent", shell) 

819 

820 self.shell = shell 

821 self.options_table = {} 

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

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

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

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

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

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

828 class_magics = self.magics 

829 self.magics = {} 

830 for mtype in magic_kinds: 

831 self.magics[mtype] = {} 

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

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

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

835 if isinstance(meth_name, str): 

836 # it's a method name, grab it 

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

838 else: 

839 # it's the real thing 

840 tab[magic_name] = meth_name 

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

842 # magics get screwed up. 

843 super().__init__(**kwargs) 

844 

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

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

847 from . import oinspect 

848 

849 print("Error in arguments:") 

850 print(oinspect.getdoc(func)) 

851 

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

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

854 

855 # Now build the string for output: 

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

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

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

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

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

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

862 return strng 

863 

864 def parse_options( 

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

866 ) -> tuple[Any, Any]: 

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

868 

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

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

871 and the stripped argument string still as a string. 

872 

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

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

875 arguments, etc. 

876 

877 Parameters 

878 ---------- 

879 arg_str : str 

880 The arguments to parse. 

881 opt_str : str 

882 The options specification. 

883 mode : str, default 'string' 

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

885 on whitespace) instead of a string. 

886 list_all : bool, default False 

887 Put all option values in lists. Normally only options 

888 appearing more than once are put in a list. 

889 posix : bool, default True 

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

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

892 library. 

893 """ 

894 

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

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

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

898 

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

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

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

902 # Get options 

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

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

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

906 

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

908 remainder_arg_str = arg_str 

909 

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

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

912 args = arg_str.split() 

913 if len(args) >= 1: 

914 from ..utils.process import arg_split 

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

916 # need to look for options 

917 argv = arg_split(arg_str, posix, strict) 

918 # Do regular option processing 

919 try: 

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

921 except GetoptError as e: 

922 raise UsageError( 

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

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

925 ) from e 

926 for o, a in opts: 

927 if mode == "string" and preserve_non_opts: 

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

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

930 # returned in the original order. 

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

932 a, "", 1 

933 ) 

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

935 o = o[2:] 

936 else: 

937 o = o[1:] 

938 try: 

939 odict[o].append(a) 

940 except AttributeError: 

941 odict[o] = [odict[o], a] 

942 except KeyError: 

943 if list_all: 

944 odict[o] = [a] 

945 else: 

946 odict[o] = a 

947 

948 # Prepare opts,args for return 

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

950 if mode == "string": 

951 if preserve_non_opts: 

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

953 else: 

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

955 

956 return opts, args 

957 

958class MagicAlias: 

959 """An alias to another magic function. 

960 

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

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

963 will call the new function. 

964 

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

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

967 """ 

968 

969 def __init__( 

970 self, 

971 shell: InteractiveShell, 

972 magic_name: str, 

973 magic_kind: _MagicKind, 

974 magic_params: str | None = None, 

975 ) -> None: 

976 self.shell = shell 

977 self.magic_name = magic_name 

978 self.magic_params = magic_params 

979 self.magic_kind = magic_kind 

980 

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

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

983 

984 self._in_call = False 

985 

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

987 """Call the magic alias.""" 

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

989 if fn is None: 

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

991 

992 # Protect against infinite recursion. 

993 if self._in_call: 

994 raise UsageError( 

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

996 ) 

997 self._in_call = True 

998 try: 

999 if self.magic_params: 

1000 args_list = list(args) 

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

1002 args = tuple(args_list) 

1003 return fn(*args, **kwargs) 

1004 finally: 

1005 self._in_call = False