Show More
@@ -1,6 +1,6 b'' | |||||
1 | from .widget import Widget, DOMWidget, CallbackDispatcher, register, widget_serialization |
|
1 | from .widget import Widget, DOMWidget, CallbackDispatcher, register, widget_serialization | |
2 |
|
2 | |||
3 | from .trait_types import Color |
|
3 | from .trait_types import Color, EventfulDict, EventfulList | |
4 |
|
4 | |||
5 | from .widget_bool import Checkbox, ToggleButton, Valid |
|
5 | from .widget_bool import Checkbox, ToggleButton, Valid | |
6 | from .widget_button import Button |
|
6 | from .widget_button import Button |
1 | NO CONTENT: file renamed from traitlets/eventful.py to IPython/html/widgets/eventful.py |
|
NO CONTENT: file renamed from traitlets/eventful.py to IPython/html/widgets/eventful.py |
@@ -6,7 +6,7 b'' | |||||
6 | from unittest import TestCase |
|
6 | from unittest import TestCase | |
7 | from IPython.utils.traitlets import HasTraits |
|
7 | from IPython.utils.traitlets import HasTraits | |
8 | from traitlets.tests.test_traitlets import TraitTestBase |
|
8 | from traitlets.tests.test_traitlets import TraitTestBase | |
9 | from IPython.html.widgets import Color |
|
9 | from IPython.html.widgets import Color, EventfulDict, EventfulList | |
10 |
|
10 | |||
11 |
|
11 | |||
12 | class ColorTrait(HasTraits): |
|
12 | class ColorTrait(HasTraits): | |
@@ -18,3 +18,66 b' class TestColor(TraitTestBase):' | |||||
18 |
|
18 | |||
19 | _good_values = ["blue", "#AA0", "#FFFFFF"] |
|
19 | _good_values = ["blue", "#AA0", "#FFFFFF"] | |
20 | _bad_values = ["vanilla", "blues"] |
|
20 | _bad_values = ["vanilla", "blues"] | |
|
21 | ||||
|
22 | ||||
|
23 | class TestEventful(TestCase): | |||
|
24 | ||||
|
25 | def test_list(self): | |||
|
26 | """Does the EventfulList work?""" | |||
|
27 | event_cache = [] | |||
|
28 | ||||
|
29 | class A(HasTraits): | |||
|
30 | x = EventfulList([c for c in 'abc']) | |||
|
31 | a = A() | |||
|
32 | a.x.on_events(lambda i, x: event_cache.append('insert'), \ | |||
|
33 | lambda i, x: event_cache.append('set'), \ | |||
|
34 | lambda i: event_cache.append('del'), \ | |||
|
35 | lambda: event_cache.append('reverse'), \ | |||
|
36 | lambda *p, **k: event_cache.append('sort')) | |||
|
37 | ||||
|
38 | a.x.remove('c') | |||
|
39 | # ab | |||
|
40 | a.x.insert(0, 'z') | |||
|
41 | # zab | |||
|
42 | del a.x[1] | |||
|
43 | # zb | |||
|
44 | a.x.reverse() | |||
|
45 | # bz | |||
|
46 | a.x[1] = 'o' | |||
|
47 | # bo | |||
|
48 | a.x.append('a') | |||
|
49 | # boa | |||
|
50 | a.x.sort() | |||
|
51 | # abo | |||
|
52 | ||||
|
53 | # Were the correct events captured? | |||
|
54 | self.assertEqual(event_cache, ['del', 'insert', 'del', 'reverse', 'set', 'set', 'sort']) | |||
|
55 | ||||
|
56 | # Is the output correct? | |||
|
57 | self.assertEqual(a.x, [c for c in 'abo']) | |||
|
58 | ||||
|
59 | def test_dict(self): | |||
|
60 | """Does the EventfulDict work?""" | |||
|
61 | event_cache = [] | |||
|
62 | ||||
|
63 | class A(HasTraits): | |||
|
64 | x = EventfulDict({c: c for c in 'abc'}) | |||
|
65 | a = A() | |||
|
66 | a.x.on_events(lambda k, v: event_cache.append('add'), \ | |||
|
67 | lambda k, v: event_cache.append('set'), \ | |||
|
68 | lambda k: event_cache.append('del')) | |||
|
69 | ||||
|
70 | del a.x['c'] | |||
|
71 | # ab | |||
|
72 | a.x['z'] = 1 | |||
|
73 | # abz | |||
|
74 | a.x['z'] = 'z' | |||
|
75 | # abz | |||
|
76 | a.x.pop('a') | |||
|
77 | # bz | |||
|
78 | ||||
|
79 | # Were the correct events captured? | |||
|
80 | self.assertEqual(event_cache, ['del', 'add', 'set', 'del']) | |||
|
81 | ||||
|
82 | # Is the output correct? | |||
|
83 | self.assertEqual(a.x, {c: c for c in 'bz'}) |
@@ -9,9 +9,7 b' Trait types for html widgets.' | |||||
9 | import re |
|
9 | import re | |
10 | from IPython.utils import traitlets |
|
10 | from IPython.utils import traitlets | |
11 |
|
11 | |||
12 | #----------------------------------------------------------------------------- |
|
12 | from . import eventful | |
13 | # Utilities |
|
|||
14 | #----------------------------------------------------------------------------- |
|
|||
15 |
|
13 | |||
16 | _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'] |
|
14 | _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'] | |
17 | _color_re = re.compile(r'#[a-fA-F0-9]{3}(?:[a-fA-F0-9]{3})?$') |
|
15 | _color_re = re.compile(r'#[a-fA-F0-9]{3}(?:[a-fA-F0-9]{3})?$') | |
@@ -26,3 +24,47 b' class Color(traitlets.Unicode):' | |||||
26 | if value.lower() in _color_names or _color_re.match(value): |
|
24 | if value.lower() in _color_names or _color_re.match(value): | |
27 | return value |
|
25 | return value | |
28 | self.error(obj, value) |
|
26 | self.error(obj, value) | |
|
27 | ||||
|
28 | ||||
|
29 | class EventfulDict(traitlets.Instance): | |||
|
30 | """An instance of an EventfulDict.""" | |||
|
31 | ||||
|
32 | def __init__(self, default_value={}, **metadata): | |||
|
33 | """Create a EventfulDict trait type from a dict. | |||
|
34 | ||||
|
35 | The default value is created by doing | |||
|
36 | ``eventful.EvenfulDict(default_value)``, which creates a copy of the | |||
|
37 | ``default_value``. | |||
|
38 | """ | |||
|
39 | if default_value is None: | |||
|
40 | args = None | |||
|
41 | elif isinstance(default_value, dict): | |||
|
42 | args = (default_value,) | |||
|
43 | elif isinstance(default_value, SequenceTypes): | |||
|
44 | args = (default_value,) | |||
|
45 | else: | |||
|
46 | raise TypeError('default value of EventfulDict was %s' % default_value) | |||
|
47 | ||||
|
48 | super(EventfulDict, self).__init__(klass=eventful.EventfulDict, args=args, | |||
|
49 | **metadata) | |||
|
50 | ||||
|
51 | ||||
|
52 | class EventfulList(traitlets.Instance): | |||
|
53 | """An instance of an EventfulList.""" | |||
|
54 | ||||
|
55 | def __init__(self, default_value=None, **metadata): | |||
|
56 | """Create a EventfulList trait type from a dict. | |||
|
57 | ||||
|
58 | The default value is created by doing | |||
|
59 | ``eventful.EvenfulList(default_value)``, which creates a copy of the | |||
|
60 | ``default_value``. | |||
|
61 | """ | |||
|
62 | if default_value is None: | |||
|
63 | args = ((),) | |||
|
64 | else: | |||
|
65 | args = (default_value,) | |||
|
66 | ||||
|
67 | super(EventfulList, self).__init__(klass=eventful.EventfulList, args=args, | |||
|
68 | **metadata) | |||
|
69 | ||||
|
70 |
@@ -20,7 +20,7 b' from IPython.utils.traitlets import (' | |||||
20 | Int, Long, Integer, Float, Complex, Bytes, Unicode, TraitError, |
|
20 | Int, Long, Integer, Float, Complex, Bytes, Unicode, TraitError, | |
21 | Union, Undefined, Type, This, Instance, TCPAddress, List, Tuple, |
|
21 | Union, Undefined, Type, This, Instance, TCPAddress, List, Tuple, | |
22 | ObjectName, DottedObjectName, CRegExp, link, directional_link, |
|
22 | ObjectName, DottedObjectName, CRegExp, link, directional_link, | |
23 |
|
|
23 | ForwardDeclaredType, ForwardDeclaredInstance, | |
24 | ) |
|
24 | ) | |
25 | from IPython.utils import py3compat |
|
25 | from IPython.utils import py3compat | |
26 | from IPython.testing.decorators import skipif |
|
26 | from IPython.testing.decorators import skipif | |
@@ -1419,67 +1419,6 b' def test_notification_order():' | |||||
1419 | nt.assert_equal(obj.notified, notifications) |
|
1419 | nt.assert_equal(obj.notified, notifications) | |
1420 |
|
1420 | |||
1421 |
|
1421 | |||
1422 | class TestEventful(TestCase): |
|
|||
1423 |
|
||||
1424 | def test_list(self): |
|
|||
1425 | """Does the EventfulList work?""" |
|
|||
1426 | event_cache = [] |
|
|||
1427 |
|
||||
1428 | class A(HasTraits): |
|
|||
1429 | x = EventfulList([c for c in 'abc']) |
|
|||
1430 | a = A() |
|
|||
1431 | a.x.on_events(lambda i, x: event_cache.append('insert'), \ |
|
|||
1432 | lambda i, x: event_cache.append('set'), \ |
|
|||
1433 | lambda i: event_cache.append('del'), \ |
|
|||
1434 | lambda: event_cache.append('reverse'), \ |
|
|||
1435 | lambda *p, **k: event_cache.append('sort')) |
|
|||
1436 |
|
||||
1437 | a.x.remove('c') |
|
|||
1438 | # ab |
|
|||
1439 | a.x.insert(0, 'z') |
|
|||
1440 | # zab |
|
|||
1441 | del a.x[1] |
|
|||
1442 | # zb |
|
|||
1443 | a.x.reverse() |
|
|||
1444 | # bz |
|
|||
1445 | a.x[1] = 'o' |
|
|||
1446 | # bo |
|
|||
1447 | a.x.append('a') |
|
|||
1448 | # boa |
|
|||
1449 | a.x.sort() |
|
|||
1450 | # abo |
|
|||
1451 |
|
||||
1452 | # Were the correct events captured? |
|
|||
1453 | self.assertEqual(event_cache, ['del', 'insert', 'del', 'reverse', 'set', 'set', 'sort']) |
|
|||
1454 |
|
||||
1455 | # Is the output correct? |
|
|||
1456 | self.assertEqual(a.x, [c for c in 'abo']) |
|
|||
1457 |
|
||||
1458 | def test_dict(self): |
|
|||
1459 | """Does the EventfulDict work?""" |
|
|||
1460 | event_cache = [] |
|
|||
1461 |
|
||||
1462 | class A(HasTraits): |
|
|||
1463 | x = EventfulDict({c: c for c in 'abc'}) |
|
|||
1464 | a = A() |
|
|||
1465 | a.x.on_events(lambda k, v: event_cache.append('add'), \ |
|
|||
1466 | lambda k, v: event_cache.append('set'), \ |
|
|||
1467 | lambda k: event_cache.append('del')) |
|
|||
1468 |
|
||||
1469 | del a.x['c'] |
|
|||
1470 | # ab |
|
|||
1471 | a.x['z'] = 1 |
|
|||
1472 | # abz |
|
|||
1473 | a.x['z'] = 'z' |
|
|||
1474 | # abz |
|
|||
1475 | a.x.pop('a') |
|
|||
1476 | # bz |
|
|||
1477 |
|
||||
1478 | # Were the correct events captured? |
|
|||
1479 | self.assertEqual(event_cache, ['del', 'add', 'set', 'del']) |
|
|||
1480 |
|
||||
1481 | # Is the output correct? |
|
|||
1482 | self.assertEqual(a.x, {c: c for c in 'bz'}) |
|
|||
1483 |
|
1422 | |||
1484 | ### |
|
1423 | ### | |
1485 | # Traits for Forward Declaration Tests |
|
1424 | # Traits for Forward Declaration Tests |
@@ -58,7 +58,6 b' from IPython.utils.getargspec import getargspec' | |||||
58 | from IPython.utils.importstring import import_item |
|
58 | from IPython.utils.importstring import import_item | |
59 | from IPython.utils.py3compat import iteritems, string_types |
|
59 | from IPython.utils.py3compat import iteritems, string_types | |
60 |
|
60 | |||
61 | from . import eventful |
|
|||
62 | from .sentinel import Sentinel |
|
61 | from .sentinel import Sentinel | |
63 | SequenceTypes = (list, tuple, set, frozenset) |
|
62 | SequenceTypes = (list, tuple, set, frozenset) | |
64 |
|
63 | |||
@@ -1793,48 +1792,6 b' class Dict(Instance):' | |||||
1793 | super(Dict, self).instance_init() |
|
1792 | super(Dict, self).instance_init() | |
1794 |
|
1793 | |||
1795 |
|
1794 | |||
1796 | class EventfulDict(Instance): |
|
|||
1797 | """An instance of an EventfulDict.""" |
|
|||
1798 |
|
||||
1799 | def __init__(self, default_value={}, **metadata): |
|
|||
1800 | """Create a EventfulDict trait type from a dict. |
|
|||
1801 |
|
||||
1802 | The default value is created by doing |
|
|||
1803 | ``eventful.EvenfulDict(default_value)``, which creates a copy of the |
|
|||
1804 | ``default_value``. |
|
|||
1805 | """ |
|
|||
1806 | if default_value is None: |
|
|||
1807 | args = None |
|
|||
1808 | elif isinstance(default_value, dict): |
|
|||
1809 | args = (default_value,) |
|
|||
1810 | elif isinstance(default_value, SequenceTypes): |
|
|||
1811 | args = (default_value,) |
|
|||
1812 | else: |
|
|||
1813 | raise TypeError('default value of EventfulDict was %s' % default_value) |
|
|||
1814 |
|
||||
1815 | super(EventfulDict, self).__init__(klass=eventful.EventfulDict, args=args, |
|
|||
1816 | **metadata) |
|
|||
1817 |
|
||||
1818 |
|
||||
1819 | class EventfulList(Instance): |
|
|||
1820 | """An instance of an EventfulList.""" |
|
|||
1821 |
|
||||
1822 | def __init__(self, default_value=None, **metadata): |
|
|||
1823 | """Create a EventfulList trait type from a dict. |
|
|||
1824 |
|
||||
1825 | The default value is created by doing |
|
|||
1826 | ``eventful.EvenfulList(default_value)``, which creates a copy of the |
|
|||
1827 | ``default_value``. |
|
|||
1828 | """ |
|
|||
1829 | if default_value is None: |
|
|||
1830 | args = ((),) |
|
|||
1831 | else: |
|
|||
1832 | args = (default_value,) |
|
|||
1833 |
|
||||
1834 | super(EventfulList, self).__init__(klass=eventful.EventfulList, args=args, |
|
|||
1835 | **metadata) |
|
|||
1836 |
|
||||
1837 |
|
||||
1838 | class TCPAddress(TraitType): |
|
1795 | class TCPAddress(TraitType): | |
1839 | """A trait for an (ip, port) tuple. |
|
1796 | """A trait for an (ip, port) tuple. | |
1840 |
|
1797 |
General Comments 0
You need to be logged in to leave comments.
Login now