diff --git a/IPython/core/callbacks.py b/IPython/core/events.py similarity index 83% rename from IPython/core/callbacks.py rename to IPython/core/events.py index 9d2e509..c2bb63c 100644 --- a/IPython/core/callbacks.py +++ b/IPython/core/events.py @@ -1,4 +1,4 @@ -"""Infrastructure for registering and firing callbacks. +"""Infrastructure for registering and firing callbacks on application events. Unlike :mod:`IPython.core.hooks`, which lets end users set single functions to be called at specific times, or a collection of alternative methods to try, @@ -10,13 +10,13 @@ events and the arguments which will be passed to them. """ from __future__ import print_function -class CallbackManager(object): +class EventManager(object): """Manage a collection of events and a sequence of callbacks for each. This is attached to :class:`~IPython.core.interactiveshell.InteractiveShell` instances as a ``callbacks`` attribute. """ - def __init__(self, shell, available_callbacks): + def __init__(self, shell, available_events): """Initialise the :class:`CallbackManager`. Parameters @@ -27,14 +27,14 @@ class CallbackManager(object): An iterable of names for callback events. """ self.shell = shell - self.callbacks = {n:[] for n in available_callbacks} + self.callbacks = {n:[] for n in available_events} - def register(self, name, function): + def register(self, event, function): """Register a new callback Parameters ---------- - name : str + event : str The event for which to register this callback. function : callable A function to be called on the given event. It should take the same @@ -45,42 +45,42 @@ class CallbackManager(object): TypeError If ``function`` is not callable. KeyError - If ``name`` is not one of the known callback events. + If ``event`` is not one of the known events. """ if not callable(function): raise TypeError('Need a callable, got %r' % function) - self.callbacks[name].append(function) + self.callbacks[event].append(function) - def unregister(self, name, function): + def unregister(self, event, function): """Remove a callback from the given event.""" - self.callbacks[name].remove(function) + self.callbacks[event].remove(function) - def reset(self, name): + def reset(self, event): """Clear all callbacks for the given event.""" - self.callbacks[name] = [] + self.callbacks[event] = [] def reset_all(self): """Clear all callbacks for all events.""" self.callbacks = {n:[] for n in self.callbacks} - def fire(self, name, *args, **kwargs): - """Call callbacks for the event ``name``. + def trigger(self, event, *args, **kwargs): + """Call callbacks for ``event``. Any additional arguments are passed to all callbacks registered for this event. Exceptions raised by callbacks are caught, and a message printed. """ - for func in self.callbacks[name]: + for func in self.callbacks[event]: try: func(*args, **kwargs) except Exception: - print("Error in callback {} (for {}):".format(func, name)) + print("Error in callback {} (for {}):".format(func, event)) self.shell.showtraceback() # event_name -> prototype mapping -available_callbacks = {} +available_events = {} def _collect(callback_proto): - available_callbacks[callback_proto.__name__] = callback_proto + available_events[callback_proto.__name__] = callback_proto return callback_proto # ------------------------------------------------------------------------------ diff --git a/IPython/core/interactiveshell.py b/IPython/core/interactiveshell.py index 2687fa4..db36f3d 100644 --- a/IPython/core/interactiveshell.py +++ b/IPython/core/interactiveshell.py @@ -41,7 +41,7 @@ from IPython.core import ultratb from IPython.core.alias import AliasManager, AliasError from IPython.core.autocall import ExitAutocall from IPython.core.builtin_trap import BuiltinTrap -from IPython.core.callbacks import CallbackManager, available_callbacks +from IPython.core.events import EventManager, available_events from IPython.core.compilerop import CachingCompiler, check_linecache_ipython from IPython.core.display_trap import DisplayTrap from IPython.core.displayhook import DisplayHook @@ -468,7 +468,7 @@ class InteractiveShell(SingletonConfigurable): self.init_syntax_highlighting() self.init_hooks() - self.init_callbacks() + self.init_events() self.init_pushd_popd_magic() # self.init_traceback_handlers use to be here, but we moved it below # because it and init_io have to come after init_readline. @@ -512,7 +512,7 @@ class InteractiveShell(SingletonConfigurable): self.init_payload() self.init_comms() self.hooks.late_startup_hook() - self.callbacks.fire('shell_initialised', self) + self.events.trigger('shell_initialised', self) atexit.register(self.atexit_operations) def get_ipython(self): @@ -840,8 +840,8 @@ class InteractiveShell(SingletonConfigurable): # Things related to callbacks #------------------------------------------------------------------------- - def init_callbacks(self): - self.callbacks = CallbackManager(self, available_callbacks) + def init_events(self): + self.events = EventManager(self, available_events) def register_post_execute(self, func): """DEPRECATED: Use ip.callbacks.register('post_execute_explicit', func) @@ -850,7 +850,7 @@ class InteractiveShell(SingletonConfigurable): """ warn("ip.register_post_execute is deprecated, use " "ip.callbacks.register('post_execute_explicit', func) instead.") - self.callbacks.register('post_execute_explicit', func) + self.events.register('post_execute_explicit', func) #------------------------------------------------------------------------- # Things related to the "main" module @@ -2667,9 +2667,9 @@ class InteractiveShell(SingletonConfigurable): if silent: store_history = False - self.callbacks.fire('pre_execute') + self.events.trigger('pre_execute') if not silent: - self.callbacks.fire('pre_execute_explicit') + self.events.trigger('pre_execute_explicit') # If any of our input transformation (input_transformer_manager or # prefilter_manager) raises an exception, we store it in this variable @@ -2740,9 +2740,9 @@ class InteractiveShell(SingletonConfigurable): self.run_ast_nodes(code_ast.body, cell_name, interactivity=interactivity, compiler=compiler) - self.callbacks.fire('post_execute') + self.events.trigger('post_execute') if not silent: - self.callbacks.fire('post_execute_explicit') + self.events.trigger('post_execute_explicit') if store_history: # Write output to the database. Does nothing unless diff --git a/IPython/core/tests/test_callbacks.py b/IPython/core/tests/test_events.py similarity index 61% rename from IPython/core/tests/test_callbacks.py rename to IPython/core/tests/test_events.py index 63e457f..e265999 100644 --- a/IPython/core/tests/test_callbacks.py +++ b/IPython/core/tests/test_events.py @@ -4,7 +4,7 @@ try: # Python 3.3 + except ImportError: from mock import Mock -from IPython.core import callbacks +from IPython.core import events import IPython.testing.tools as tt def ping_received(): @@ -12,35 +12,35 @@ def ping_received(): class CallbackTests(unittest.TestCase): def setUp(self): - self.cbm = callbacks.CallbackManager(get_ipython(), {'ping_received': ping_received}) + self.em = events.EventManager(get_ipython(), {'ping_received': ping_received}) def test_register_unregister(self): cb = Mock() - self.cbm.register('ping_received', cb) - self.cbm.fire('ping_received') + self.em.register('ping_received', cb) + self.em.trigger('ping_received') self.assertEqual(cb.call_count, 1) - self.cbm.unregister('ping_received', cb) - self.cbm.fire('ping_received') + self.em.unregister('ping_received', cb) + self.em.trigger('ping_received') self.assertEqual(cb.call_count, 1) def test_reset(self): cb = Mock() - self.cbm.register('ping_received', cb) - self.cbm.reset('ping_received') - self.cbm.fire('ping_received') + self.em.register('ping_received', cb) + self.em.reset('ping_received') + self.em.trigger('ping_received') assert not cb.called def test_reset_all(self): cb = Mock() - self.cbm.register('ping_received', cb) - self.cbm.reset_all() - self.cbm.fire('ping_received') + self.em.register('ping_received', cb) + self.em.reset_all() + self.em.trigger('ping_received') assert not cb.called def test_cb_error(self): cb = Mock(side_effect=ValueError) - self.cbm.register('ping_received', cb) + self.em.register('ping_received', cb) with tt.AssertPrints("Error in callback"): - self.cbm.fire('ping_received') \ No newline at end of file + self.em.trigger('ping_received') \ No newline at end of file diff --git a/IPython/core/tests/test_interactiveshell.py b/IPython/core/tests/test_interactiveshell.py index eedcdc0..15ca8c1 100644 --- a/IPython/core/tests/test_interactiveshell.py +++ b/IPython/core/tests/test_interactiveshell.py @@ -288,10 +288,10 @@ class InteractiveShellTestCase(unittest.TestCase): post_explicit = mock.Mock() post_always = mock.Mock() - ip.callbacks.register('pre_execute_explicit', pre_explicit) - ip.callbacks.register('pre_execute', pre_always) - ip.callbacks.register('post_execute_explicit', post_explicit) - ip.callbacks.register('post_execute', post_always) + ip.events.register('pre_execute_explicit', pre_explicit) + ip.events.register('pre_execute', pre_always) + ip.events.register('post_execute_explicit', post_explicit) + ip.events.register('post_execute', post_always) try: ip.run_cell("1", silent=True) @@ -306,7 +306,7 @@ class InteractiveShellTestCase(unittest.TestCase): assert post_explicit.called finally: # remove post-exec - ip.callbacks.reset_all() + ip.events.reset_all() def test_silent_noadvance(self): """run_cell(silent=True) doesn't advance execution_count""" diff --git a/IPython/extensions/autoreload.py b/IPython/extensions/autoreload.py index ac68826..b78b924 100644 --- a/IPython/extensions/autoreload.py +++ b/IPython/extensions/autoreload.py @@ -502,4 +502,4 @@ def load_ipython_extension(ip): """Load the extension in IPython.""" auto_reload = AutoreloadMagics(ip) ip.register_magics(auto_reload) - ip.callbacks.register('pre_execute_explicit', auto_reload.pre_execute_explicit) + ip.events.register('pre_execute_explicit', auto_reload.pre_execute_explicit) diff --git a/IPython/extensions/tests/test_autoreload.py b/IPython/extensions/tests/test_autoreload.py index 036ec40..5f30a97 100644 --- a/IPython/extensions/tests/test_autoreload.py +++ b/IPython/extensions/tests/test_autoreload.py @@ -23,7 +23,7 @@ import nose.tools as nt import IPython.testing.tools as tt from IPython.extensions.autoreload import AutoreloadMagics -from IPython.core.callbacks import CallbackManager, pre_execute_explicit +from IPython.core.events import EventManager, pre_execute_explicit from IPython.utils.py3compat import PY3 if PY3: @@ -41,14 +41,14 @@ class FakeShell(object): def __init__(self): self.ns = {} - self.callbacks = CallbackManager(self, {'pre_execute_explicit', pre_execute_explicit}) + self.events = EventManager(self, {'pre_execute_explicit', pre_execute_explicit}) self.auto_magics = AutoreloadMagics(shell=self) - self.callbacks.register('pre_execute_explicit', self.auto_magics.pre_execute_explicit) + self.events.register('pre_execute_explicit', self.auto_magics.pre_execute_explicit) register_magics = set_hook = noop def run_code(self, code): - self.callbacks.fire('pre_execute_explicit') + self.events.trigger('pre_execute_explicit') exec(code, self.ns) def push(self, items): diff --git a/IPython/kernel/comm/comm.py b/IPython/kernel/comm/comm.py index 30fcad8..3f89625 100644 --- a/IPython/kernel/comm/comm.py +++ b/IPython/kernel/comm/comm.py @@ -134,9 +134,9 @@ class Comm(LoggingConfigurable): """Handle a comm_msg message""" self.log.debug("handle_msg[%s](%s)", self.comm_id, msg) if self._msg_callback: - self.shell.callbacks.fire('pre_execute') + self.shell.events.trigger('pre_execute') self._msg_callback(msg) - self.shell.callbacks.fire('post_execute') + self.shell.events.trigger('post_execute') __all__ = ['Comm']