Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/IPython/core/events.py: 44%
48 statements
« prev ^ index » next coverage.py v7.4.4, created at 2024-04-20 06:09 +0000
« prev ^ index » next coverage.py v7.4.4, created at 2024-04-20 06:09 +0000
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 backcall import callback_prototype
19class EventManager(object):
20 """Manage a collection of events and a sequence of callbacks for each.
22 This is attached to :class:`~IPython.core.interactiveshell.InteractiveShell`
23 instances as an ``events`` attribute.
25 .. note::
27 This API is experimental in IPython 2.0, and may be revised in future versions.
28 """
29 def __init__(self, shell, available_events):
30 """Initialise the :class:`CallbackManager`.
32 Parameters
33 ----------
34 shell
35 The :class:`~IPython.core.interactiveshell.InteractiveShell` instance
36 available_events
37 An iterable of names for callback events.
38 """
39 self.shell = shell
40 self.callbacks = {n:[] for n in available_events}
42 def register(self, event, function):
43 """Register a new event callback.
45 Parameters
46 ----------
47 event : str
48 The event for which to register this callback.
49 function : callable
50 A function to be called on the given event. It should take the same
51 parameters as the appropriate callback prototype.
53 Raises
54 ------
55 TypeError
56 If ``function`` is not callable.
57 KeyError
58 If ``event`` is not one of the known events.
59 """
60 if not callable(function):
61 raise TypeError('Need a callable, got %r' % function)
62 callback_proto = available_events.get(event)
63 if function not in self.callbacks[event]:
64 self.callbacks[event].append(callback_proto.adapt(function))
66 def unregister(self, event, function):
67 """Remove a callback from the given event."""
68 if function in self.callbacks[event]:
69 return self.callbacks[event].remove(function)
71 # Remove callback in case ``function`` was adapted by `backcall`.
72 for callback in self.callbacks[event]:
73 try:
74 if callback.__wrapped__ is function:
75 return self.callbacks[event].remove(callback)
76 except AttributeError:
77 pass
79 raise ValueError('Function {!r} is not registered as a {} callback'.format(function, event))
81 def trigger(self, event, *args, **kwargs):
82 """Call callbacks for ``event``.
84 Any additional arguments are passed to all callbacks registered for this
85 event. Exceptions raised by callbacks are caught, and a message printed.
86 """
87 for func in self.callbacks[event][:]:
88 try:
89 func(*args, **kwargs)
90 except (Exception, KeyboardInterrupt):
91 print("Error in callback {} (for {}):".format(func, event))
92 self.shell.showtraceback()
94# event_name -> prototype mapping
95available_events = {}
97def _define_event(callback_function):
98 callback_proto = callback_prototype(callback_function)
99 available_events[callback_function.__name__] = callback_proto
100 return callback_proto
102# ------------------------------------------------------------------------------
103# Callback prototypes
104#
105# No-op functions which describe the names of available events and the
106# signatures of callbacks for those events.
107# ------------------------------------------------------------------------------
109@_define_event
110def pre_execute():
111 """Fires before code is executed in response to user/frontend action.
113 This includes comm and widget messages and silent execution, as well as user
114 code cells.
115 """
116 pass
118@_define_event
119def pre_run_cell(info):
120 """Fires before user-entered code runs.
122 Parameters
123 ----------
124 info : :class:`~IPython.core.interactiveshell.ExecutionInfo`
125 An object containing information used for the code execution.
126 """
127 pass
129@_define_event
130def post_execute():
131 """Fires after code is executed in response to user/frontend action.
133 This includes comm and widget messages and silent execution, as well as user
134 code cells.
135 """
136 pass
138@_define_event
139def post_run_cell(result):
140 """Fires after user-entered code runs.
142 Parameters
143 ----------
144 result : :class:`~IPython.core.interactiveshell.ExecutionResult`
145 The object which will be returned as the execution result.
146 """
147 pass
149@_define_event
150def shell_initialized(ip):
151 """Fires after initialisation of :class:`~IPython.core.interactiveshell.InteractiveShell`.
153 This is before extensions and startup scripts are loaded, so it can only be
154 set by subclassing.
156 Parameters
157 ----------
158 ip : :class:`~IPython.core.interactiveshell.InteractiveShell`
159 The newly initialised shell.
160 """
161 pass