diff --git a/lib/python3.12/site-packages/IPython/core/magics/__init__.py b/lib/python3.12/site-packages/IPython/core/magics/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..a6c5f474c15d29032a23a50d9c884e00235e56ac --- /dev/null +++ b/lib/python3.12/site-packages/IPython/core/magics/__init__.py @@ -0,0 +1,42 @@ +"""Implementation of all the magic functions built into IPython. +""" +#----------------------------------------------------------------------------- +# Copyright (c) 2012 The IPython Development Team. +# +# Distributed under the terms of the Modified BSD License. +# +# The full license is in the file COPYING.txt, distributed with this software. +#----------------------------------------------------------------------------- + +#----------------------------------------------------------------------------- +# Imports +#----------------------------------------------------------------------------- + +from ..magic import Magics, magics_class +from .auto import AutoMagics +from .basic import BasicMagics, AsyncMagics +from .code import CodeMagics, MacroToEdit +from .config import ConfigMagics +from .display import DisplayMagics +from .execution import ExecutionMagics +from .extension import ExtensionMagics +from .history import HistoryMagics +from .logging import LoggingMagics +from .namespace import NamespaceMagics +from .osm import OSMagics +from .packaging import PackagingMagics +from .pylab import PylabMagics +from .script import ScriptMagics + +#----------------------------------------------------------------------------- +# Magic implementation classes +#----------------------------------------------------------------------------- + +@magics_class +class UserMagics(Magics): + """Placeholder for user-defined magics to be added at runtime. + + All magics are eventually merged into a single namespace at runtime, but we + use this class to isolate the magics defined dynamically by the user into + their own class. + """ diff --git a/lib/python3.12/site-packages/IPython/core/magics/__pycache__/__init__.cpython-312.pyc b/lib/python3.12/site-packages/IPython/core/magics/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..65d293016f51531d3ff5661c881edec6ec2160c4 Binary files /dev/null and b/lib/python3.12/site-packages/IPython/core/magics/__pycache__/__init__.cpython-312.pyc differ diff --git a/lib/python3.12/site-packages/IPython/core/magics/__pycache__/ast_mod.cpython-312.pyc b/lib/python3.12/site-packages/IPython/core/magics/__pycache__/ast_mod.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..55761c6c145d7331a9dd938bc51c8d9ad00c4c76 Binary files /dev/null and b/lib/python3.12/site-packages/IPython/core/magics/__pycache__/ast_mod.cpython-312.pyc differ diff --git a/lib/python3.12/site-packages/IPython/core/magics/__pycache__/auto.cpython-312.pyc b/lib/python3.12/site-packages/IPython/core/magics/__pycache__/auto.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a03b7a0bbd58120f901acc188ae6d5082afcc0a9 Binary files /dev/null and b/lib/python3.12/site-packages/IPython/core/magics/__pycache__/auto.cpython-312.pyc differ diff --git a/lib/python3.12/site-packages/IPython/core/magics/__pycache__/basic.cpython-312.pyc b/lib/python3.12/site-packages/IPython/core/magics/__pycache__/basic.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0800eeca382a7305512433c7d4a9e36ba5340ec1 Binary files /dev/null and b/lib/python3.12/site-packages/IPython/core/magics/__pycache__/basic.cpython-312.pyc differ diff --git a/lib/python3.12/site-packages/IPython/core/magics/__pycache__/code.cpython-312.pyc b/lib/python3.12/site-packages/IPython/core/magics/__pycache__/code.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..05c8c3ebd23c438a7ba821ece0fda3a2286d8cf9 Binary files /dev/null and b/lib/python3.12/site-packages/IPython/core/magics/__pycache__/code.cpython-312.pyc differ diff --git a/lib/python3.12/site-packages/IPython/core/magics/__pycache__/config.cpython-312.pyc b/lib/python3.12/site-packages/IPython/core/magics/__pycache__/config.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..375f8525b30c7a1974990d7f25be719f21d16851 Binary files /dev/null and b/lib/python3.12/site-packages/IPython/core/magics/__pycache__/config.cpython-312.pyc differ diff --git a/lib/python3.12/site-packages/IPython/core/magics/__pycache__/display.cpython-312.pyc b/lib/python3.12/site-packages/IPython/core/magics/__pycache__/display.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ca6ab849d9d049ce06af793d3d60c258e2eda26d Binary files /dev/null and b/lib/python3.12/site-packages/IPython/core/magics/__pycache__/display.cpython-312.pyc differ diff --git a/lib/python3.12/site-packages/IPython/core/magics/__pycache__/execution.cpython-312.pyc b/lib/python3.12/site-packages/IPython/core/magics/__pycache__/execution.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..52b4532dbb161e3997a2aefea0d5b4ef6acd5f64 Binary files /dev/null and b/lib/python3.12/site-packages/IPython/core/magics/__pycache__/execution.cpython-312.pyc differ diff --git a/lib/python3.12/site-packages/IPython/core/magics/__pycache__/extension.cpython-312.pyc b/lib/python3.12/site-packages/IPython/core/magics/__pycache__/extension.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..266faffbbed71dc454fcf6dddb5bcd82acaca177 Binary files /dev/null and b/lib/python3.12/site-packages/IPython/core/magics/__pycache__/extension.cpython-312.pyc differ diff --git a/lib/python3.12/site-packages/IPython/core/magics/__pycache__/history.cpython-312.pyc b/lib/python3.12/site-packages/IPython/core/magics/__pycache__/history.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fd242fb3c91908000ef34d17417e9be1cd0d1c2b Binary files /dev/null and b/lib/python3.12/site-packages/IPython/core/magics/__pycache__/history.cpython-312.pyc differ diff --git a/lib/python3.12/site-packages/IPython/core/magics/__pycache__/logging.cpython-312.pyc b/lib/python3.12/site-packages/IPython/core/magics/__pycache__/logging.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6a67cb7cb27e7de85eab8b4f7dd7184cad84fb36 Binary files /dev/null and b/lib/python3.12/site-packages/IPython/core/magics/__pycache__/logging.cpython-312.pyc differ diff --git a/lib/python3.12/site-packages/IPython/core/magics/__pycache__/namespace.cpython-312.pyc b/lib/python3.12/site-packages/IPython/core/magics/__pycache__/namespace.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f1e44214abcb12cf7206d307273cc7f0fb1c459e Binary files /dev/null and b/lib/python3.12/site-packages/IPython/core/magics/__pycache__/namespace.cpython-312.pyc differ diff --git a/lib/python3.12/site-packages/IPython/core/magics/__pycache__/osm.cpython-312.pyc b/lib/python3.12/site-packages/IPython/core/magics/__pycache__/osm.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f1320668e8e6c2316ebb0ce540f706f3d8225c8d Binary files /dev/null and b/lib/python3.12/site-packages/IPython/core/magics/__pycache__/osm.cpython-312.pyc differ diff --git a/lib/python3.12/site-packages/IPython/core/magics/__pycache__/packaging.cpython-312.pyc b/lib/python3.12/site-packages/IPython/core/magics/__pycache__/packaging.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..995935770c8eaaf2c939654268b0d04592fa1ac9 Binary files /dev/null and b/lib/python3.12/site-packages/IPython/core/magics/__pycache__/packaging.cpython-312.pyc differ diff --git a/lib/python3.12/site-packages/IPython/core/magics/__pycache__/pylab.cpython-312.pyc b/lib/python3.12/site-packages/IPython/core/magics/__pycache__/pylab.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..53914e5daa5846e18bef38ff5861fc4161d77c27 Binary files /dev/null and b/lib/python3.12/site-packages/IPython/core/magics/__pycache__/pylab.cpython-312.pyc differ diff --git a/lib/python3.12/site-packages/IPython/core/magics/__pycache__/script.cpython-312.pyc b/lib/python3.12/site-packages/IPython/core/magics/__pycache__/script.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dbcf5ae239524d2bc762d8ca9c8100a4930b3ede Binary files /dev/null and b/lib/python3.12/site-packages/IPython/core/magics/__pycache__/script.cpython-312.pyc differ diff --git a/lib/python3.12/site-packages/IPython/core/magics/ast_mod.py b/lib/python3.12/site-packages/IPython/core/magics/ast_mod.py new file mode 100644 index 0000000000000000000000000000000000000000..dc3c5bc76838008d970f50416a4565ebb7ad78b9 --- /dev/null +++ b/lib/python3.12/site-packages/IPython/core/magics/ast_mod.py @@ -0,0 +1,330 @@ +""" +This module contains utility function and classes to inject simple ast +transformations based on code strings into IPython. While it is already possible +with ast-transformers it is not easy to directly manipulate ast. + + +IPython has pre-code and post-code hooks, but are ran from within the IPython +machinery so may be inappropriate, for example for performance measurement. + +This module give you tools to simplify this, and expose 2 classes: + +- `ReplaceCodeTransformer` which is a simple ast transformer based on code + template, + +and for advance case: + +- `Mangler` which is a simple ast transformer that mangle names in the ast. + + +Example, let's try to make a simple version of the ``timeit`` magic, that run a +code snippet 10 times and print the average time taken. + +Basically we want to run : + +.. code-block:: python + + from time import perf_counter + now = perf_counter() + for i in range(10): + __code__ # our code + print(f"Time taken: {(perf_counter() - now)/10}") + __ret__ # the result of the last statement + +Where ``__code__`` is the code snippet we want to run, and ``__ret__`` is the +result, so that if we for example run `dataframe.head()` IPython still display +the head of dataframe instead of nothing. + +Here is a complete example of a file `timit2.py` that define such a magic: + +.. code-block:: python + + from IPython.core.magic import ( + Magics, + magics_class, + line_cell_magic, + ) + from IPython.core.magics.ast_mod import ReplaceCodeTransformer + from textwrap import dedent + import ast + + template = template = dedent(''' + from time import perf_counter + now = perf_counter() + for i in range(10): + __code__ + print(f"Time taken: {(perf_counter() - now)/10}") + __ret__ + ''' + ) + + + @magics_class + class AstM(Magics): + @line_cell_magic + def t2(self, line, cell): + transformer = ReplaceCodeTransformer.from_string(template) + transformer.debug = True + transformer.mangler.debug = True + new_code = transformer.visit(ast.parse(cell)) + return exec(compile(new_code, "", "exec")) + + + def load_ipython_extension(ip): + ip.register_magics(AstM) + + + +.. code-block:: python + + In [1]: %load_ext timit2 + + In [2]: %%t2 + ...: import time + ...: time.sleep(0.05) + ...: + ...: + Time taken: 0.05435649999999441 + + +If you wish to ran all the code enter in IPython in an ast transformer, you can +do so as well: + +.. code-block:: python + + In [1]: from IPython.core.magics.ast_mod import ReplaceCodeTransformer + ...: + ...: template = ''' + ...: from time import perf_counter + ...: now = perf_counter() + ...: __code__ + ...: print(f"Code ran in {perf_counter()-now}") + ...: __ret__''' + ...: + ...: get_ipython().ast_transformers.append(ReplaceCodeTransformer.from_string(template)) + + In [2]: 1+1 + Code ran in 3.40410006174352e-05 + Out[2]: 2 + + + +Hygiene and Mangling +-------------------- + +The ast transformer above is not hygienic, it may not work if the user code use +the same variable names as the ones used in the template. For example. + +To help with this by default the `ReplaceCodeTransformer` will mangle all names +staring with 3 underscores. This is a simple heuristic that should work in most +case, but can be cumbersome in some case. We provide a `Mangler` class that can +be overridden to change the mangling heuristic, or simply use the `mangle_all` +utility function. It will _try_ to mangle all names (except `__ret__` and +`__code__`), but this include builtins (``print``, ``range``, ``type``) and +replace those by invalid identifiers py prepending ``mangle-``: +``mangle-print``, ``mangle-range``, ``mangle-type`` etc. This is not a problem +as currently Python AST support invalid identifiers, but it may not be the case +in the future. + +You can set `ReplaceCodeTransformer.debug=True` and +`ReplaceCodeTransformer.mangler.debug=True` to see the code after mangling and +transforming: + +.. code-block:: python + + + In [1]: from IPython.core.magics.ast_mod import ReplaceCodeTransformer, mangle_all + ...: + ...: template = ''' + ...: from builtins import type, print + ...: from time import perf_counter + ...: now = perf_counter() + ...: __code__ + ...: print(f"Code ran in {perf_counter()-now}") + ...: __ret__''' + ...: + ...: transformer = ReplaceCodeTransformer.from_string(template, mangling_predicate=mangle_all) + + + In [2]: transformer.debug = True + ...: transformer.mangler.debug = True + ...: get_ipython().ast_transformers.append(transformer) + + In [3]: 1+1 + Mangling Alias mangle-type + Mangling Alias mangle-print + Mangling Alias mangle-perf_counter + Mangling now + Mangling perf_counter + Not mangling __code__ + Mangling print + Mangling perf_counter + Mangling now + Not mangling __ret__ + ---- Transformed code ---- + from builtins import type as mangle-type, print as mangle-print + from time import perf_counter as mangle-perf_counter + mangle-now = mangle-perf_counter() + ret-tmp = 1 + 1 + mangle-print(f'Code ran in {mangle-perf_counter() - mangle-now}') + ret-tmp + ---- ---------------- ---- + Code ran in 0.00013654199938173406 + Out[3]: 2 + + +""" + +__skip_doctest__ = True + + +from ast import ( + NodeTransformer, + Store, + Load, + Name, + Expr, + Assign, + Module, + Import, + ImportFrom, +) +import ast +import copy + +from typing import Dict, Optional, Union + + +mangle_all = lambda name: False if name in ("__ret__", "__code__") else True + + +class Mangler(NodeTransformer): + """ + Mangle given names in and ast tree to make sure they do not conflict with + user code. + """ + + enabled: bool = True + debug: bool = False + + def log(self, *args, **kwargs): + if self.debug: + print(*args, **kwargs) + + def __init__(self, predicate=None): + if predicate is None: + predicate = lambda name: name.startswith("___") + self.predicate = predicate + + def visit_Name(self, node): + if self.predicate(node.id): + self.log("Mangling", node.id) + # Once in the ast we do not need + # names to be valid identifiers. + node.id = "mangle-" + node.id + else: + self.log("Not mangling", node.id) + return node + + def visit_FunctionDef(self, node): + if self.predicate(node.name): + self.log("Mangling", node.name) + node.name = "mangle-" + node.name + else: + self.log("Not mangling", node.name) + + for arg in node.args.args: + if self.predicate(arg.arg): + self.log("Mangling function arg", arg.arg) + arg.arg = "mangle-" + arg.arg + else: + self.log("Not mangling function arg", arg.arg) + return self.generic_visit(node) + + def visit_ImportFrom(self, node: ImportFrom): + return self._visit_Import_and_ImportFrom(node) + + def visit_Import(self, node: Import): + return self._visit_Import_and_ImportFrom(node) + + def _visit_Import_and_ImportFrom(self, node: Union[Import, ImportFrom]): + for alias in node.names: + asname = alias.name if alias.asname is None else alias.asname + if self.predicate(asname): + new_name: str = "mangle-" + asname + self.log("Mangling Alias", new_name) + alias.asname = new_name + else: + self.log("Not mangling Alias", alias.asname) + return node + + +class ReplaceCodeTransformer(NodeTransformer): + enabled: bool = True + debug: bool = False + mangler: Mangler + + def __init__( + self, template: Module, mapping: Optional[Dict] = None, mangling_predicate=None + ): + assert isinstance(mapping, (dict, type(None))) + assert isinstance(mangling_predicate, (type(None), type(lambda: None))) + assert isinstance(template, ast.Module) + self.template = template + self.mangler = Mangler(predicate=mangling_predicate) + if mapping is None: + mapping = {} + self.mapping = mapping + + @classmethod + def from_string( + cls, template: str, mapping: Optional[Dict] = None, mangling_predicate=None + ): + return cls( + ast.parse(template), mapping=mapping, mangling_predicate=mangling_predicate + ) + + def visit_Module(self, code): + if not self.enabled: + return code + # if not isinstance(code, ast.Module): + # recursively called... + # return generic_visit(self, code) + last = code.body[-1] + if isinstance(last, Expr): + code.body.pop() + code.body.append(Assign([Name("ret-tmp", ctx=Store())], value=last.value)) + ast.fix_missing_locations(code) + ret = Expr(value=Name("ret-tmp", ctx=Load())) + ret = ast.fix_missing_locations(ret) + self.mapping["__ret__"] = ret + else: + self.mapping["__ret__"] = ast.parse("None").body[0] + self.mapping["__code__"] = code.body + tpl = ast.fix_missing_locations(self.template) + + tx = copy.deepcopy(tpl) + tx = self.mangler.visit(tx) + node = self.generic_visit(tx) + node_2 = ast.fix_missing_locations(node) + if self.debug: + print("---- Transformed code ----") + print(ast.unparse(node_2)) + print("---- ---------------- ----") + return node_2 + + # this does not work as the name might be in a list and one might want to extend the list. + # def visit_Name(self, name): + # if name.id in self.mapping and name.id == "__ret__": + # print(name, "in mapping") + # if isinstance(name.ctx, ast.Store): + # return Name("tmp", ctx=Store()) + # else: + # return copy.deepcopy(self.mapping[name.id]) + # return name + + def visit_Expr(self, expr): + if isinstance(expr.value, Name) and expr.value.id in self.mapping: + if self.mapping[expr.value.id] is not None: + return copy.deepcopy(self.mapping[expr.value.id]) + return self.generic_visit(expr) diff --git a/lib/python3.12/site-packages/IPython/core/magics/auto.py b/lib/python3.12/site-packages/IPython/core/magics/auto.py new file mode 100644 index 0000000000000000000000000000000000000000..329e7acdbe518725443352523112f4805322e8fe --- /dev/null +++ b/lib/python3.12/site-packages/IPython/core/magics/auto.py @@ -0,0 +1,144 @@ +"""Implementation of magic functions that control various automatic behaviors. +""" +#----------------------------------------------------------------------------- +# Copyright (c) 2012 The IPython Development Team. +# +# Distributed under the terms of the Modified BSD License. +# +# The full license is in the file COPYING.txt, distributed with this software. +#----------------------------------------------------------------------------- + +#----------------------------------------------------------------------------- +# Imports +#----------------------------------------------------------------------------- + +# Our own packages +from IPython.core.magic import Bunch, Magics, magics_class, line_magic +from IPython.testing.skipdoctest import skip_doctest +from logging import error + +#----------------------------------------------------------------------------- +# Magic implementation classes +#----------------------------------------------------------------------------- + +@magics_class +class AutoMagics(Magics): + """Magics that control various autoX behaviors.""" + + def __init__(self, shell): + super(AutoMagics, self).__init__(shell) + # namespace for holding state we may need + self._magic_state = Bunch() + + @line_magic + def automagic(self, parameter_s=''): + """Make magic functions callable without having to type the initial %. + + Without arguments toggles on/off (when off, you must call it as + %automagic, of course). With arguments it sets the value, and you can + use any of (case insensitive): + + - on, 1, True: to activate + + - off, 0, False: to deactivate. + + Note that magic functions have lowest priority, so if there's a + variable whose name collides with that of a magic fn, automagic won't + work for that function (you get the variable instead). However, if you + delete the variable (del var), the previously shadowed magic function + becomes visible to automagic again.""" + + arg = parameter_s.lower() + mman = self.shell.magics_manager + if arg in ('on', '1', 'true'): + val = True + elif arg in ('off', '0', 'false'): + val = False + else: + val = not mman.auto_magic + mman.auto_magic = val + print('\n' + self.shell.magics_manager.auto_status()) + + @skip_doctest + @line_magic + def autocall(self, parameter_s=''): + """Make functions callable without having to type parentheses. + + Usage: + + %autocall [mode] + + The mode can be one of: 0->Off, 1->Smart, 2->Full. If not given, the + value is toggled on and off (remembering the previous state). + + In more detail, these values mean: + + 0 -> fully disabled + + 1 -> active, but do not apply if there are no arguments on the line. + + In this mode, you get:: + + In [1]: callable + Out[1]: + + In [2]: callable 'hello' + ------> callable('hello') + Out[2]: False + + 2 -> Active always. Even if no arguments are present, the callable + object is called:: + + In [2]: float + ------> float() + Out[2]: 0.0 + + Note that even with autocall off, you can still use '/' at the start of + a line to treat the first argument on the command line as a function + and add parentheses to it:: + + In [8]: /str 43 + ------> str(43) + Out[8]: '43' + + # all-random (note for auto-testing) + """ + + valid_modes = { + 0: "Off", + 1: "Smart", + 2: "Full", + } + + def errorMessage() -> str: + error = "Valid modes: " + for k, v in valid_modes.items(): + error += str(k) + "->" + v + ", " + error = error[:-2] # remove tailing `, ` after last element + return error + + if parameter_s: + if parameter_s not in map(str, valid_modes.keys()): + error(errorMessage()) + return + arg = int(parameter_s) + else: + arg = 'toggle' + + if arg not in (*list(valid_modes.keys()), "toggle"): + error(errorMessage()) + return + + if arg in (valid_modes.keys()): + self.shell.autocall = arg + else: # toggle + if self.shell.autocall: + self._magic_state.autocall_save = self.shell.autocall + self.shell.autocall = 0 + else: + try: + self.shell.autocall = self._magic_state.autocall_save + except AttributeError: + self.shell.autocall = self._magic_state.autocall_save = 1 + + print("Automatic calling is:", list(valid_modes.values())[self.shell.autocall]) diff --git a/lib/python3.12/site-packages/IPython/core/magics/config.py b/lib/python3.12/site-packages/IPython/core/magics/config.py new file mode 100644 index 0000000000000000000000000000000000000000..9e1cb38c254f412cae88890bdd2da92da5232908 --- /dev/null +++ b/lib/python3.12/site-packages/IPython/core/magics/config.py @@ -0,0 +1,140 @@ +"""Implementation of configuration-related magic functions. +""" +#----------------------------------------------------------------------------- +# Copyright (c) 2012 The IPython Development Team. +# +# Distributed under the terms of the Modified BSD License. +# +# The full license is in the file COPYING.txt, distributed with this software. +#----------------------------------------------------------------------------- + +#----------------------------------------------------------------------------- +# Imports +#----------------------------------------------------------------------------- + +# Stdlib +import re + +# Our own packages +from IPython.core.error import UsageError +from IPython.core.magic import Magics, magics_class, line_magic +from logging import error + +#----------------------------------------------------------------------------- +# Magic implementation classes +#----------------------------------------------------------------------------- + +reg = re.compile(r'^\w+\.\w+$') +@magics_class +class ConfigMagics(Magics): + + def __init__(self, shell): + super(ConfigMagics, self).__init__(shell) + self.configurables = [] + + @line_magic + def config(self, s): + """configure IPython + + %config Class[.trait=value] + + This magic exposes most of the IPython config system. Any + Configurable class should be able to be configured with the simple + line:: + + %config Class.trait=value + + Where `value` will be resolved in the user's namespace, if it is an + expression or variable name. + + Examples + -------- + + To see what classes are available for config, pass no arguments:: + + In [1]: %config + Available objects for config: + AliasManager + DisplayFormatter + HistoryManager + IPCompleter + LoggingMagics + MagicsManager + OSMagics + PrefilterManager + ScriptMagics + TerminalInteractiveShell + + To view what is configurable on a given class, just pass the class + name:: + + In [2]: %config LoggingMagics + LoggingMagics(Magics) options + --------------------------- + LoggingMagics.quiet= + Suppress output of log state when logging is enabled + Current: False + + but the real use is in setting values:: + + In [3]: %config LoggingMagics.quiet = True + + and these values are read from the user_ns if they are variables:: + + In [4]: feeling_quiet=False + + In [5]: %config LoggingMagics.quiet = feeling_quiet + + """ + from traitlets.config.loader import Config + # some IPython objects are Configurable, but do not yet have + # any configurable traits. Exclude them from the effects of + # this magic, as their presence is just noise: + configurables = sorted(set([ c for c in self.shell.configurables + if c.__class__.class_traits(config=True) + ]), key=lambda x: x.__class__.__name__) + classnames = [ c.__class__.__name__ for c in configurables ] + + line = s.strip() + if not line: + # print available configurable names + print("Available objects for config:") + for name in classnames: + print(" ", name) + return + elif line in classnames: + # `%config TerminalInteractiveShell` will print trait info for + # TerminalInteractiveShell + c = configurables[classnames.index(line)] + cls = c.__class__ + help = cls.class_get_help(c) + # strip leading '--' from cl-args: + help = re.sub(re.compile(r'^--', re.MULTILINE), '', help) + print(help) + return + elif reg.match(line): + cls, attr = line.split('.') + return getattr(configurables[classnames.index(cls)],attr) + elif '=' not in line: + msg = "Invalid config statement: %r, "\ + "should be `Class.trait = value`." + + ll = line.lower() + for classname in classnames: + if ll == classname.lower(): + msg = msg + '\nDid you mean %s (note the case)?' % classname + break + + raise UsageError( msg % line) + + # otherwise, assume we are setting configurables. + # leave quotes on args when splitting, because we want + # unquoted args to eval in user_ns + cfg = Config() + exec("cfg."+line, self.shell.user_ns, locals()) + + for configurable in configurables: + try: + configurable.update_config(cfg) + except Exception as e: + error(e) diff --git a/lib/python3.12/site-packages/IPython/core/magics/display.py b/lib/python3.12/site-packages/IPython/core/magics/display.py new file mode 100644 index 0000000000000000000000000000000000000000..6c0eff6884f7666548f2c701c3a901b59f4c5abc --- /dev/null +++ b/lib/python3.12/site-packages/IPython/core/magics/display.py @@ -0,0 +1,93 @@ +"""Simple magics for display formats""" +#----------------------------------------------------------------------------- +# Copyright (c) 2012 The IPython Development Team. +# +# Distributed under the terms of the Modified BSD License. +# +# The full license is in the file COPYING.txt, distributed with this software. +#----------------------------------------------------------------------------- + +#----------------------------------------------------------------------------- +# Imports +#----------------------------------------------------------------------------- + +# Our own packages +from IPython.display import display, Javascript, Latex, SVG, HTML, Markdown +from IPython.core.magic import ( + Magics, magics_class, cell_magic +) +from IPython.core import magic_arguments + +#----------------------------------------------------------------------------- +# Magic implementation classes +#----------------------------------------------------------------------------- + + +@magics_class +class DisplayMagics(Magics): + """Magics for displaying various output types with literals + + Defines javascript/latex/svg/html cell magics for writing + blocks in those languages, to be rendered in the frontend. + """ + + @cell_magic + def js(self, line, cell): + """Run the cell block of Javascript code + + Alias of `%%javascript` + + Starting with IPython 8.0 %%javascript is pending deprecation to be replaced + by a more flexible system + + Please See https://github.com/ipython/ipython/issues/13376 + """ + self.javascript(line, cell) + + @cell_magic + def javascript(self, line, cell): + """Run the cell block of Javascript code + + Starting with IPython 8.0 %%javascript is pending deprecation to be replaced + by a more flexible system + + Please See https://github.com/ipython/ipython/issues/13376 + """ + display(Javascript(cell)) + + + @cell_magic + def latex(self, line, cell): + """Render the cell as a block of LaTeX + + The subset of LaTeX which is supported depends on the implementation in + the client. In the Jupyter Notebook, this magic only renders the subset + of LaTeX defined by MathJax + [here](https://docs.mathjax.org/en/v2.5-latest/tex.html).""" + display(Latex(cell)) + + @cell_magic + def svg(self, line, cell): + """Render the cell as an SVG literal""" + display(SVG(cell)) + + @magic_arguments.magic_arguments() + @magic_arguments.argument( + '--isolated', action='store_true', default=False, + help="""Annotate the cell as 'isolated'. +Isolated cells are rendered inside their own