Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 0 additions & 8 deletions IPython/core/events.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,14 +63,6 @@ def unregister(self, event, function):
"""Remove a callback from the given event."""
self.callbacks[event].remove(function)

def reset(self, event):
"""Clear all callbacks for the given event."""
self.callbacks[event] = []

def reset_all(self):
"""Clear all callbacks for all events."""
self.callbacks = {n:[] for n in self.callbacks}

def trigger(self, event, *args, **kwargs):
"""Call callbacks for ``event``.

Expand Down
9 changes: 9 additions & 0 deletions IPython/core/interactiveshell.py
Original file line number Diff line number Diff line change
Expand Up @@ -874,6 +874,8 @@ def set_hook(self,name,hook, priority=50, str_key=None, re_key=None,
def init_events(self):
self.events = EventManager(self, available_events)

self.events.register("pre_execute", self._clear_warning_registry)

def register_post_execute(self, func):
"""DEPRECATED: Use ip.events.register('post_run_cell', func)

Expand All @@ -883,6 +885,13 @@ def register_post_execute(self, func):
"ip.events.register('post_run_cell', func) instead.")
self.events.register('post_run_cell', func)

def _clear_warning_registry(self):
# clear the warning registry, so that different code blocks with
# overlapping line number ranges don't cause spurious suppression of
# warnings (see gh-6611 for details)
if "__warningregistry__" in self.user_global_ns:
del self.user_global_ns["__warningregistry__"]

#-------------------------------------------------------------------------
# Things related to the "main" module
#-------------------------------------------------------------------------
Expand Down
16 changes: 1 addition & 15 deletions IPython/core/tests/test_events.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,22 +25,8 @@ def test_register_unregister(self):
self.em.trigger('ping_received')
self.assertEqual(cb.call_count, 1)

def test_reset(self):
cb = Mock()
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.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.em.register('ping_received', cb)
with tt.AssertPrints("Error in callback"):
self.em.trigger('ping_received')
self.em.trigger('ping_received')
19 changes: 18 additions & 1 deletion IPython/core/tests/test_interactiveshell.py
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,10 @@ def test_silent_postexec(self):
assert post_explicit.called
finally:
# remove post-exec
ip.events.reset_all()
ip.events.unregister('pre_run_cell', pre_explicit)
ip.events.unregister('pre_execute', pre_always)
ip.events.unregister('post_run_cell', post_explicit)
ip.events.unregister('post_execute', post_always)

def test_silent_noadvance(self):
"""run_cell(silent=True) doesn't advance execution_count"""
Expand Down Expand Up @@ -840,3 +843,17 @@ def test_syntaxerror_input_transformer(self):



def test_warning_suppression():
ip.run_cell("import warnings")
try:
with tt.AssertPrints("UserWarning: asdf", channel="stderr"):
ip.run_cell("warnings.warn('asdf')")
# Here's the real test -- if we run that again, we should get the
# warning again. Traditionally, each warning was only issued once per
# IPython session (approximately), even if the user typed in new and
# different code that should have also triggered the warning, leading
# to much confusion.
with tt.AssertPrints("UserWarning: asdf", channel="stderr"):
ip.run_cell("warnings.warn('asdf')")
finally:
ip.run_cell("del warnings")