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
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
1from __future__ import annotations
3"""Magic functions for InteractiveShell."""
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
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# -----------------------------------------------------------------------------
14import os
15import re
16import sys
17from getopt import getopt, GetoptError
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
26import typing as t
27from typing import Any, Literal, TypeVar, overload
28from collections.abc import Callable
30if t.TYPE_CHECKING:
31 from types import FrameType
33 from IPython.core.interactiveshell import InteractiveShell
35_F = TypeVar("_F", bound=Callable[..., Any])
36_MagicKind = Literal["line", "cell"]
37_MagicSpec = Literal["line", "cell", "line_cell"]
40# -----------------------------------------------------------------------------
41# Globals
42# -----------------------------------------------------------------------------
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
50magics: dict[str, dict[str, str]] = dict(line={}, cell={})
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)
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")
68# -----------------------------------------------------------------------------
69# Utility classes and functions
70# -----------------------------------------------------------------------------
73class Bunch:
74 pass
77def compress_dhist(dh: list[str]) -> list[str]:
78 """Compress a directory history into a new one with at most 20 entries.
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:]
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)
93 return newhead + tail
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
102# -----------------------------------------------------------------------------
103# Class and method decorators for registering magics
104# -----------------------------------------------------------------------------
107_T = TypeVar("_T", bound=type["Magics"])
110def magics_class(cls: _T) -> _T:
111 """Class decorator for all subclasses of the main Magics class.
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.
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
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.
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
160def validate_type(magic_kind: str) -> None:
161 """Ensure that the given magic_kind is valid.
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 )
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.
177The decorator can be used with or without arguments, as follows.
179i) without arguments: it will create a {1} magic named as the {0} being
180decorated::
182 @deco
183 def foo(...)
185will create a {1} magic named `foo`.
187ii) with one string argument: which will be used as the actual name of the
188resulting magic::
190 @deco('bar')
191 def foo(...)
193will create a {1} magic named `bar`.
195To register a class magic use ``Interactiveshell.register_magic(class or instance)``.
196"""
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.
204def _method_magic_marker(
205 magic_kind: _MagicSpec,
206) -> Callable[[_F | str], _F | Callable[[_F], _F]]:
207 """Decorator factory for methods in Magics subclasses."""
209 validate_type(magic_kind)
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
225 def mark(func: _F, *a: Any, **kw: Any) -> _F:
226 record_magic(magics, magic_kind, name, func.__name__)
227 return func
229 retval = mark
230 else:
231 raise TypeError("Decorator can only be called with string or function")
232 return retval
234 # Ensure the resulting decorator has a usable docstring
235 magic_deco.__doc__ = _docstring_template.format("method", magic_kind)
236 return magic_deco
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)
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 )
260 ip: InteractiveShell = get_ipython()
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
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
277 retval = mark
278 else:
279 raise TypeError("Decorator can only be called with string or function")
280 return retval
282 # Ensure the resulting decorator has a usable docstring
283 ds = _docstring_template.format("function", magic_kind)
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 )
296 magic_deco.__doc__ = ds
297 return magic_deco
300MAGIC_NO_VAR_EXPAND_ATTR = "_ipython_magic_no_var_expand"
301MAGIC_OUTPUT_CAN_BE_SILENCED = "_ipython_magic_output_can_be_silenced"
304def no_var_expand(magic_func: _F) -> _F:
305 """Mark a magic function as not needing variable expansion
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.
314 .. versionadded:: 7.3
315 """
316 setattr(magic_func, MAGIC_NO_VAR_EXPAND_ATTR, True)
317 return magic_func
320def output_can_be_silenced(magic_func: _F) -> _F:
321 """Mark a magic function so its output may be silenced.
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
331# Create the actual decorators for public use
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")
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")
344# -----------------------------------------------------------------------------
345# Core Magic classes
346# -----------------------------------------------------------------------------
349class LazyMagic:
350 """Stands in the magics table for a magic that is not imported yet.
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 """
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
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
378 def __call__(self, *args: Any, **kwargs: Any) -> Any:
379 return self._resolve()(*args, **kwargs)
381 def __getattr__(self, name: str) -> Any:
382 return getattr(self._resolve(), name)
384 def __repr__(self) -> str:
385 return f"<unloaded magic {self._name} from {self.spec}>"
388class _MagicsRegistry(dict[str, Any]):
389 """``MagicsManager.registry``, which loads a lazy class on a miss.
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 """
395 def __init__(self, manager: MagicsManager) -> None:
396 super().__init__()
397 self._manager = manager
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]
413class MagicsManager(Configurable):
414 """Object that handles all magic-related functionality for IPython."""
416 # Non-configurable class attributes
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.
426 This can be used in IPython/IPykernel configuration to declare lazy magics
427 that will only be imported/registered on first use.
429 For example::
431 c.MagicsManager.lazy_magics = {
432 "my_magic": "slow.to.import",
433 "my_other_magic": "also.slow",
434 }
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`.
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`.
445 Magics names should be without percent(s) as magics can be both cell
446 and line magics.
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 )
456 # A registry of the original objects that we've been given holding magics.
457 registry = Dict()
459 shell = Instance(
460 "IPython.core.interactiveshell.InteractiveShellABC", allow_none=True
461 )
463 auto_magic = Bool(
464 True, help="Automatically call line magics without requiring explicit % prefix"
465 ).tag(config=True)
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"]
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 ]
477 user_magics = Instance("IPython.core.magics.UserMagics", allow_none=True)
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
498 def auto_status(self) -> str:
499 """Return descriptive string with automagic status."""
500 return self._auto_status[self.auto_magic]
502 def lsmagic(self) -> dict[str, dict[str, Any]]:
503 """Return a dict of currently available magic functions.
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
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.
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.
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
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.
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.
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)
575 def load_lazy(self, magic_name: str, magic_kind: _MagicKind | None = None) -> None:
576 """Import and register whatever provides `magic_name`.
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.
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
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
620 def _lazy_declarations(self) -> list[tuple[str, _MagicKind | None, str]]:
621 """Every live lazy declaration, as ``(name, kind, spec)``.
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
641 def load_all_lazy_magics(self) -> None:
642 """Import and register every magic still declared lazily.
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)
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.
656 Returns None if there is no such magic.
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)
685 def register(self, *magic_objects: type[Magics] | Magics) -> None:
686 """Register one or more instances of Magics.
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.
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.
699 The provided arguments can be an arbitrary mix of classes and instances.
701 Parameters
702 ----------
703 *magic_objects : one or more classes or instances
704 """
705 self._register(magic_objects, lazy_spec=None)
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`.
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)
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
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.
756 This will create an IPython magic (line, cell or both) from a
757 standalone function. The functions should have the following
758 signatures:
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)`
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`.
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 """
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)
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.
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.
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 """
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 )
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)
824# Key base class that provides the central functionality for magics.
827class Magics(Configurable):
828 """Base class for implementing magic functions.
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("../")`
835 Classes providing magic functions need to subclass this class, and they
836 MUST:
838 - Use the method decorators `@line_magic` and `@cell_magic` to decorate
839 individual methods as magic functions, AND
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.
845 See :mod:`magic_functions` for examples of actual implementation classes.
846 """
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
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)
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)
896 def arg_err(self, func: Callable[..., Any]) -> None:
897 """Print docstring if incorrect arguments were passed"""
898 from . import oinspect
900 print("Error in arguments:")
901 print(oinspect.getdoc(func))
903 def format_latex(self, strng: str) -> str:
904 """Format a string for latex inclusion."""
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
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.
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.
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.
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 """
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)
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)
958 preserve_non_opts = kw.get("preserve_non_opts", False)
959 remainder_arg_str = arg_str
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
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]
1007 return opts, args
1009class MagicAlias:
1010 """An alias to another magic function.
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.
1016 Use the :meth:`MagicsManager.register_alias` method or the
1017 `%alias_magic` magic function to create and register a new alias.
1018 """
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
1032 self.pretty_target = "{}{}".format(magic_escapes[self.magic_kind], self.magic_name)
1033 self.__doc__ = "Alias for `%s`." % self.pretty_target
1035 self._in_call = False
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)
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