##// END OF EJS Templates
Document new callbacks system
Thomas Kluyver -
Show More
@@ -0,0 +1,38 b''
1 =====================
2 Registering callbacks
3 =====================
4
5 Extension code can register callbacks functions which will be called on specific
6 events within the IPython code. You can see the current list of available
7 callbacks, and the parameters that will be passed with each, in the callback
8 prototype functions defined in :mod:`IPython.core.callbacks`.
9
10 To register callbacks, use :meth:`IPython.core.callbacks.CallbackManager.register`.
11 For example::
12
13 class VarWatcher(object):
14 def __init__(self, ip):
15 self.shell = ip
16 self.last_x = None
17
18 def pre_execute(self):
19 self.last_x = self.shell.user_ns.get('x', None)
20
21 def post_execute(self):
22 if self.shell.user_ns.get('x', None) != self.last_x:
23 print("x changed!")
24
25 def load_ipython_extension(ip):
26 vw = VarWatcher(ip)
27 ip.callbacks.register('pre_execute', vw.pre_execute)
28 ip.callbacks.register('post_execute', vw.post_execute)
29
30 .. seealso::
31
32 Module :mod:`IPython.core.hooks`
33 The older 'hooks' system allows end users to customise some parts of
34 IPython's behaviour.
35
36 :doc:`inputtransforms`
37 By registering input transformers that don't change code, you can monitor
38 what is being executed.
@@ -0,0 +1,1 b''
1 * A new callback system has been introduced. For details, see :doc:`/config/callbacks`.
@@ -1,124 +1,129 b''
1 """Infrastructure for registering and firing callbacks.
1 """Infrastructure for registering and firing callbacks.
2
2
3 Unlike :mod:`IPython.core.hooks`, which lets end users set single functions to
3 Unlike :mod:`IPython.core.hooks`, which lets end users set single functions to
4 be called at specific times, or a collection of alternative methods to try,
4 be called at specific times, or a collection of alternative methods to try,
5 callbacks are designed to be used by extension authors. A number of callbacks
5 callbacks are designed to be used by extension authors. A number of callbacks
6 can be registered for the same event without needing to be aware of one another.
6 can be registered for the same event without needing to be aware of one another.
7
7
8 The functions defined in this module are no-ops indicating the names of available
8 The functions defined in this module are no-ops indicating the names of available
9 events and the arguments which will be passed to them.
9 events and the arguments which will be passed to them.
10 """
10 """
11 from __future__ import print_function
11 from __future__ import print_function
12
12
13 class CallbackManager(object):
13 class CallbackManager(object):
14 """Manage a collection of events and a sequence of callbacks for each.
14 """Manage a collection of events and a sequence of callbacks for each.
15
15
16 This is attached to :class:`~IPython.core.interactiveshell.InteractiveShell`
16 This is attached to :class:`~IPython.core.interactiveshell.InteractiveShell`
17 instances as a ``callbacks`` attribute.
17 instances as a ``callbacks`` attribute.
18 """
18 """
19 def __init__(self, shell, available_callbacks):
19 def __init__(self, shell, available_callbacks):
20 """Initialise the :class:`CallbackManager`.
20 """Initialise the :class:`CallbackManager`.
21
21
22 Parameters
22 Parameters
23 ----------
23 ----------
24 shell
24 shell
25 The :class:`~IPython.core.interactiveshell.InteractiveShell` instance
25 The :class:`~IPython.core.interactiveshell.InteractiveShell` instance
26 available_callbacks
26 available_callbacks
27 An iterable of names for callback events.
27 An iterable of names for callback events.
28 """
28 """
29 self.shell = shell
29 self.shell = shell
30 self.callbacks = {n:[] for n in available_callbacks}
30 self.callbacks = {n:[] for n in available_callbacks}
31
31
32 def register(self, name, function):
32 def register(self, name, function):
33 """Register a new callback
33 """Register a new callback
34
34
35 Parameters
35 Parameters
36 ----------
36 ----------
37 name : str
37 name : str
38 The event for which to register this callback.
38 The event for which to register this callback.
39 function : callable
39 function : callable
40 A function to be called on the given event. It should take the same
40 A function to be called on the given event. It should take the same
41 parameters as the appropriate callback prototype.
41 parameters as the appropriate callback prototype.
42
42
43 Raises
43 Raises
44 ------
44 ------
45 TypeError
45 TypeError
46 If ``function`` is not callable.
46 If ``function`` is not callable.
47 KeyError
47 KeyError
48 If ``name`` is not one of the known callback events.
48 If ``name`` is not one of the known callback events.
49 """
49 """
50 if not callable(function):
50 if not callable(function):
51 raise TypeError('Need a callable, got %r' % function)
51 raise TypeError('Need a callable, got %r' % function)
52 self.callbacks[name].append(function)
52 self.callbacks[name].append(function)
53
53
54 def unregister(self, name, function):
54 def unregister(self, name, function):
55 """Remove a callback from the given event."""
55 """Remove a callback from the given event."""
56 self.callbacks[name].remove(function)
56 self.callbacks[name].remove(function)
57
57
58 def reset(self, name):
58 def reset(self, name):
59 """Clear all callbacks for the given event."""
59 """Clear all callbacks for the given event."""
60 self.callbacks[name] = []
60 self.callbacks[name] = []
61
61
62 def reset_all(self):
62 def reset_all(self):
63 """Clear all callbacks for all events."""
63 """Clear all callbacks for all events."""
64 self.callbacks = {n:[] for n in self.callbacks}
64 self.callbacks = {n:[] for n in self.callbacks}
65
65
66 def fire(self, name, *args, **kwargs):
66 def fire(self, name, *args, **kwargs):
67 """Call callbacks for the event ``name``.
67 """Call callbacks for the event ``name``.
68
68
69 Any additional arguments are passed to all callbacks registered for this
69 Any additional arguments are passed to all callbacks registered for this
70 event. Exceptions raised by callbacks are caught, and a message printed.
70 event. Exceptions raised by callbacks are caught, and a message printed.
71 """
71 """
72 for func in self.callbacks[name]:
72 for func in self.callbacks[name]:
73 try:
73 try:
74 func(*args, **kwargs)
74 func(*args, **kwargs)
75 except Exception:
75 except Exception:
76 print("Error in callback {} (for {}):".format(func, name))
76 print("Error in callback {} (for {}):".format(func, name))
77 self.shell.showtraceback()
77 self.shell.showtraceback()
78
78
79 # event_name -> prototype mapping
79 # event_name -> prototype mapping
80 available_callbacks = {}
80 available_callbacks = {}
81
81
82 def _collect(callback_proto):
82 def _collect(callback_proto):
83 available_callbacks[callback_proto.__name__] = callback_proto
83 available_callbacks[callback_proto.__name__] = callback_proto
84 return callback_proto
84 return callback_proto
85
85
86 # ------------------------------------------------------------------------------
86 # ------------------------------------------------------------------------------
87 # Callback prototypes
87 # Callback prototypes
88 #
88 #
89 # No-op functions which describe the names of available events and the
89 # No-op functions which describe the names of available events and the
90 # signatures of callbacks for those events.
90 # signatures of callbacks for those events.
91 # ------------------------------------------------------------------------------
91 # ------------------------------------------------------------------------------
92
92
93 @_collect
93 @_collect
94 def pre_execute():
94 def pre_execute():
95 """Fires before code is executed in response to user/frontend action.
95 """Fires before code is executed in response to user/frontend action.
96
96
97 This includes comm and widget messages as well as user code cells."""
97 This includes comm and widget messages as well as user code cells."""
98 pass
98 pass
99
99
100 @_collect
100 @_collect
101 def pre_execute_explicit():
101 def pre_execute_explicit():
102 """Fires before user-entered code runs."""
102 """Fires before user-entered code runs."""
103 pass
103 pass
104
104
105 @_collect
105 @_collect
106 def post_execute():
106 def post_execute():
107 """Fires after code is executed in response to user/frontend action.
107 """Fires after code is executed in response to user/frontend action.
108
108
109 This includes comm and widget messages as well as user code cells."""
109 This includes comm and widget messages as well as user code cells."""
110 pass
110 pass
111
111
112 @_collect
112 @_collect
113 def post_execute_explicit():
113 def post_execute_explicit():
114 """Fires after user-entered code runs."""
114 """Fires after user-entered code runs."""
115 pass
115 pass
116
116
117 @_collect
117 @_collect
118 def shell_initialised(ip):
118 def shell_initialised(ip):
119 """Fires after initialisation of :class:`~IPython.core.interactiveshell.InteractiveShell`.
119 """Fires after initialisation of :class:`~IPython.core.interactiveshell.InteractiveShell`.
120
120
121 This is before extensions and startup scripts are loaded, so it can only be
121 This is before extensions and startup scripts are loaded, so it can only be
122 set by subclassing.
122 set by subclassing.
123
124 Parameters
125 ----------
126 ip : :class:`~IPython.core.interactiveshell.InteractiveShell`
127 The newly initialised shell.
123 """
128 """
124 pass
129 pass
@@ -1,30 +1,31 b''
1 .. _config_index:
1 .. _config_index:
2
2
3 ===============================
3 ===============================
4 Configuration and customization
4 Configuration and customization
5 ===============================
5 ===============================
6
6
7 Configuring IPython
7 Configuring IPython
8 -------------------
8 -------------------
9
9
10 .. toctree::
10 .. toctree::
11 :maxdepth: 2
11 :maxdepth: 2
12
12
13 intro
13 intro
14 options/index
14 options/index
15 details
15 details
16
16
17 .. seealso::
17 .. seealso::
18
18
19 :doc:`/development/config`
19 :doc:`/development/config`
20 Technical details of the config system.
20 Technical details of the config system.
21
21
22 Extending and integrating with IPython
22 Extending and integrating with IPython
23 --------------------------------------
23 --------------------------------------
24
24
25 .. toctree::
25 .. toctree::
26 :maxdepth: 2
26 :maxdepth: 2
27
27
28 extensions/index
28 extensions/index
29 integrating
29 integrating
30 inputtransforms
30 inputtransforms
31 callbacks
General Comments 0
You need to be logged in to leave comments. Login now