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
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, 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]
410class MagicsManager(Configurable):
411 """Object that handles all magic-related functionality for IPython."""
413 # Non-configurable class attributes
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.
423 This can be used in IPython/IPykernel configuration to declare lazy magics
424 that will only be imported/registered on first use.
426 For example::
428 c.MagicsManager.lazy_magics = {
429 "my_magic": "slow.to.import",
430 "my_other_magic": "also.slow",
431 }
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`.
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`.
442 Magics names should be without percent(s) as magics can be both cell
443 and line magics.
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 )
453 # A registry of the original objects that we've been given holding magics.
454 registry = Dict()
456 shell = Instance(
457 "IPython.core.interactiveshell.InteractiveShellABC", allow_none=True
458 )
460 auto_magic = Bool(
461 True, help="Automatically call line magics without requiring explicit % prefix"
462 ).tag(config=True)
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"]
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 ]
474 user_magics = Instance("IPython.core.magics.UserMagics", allow_none=True)
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
495 def auto_status(self) -> str:
496 """Return descriptive string with automagic status."""
497 return self._auto_status[self.auto_magic]
499 def lsmagic(self) -> dict[str, dict[str, Any]]:
500 """Return a dict of currently available magic functions.
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
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.
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.
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
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.
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.
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)
572 def load_lazy(self, magic_name: str) -> None:
573 """Import and register whatever provides `magic_name`.
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
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
607 def load_all_lazy_magics(self) -> None:
608 """Import and register every magic still declared lazily.
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)
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.
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)
634 def register(self, *magic_objects: type[Magics] | Magics) -> None:
635 """Register one or more instances of Magics.
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.
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.
648 The provided arguments can be an arbitrary mix of classes and instances.
650 Parameters
651 ----------
652 *magic_objects : one or more classes or instances
653 """
654 self._register(magic_objects, lazy_spec=None)
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`.
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)
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
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.
705 This will create an IPython magic (line, cell or both) from a
706 standalone function. The functions should have the following
707 signatures:
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)`
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`.
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 """
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)
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.
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.
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 """
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 )
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)
773# Key base class that provides the central functionality for magics.
776class Magics(Configurable):
777 """Base class for implementing magic functions.
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("../")`
784 Classes providing magic functions need to subclass this class, and they
785 MUST:
787 - Use the method decorators `@line_magic` and `@cell_magic` to decorate
788 individual methods as magic functions, AND
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.
794 See :mod:`magic_functions` for examples of actual implementation classes.
795 """
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
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)
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)
845 def arg_err(self, func: Callable[..., Any]) -> None:
846 """Print docstring if incorrect arguments were passed"""
847 from . import oinspect
849 print("Error in arguments:")
850 print(oinspect.getdoc(func))
852 def format_latex(self, strng: str) -> str:
853 """Format a string for latex inclusion."""
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
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.
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.
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.
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 """
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)
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)
907 preserve_non_opts = kw.get("preserve_non_opts", False)
908 remainder_arg_str = arg_str
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
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]
956 return opts, args
958class MagicAlias:
959 """An alias to another magic function.
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.
965 Use the :meth:`MagicsManager.register_alias` method or the
966 `%alias_magic` magic function to create and register a new alias.
967 """
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
981 self.pretty_target = "{}{}".format(magic_escapes[self.magic_kind], self.magic_name)
982 self.__doc__ = "Alias for `%s`." % self.pretty_target
984 self._in_call = False
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)
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