Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/IPython/core/events.py: 50%
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
1"""Infrastructure for registering and firing callbacks on application events.
3Unlike :mod:`IPython.core.hooks`, which lets end users set single functions to
4be called at specific times, or a collection of alternative methods to try,
5callbacks are designed to be used by extension authors. A number of callbacks
6can be registered for the same event without needing to be aware of one another.
8The functions defined in this module are no-ops indicating the names of available
9events and the arguments which will be passed to them.
11.. note::
13 This API is experimental in IPython 2.0, and may be revised in future versions.
14"""
16from __future__ import annotations
18from typing import TYPE_CHECKING, Any, Callable, Iterable
20if TYPE_CHECKING:
21 from IPython.core.interactiveshell import InteractiveShell
24class EventManager:
25 """Manage a collection of events and a sequence of callbacks for each.
27 This is attached to :class:`~IPython.core.interactiveshell.InteractiveShell`
28 instances as an ``events`` attribute.
30 .. note::
32 This API is experimental in IPython 2.0, and may be revised in future versions.
33 """
35 def __init__(
36 self,
37 shell: InteractiveShell,
38 available_events: Iterable[str],
39 print_on_error: bool = True,
40 ) -> None:
41 """Initialise the :class:`CallbackManager`.
43 Parameters
44 ----------
45 shell
46 The :class:`~IPython.core.interactiveshell.InteractiveShell` instance
47 available_events
48 An iterable of names for callback events.
49 print_on_error:
50 A boolean flag to set whether the EventManager will print a warning which a event errors.
51 """
52 self.shell = shell
53 self.callbacks: dict[str, list[Callable[..., Any]]] = {
54 n: [] for n in available_events
55 }
56 self.print_on_error = print_on_error
58 def register(self, event: str, function: Callable[..., Any]) -> None:
59 """Register a new event callback.
61 Parameters
62 ----------
63 event : str
64 The event for which to register this callback.
65 function : callable
66 A function to be called on the given event. It should take the same
67 parameters as the appropriate callback prototype.
69 Raises
70 ------
71 TypeError
72 If ``function`` is not callable.
73 KeyError
74 If ``event`` is not one of the known events.
75 """
76 if not callable(function):
77 raise TypeError('Need a callable, got %r' % function)
78 if function not in self.callbacks[event]:
79 self.callbacks[event].append(function)
81 def unregister(self, event: str, function: Callable[..., Any]) -> None:
82 """Remove a callback from the given event."""
83 if function in self.callbacks[event]:
84 return self.callbacks[event].remove(function)
86 raise ValueError('Function {!r} is not registered as a {} callback'.format(function, event))
88 def trigger(self, event: str, *args: Any, **kwargs: Any) -> None:
89 """Call callbacks for ``event``.
91 Any additional arguments are passed to all callbacks registered for this
92 event. Exceptions raised by callbacks are caught, and a message printed.
93 """
94 for func in self.callbacks[event][:]:
95 try:
96 func(*args, **kwargs)
97 except (Exception, KeyboardInterrupt):
98 if self.print_on_error:
99 print(
100 "Error in callback {} (for {}), with arguments args {},kwargs {}:".format(
101 func, event, args, kwargs
102 )
103 )
104 self.shell.showtraceback()
106# event_name -> prototype mapping
107available_events: dict[str, Callable[..., Any]] = {}
109def _define_event(callback_function: Callable[..., Any]) -> Callable[..., Any]:
110 available_events[callback_function.__name__] = callback_function
111 return callback_function
113# ------------------------------------------------------------------------------
114# Callback prototypes
115#
116# No-op functions which describe the names of available events and the
117# signatures of callbacks for those events.
118# ------------------------------------------------------------------------------
120@_define_event
121def pre_execute() -> None:
122 """Fires before code is executed in response to user/frontend action.
124 This includes comm and widget messages and silent execution, as well as user
125 code cells.
126 """
127 pass
129@_define_event
130def pre_run_cell(info: Any) -> None:
131 """Fires before user-entered code runs.
133 Parameters
134 ----------
135 info : :class:`~IPython.core.interactiveshell.ExecutionInfo`
136 An object containing information used for the code execution.
137 """
138 pass
140@_define_event
141def post_execute() -> None:
142 """Fires after code is executed in response to user/frontend action.
144 This includes comm and widget messages and silent execution, as well as user
145 code cells.
146 """
147 pass
149@_define_event
150def post_run_cell(result: Any) -> None:
151 """Fires after user-entered code runs.
153 Parameters
154 ----------
155 result : :class:`~IPython.core.interactiveshell.ExecutionResult`
156 The object which will be returned as the execution result.
157 """
158 pass
160@_define_event
161def shell_initialized(ip: InteractiveShell) -> None:
162 """Fires after initialisation of :class:`~IPython.core.interactiveshell.InteractiveShell`.
164 This is before extensions and startup scripts are loaded, so it can only be
165 set by subclassing.
167 Parameters
168 ----------
169 ip : :class:`~IPython.core.interactiveshell.InteractiveShell`
170 The newly initialised shell.
171 """
172 pass