diff --git a/IPython/html/widgets/__init__.py b/IPython/html/widgets/__init__.py
index a91d3a0..ab5b2f8 100644
--- a/IPython/html/widgets/__init__.py
+++ b/IPython/html/widgets/__init__.py
@@ -1,6 +1,6 @@
from .widget import Widget, DOMWidget, CallbackDispatcher, register, widget_serialization
-from .trait_types import Color
+from .trait_types import Color, EventfulDict, EventfulList
from .widget_bool import Checkbox, ToggleButton, Valid
from .widget_button import Button
diff --git a/traitlets/eventful.py b/IPython/html/widgets/eventful.py
similarity index 100%
rename from traitlets/eventful.py
rename to IPython/html/widgets/eventful.py
diff --git a/IPython/html/widgets/tests/test_traits.py b/IPython/html/widgets/tests/test_traits.py
index bb74949..474743b 100644
--- a/IPython/html/widgets/tests/test_traits.py
+++ b/IPython/html/widgets/tests/test_traits.py
@@ -6,7 +6,7 @@
from unittest import TestCase
from IPython.utils.traitlets import HasTraits
from traitlets.tests.test_traitlets import TraitTestBase
-from IPython.html.widgets import Color
+from IPython.html.widgets import Color, EventfulDict, EventfulList
class ColorTrait(HasTraits):
@@ -18,3 +18,66 @@ class TestColor(TraitTestBase):
_good_values = ["blue", "#AA0", "#FFFFFF"]
_bad_values = ["vanilla", "blues"]
+
+
+class TestEventful(TestCase):
+
+ def test_list(self):
+ """Does the EventfulList work?"""
+ event_cache = []
+
+ class A(HasTraits):
+ x = EventfulList([c for c in 'abc'])
+ a = A()
+ a.x.on_events(lambda i, x: event_cache.append('insert'), \
+ lambda i, x: event_cache.append('set'), \
+ lambda i: event_cache.append('del'), \
+ lambda: event_cache.append('reverse'), \
+ lambda *p, **k: event_cache.append('sort'))
+
+ a.x.remove('c')
+ # ab
+ a.x.insert(0, 'z')
+ # zab
+ del a.x[1]
+ # zb
+ a.x.reverse()
+ # bz
+ a.x[1] = 'o'
+ # bo
+ a.x.append('a')
+ # boa
+ a.x.sort()
+ # abo
+
+ # Were the correct events captured?
+ self.assertEqual(event_cache, ['del', 'insert', 'del', 'reverse', 'set', 'set', 'sort'])
+
+ # Is the output correct?
+ self.assertEqual(a.x, [c for c in 'abo'])
+
+ def test_dict(self):
+ """Does the EventfulDict work?"""
+ event_cache = []
+
+ class A(HasTraits):
+ x = EventfulDict({c: c for c in 'abc'})
+ a = A()
+ a.x.on_events(lambda k, v: event_cache.append('add'), \
+ lambda k, v: event_cache.append('set'), \
+ lambda k: event_cache.append('del'))
+
+ del a.x['c']
+ # ab
+ a.x['z'] = 1
+ # abz
+ a.x['z'] = 'z'
+ # abz
+ a.x.pop('a')
+ # bz
+
+ # Were the correct events captured?
+ self.assertEqual(event_cache, ['del', 'add', 'set', 'del'])
+
+ # Is the output correct?
+ self.assertEqual(a.x, {c: c for c in 'bz'})
diff --git a/IPython/html/widgets/trait_types.py b/IPython/html/widgets/trait_types.py
index e09caaa..b6bb670 100644
--- a/IPython/html/widgets/trait_types.py
+++ b/IPython/html/widgets/trait_types.py
@@ -9,9 +9,7 @@ Trait types for html widgets.
import re
from IPython.utils import traitlets
-#-----------------------------------------------------------------------------
-# Utilities
-#-----------------------------------------------------------------------------
+from . import eventful
_color_names = ['aliceblue', 'antiquewhite', 'aqua', 'aquamarine', 'azure', 'beige', 'bisque', 'black', 'blanchedalmond', 'blue', 'blueviolet', 'brown', 'burlywood', 'cadetblue', 'chartreuse', 'chocolate', 'coral', 'cornflowerblue', 'cornsilk', 'crimson', 'cyan', 'darkblue', 'darkcyan', 'darkgoldenrod', 'darkgray', 'darkgreen', 'darkkhaki', 'darkmagenta', 'darkolivegreen', 'darkorange', 'darkorchid', 'darkred', 'darksalmon', 'darkseagreen', 'darkslateblue', 'darkslategray', 'darkturquoise', 'darkviolet', 'deeppink', 'deepskyblue', 'dimgray', 'dodgerblue', 'firebrick', 'floralwhite', 'forestgreen', 'fuchsia', 'gainsboro', 'ghostwhite', 'gold', 'goldenrod', 'gray', 'green', 'greenyellow', 'honeydew', 'hotpink', 'indianred ', 'indigo ', 'ivory', 'khaki', 'lavender', 'lavenderblush', 'lawngreen', 'lemonchiffon', 'lightblue', 'lightcoral', 'lightcyan', 'lightgoldenrodyellow', 'lightgray', 'lightgreen', 'lightpink', 'lightsalmon', 'lightseagreen', 'lightskyblue', 'lightslategray', 'lightsteelblue', 'lightyellow', 'lime', 'limegreen', 'linen', 'magenta', 'maroon', 'mediumaquamarine', 'mediumblue', 'mediumorchid', 'mediumpurple', 'mediumseagreen', 'mediumslateblue', 'mediumspringgreen', 'mediumturquoise', 'mediumvioletred', 'midnightblue', 'mintcream', 'mistyrose', 'moccasin', 'navajowhite', 'navy', 'oldlace', 'olive', 'olivedrab', 'orange', 'orangered', 'orchid', 'palegoldenrod', 'palegreen', 'paleturquoise', 'palevioletred', 'papayawhip', 'peachpuff', 'peru', 'pink', 'plum', 'powderblue', 'purple', 'rebeccapurple', 'red', 'rosybrown', 'royalblue', 'saddlebrown', 'salmon', 'sandybrown', 'seagreen', 'seashell', 'sienna', 'silver', 'skyblue', 'slateblue', 'slategray', 'snow', 'springgreen', 'steelblue', 'tan', 'teal', 'thistle', 'tomato', 'turquoise', 'violet', 'wheat', 'white', 'whitesmoke', 'yellow', 'yellowgreen']
_color_re = re.compile(r'#[a-fA-F0-9]{3}(?:[a-fA-F0-9]{3})?$')
@@ -26,3 +24,47 @@ class Color(traitlets.Unicode):
if value.lower() in _color_names or _color_re.match(value):
return value
self.error(obj, value)
+
+
+class EventfulDict(traitlets.Instance):
+ """An instance of an EventfulDict."""
+
+ def __init__(self, default_value={}, **metadata):
+ """Create a EventfulDict trait type from a dict.
+
+ The default value is created by doing
+ ``eventful.EvenfulDict(default_value)``, which creates a copy of the
+ ``default_value``.
+ """
+ if default_value is None:
+ args = None
+ elif isinstance(default_value, dict):
+ args = (default_value,)
+ elif isinstance(default_value, SequenceTypes):
+ args = (default_value,)
+ else:
+ raise TypeError('default value of EventfulDict was %s' % default_value)
+
+ super(EventfulDict, self).__init__(klass=eventful.EventfulDict, args=args,
+ **metadata)
+
+
+class EventfulList(traitlets.Instance):
+ """An instance of an EventfulList."""
+
+ def __init__(self, default_value=None, **metadata):
+ """Create a EventfulList trait type from a dict.
+
+ The default value is created by doing
+ ``eventful.EvenfulList(default_value)``, which creates a copy of the
+ ``default_value``.
+ """
+ if default_value is None:
+ args = ((),)
+ else:
+ args = (default_value,)
+
+ super(EventfulList, self).__init__(klass=eventful.EventfulList, args=args,
+ **metadata)
+
+
diff --git a/traitlets/tests/test_traitlets.py b/traitlets/tests/test_traitlets.py
index 6c9b7c5..3bab848 100644
--- a/traitlets/tests/test_traitlets.py
+++ b/traitlets/tests/test_traitlets.py
@@ -20,7 +20,7 @@ from IPython.utils.traitlets import (
Int, Long, Integer, Float, Complex, Bytes, Unicode, TraitError,
Union, Undefined, Type, This, Instance, TCPAddress, List, Tuple,
ObjectName, DottedObjectName, CRegExp, link, directional_link,
- EventfulList, EventfulDict, ForwardDeclaredType, ForwardDeclaredInstance,
+ ForwardDeclaredType, ForwardDeclaredInstance,
)
from IPython.utils import py3compat
from IPython.testing.decorators import skipif
@@ -1419,67 +1419,6 @@ def test_notification_order():
nt.assert_equal(obj.notified, notifications)
-class TestEventful(TestCase):
-
- def test_list(self):
- """Does the EventfulList work?"""
- event_cache = []
-
- class A(HasTraits):
- x = EventfulList([c for c in 'abc'])
- a = A()
- a.x.on_events(lambda i, x: event_cache.append('insert'), \
- lambda i, x: event_cache.append('set'), \
- lambda i: event_cache.append('del'), \
- lambda: event_cache.append('reverse'), \
- lambda *p, **k: event_cache.append('sort'))
-
- a.x.remove('c')
- # ab
- a.x.insert(0, 'z')
- # zab
- del a.x[1]
- # zb
- a.x.reverse()
- # bz
- a.x[1] = 'o'
- # bo
- a.x.append('a')
- # boa
- a.x.sort()
- # abo
-
- # Were the correct events captured?
- self.assertEqual(event_cache, ['del', 'insert', 'del', 'reverse', 'set', 'set', 'sort'])
-
- # Is the output correct?
- self.assertEqual(a.x, [c for c in 'abo'])
-
- def test_dict(self):
- """Does the EventfulDict work?"""
- event_cache = []
-
- class A(HasTraits):
- x = EventfulDict({c: c for c in 'abc'})
- a = A()
- a.x.on_events(lambda k, v: event_cache.append('add'), \
- lambda k, v: event_cache.append('set'), \
- lambda k: event_cache.append('del'))
-
- del a.x['c']
- # ab
- a.x['z'] = 1
- # abz
- a.x['z'] = 'z'
- # abz
- a.x.pop('a')
- # bz
-
- # Were the correct events captured?
- self.assertEqual(event_cache, ['del', 'add', 'set', 'del'])
-
- # Is the output correct?
- self.assertEqual(a.x, {c: c for c in 'bz'})
###
# Traits for Forward Declaration Tests
diff --git a/traitlets/traitlets.py b/traitlets/traitlets.py
index 876a4a9..2983b61 100644
--- a/traitlets/traitlets.py
+++ b/traitlets/traitlets.py
@@ -58,7 +58,6 @@ from IPython.utils.getargspec import getargspec
from IPython.utils.importstring import import_item
from IPython.utils.py3compat import iteritems, string_types
-from . import eventful
from .sentinel import Sentinel
SequenceTypes = (list, tuple, set, frozenset)
@@ -1793,48 +1792,6 @@ class Dict(Instance):
super(Dict, self).instance_init()
-class EventfulDict(Instance):
- """An instance of an EventfulDict."""
-
- def __init__(self, default_value={}, **metadata):
- """Create a EventfulDict trait type from a dict.
-
- The default value is created by doing
- ``eventful.EvenfulDict(default_value)``, which creates a copy of the
- ``default_value``.
- """
- if default_value is None:
- args = None
- elif isinstance(default_value, dict):
- args = (default_value,)
- elif isinstance(default_value, SequenceTypes):
- args = (default_value,)
- else:
- raise TypeError('default value of EventfulDict was %s' % default_value)
-
- super(EventfulDict, self).__init__(klass=eventful.EventfulDict, args=args,
- **metadata)
-
-
-class EventfulList(Instance):
- """An instance of an EventfulList."""
-
- def __init__(self, default_value=None, **metadata):
- """Create a EventfulList trait type from a dict.
-
- The default value is created by doing
- ``eventful.EvenfulList(default_value)``, which creates a copy of the
- ``default_value``.
- """
- if default_value is None:
- args = ((),)
- else:
- args = (default_value,)
-
- super(EventfulList, self).__init__(klass=eventful.EventfulList, args=args,
- **metadata)
-
-
class TCPAddress(TraitType):
"""A trait for an (ip, port) tuple.