##// END OF EJS Templates
Merging Dav's traitlets rename branch.
Dav Clark -
r2537:535d8779 merge
parent child Browse files
Show More
@@ -5,7 +5,6 b' IPython.'
5
5
6 IPython is a set of tools for interactive and exploratory computing in Python.
6 IPython is a set of tools for interactive and exploratory computing in Python.
7 """
7 """
8
9 #-----------------------------------------------------------------------------
8 #-----------------------------------------------------------------------------
10 # Copyright (C) 2008-2009 The IPython Development Team
9 # Copyright (C) 2008-2009 The IPython Development Team
11 #
10 #
@@ -224,7 +224,7 b' class Application(object):'
224
224
225 For the most part, we try to set default in the class attributes
225 For the most part, we try to set default in the class attributes
226 of Components. But, defaults the top-level Application (which is
226 of Components. But, defaults the top-level Application (which is
227 not a HasTraitlets or Component) are not set in this way. Instead
227 not a HasTraits or Component) are not set in this way. Instead
228 we set them here. The Global section is for variables like this that
228 we set them here. The Global section is for variables like this that
229 don't belong to a particular component.
229 don't belong to a particular component.
230 """
230 """
@@ -27,7 +27,7 b' from weakref import WeakValueDictionary'
27 from IPython.utils.importstring import import_item
27 from IPython.utils.importstring import import_item
28 from IPython.config.loader import Config
28 from IPython.config.loader import Config
29 from IPython.utils.traitlets import (
29 from IPython.utils.traitlets import (
30 HasTraitlets, MetaHasTraitlets, Instance, This
30 HasTraits, MetaHasTraits, Instance, This
31 )
31 )
32
32
33
33
@@ -173,7 +173,7 b' class __ComponentNameGenerator(object):'
173 ComponentNameGenerator = __ComponentNameGenerator('ipython.component')
173 ComponentNameGenerator = __ComponentNameGenerator('ipython.component')
174
174
175
175
176 class MetaComponent(MetaHasTraitlets, MetaComponentTracker):
176 class MetaComponent(MetaHasTraits, MetaComponentTracker):
177 pass
177 pass
178
178
179
179
@@ -182,11 +182,11 b' class MetaComponent(MetaHasTraitlets, MetaComponentTracker):'
182 #-----------------------------------------------------------------------------
182 #-----------------------------------------------------------------------------
183
183
184
184
185 class Component(HasTraitlets):
185 class Component(HasTraits):
186
186
187 __metaclass__ = MetaComponent
187 __metaclass__ = MetaComponent
188
188
189 # Traitlets are fun!
189 # Traits are fun!
190 config = Instance(Config,(),{})
190 config = Instance(Config,(),{})
191 parent = This()
191 parent = This()
192 root = This()
192 root = This()
@@ -256,7 +256,7 b' class Component(HasTraitlets):'
256 self.created = datetime.datetime.now()
256 self.created = datetime.datetime.now()
257
257
258 #-------------------------------------------------------------------------
258 #-------------------------------------------------------------------------
259 # Static traitlet notifiations
259 # Static trait notifiations
260 #-------------------------------------------------------------------------
260 #-------------------------------------------------------------------------
261
261
262 def _parent_changed(self, name, old, new):
262 def _parent_changed(self, name, old, new):
@@ -282,12 +282,12 b' class Component(HasTraitlets):'
282 def _config_changed(self, name, old, new):
282 def _config_changed(self, name, old, new):
283 """Update all the class traits having ``config=True`` as metadata.
283 """Update all the class traits having ``config=True`` as metadata.
284
284
285 For any class traitlet with a ``config`` metadata attribute that is
285 For any class trait with a ``config`` metadata attribute that is
286 ``True``, we update the traitlet with the value of the corresponding
286 ``True``, we update the trait with the value of the corresponding
287 config entry.
287 config entry.
288 """
288 """
289 # Get all traitlets with a config metadata entry that is True
289 # Get all traits with a config metadata entry that is True
290 traitlets = self.traitlets(config=True)
290 traits = self.traits(config=True)
291
291
292 # We auto-load config section for this class as well as any parent
292 # We auto-load config section for this class as well as any parent
293 # classes that are Component subclasses. This starts with Component
293 # classes that are Component subclasses. This starts with Component
@@ -301,7 +301,7 b' class Component(HasTraitlets):'
301 # dynamically create the section with name self.__class__.__name__.
301 # dynamically create the section with name self.__class__.__name__.
302 if new._has_section(sname):
302 if new._has_section(sname):
303 my_config = new[sname]
303 my_config = new[sname]
304 for k, v in traitlets.items():
304 for k, v in traits.items():
305 # Don't allow traitlets with config=True to start with
305 # Don't allow traitlets with config=True to start with
306 # uppercase. Otherwise, they are confused with Config
306 # uppercase. Otherwise, they are confused with Config
307 # subsections. But, developers shouldn't have uppercase
307 # subsections. But, developers shouldn't have uppercase
@@ -182,7 +182,7 b' def get_default_colors():'
182 class SeparateStr(Str):
182 class SeparateStr(Str):
183 """A Str subclass to validate separate_in, separate_out, etc.
183 """A Str subclass to validate separate_in, separate_out, etc.
184
184
185 This is a Str based traitlet that converts '0'->'' and '\\n'->'\n'.
185 This is a Str based trait that converts '0'->'' and '\\n'->'\n'.
186 """
186 """
187
187
188 def validate(self, obj, value):
188 def validate(self, obj, value):
@@ -263,7 +263,7 b' class InteractiveShell(Component, Magic):'
263
263
264 screen_length = Int(0, config=True)
264 screen_length = Int(0, config=True)
265
265
266 # Use custom TraitletTypes that convert '0'->'' and '\\n'->'\n'
266 # Use custom TraitTypes that convert '0'->'' and '\\n'->'\n'
267 separate_in = SeparateStr('\n', config=True)
267 separate_in = SeparateStr('\n', config=True)
268 separate_out = SeparateStr('', config=True)
268 separate_out = SeparateStr('', config=True)
269 separate_out2 = SeparateStr('', config=True)
269 separate_out2 = SeparateStr('', config=True)
@@ -286,7 +286,7 b' class InteractiveShell(Component, Magic):'
286 banner1=None, banner2=None, display_banner=None,
286 banner1=None, banner2=None, display_banner=None,
287 custom_exceptions=((),None)):
287 custom_exceptions=((),None)):
288
288
289 # This is where traitlets with a config_key argument are updated
289 # This is where traits with a config_key argument are updated
290 # from the values on config.
290 # from the values on config.
291 super(InteractiveShell, self).__init__(parent, config=config)
291 super(InteractiveShell, self).__init__(parent, config=config)
292
292
@@ -341,7 +341,7 b' class InteractiveShell(Component, Magic):'
341 return self
341 return self
342
342
343 #-------------------------------------------------------------------------
343 #-------------------------------------------------------------------------
344 # Traitlet changed handlers
344 # Trait changed handlers
345 #-------------------------------------------------------------------------
345 #-------------------------------------------------------------------------
346
346
347 def _banner1_changed(self):
347 def _banner1_changed(self):
@@ -24,7 +24,7 b' from unittest import TestCase'
24
24
25 from IPython.core.component import Component, ComponentError
25 from IPython.core.component import Component, ComponentError
26 from IPython.utils.traitlets import (
26 from IPython.utils.traitlets import (
27 TraitletError, Int, Float, Str
27 TraitError, Int, Float, Str
28 )
28 )
29 from IPython.config.loader import Config
29 from IPython.config.loader import Config
30
30
@@ -109,7 +109,7 b' class TestComponent(TestCase):'
109
109
110 def test_subclass_parent(self):
110 def test_subclass_parent(self):
111 c1 = Component(None)
111 c1 = Component(None)
112 self.assertRaises(TraitletError, setattr, c1, 'parent', 10)
112 self.assertRaises(TraitError, setattr, c1, 'parent', 10)
113
113
114 class MyComponent(Component):
114 class MyComponent(Component):
115 pass
115 pass
@@ -25,8 +25,8 b' Authors:'
25 from unittest import TestCase
25 from unittest import TestCase
26
26
27 from IPython.utils.traitlets import (
27 from IPython.utils.traitlets import (
28 HasTraitlets, MetaHasTraitlets, TraitletType, Any,
28 HasTraits, MetaHasTraits, TraitType, Any,
29 Int, Long, Float, Complex, Str, Unicode, TraitletError,
29 Int, Long, Float, Complex, Str, Unicode, TraitError,
30 Undefined, Type, This, Instance
30 Undefined, Type, This, Instance
31 )
31 )
32
32
@@ -36,9 +36,9 b' from IPython.utils.traitlets import ('
36 #-----------------------------------------------------------------------------
36 #-----------------------------------------------------------------------------
37
37
38
38
39 class HasTraitletsStub(HasTraitlets):
39 class HasTraitsStub(HasTraits):
40
40
41 def _notify_traitlet(self, name, old, new):
41 def _notify_trait(self, name, old, new):
42 self._notify_name = name
42 self._notify_name = name
43 self._notify_old = old
43 self._notify_old = old
44 self._notify_new = new
44 self._notify_new = new
@@ -49,17 +49,17 b' class HasTraitletsStub(HasTraitlets):'
49 #-----------------------------------------------------------------------------
49 #-----------------------------------------------------------------------------
50
50
51
51
52 class TestTraitletType(TestCase):
52 class TestTraitType(TestCase):
53
53
54 def test_get_undefined(self):
54 def test_get_undefined(self):
55 class A(HasTraitlets):
55 class A(HasTraits):
56 a = TraitletType
56 a = TraitType
57 a = A()
57 a = A()
58 self.assertEquals(a.a, Undefined)
58 self.assertEquals(a.a, Undefined)
59
59
60 def test_set(self):
60 def test_set(self):
61 class A(HasTraitletsStub):
61 class A(HasTraitsStub):
62 a = TraitletType
62 a = TraitType
63
63
64 a = A()
64 a = A()
65 a.a = 10
65 a.a = 10
@@ -69,10 +69,10 b' class TestTraitletType(TestCase):'
69 self.assertEquals(a._notify_new, 10)
69 self.assertEquals(a._notify_new, 10)
70
70
71 def test_validate(self):
71 def test_validate(self):
72 class MyTT(TraitletType):
72 class MyTT(TraitType):
73 def validate(self, inst, value):
73 def validate(self, inst, value):
74 return -1
74 return -1
75 class A(HasTraitletsStub):
75 class A(HasTraitsStub):
76 tt = MyTT
76 tt = MyTT
77
77
78 a = A()
78 a = A()
@@ -80,26 +80,26 b' class TestTraitletType(TestCase):'
80 self.assertEquals(a.tt, -1)
80 self.assertEquals(a.tt, -1)
81
81
82 def test_default_validate(self):
82 def test_default_validate(self):
83 class MyIntTT(TraitletType):
83 class MyIntTT(TraitType):
84 def validate(self, obj, value):
84 def validate(self, obj, value):
85 if isinstance(value, int):
85 if isinstance(value, int):
86 return value
86 return value
87 self.error(obj, value)
87 self.error(obj, value)
88 class A(HasTraitlets):
88 class A(HasTraits):
89 tt = MyIntTT(10)
89 tt = MyIntTT(10)
90 a = A()
90 a = A()
91 self.assertEquals(a.tt, 10)
91 self.assertEquals(a.tt, 10)
92
92
93 # Defaults are validated when the HasTraitlets is instantiated
93 # Defaults are validated when the HasTraits is instantiated
94 class B(HasTraitlets):
94 class B(HasTraits):
95 tt = MyIntTT('bad default')
95 tt = MyIntTT('bad default')
96 self.assertRaises(TraitletError, B)
96 self.assertRaises(TraitError, B)
97
97
98 def test_is_valid_for(self):
98 def test_is_valid_for(self):
99 class MyTT(TraitletType):
99 class MyTT(TraitType):
100 def is_valid_for(self, value):
100 def is_valid_for(self, value):
101 return True
101 return True
102 class A(HasTraitlets):
102 class A(HasTraits):
103 tt = MyTT
103 tt = MyTT
104
104
105 a = A()
105 a = A()
@@ -107,10 +107,10 b' class TestTraitletType(TestCase):'
107 self.assertEquals(a.tt, 10)
107 self.assertEquals(a.tt, 10)
108
108
109 def test_value_for(self):
109 def test_value_for(self):
110 class MyTT(TraitletType):
110 class MyTT(TraitType):
111 def value_for(self, value):
111 def value_for(self, value):
112 return 20
112 return 20
113 class A(HasTraitlets):
113 class A(HasTraits):
114 tt = MyTT
114 tt = MyTT
115
115
116 a = A()
116 a = A()
@@ -118,33 +118,33 b' class TestTraitletType(TestCase):'
118 self.assertEquals(a.tt, 20)
118 self.assertEquals(a.tt, 20)
119
119
120 def test_info(self):
120 def test_info(self):
121 class A(HasTraitlets):
121 class A(HasTraits):
122 tt = TraitletType
122 tt = TraitType
123 a = A()
123 a = A()
124 self.assertEquals(A.tt.info(), 'any value')
124 self.assertEquals(A.tt.info(), 'any value')
125
125
126 def test_error(self):
126 def test_error(self):
127 class A(HasTraitlets):
127 class A(HasTraits):
128 tt = TraitletType
128 tt = TraitType
129 a = A()
129 a = A()
130 self.assertRaises(TraitletError, A.tt.error, a, 10)
130 self.assertRaises(TraitError, A.tt.error, a, 10)
131
131
132
132
133 class TestHasTraitletsMeta(TestCase):
133 class TestHasTraitsMeta(TestCase):
134
134
135 def test_metaclass(self):
135 def test_metaclass(self):
136 self.assertEquals(type(HasTraitlets), MetaHasTraitlets)
136 self.assertEquals(type(HasTraits), MetaHasTraits)
137
137
138 class A(HasTraitlets):
138 class A(HasTraits):
139 a = Int
139 a = Int
140
140
141 a = A()
141 a = A()
142 self.assertEquals(type(a.__class__), MetaHasTraitlets)
142 self.assertEquals(type(a.__class__), MetaHasTraits)
143 self.assertEquals(a.a,0)
143 self.assertEquals(a.a,0)
144 a.a = 10
144 a.a = 10
145 self.assertEquals(a.a,10)
145 self.assertEquals(a.a,10)
146
146
147 class B(HasTraitlets):
147 class B(HasTraits):
148 b = Int()
148 b = Int()
149
149
150 b = B()
150 b = B()
@@ -152,7 +152,7 b' class TestHasTraitletsMeta(TestCase):'
152 b.b = 10
152 b.b = 10
153 self.assertEquals(b.b,10)
153 self.assertEquals(b.b,10)
154
154
155 class C(HasTraitlets):
155 class C(HasTraits):
156 c = Int(30)
156 c = Int(30)
157
157
158 c = C()
158 c = C()
@@ -161,7 +161,7 b' class TestHasTraitletsMeta(TestCase):'
161 self.assertEquals(c.c,10)
161 self.assertEquals(c.c,10)
162
162
163 def test_this_class(self):
163 def test_this_class(self):
164 class A(HasTraitlets):
164 class A(HasTraits):
165 t = This()
165 t = This()
166 tt = This()
166 tt = This()
167 class B(A):
167 class B(A):
@@ -172,7 +172,7 b' class TestHasTraitletsMeta(TestCase):'
172 self.assertEquals(B.tt.this_class, B)
172 self.assertEquals(B.tt.this_class, B)
173 self.assertEquals(B.ttt.this_class, B)
173 self.assertEquals(B.ttt.this_class, B)
174
174
175 class TestHasTraitletsNotify(TestCase):
175 class TestHasTraitsNotify(TestCase):
176
176
177 def setUp(self):
177 def setUp(self):
178 self._notify1 = []
178 self._notify1 = []
@@ -186,12 +186,12 b' class TestHasTraitletsNotify(TestCase):'
186
186
187 def test_notify_all(self):
187 def test_notify_all(self):
188
188
189 class A(HasTraitlets):
189 class A(HasTraits):
190 a = Int
190 a = Int
191 b = Float
191 b = Float
192
192
193 a = A()
193 a = A()
194 a.on_traitlet_change(self.notify1)
194 a.on_trait_change(self.notify1)
195 a.a = 0
195 a.a = 0
196 self.assertEquals(len(self._notify1),0)
196 self.assertEquals(len(self._notify1),0)
197 a.b = 0.0
197 a.b = 0.0
@@ -200,31 +200,31 b' class TestHasTraitletsNotify(TestCase):'
200 self.assert_(('a',0,10) in self._notify1)
200 self.assert_(('a',0,10) in self._notify1)
201 a.b = 10.0
201 a.b = 10.0
202 self.assert_(('b',0.0,10.0) in self._notify1)
202 self.assert_(('b',0.0,10.0) in self._notify1)
203 self.assertRaises(TraitletError,setattr,a,'a','bad string')
203 self.assertRaises(TraitError,setattr,a,'a','bad string')
204 self.assertRaises(TraitletError,setattr,a,'b','bad string')
204 self.assertRaises(TraitError,setattr,a,'b','bad string')
205 self._notify1 = []
205 self._notify1 = []
206 a.on_traitlet_change(self.notify1,remove=True)
206 a.on_trait_change(self.notify1,remove=True)
207 a.a = 20
207 a.a = 20
208 a.b = 20.0
208 a.b = 20.0
209 self.assertEquals(len(self._notify1),0)
209 self.assertEquals(len(self._notify1),0)
210
210
211 def test_notify_one(self):
211 def test_notify_one(self):
212
212
213 class A(HasTraitlets):
213 class A(HasTraits):
214 a = Int
214 a = Int
215 b = Float
215 b = Float
216
216
217 a = A()
217 a = A()
218 a.on_traitlet_change(self.notify1, 'a')
218 a.on_trait_change(self.notify1, 'a')
219 a.a = 0
219 a.a = 0
220 self.assertEquals(len(self._notify1),0)
220 self.assertEquals(len(self._notify1),0)
221 a.a = 10
221 a.a = 10
222 self.assert_(('a',0,10) in self._notify1)
222 self.assert_(('a',0,10) in self._notify1)
223 self.assertRaises(TraitletError,setattr,a,'a','bad string')
223 self.assertRaises(TraitError,setattr,a,'a','bad string')
224
224
225 def test_subclass(self):
225 def test_subclass(self):
226
226
227 class A(HasTraitlets):
227 class A(HasTraits):
228 a = Int
228 a = Int
229
229
230 class B(A):
230 class B(A):
@@ -240,15 +240,15 b' class TestHasTraitletsNotify(TestCase):'
240
240
241 def test_notify_subclass(self):
241 def test_notify_subclass(self):
242
242
243 class A(HasTraitlets):
243 class A(HasTraits):
244 a = Int
244 a = Int
245
245
246 class B(A):
246 class B(A):
247 b = Float
247 b = Float
248
248
249 b = B()
249 b = B()
250 b.on_traitlet_change(self.notify1, 'a')
250 b.on_trait_change(self.notify1, 'a')
251 b.on_traitlet_change(self.notify2, 'b')
251 b.on_trait_change(self.notify2, 'b')
252 b.a = 0
252 b.a = 0
253 b.b = 0.0
253 b.b = 0.0
254 self.assertEquals(len(self._notify1),0)
254 self.assertEquals(len(self._notify1),0)
@@ -260,7 +260,7 b' class TestHasTraitletsNotify(TestCase):'
260
260
261 def test_static_notify(self):
261 def test_static_notify(self):
262
262
263 class A(HasTraitlets):
263 class A(HasTraits):
264 a = Int
264 a = Int
265 _notify1 = []
265 _notify1 = []
266 def _a_changed(self, name, old, new):
266 def _a_changed(self, name, old, new):
@@ -296,73 +296,73 b' class TestHasTraitletsNotify(TestCase):'
296 def callback3(name, old, new):
296 def callback3(name, old, new):
297 self.cb = (name, old, new)
297 self.cb = (name, old, new)
298
298
299 class A(HasTraitlets):
299 class A(HasTraits):
300 a = Int
300 a = Int
301
301
302 a = A()
302 a = A()
303 a.on_traitlet_change(callback0, 'a')
303 a.on_trait_change(callback0, 'a')
304 a.a = 10
304 a.a = 10
305 self.assertEquals(self.cb,())
305 self.assertEquals(self.cb,())
306 a.on_traitlet_change(callback0, 'a', remove=True)
306 a.on_trait_change(callback0, 'a', remove=True)
307
307
308 a.on_traitlet_change(callback1, 'a')
308 a.on_trait_change(callback1, 'a')
309 a.a = 100
309 a.a = 100
310 self.assertEquals(self.cb,('a',))
310 self.assertEquals(self.cb,('a',))
311 a.on_traitlet_change(callback1, 'a', remove=True)
311 a.on_trait_change(callback1, 'a', remove=True)
312
312
313 a.on_traitlet_change(callback2, 'a')
313 a.on_trait_change(callback2, 'a')
314 a.a = 1000
314 a.a = 1000
315 self.assertEquals(self.cb,('a',1000))
315 self.assertEquals(self.cb,('a',1000))
316 a.on_traitlet_change(callback2, 'a', remove=True)
316 a.on_trait_change(callback2, 'a', remove=True)
317
317
318 a.on_traitlet_change(callback3, 'a')
318 a.on_trait_change(callback3, 'a')
319 a.a = 10000
319 a.a = 10000
320 self.assertEquals(self.cb,('a',1000,10000))
320 self.assertEquals(self.cb,('a',1000,10000))
321 a.on_traitlet_change(callback3, 'a', remove=True)
321 a.on_trait_change(callback3, 'a', remove=True)
322
322
323 self.assertEquals(len(a._traitlet_notifiers['a']),0)
323 self.assertEquals(len(a._trait_notifiers['a']),0)
324
324
325
325
326 class TestHasTraitlets(TestCase):
326 class TestHasTraits(TestCase):
327
327
328 def test_traitlet_names(self):
328 def test_trait_names(self):
329 class A(HasTraitlets):
329 class A(HasTraits):
330 i = Int
330 i = Int
331 f = Float
331 f = Float
332 a = A()
332 a = A()
333 self.assertEquals(a.traitlet_names(),['i','f'])
333 self.assertEquals(a.trait_names(),['i','f'])
334
334
335 def test_traitlet_metadata(self):
335 def test_trait_metadata(self):
336 class A(HasTraitlets):
336 class A(HasTraits):
337 i = Int(config_key='MY_VALUE')
337 i = Int(config_key='MY_VALUE')
338 a = A()
338 a = A()
339 self.assertEquals(a.traitlet_metadata('i','config_key'), 'MY_VALUE')
339 self.assertEquals(a.trait_metadata('i','config_key'), 'MY_VALUE')
340
340
341 def test_traitlets(self):
341 def test_traits(self):
342 class A(HasTraitlets):
342 class A(HasTraits):
343 i = Int
343 i = Int
344 f = Float
344 f = Float
345 a = A()
345 a = A()
346 self.assertEquals(a.traitlets(), dict(i=A.i, f=A.f))
346 self.assertEquals(a.traits(), dict(i=A.i, f=A.f))
347
347
348 def test_traitlets_metadata(self):
348 def test_traits_metadata(self):
349 class A(HasTraitlets):
349 class A(HasTraits):
350 i = Int(config_key='VALUE1', other_thing='VALUE2')
350 i = Int(config_key='VALUE1', other_thing='VALUE2')
351 f = Float(config_key='VALUE3', other_thing='VALUE2')
351 f = Float(config_key='VALUE3', other_thing='VALUE2')
352 j = Int(0)
352 j = Int(0)
353 a = A()
353 a = A()
354 self.assertEquals(a.traitlets(), dict(i=A.i, f=A.f, j=A.j))
354 self.assertEquals(a.traits(), dict(i=A.i, f=A.f, j=A.j))
355 traitlets = a.traitlets(config_key='VALUE1', other_thing='VALUE2')
355 traits = a.traits(config_key='VALUE1', other_thing='VALUE2')
356 self.assertEquals(traitlets, dict(i=A.i))
356 self.assertEquals(traits, dict(i=A.i))
357
357
358 # This passes, but it shouldn't because I am replicating a bug in
358 # This passes, but it shouldn't because I am replicating a bug in
359 # traits.
359 # traits.
360 traitlets = a.traitlets(config_key=lambda v: True)
360 traits = a.traits(config_key=lambda v: True)
361 self.assertEquals(traitlets, dict(i=A.i, f=A.f, j=A.j))
361 self.assertEquals(traits, dict(i=A.i, f=A.f, j=A.j))
362
362
363
363
364 #-----------------------------------------------------------------------------
364 #-----------------------------------------------------------------------------
365 # Tests for specific traitlet types
365 # Tests for specific trait types
366 #-----------------------------------------------------------------------------
366 #-----------------------------------------------------------------------------
367
367
368
368
@@ -371,7 +371,7 b' class TestType(TestCase):'
371 def test_default(self):
371 def test_default(self):
372
372
373 class B(object): pass
373 class B(object): pass
374 class A(HasTraitlets):
374 class A(HasTraits):
375 klass = Type
375 klass = Type
376
376
377 a = A()
377 a = A()
@@ -379,42 +379,42 b' class TestType(TestCase):'
379
379
380 a.klass = B
380 a.klass = B
381 self.assertEquals(a.klass, B)
381 self.assertEquals(a.klass, B)
382 self.assertRaises(TraitletError, setattr, a, 'klass', 10)
382 self.assertRaises(TraitError, setattr, a, 'klass', 10)
383
383
384 def test_value(self):
384 def test_value(self):
385
385
386 class B(object): pass
386 class B(object): pass
387 class C(object): pass
387 class C(object): pass
388 class A(HasTraitlets):
388 class A(HasTraits):
389 klass = Type(B)
389 klass = Type(B)
390
390
391 a = A()
391 a = A()
392 self.assertEquals(a.klass, B)
392 self.assertEquals(a.klass, B)
393 self.assertRaises(TraitletError, setattr, a, 'klass', C)
393 self.assertRaises(TraitError, setattr, a, 'klass', C)
394 self.assertRaises(TraitletError, setattr, a, 'klass', object)
394 self.assertRaises(TraitError, setattr, a, 'klass', object)
395 a.klass = B
395 a.klass = B
396
396
397 def test_allow_none(self):
397 def test_allow_none(self):
398
398
399 class B(object): pass
399 class B(object): pass
400 class C(B): pass
400 class C(B): pass
401 class A(HasTraitlets):
401 class A(HasTraits):
402 klass = Type(B, allow_none=False)
402 klass = Type(B, allow_none=False)
403
403
404 a = A()
404 a = A()
405 self.assertEquals(a.klass, B)
405 self.assertEquals(a.klass, B)
406 self.assertRaises(TraitletError, setattr, a, 'klass', None)
406 self.assertRaises(TraitError, setattr, a, 'klass', None)
407 a.klass = C
407 a.klass = C
408 self.assertEquals(a.klass, C)
408 self.assertEquals(a.klass, C)
409
409
410 def test_validate_klass(self):
410 def test_validate_klass(self):
411
411
412 class A(HasTraitlets):
412 class A(HasTraits):
413 klass = Type('no strings allowed')
413 klass = Type('no strings allowed')
414
414
415 self.assertRaises(ImportError, A)
415 self.assertRaises(ImportError, A)
416
416
417 class A(HasTraitlets):
417 class A(HasTraits):
418 klass = Type('rub.adub.Duck')
418 klass = Type('rub.adub.Duck')
419
419
420 self.assertRaises(ImportError, A)
420 self.assertRaises(ImportError, A)
@@ -422,19 +422,19 b' class TestType(TestCase):'
422 def test_validate_default(self):
422 def test_validate_default(self):
423
423
424 class B(object): pass
424 class B(object): pass
425 class A(HasTraitlets):
425 class A(HasTraits):
426 klass = Type('bad default', B)
426 klass = Type('bad default', B)
427
427
428 self.assertRaises(ImportError, A)
428 self.assertRaises(ImportError, A)
429
429
430 class C(HasTraitlets):
430 class C(HasTraits):
431 klass = Type(None, B, allow_none=False)
431 klass = Type(None, B, allow_none=False)
432
432
433 self.assertRaises(TraitletError, C)
433 self.assertRaises(TraitError, C)
434
434
435 def test_str_klass(self):
435 def test_str_klass(self):
436
436
437 class A(HasTraitlets):
437 class A(HasTraits):
438 klass = Type('IPython.utils.ipstruct.Struct')
438 klass = Type('IPython.utils.ipstruct.Struct')
439
439
440 from IPython.utils.ipstruct import Struct
440 from IPython.utils.ipstruct import Struct
@@ -442,7 +442,7 b' class TestType(TestCase):'
442 a.klass = Struct
442 a.klass = Struct
443 self.assertEquals(a.klass, Struct)
443 self.assertEquals(a.klass, Struct)
444
444
445 self.assertRaises(TraitletError, setattr, a, 'klass', 10)
445 self.assertRaises(TraitError, setattr, a, 'klass', 10)
446
446
447 class TestInstance(TestCase):
447 class TestInstance(TestCase):
448
448
@@ -451,7 +451,7 b' class TestInstance(TestCase):'
451 class Bar(Foo): pass
451 class Bar(Foo): pass
452 class Bah(object): pass
452 class Bah(object): pass
453
453
454 class A(HasTraitlets):
454 class A(HasTraits):
455 inst = Instance(Foo)
455 inst = Instance(Foo)
456
456
457 a = A()
457 a = A()
@@ -460,13 +460,13 b' class TestInstance(TestCase):'
460 self.assert_(isinstance(a.inst, Foo))
460 self.assert_(isinstance(a.inst, Foo))
461 a.inst = Bar()
461 a.inst = Bar()
462 self.assert_(isinstance(a.inst, Foo))
462 self.assert_(isinstance(a.inst, Foo))
463 self.assertRaises(TraitletError, setattr, a, 'inst', Foo)
463 self.assertRaises(TraitError, setattr, a, 'inst', Foo)
464 self.assertRaises(TraitletError, setattr, a, 'inst', Bar)
464 self.assertRaises(TraitError, setattr, a, 'inst', Bar)
465 self.assertRaises(TraitletError, setattr, a, 'inst', Bah())
465 self.assertRaises(TraitError, setattr, a, 'inst', Bah())
466
466
467 def test_unique_default_value(self):
467 def test_unique_default_value(self):
468 class Foo(object): pass
468 class Foo(object): pass
469 class A(HasTraitlets):
469 class A(HasTraits):
470 inst = Instance(Foo,(),{})
470 inst = Instance(Foo,(),{})
471
471
472 a = A()
472 a = A()
@@ -481,18 +481,18 b' class TestInstance(TestCase):'
481 def __init__(self, c, d):
481 def __init__(self, c, d):
482 self.c = c; self.d = d
482 self.c = c; self.d = d
483
483
484 class A(HasTraitlets):
484 class A(HasTraits):
485 inst = Instance(Foo, (10,))
485 inst = Instance(Foo, (10,))
486 a = A()
486 a = A()
487 self.assertEquals(a.inst.c, 10)
487 self.assertEquals(a.inst.c, 10)
488
488
489 class B(HasTraitlets):
489 class B(HasTraits):
490 inst = Instance(Bah, args=(10,), kw=dict(d=20))
490 inst = Instance(Bah, args=(10,), kw=dict(d=20))
491 b = B()
491 b = B()
492 self.assertEquals(b.inst.c, 10)
492 self.assertEquals(b.inst.c, 10)
493 self.assertEquals(b.inst.d, 20)
493 self.assertEquals(b.inst.d, 20)
494
494
495 class C(HasTraitlets):
495 class C(HasTraits):
496 inst = Instance(Foo)
496 inst = Instance(Foo)
497 c = C()
497 c = C()
498 self.assert_(c.inst is None)
498 self.assert_(c.inst is None)
@@ -500,25 +500,25 b' class TestInstance(TestCase):'
500 def test_bad_default(self):
500 def test_bad_default(self):
501 class Foo(object): pass
501 class Foo(object): pass
502
502
503 class A(HasTraitlets):
503 class A(HasTraits):
504 inst = Instance(Foo, allow_none=False)
504 inst = Instance(Foo, allow_none=False)
505
505
506 self.assertRaises(TraitletError, A)
506 self.assertRaises(TraitError, A)
507
507
508 def test_instance(self):
508 def test_instance(self):
509 class Foo(object): pass
509 class Foo(object): pass
510
510
511 def inner():
511 def inner():
512 class A(HasTraitlets):
512 class A(HasTraits):
513 inst = Instance(Foo())
513 inst = Instance(Foo())
514
514
515 self.assertRaises(TraitletError, inner)
515 self.assertRaises(TraitError, inner)
516
516
517
517
518 class TestThis(TestCase):
518 class TestThis(TestCase):
519
519
520 def test_this_class(self):
520 def test_this_class(self):
521 class Foo(HasTraitlets):
521 class Foo(HasTraits):
522 this = This
522 this = This
523
523
524 f = Foo()
524 f = Foo()
@@ -526,10 +526,10 b' class TestThis(TestCase):'
526 g = Foo()
526 g = Foo()
527 f.this = g
527 f.this = g
528 self.assertEquals(f.this, g)
528 self.assertEquals(f.this, g)
529 self.assertRaises(TraitletError, setattr, f, 'this', 10)
529 self.assertRaises(TraitError, setattr, f, 'this', 10)
530
530
531 def test_this_inst(self):
531 def test_this_inst(self):
532 class Foo(HasTraitlets):
532 class Foo(HasTraits):
533 this = This()
533 this = This()
534
534
535 f = Foo()
535 f = Foo()
@@ -537,7 +537,7 b' class TestThis(TestCase):'
537 self.assert_(isinstance(f.this, Foo))
537 self.assert_(isinstance(f.this, Foo))
538
538
539 def test_subclass(self):
539 def test_subclass(self):
540 class Foo(HasTraitlets):
540 class Foo(HasTraits):
541 t = This()
541 t = This()
542 class Bar(Foo):
542 class Bar(Foo):
543 pass
543 pass
@@ -549,7 +549,7 b' class TestThis(TestCase):'
549 self.assertEquals(b.t, f)
549 self.assertEquals(b.t, f)
550
550
551 def test_subclass_override(self):
551 def test_subclass_override(self):
552 class Foo(HasTraitlets):
552 class Foo(HasTraits):
553 t = This()
553 t = This()
554 class Bar(Foo):
554 class Bar(Foo):
555 t = This()
555 t = This()
@@ -557,10 +557,10 b' class TestThis(TestCase):'
557 b = Bar()
557 b = Bar()
558 f.t = b
558 f.t = b
559 self.assertEquals(f.t, b)
559 self.assertEquals(f.t, b)
560 self.assertRaises(TraitletError, setattr, b, 't', f)
560 self.assertRaises(TraitError, setattr, b, 't', f)
561
561
562 class TraitletTestBase(TestCase):
562 class TraitTestBase(TestCase):
563 """A best testing class for basic traitlet types."""
563 """A best testing class for basic trait types."""
564
564
565 def assign(self, value):
565 def assign(self, value):
566 self.obj.value = value
566 self.obj.value = value
@@ -577,33 +577,33 b' class TraitletTestBase(TestCase):'
577 def test_bad_values(self):
577 def test_bad_values(self):
578 if hasattr(self, '_bad_values'):
578 if hasattr(self, '_bad_values'):
579 for value in self._bad_values:
579 for value in self._bad_values:
580 self.assertRaises(TraitletError, self.assign, value)
580 self.assertRaises(TraitError, self.assign, value)
581
581
582 def test_default_value(self):
582 def test_default_value(self):
583 if hasattr(self, '_default_value'):
583 if hasattr(self, '_default_value'):
584 self.assertEquals(self._default_value, self.obj.value)
584 self.assertEquals(self._default_value, self.obj.value)
585
585
586
586
587 class AnyTraitlet(HasTraitlets):
587 class AnyTrait(HasTraits):
588
588
589 value = Any
589 value = Any
590
590
591 class AnyTraitTest(TraitletTestBase):
591 class AnyTraitTest(TraitTestBase):
592
592
593 obj = AnyTraitlet()
593 obj = AnyTrait()
594
594
595 _default_value = None
595 _default_value = None
596 _good_values = [10.0, 'ten', u'ten', [10], {'ten': 10},(10,), None, 1j]
596 _good_values = [10.0, 'ten', u'ten', [10], {'ten': 10},(10,), None, 1j]
597 _bad_values = []
597 _bad_values = []
598
598
599
599
600 class IntTraitlet(HasTraitlets):
600 class IntTrait(HasTraits):
601
601
602 value = Int(99)
602 value = Int(99)
603
603
604 class TestInt(TraitletTestBase):
604 class TestInt(TraitTestBase):
605
605
606 obj = IntTraitlet()
606 obj = IntTrait()
607 _default_value = 99
607 _default_value = 99
608 _good_values = [10, -10]
608 _good_values = [10, -10]
609 _bad_values = ['ten', u'ten', [10], {'ten': 10},(10,), None, 1j, 10L,
609 _bad_values = ['ten', u'ten', [10], {'ten': 10},(10,), None, 1j, 10L,
@@ -611,13 +611,13 b' class TestInt(TraitletTestBase):'
611 u'-10L', u'10.1', u'-10.1', '10', '-10', u'10', u'-10']
611 u'-10L', u'10.1', u'-10.1', '10', '-10', u'10', u'-10']
612
612
613
613
614 class LongTraitlet(HasTraitlets):
614 class LongTrait(HasTraits):
615
615
616 value = Long(99L)
616 value = Long(99L)
617
617
618 class TestLong(TraitletTestBase):
618 class TestLong(TraitTestBase):
619
619
620 obj = LongTraitlet()
620 obj = LongTrait()
621
621
622 _default_value = 99L
622 _default_value = 99L
623 _good_values = [10, -10, 10L, -10L]
623 _good_values = [10, -10, 10L, -10L]
@@ -627,13 +627,13 b' class TestLong(TraitletTestBase):'
627 u'-10.1']
627 u'-10.1']
628
628
629
629
630 class FloatTraitlet(HasTraitlets):
630 class FloatTrait(HasTraits):
631
631
632 value = Float(99.0)
632 value = Float(99.0)
633
633
634 class TestFloat(TraitletTestBase):
634 class TestFloat(TraitTestBase):
635
635
636 obj = FloatTraitlet()
636 obj = FloatTrait()
637
637
638 _default_value = 99.0
638 _default_value = 99.0
639 _good_values = [10, -10, 10.1, -10.1]
639 _good_values = [10, -10, 10.1, -10.1]
@@ -642,13 +642,13 b' class TestFloat(TraitletTestBase):'
642 u'-10', u'10L', u'-10L', u'10.1', u'-10.1']
642 u'-10', u'10L', u'-10L', u'10.1', u'-10.1']
643
643
644
644
645 class ComplexTraitlet(HasTraitlets):
645 class ComplexTrait(HasTraits):
646
646
647 value = Complex(99.0-99.0j)
647 value = Complex(99.0-99.0j)
648
648
649 class TestComplex(TraitletTestBase):
649 class TestComplex(TraitTestBase):
650
650
651 obj = ComplexTraitlet()
651 obj = ComplexTrait()
652
652
653 _default_value = 99.0-99.0j
653 _default_value = 99.0-99.0j
654 _good_values = [10, -10, 10.1, -10.1, 10j, 10+10j, 10-10j,
654 _good_values = [10, -10, 10.1, -10.1, 10j, 10+10j, 10-10j,
@@ -656,13 +656,13 b' class TestComplex(TraitletTestBase):'
656 _bad_values = [10L, -10L, u'10L', u'-10L', 'ten', [10], {'ten': 10},(10,), None]
656 _bad_values = [10L, -10L, u'10L', u'-10L', 'ten', [10], {'ten': 10},(10,), None]
657
657
658
658
659 class StringTraitlet(HasTraitlets):
659 class StringTrait(HasTraits):
660
660
661 value = Str('string')
661 value = Str('string')
662
662
663 class TestString(TraitletTestBase):
663 class TestString(TraitTestBase):
664
664
665 obj = StringTraitlet()
665 obj = StringTrait()
666
666
667 _default_value = 'string'
667 _default_value = 'string'
668 _good_values = ['10', '-10', '10L',
668 _good_values = ['10', '-10', '10L',
@@ -671,13 +671,13 b' class TestString(TraitletTestBase):'
671 ['ten'],{'ten': 10},(10,), None, u'string']
671 ['ten'],{'ten': 10},(10,), None, u'string']
672
672
673
673
674 class UnicodeTraitlet(HasTraitlets):
674 class UnicodeTrait(HasTraits):
675
675
676 value = Unicode(u'unicode')
676 value = Unicode(u'unicode')
677
677
678 class TestUnicode(TraitletTestBase):
678 class TestUnicode(TraitTestBase):
679
679
680 obj = UnicodeTraitlet()
680 obj = UnicodeTrait()
681
681
682 _default_value = u'unicode'
682 _default_value = u'unicode'
683 _good_values = ['10', '-10', '10L', '-10L', '10.1',
683 _good_values = ['10', '-10', '10L', '-10L', '10.1',
@@ -17,7 +17,7 b" We don't support:"
17 * Delegation
17 * Delegation
18 * Automatic GUI generation
18 * Automatic GUI generation
19 * A full set of trait types. Most importantly, we don't provide container
19 * A full set of trait types. Most importantly, we don't provide container
20 traitlets (list, dict, tuple) that can trigger notifications if their
20 traits (list, dict, tuple) that can trigger notifications if their
21 contents change.
21 contents change.
22 * API compatibility with enthought.traits
22 * API compatibility with enthought.traits
23
23
@@ -57,7 +57,18 b' from types import ('
57 ListType, TupleType
57 ListType, TupleType
58 )
58 )
59
59
60 from IPython.utils.importstring import import_item
60 def import_item(name):
61 """Import and return bar given the string foo.bar."""
62 package = '.'.join(name.split('.')[0:-1])
63 obj = name.split('.')[-1]
64 execString = 'from %s import %s' % (package, obj)
65 try:
66 exec execString
67 except SyntaxError:
68 raise ImportError("Invalid class specification: %s" % name)
69 exec 'temp = %s' % obj
70 return temp
71
61
72
62 ClassTypes = (ClassType, type)
73 ClassTypes = (ClassType, type)
63
74
@@ -75,11 +86,9 b' NoDefaultSpecified = NoDefaultSpecified()'
75 class Undefined ( object ): pass
86 class Undefined ( object ): pass
76 Undefined = Undefined()
87 Undefined = Undefined()
77
88
78
89 class TraitError(Exception):
79 class TraitletError(Exception):
80 pass
90 pass
81
91
82
83 #-----------------------------------------------------------------------------
92 #-----------------------------------------------------------------------------
84 # Utilities
93 # Utilities
85 #-----------------------------------------------------------------------------
94 #-----------------------------------------------------------------------------
@@ -129,12 +138,12 b' def parse_notifier_name(name):'
129 >>> parse_notifier_name(['a','b'])
138 >>> parse_notifier_name(['a','b'])
130 ['a', 'b']
139 ['a', 'b']
131 >>> parse_notifier_name(None)
140 >>> parse_notifier_name(None)
132 ['anytraitlet']
141 ['anytrait']
133 """
142 """
134 if isinstance(name, str):
143 if isinstance(name, str):
135 return [name]
144 return [name]
136 elif name is None:
145 elif name is None:
137 return ['anytraitlet']
146 return ['anytrait']
138 elif isinstance(name, (list, tuple)):
147 elif isinstance(name, (list, tuple)):
139 for n in name:
148 for n in name:
140 assert isinstance(n, str), "names must be strings"
149 assert isinstance(n, str), "names must be strings"
@@ -172,25 +181,25 b' def getmembers(object, predicate=None):'
172
181
173
182
174 #-----------------------------------------------------------------------------
183 #-----------------------------------------------------------------------------
175 # Base TraitletType for all traitlets
184 # Base TraitType for all traits
176 #-----------------------------------------------------------------------------
185 #-----------------------------------------------------------------------------
177
186
178
187
179 class TraitletType(object):
188 class TraitType(object):
180 """A base class for all traitlet descriptors.
189 """A base class for all trait descriptors.
181
190
182 Notes
191 Notes
183 -----
192 -----
184 Our implementation of traitlets is based on Python's descriptor
193 Our implementation of traits is based on Python's descriptor
185 prototol. This class is the base class for all such descriptors. The
194 prototol. This class is the base class for all such descriptors. The
186 only magic we use is a custom metaclass for the main :class:`HasTraitlets`
195 only magic we use is a custom metaclass for the main :class:`HasTraits`
187 class that does the following:
196 class that does the following:
188
197
189 1. Sets the :attr:`name` attribute of every :class:`TraitletType`
198 1. Sets the :attr:`name` attribute of every :class:`TraitType`
190 instance in the class dict to the name of the attribute.
199 instance in the class dict to the name of the attribute.
191 2. Sets the :attr:`this_class` attribute of every :class:`TraitletType`
200 2. Sets the :attr:`this_class` attribute of every :class:`TraitType`
192 instance in the class dict to the *class* that declared the traitlet.
201 instance in the class dict to the *class* that declared the trait.
193 This is used by the :class:`This` traitlet to allow subclasses to
202 This is used by the :class:`This` trait to allow subclasses to
194 accept superclasses for :class:`This` values.
203 accept superclasses for :class:`This` values.
195 """
204 """
196
205
@@ -200,7 +209,7 b' class TraitletType(object):'
200 info_text = 'any value'
209 info_text = 'any value'
201
210
202 def __init__(self, default_value=NoDefaultSpecified, **metadata):
211 def __init__(self, default_value=NoDefaultSpecified, **metadata):
203 """Create a TraitletType.
212 """Create a TraitType.
204 """
213 """
205 if default_value is not NoDefaultSpecified:
214 if default_value is not NoDefaultSpecified:
206 self.default_value = default_value
215 self.default_value = default_value
@@ -225,11 +234,11 b' class TraitletType(object):'
225 return dv
234 return dv
226
235
227 def instance_init(self, obj):
236 def instance_init(self, obj):
228 """This is called by :meth:`HasTraitlets.__new__` to finish init'ing.
237 """This is called by :meth:`HasTraits.__new__` to finish init'ing.
229
238
230 Some stages of initialization must be delayed until the parent
239 Some stages of initialization must be delayed until the parent
231 :class:`HasTraitlets` instance has been created. This method is
240 :class:`HasTraits` instance has been created. This method is
232 called in :meth:`HasTraitlets.__new__` after the instance has been
241 called in :meth:`HasTraits.__new__` after the instance has been
233 created.
242 created.
234
243
235 This method trigger the creation and validation of default values
244 This method trigger the creation and validation of default values
@@ -238,8 +247,8 b' class TraitletType(object):'
238
247
239 Parameters
248 Parameters
240 ----------
249 ----------
241 obj : :class:`HasTraitlets` instance
250 obj : :class:`HasTraits` instance
242 The parent :class:`HasTraitlets` instance that has just been
251 The parent :class:`HasTraits` instance that has just been
243 created.
252 created.
244 """
253 """
245 self.set_default_value(obj)
254 self.set_default_value(obj)
@@ -249,30 +258,30 b' class TraitletType(object):'
249
258
250 This method is called by :meth:`instance_init` to create and
259 This method is called by :meth:`instance_init` to create and
251 validate the default value. The creation and validation of
260 validate the default value. The creation and validation of
252 default values must be delayed until the parent :class:`HasTraitlets`
261 default values must be delayed until the parent :class:`HasTraits`
253 class has been instantiated.
262 class has been instantiated.
254 """
263 """
255 dv = self.get_default_value()
264 dv = self.get_default_value()
256 newdv = self._validate(obj, dv)
265 newdv = self._validate(obj, dv)
257 obj._traitlet_values[self.name] = newdv
266 obj._trait_values[self.name] = newdv
258
267
259 def __get__(self, obj, cls=None):
268 def __get__(self, obj, cls=None):
260 """Get the value of the traitlet by self.name for the instance.
269 """Get the value of the trait by self.name for the instance.
261
270
262 Default values are instantiated when :meth:`HasTraitlets.__new__`
271 Default values are instantiated when :meth:`HasTraits.__new__`
263 is called. Thus by the time this method gets called either the
272 is called. Thus by the time this method gets called either the
264 default value or a user defined value (they called :meth:`__set__`)
273 default value or a user defined value (they called :meth:`__set__`)
265 is in the :class:`HasTraitlets` instance.
274 is in the :class:`HasTraits` instance.
266 """
275 """
267 if obj is None:
276 if obj is None:
268 return self
277 return self
269 else:
278 else:
270 try:
279 try:
271 value = obj._traitlet_values[self.name]
280 value = obj._trait_values[self.name]
272 except:
281 except:
273 # HasTraitlets should call set_default_value to populate
282 # HasTraits should call set_default_value to populate
274 # this. So this should never be reached.
283 # this. So this should never be reached.
275 raise TraitletError('Unexpected error in TraitletType: '
284 raise TraitError('Unexpected error in TraitType: '
276 'default value not set properly')
285 'default value not set properly')
277 else:
286 else:
278 return value
287 return value
@@ -281,8 +290,8 b' class TraitletType(object):'
281 new_value = self._validate(obj, value)
290 new_value = self._validate(obj, value)
282 old_value = self.__get__(obj)
291 old_value = self.__get__(obj)
283 if old_value != new_value:
292 if old_value != new_value:
284 obj._traitlet_values[self.name] = new_value
293 obj._trait_values[self.name] = new_value
285 obj._notify_traitlet(self.name, old_value, new_value)
294 obj._notify_trait(self.name, old_value, new_value)
286
295
287 def _validate(self, obj, value):
296 def _validate(self, obj, value):
288 if hasattr(self, 'validate'):
297 if hasattr(self, 'validate'):
@@ -292,7 +301,7 b' class TraitletType(object):'
292 if valid:
301 if valid:
293 return value
302 return value
294 else:
303 else:
295 raise TraitletError('invalid value for type: %r' % value)
304 raise TraitError('invalid value for type: %r' % value)
296 elif hasattr(self, 'value_for'):
305 elif hasattr(self, 'value_for'):
297 return self.value_for(value)
306 return self.value_for(value)
298 else:
307 else:
@@ -303,13 +312,13 b' class TraitletType(object):'
303
312
304 def error(self, obj, value):
313 def error(self, obj, value):
305 if obj is not None:
314 if obj is not None:
306 e = "The '%s' traitlet of %s instance must be %s, but a value of %s was specified." \
315 e = "The '%s' trait of %s instance must be %s, but a value of %s was specified." \
307 % (self.name, class_of(obj),
316 % (self.name, class_of(obj),
308 self.info(), repr_type(value))
317 self.info(), repr_type(value))
309 else:
318 else:
310 e = "The '%s' traitlet must be %s, but a value of %r was specified." \
319 e = "The '%s' trait must be %s, but a value of %r was specified." \
311 % (self.name, self.info(), repr_type(value))
320 % (self.name, self.info(), repr_type(value))
312 raise TraitletError(e)
321 raise TraitError(e)
313
322
314 def get_metadata(self, key):
323 def get_metadata(self, key):
315 return getattr(self, '_metadata', {}).get(key, None)
324 return getattr(self, '_metadata', {}).get(key, None)
@@ -319,62 +328,62 b' class TraitletType(object):'
319
328
320
329
321 #-----------------------------------------------------------------------------
330 #-----------------------------------------------------------------------------
322 # The HasTraitlets implementation
331 # The HasTraits implementation
323 #-----------------------------------------------------------------------------
332 #-----------------------------------------------------------------------------
324
333
325
334
326 class MetaHasTraitlets(type):
335 class MetaHasTraits(type):
327 """A metaclass for HasTraitlets.
336 """A metaclass for HasTraits.
328
337
329 This metaclass makes sure that any TraitletType class attributes are
338 This metaclass makes sure that any TraitType class attributes are
330 instantiated and sets their name attribute.
339 instantiated and sets their name attribute.
331 """
340 """
332
341
333 def __new__(mcls, name, bases, classdict):
342 def __new__(mcls, name, bases, classdict):
334 """Create the HasTraitlets class.
343 """Create the HasTraits class.
335
344
336 This instantiates all TraitletTypes in the class dict and sets their
345 This instantiates all TraitTypes in the class dict and sets their
337 :attr:`name` attribute.
346 :attr:`name` attribute.
338 """
347 """
339 # print "MetaHasTraitlets (mcls, name): ", mcls, name
348 # print "MetaHasTraitlets (mcls, name): ", mcls, name
340 # print "MetaHasTraitlets (bases): ", bases
349 # print "MetaHasTraitlets (bases): ", bases
341 # print "MetaHasTraitlets (classdict): ", classdict
350 # print "MetaHasTraitlets (classdict): ", classdict
342 for k,v in classdict.iteritems():
351 for k,v in classdict.iteritems():
343 if isinstance(v, TraitletType):
352 if isinstance(v, TraitType):
344 v.name = k
353 v.name = k
345 elif inspect.isclass(v):
354 elif inspect.isclass(v):
346 if issubclass(v, TraitletType):
355 if issubclass(v, TraitType):
347 vinst = v()
356 vinst = v()
348 vinst.name = k
357 vinst.name = k
349 classdict[k] = vinst
358 classdict[k] = vinst
350 return super(MetaHasTraitlets, mcls).__new__(mcls, name, bases, classdict)
359 return super(MetaHasTraits, mcls).__new__(mcls, name, bases, classdict)
351
360
352 def __init__(cls, name, bases, classdict):
361 def __init__(cls, name, bases, classdict):
353 """Finish initializing the HasTraitlets class.
362 """Finish initializing the HasTraits class.
354
363
355 This sets the :attr:`this_class` attribute of each TraitletType in the
364 This sets the :attr:`this_class` attribute of each TraitType in the
356 class dict to the newly created class ``cls``.
365 class dict to the newly created class ``cls``.
357 """
366 """
358 for k, v in classdict.iteritems():
367 for k, v in classdict.iteritems():
359 if isinstance(v, TraitletType):
368 if isinstance(v, TraitType):
360 v.this_class = cls
369 v.this_class = cls
361 super(MetaHasTraitlets, cls).__init__(name, bases, classdict)
370 super(MetaHasTraits, cls).__init__(name, bases, classdict)
362
371
363 class HasTraitlets(object):
372 class HasTraits(object):
364
373
365 __metaclass__ = MetaHasTraitlets
374 __metaclass__ = MetaHasTraits
366
375
367 def __new__(cls, *args, **kw):
376 def __new__(cls, *args, **kw):
368 # This is needed because in Python 2.6 object.__new__ only accepts
377 # This is needed because in Python 2.6 object.__new__ only accepts
369 # the cls argument.
378 # the cls argument.
370 new_meth = super(HasTraitlets, cls).__new__
379 new_meth = super(HasTraits, cls).__new__
371 if new_meth is object.__new__:
380 if new_meth is object.__new__:
372 inst = new_meth(cls)
381 inst = new_meth(cls)
373 else:
382 else:
374 inst = new_meth(cls, *args, **kw)
383 inst = new_meth(cls, *args, **kw)
375 inst._traitlet_values = {}
384 inst._trait_values = {}
376 inst._traitlet_notifiers = {}
385 inst._trait_notifiers = {}
377 # Here we tell all the TraitletType instances to set their default
386 # Here we tell all the TraitType instances to set their default
378 # values on the instance.
387 # values on the instance.
379 for key in dir(cls):
388 for key in dir(cls):
380 # Some descriptors raise AttributeError like zope.interface's
389 # Some descriptors raise AttributeError like zope.interface's
@@ -385,19 +394,20 b' class HasTraitlets(object):'
385 except AttributeError:
394 except AttributeError:
386 pass
395 pass
387 else:
396 else:
388 if isinstance(value, TraitletType):
397 if isinstance(value, TraitType):
389 value.instance_init(inst)
398 value.instance_init(inst)
399
390 return inst
400 return inst
391
401
392 # def __init__(self):
402 # def __init__(self):
393 # self._traitlet_values = {}
403 # self._trait_values = {}
394 # self._traitlet_notifiers = {}
404 # self._trait_notifiers = {}
395
405
396 def _notify_traitlet(self, name, old_value, new_value):
406 def _notify_trait(self, name, old_value, new_value):
397
407
398 # First dynamic ones
408 # First dynamic ones
399 callables = self._traitlet_notifiers.get(name,[])
409 callables = self._trait_notifiers.get(name,[])
400 more_callables = self._traitlet_notifiers.get('anytraitlet',[])
410 more_callables = self._trait_notifiers.get('anytrait',[])
401 callables.extend(more_callables)
411 callables.extend(more_callables)
402
412
403 # Now static ones
413 # Now static ones
@@ -430,25 +440,25 b' class HasTraitlets(object):'
430 elif nargs + offset == 3:
440 elif nargs + offset == 3:
431 c(name, old_value, new_value)
441 c(name, old_value, new_value)
432 else:
442 else:
433 raise TraitletError('a traitlet changed callback '
443 raise TraitError('a trait changed callback '
434 'must have 0-3 arguments.')
444 'must have 0-3 arguments.')
435 else:
445 else:
436 raise TraitletError('a traitlet changed callback '
446 raise TraitError('a trait changed callback '
437 'must be callable.')
447 'must be callable.')
438
448
439
449
440 def _add_notifiers(self, handler, name):
450 def _add_notifiers(self, handler, name):
441 if not self._traitlet_notifiers.has_key(name):
451 if not self._trait_notifiers.has_key(name):
442 nlist = []
452 nlist = []
443 self._traitlet_notifiers[name] = nlist
453 self._trait_notifiers[name] = nlist
444 else:
454 else:
445 nlist = self._traitlet_notifiers[name]
455 nlist = self._trait_notifiers[name]
446 if handler not in nlist:
456 if handler not in nlist:
447 nlist.append(handler)
457 nlist.append(handler)
448
458
449 def _remove_notifiers(self, handler, name):
459 def _remove_notifiers(self, handler, name):
450 if self._traitlet_notifiers.has_key(name):
460 if self._trait_notifiers.has_key(name):
451 nlist = self._traitlet_notifiers[name]
461 nlist = self._trait_notifiers[name]
452 try:
462 try:
453 index = nlist.index(handler)
463 index = nlist.index(handler)
454 except ValueError:
464 except ValueError:
@@ -456,25 +466,25 b' class HasTraitlets(object):'
456 else:
466 else:
457 del nlist[index]
467 del nlist[index]
458
468
459 def on_traitlet_change(self, handler, name=None, remove=False):
469 def on_trait_change(self, handler, name=None, remove=False):
460 """Setup a handler to be called when a traitlet changes.
470 """Setup a handler to be called when a trait changes.
461
471
462 This is used to setup dynamic notifications of traitlet changes.
472 This is used to setup dynamic notifications of trait changes.
463
473
464 Static handlers can be created by creating methods on a HasTraitlets
474 Static handlers can be created by creating methods on a HasTraits
465 subclass with the naming convention '_[traitletname]_changed'. Thus,
475 subclass with the naming convention '_[traitname]_changed'. Thus,
466 to create static handler for the traitlet 'a', create the method
476 to create static handler for the trait 'a', create the method
467 _a_changed(self, name, old, new) (fewer arguments can be used, see
477 _a_changed(self, name, old, new) (fewer arguments can be used, see
468 below).
478 below).
469
479
470 Parameters
480 Parameters
471 ----------
481 ----------
472 handler : callable
482 handler : callable
473 A callable that is called when a traitlet changes. Its
483 A callable that is called when a trait changes. Its
474 signature can be handler(), handler(name), handler(name, new)
484 signature can be handler(), handler(name), handler(name, new)
475 or handler(name, old, new).
485 or handler(name, old, new).
476 name : list, str, None
486 name : list, str, None
477 If None, the handler will apply to all traitlets. If a list
487 If None, the handler will apply to all traits. If a list
478 of str, handler will apply to all names in the list. If a
488 of str, handler will apply to all names in the list. If a
479 str, the handler will apply just to that name.
489 str, the handler will apply just to that name.
480 remove : bool
490 remove : bool
@@ -490,62 +500,62 b' class HasTraitlets(object):'
490 for n in names:
500 for n in names:
491 self._add_notifiers(handler, n)
501 self._add_notifiers(handler, n)
492
502
493 def traitlet_names(self, **metadata):
503 def trait_names(self, **metadata):
494 """Get a list of all the names of this classes traitlets."""
504 """Get a list of all the names of this classes traits."""
495 return self.traitlets(**metadata).keys()
505 return self.traits(**metadata).keys()
496
506
497 def traitlets(self, **metadata):
507 def traits(self, **metadata):
498 """Get a list of all the traitlets of this class.
508 """Get a list of all the traits of this class.
499
509
500 The TraitletTypes returned don't know anything about the values
510 The TraitTypes returned don't know anything about the values
501 that the various HasTraitlet's instances are holding.
511 that the various HasTrait's instances are holding.
502
512
503 This follows the same algorithm as traits does and does not allow
513 This follows the same algorithm as traits does and does not allow
504 for any simple way of specifying merely that a metadata name
514 for any simple way of specifying merely that a metadata name
505 exists, but has any value. This is because get_metadata returns
515 exists, but has any value. This is because get_metadata returns
506 None if a metadata key doesn't exist.
516 None if a metadata key doesn't exist.
507 """
517 """
508 traitlets = dict([memb for memb in getmembers(self.__class__) if \
518 traits = dict([memb for memb in getmembers(self.__class__) if \
509 isinstance(memb[1], TraitletType)])
519 isinstance(memb[1], TraitType)])
510
520
511 if len(metadata) == 0:
521 if len(metadata) == 0:
512 return traitlets
522 return traits
513
523
514 for meta_name, meta_eval in metadata.items():
524 for meta_name, meta_eval in metadata.items():
515 if type(meta_eval) is not FunctionType:
525 if type(meta_eval) is not FunctionType:
516 metadata[meta_name] = _SimpleTest(meta_eval)
526 metadata[meta_name] = _SimpleTest(meta_eval)
517
527
518 result = {}
528 result = {}
519 for name, traitlet in traitlets.items():
529 for name, trait in traits.items():
520 for meta_name, meta_eval in metadata.items():
530 for meta_name, meta_eval in metadata.items():
521 if not meta_eval(traitlet.get_metadata(meta_name)):
531 if not meta_eval(trait.get_metadata(meta_name)):
522 break
532 break
523 else:
533 else:
524 result[name] = traitlet
534 result[name] = trait
525
535
526 return result
536 return result
527
537
528 def traitlet_metadata(self, traitletname, key):
538 def trait_metadata(self, traitname, key):
529 """Get metadata values for traitlet by key."""
539 """Get metadata values for trait by key."""
530 try:
540 try:
531 traitlet = getattr(self.__class__, traitletname)
541 trait = getattr(self.__class__, traitname)
532 except AttributeError:
542 except AttributeError:
533 raise TraitletError("Class %s does not have a traitlet named %s" %
543 raise TraitError("Class %s does not have a trait named %s" %
534 (self.__class__.__name__, traitletname))
544 (self.__class__.__name__, traitname))
535 else:
545 else:
536 return traitlet.get_metadata(key)
546 return trait.get_metadata(key)
537
547
538 #-----------------------------------------------------------------------------
548 #-----------------------------------------------------------------------------
539 # Actual TraitletTypes implementations/subclasses
549 # Actual TraitTypes implementations/subclasses
540 #-----------------------------------------------------------------------------
550 #-----------------------------------------------------------------------------
541
551
542 #-----------------------------------------------------------------------------
552 #-----------------------------------------------------------------------------
543 # TraitletTypes subclasses for handling classes and instances of classes
553 # TraitTypes subclasses for handling classes and instances of classes
544 #-----------------------------------------------------------------------------
554 #-----------------------------------------------------------------------------
545
555
546
556
547 class ClassBasedTraitletType(TraitletType):
557 class ClassBasedTraitType(TraitType):
548 """A traitlet with error reporting for Type, Instance and This."""
558 """A trait with error reporting for Type, Instance and This."""
549
559
550 def error(self, obj, value):
560 def error(self, obj, value):
551 kind = type(value)
561 kind = type(value)
@@ -554,16 +564,16 b' class ClassBasedTraitletType(TraitletType):'
554 else:
564 else:
555 msg = '%s (i.e. %s)' % ( str( kind )[1:-1], repr( value ) )
565 msg = '%s (i.e. %s)' % ( str( kind )[1:-1], repr( value ) )
556
566
557 super(ClassBasedTraitletType, self).error(obj, msg)
567 super(ClassBasedTraitType, self).error(obj, msg)
558
568
559
569
560 class Type(ClassBasedTraitletType):
570 class Type(ClassBasedTraitType):
561 """A traitlet whose value must be a subclass of a specified class."""
571 """A trait whose value must be a subclass of a specified class."""
562
572
563 def __init__ (self, default_value=None, klass=None, allow_none=True, **metadata ):
573 def __init__ (self, default_value=None, klass=None, allow_none=True, **metadata ):
564 """Construct a Type traitlet
574 """Construct a Type trait
565
575
566 A Type traitlet specifies that its values must be subclasses of
576 A Type trait specifies that its values must be subclasses of
567 a particular class.
577 a particular class.
568
578
569 If only ``default_value`` is given, it is used for the ``klass`` as
579 If only ``default_value`` is given, it is used for the ``klass`` as
@@ -575,12 +585,12 b' class Type(ClassBasedTraitletType):'
575 The default value must be a subclass of klass. If an str,
585 The default value must be a subclass of klass. If an str,
576 the str must be a fully specified class name, like 'foo.bar.Bah'.
586 the str must be a fully specified class name, like 'foo.bar.Bah'.
577 The string is resolved into real class, when the parent
587 The string is resolved into real class, when the parent
578 :class:`HasTraitlets` class is instantiated.
588 :class:`HasTraits` class is instantiated.
579 klass : class, str, None
589 klass : class, str, None
580 Values of this traitlet must be a subclass of klass. The klass
590 Values of this trait must be a subclass of klass. The klass
581 may be specified in a string like: 'foo.bar.MyClass'.
591 may be specified in a string like: 'foo.bar.MyClass'.
582 The string is resolved into real class, when the parent
592 The string is resolved into real class, when the parent
583 :class:`HasTraitlets` class is instantiated.
593 :class:`HasTraits` class is instantiated.
584 allow_none : boolean
594 allow_none : boolean
585 Indicates whether None is allowed as an assignable value. Even if
595 Indicates whether None is allowed as an assignable value. Even if
586 ``False``, the default value may be ``None``.
596 ``False``, the default value may be ``None``.
@@ -592,7 +602,7 b' class Type(ClassBasedTraitletType):'
592 klass = default_value
602 klass = default_value
593
603
594 if not (inspect.isclass(klass) or isinstance(klass, basestring)):
604 if not (inspect.isclass(klass) or isinstance(klass, basestring)):
595 raise TraitletError("A Type traitlet must specify a class.")
605 raise TraitError("A Type trait must specify a class.")
596
606
597 self.klass = klass
607 self.klass = klass
598 self._allow_none = allow_none
608 self._allow_none = allow_none
@@ -646,7 +656,7 b' class DefaultValueGenerator(object):'
646 return klass(*self.args, **self.kw)
656 return klass(*self.args, **self.kw)
647
657
648
658
649 class Instance(ClassBasedTraitletType):
659 class Instance(ClassBasedTraitType):
650 """A trait whose value must be an instance of a specified class.
660 """A trait whose value must be an instance of a specified class.
651
661
652 The value can also be an instance of a subclass of the specified class.
662 The value can also be an instance of a subclass of the specified class.
@@ -654,9 +664,9 b' class Instance(ClassBasedTraitletType):'
654
664
655 def __init__(self, klass=None, args=None, kw=None,
665 def __init__(self, klass=None, args=None, kw=None,
656 allow_none=True, **metadata ):
666 allow_none=True, **metadata ):
657 """Construct an Instance traitlet.
667 """Construct an Instance trait.
658
668
659 This traitlet allows values that are instances of a particular
669 This trait allows values that are instances of a particular
660 class or its sublclasses. Our implementation is quite different
670 class or its sublclasses. Our implementation is quite different
661 from that of enthough.traits as we don't allow instances to be used
671 from that of enthough.traits as we don't allow instances to be used
662 for klass and we handle the ``args`` and ``kw`` arguments differently.
672 for klass and we handle the ``args`` and ``kw`` arguments differently.
@@ -664,7 +674,7 b' class Instance(ClassBasedTraitletType):'
664 Parameters
674 Parameters
665 ----------
675 ----------
666 klass : class, str
676 klass : class, str
667 The class that forms the basis for the traitlet. Class names
677 The class that forms the basis for the trait. Class names
668 can also be specified as strings, like 'foo.bar.Bar'.
678 can also be specified as strings, like 'foo.bar.Bar'.
669 args : tuple
679 args : tuple
670 Positional arguments for generating the default value.
680 Positional arguments for generating the default value.
@@ -684,7 +694,7 b' class Instance(ClassBasedTraitletType):'
684 self._allow_none = allow_none
694 self._allow_none = allow_none
685
695
686 if (klass is None) or (not (inspect.isclass(klass) or isinstance(klass, basestring))):
696 if (klass is None) or (not (inspect.isclass(klass) or isinstance(klass, basestring))):
687 raise TraitletError('The klass argument must be a class'
697 raise TraitError('The klass argument must be a class'
688 ' you gave: %r' % klass)
698 ' you gave: %r' % klass)
689 self.klass = klass
699 self.klass = klass
690
700
@@ -700,9 +710,9 b' class Instance(ClassBasedTraitletType):'
700 kw = {}
710 kw = {}
701
711
702 if not isinstance(kw, dict):
712 if not isinstance(kw, dict):
703 raise TraitletError("The 'kw' argument must be a dict or None.")
713 raise TraitError("The 'kw' argument must be a dict or None.")
704 if not isinstance(args, tuple):
714 if not isinstance(args, tuple):
705 raise TraitletError("The 'args' argument must be a tuple or None.")
715 raise TraitError("The 'args' argument must be a tuple or None.")
706
716
707 default_value = DefaultValueGenerator(*args, **kw)
717 default_value = DefaultValueGenerator(*args, **kw)
708
718
@@ -741,9 +751,9 b' class Instance(ClassBasedTraitletType):'
741 def get_default_value(self):
751 def get_default_value(self):
742 """Instantiate a default value instance.
752 """Instantiate a default value instance.
743
753
744 This is called when the containing HasTraitlets classes'
754 This is called when the containing HasTraits classes'
745 :meth:`__new__` method is called to ensure that a unique instance
755 :meth:`__new__` method is called to ensure that a unique instance
746 is created for each HasTraitlets instance.
756 is created for each HasTraits instance.
747 """
757 """
748 dv = self.default_value
758 dv = self.default_value
749 if isinstance(dv, DefaultValueGenerator):
759 if isinstance(dv, DefaultValueGenerator):
@@ -752,11 +762,11 b' class Instance(ClassBasedTraitletType):'
752 return dv
762 return dv
753
763
754
764
755 class This(ClassBasedTraitletType):
765 class This(ClassBasedTraitType):
756 """A traitlet for instances of the class containing this trait.
766 """A trait for instances of the class containing this trait.
757
767
758 Because how how and when class bodies are executed, the ``This``
768 Because how how and when class bodies are executed, the ``This``
759 traitlet can only have a default value of None. This, and because we
769 trait can only have a default value of None. This, and because we
760 always validate default values, ``allow_none`` is *always* true.
770 always validate default values, ``allow_none`` is *always* true.
761 """
771 """
762
772
@@ -768,7 +778,7 b' class This(ClassBasedTraitletType):'
768 def validate(self, obj, value):
778 def validate(self, obj, value):
769 # What if value is a superclass of obj.__class__? This is
779 # What if value is a superclass of obj.__class__? This is
770 # complicated if it was the superclass that defined the This
780 # complicated if it was the superclass that defined the This
771 # traitlet.
781 # trait.
772 if isinstance(value, self.this_class) or (value is None):
782 if isinstance(value, self.this_class) or (value is None):
773 return value
783 return value
774 else:
784 else:
@@ -776,17 +786,17 b' class This(ClassBasedTraitletType):'
776
786
777
787
778 #-----------------------------------------------------------------------------
788 #-----------------------------------------------------------------------------
779 # Basic TraitletTypes implementations/subclasses
789 # Basic TraitTypes implementations/subclasses
780 #-----------------------------------------------------------------------------
790 #-----------------------------------------------------------------------------
781
791
782
792
783 class Any(TraitletType):
793 class Any(TraitType):
784 default_value = None
794 default_value = None
785 info_text = 'any value'
795 info_text = 'any value'
786
796
787
797
788 class Int(TraitletType):
798 class Int(TraitType):
789 """A integer traitlet."""
799 """A integer trait."""
790
800
791 evaluate = int
801 evaluate = int
792 default_value = 0
802 default_value = 0
@@ -798,7 +808,7 b' class Int(TraitletType):'
798 self.error(obj, value)
808 self.error(obj, value)
799
809
800 class CInt(Int):
810 class CInt(Int):
801 """A casting version of the int traitlet."""
811 """A casting version of the int trait."""
802
812
803 def validate(self, obj, value):
813 def validate(self, obj, value):
804 try:
814 try:
@@ -807,8 +817,8 b' class CInt(Int):'
807 self.error(obj, value)
817 self.error(obj, value)
808
818
809
819
810 class Long(TraitletType):
820 class Long(TraitType):
811 """A long integer traitlet."""
821 """A long integer trait."""
812
822
813 evaluate = long
823 evaluate = long
814 default_value = 0L
824 default_value = 0L
@@ -823,7 +833,7 b' class Long(TraitletType):'
823
833
824
834
825 class CLong(Long):
835 class CLong(Long):
826 """A casting version of the long integer traitlet."""
836 """A casting version of the long integer trait."""
827
837
828 def validate(self, obj, value):
838 def validate(self, obj, value):
829 try:
839 try:
@@ -832,8 +842,8 b' class CLong(Long):'
832 self.error(obj, value)
842 self.error(obj, value)
833
843
834
844
835 class Float(TraitletType):
845 class Float(TraitType):
836 """A float traitlet."""
846 """A float trait."""
837
847
838 evaluate = float
848 evaluate = float
839 default_value = 0.0
849 default_value = 0.0
@@ -848,7 +858,7 b' class Float(TraitletType):'
848
858
849
859
850 class CFloat(Float):
860 class CFloat(Float):
851 """A casting version of the float traitlet."""
861 """A casting version of the float trait."""
852
862
853 def validate(self, obj, value):
863 def validate(self, obj, value):
854 try:
864 try:
@@ -856,8 +866,8 b' class CFloat(Float):'
856 except:
866 except:
857 self.error(obj, value)
867 self.error(obj, value)
858
868
859 class Complex(TraitletType):
869 class Complex(TraitType):
860 """A traitlet for complex numbers."""
870 """A trait for complex numbers."""
861
871
862 evaluate = complex
872 evaluate = complex
863 default_value = 0.0 + 0.0j
873 default_value = 0.0 + 0.0j
@@ -872,7 +882,7 b' class Complex(TraitletType):'
872
882
873
883
874 class CComplex(Complex):
884 class CComplex(Complex):
875 """A casting version of the complex number traitlet."""
885 """A casting version of the complex number trait."""
876
886
877 def validate (self, obj, value):
887 def validate (self, obj, value):
878 try:
888 try:
@@ -881,8 +891,8 b' class CComplex(Complex):'
881 self.error(obj, value)
891 self.error(obj, value)
882
892
883
893
884 class Str(TraitletType):
894 class Str(TraitType):
885 """A traitlet for strings."""
895 """A trait for strings."""
886
896
887 evaluate = lambda x: x
897 evaluate = lambda x: x
888 default_value = ''
898 default_value = ''
@@ -895,7 +905,7 b' class Str(TraitletType):'
895
905
896
906
897 class CStr(Str):
907 class CStr(Str):
898 """A casting version of the string traitlet."""
908 """A casting version of the string trait."""
899
909
900 def validate(self, obj, value):
910 def validate(self, obj, value):
901 try:
911 try:
@@ -907,8 +917,8 b' class CStr(Str):'
907 self.error(obj, value)
917 self.error(obj, value)
908
918
909
919
910 class Unicode(TraitletType):
920 class Unicode(TraitType):
911 """A traitlet for unicode strings."""
921 """A trait for unicode strings."""
912
922
913 evaluate = unicode
923 evaluate = unicode
914 default_value = u''
924 default_value = u''
@@ -923,7 +933,7 b' class Unicode(TraitletType):'
923
933
924
934
925 class CUnicode(Unicode):
935 class CUnicode(Unicode):
926 """A casting version of the unicode traitlet."""
936 """A casting version of the unicode trait."""
927
937
928 def validate(self, obj, value):
938 def validate(self, obj, value):
929 try:
939 try:
@@ -932,8 +942,8 b' class CUnicode(Unicode):'
932 self.error(obj, value)
942 self.error(obj, value)
933
943
934
944
935 class Bool(TraitletType):
945 class Bool(TraitType):
936 """A boolean (True, False) traitlet."""
946 """A boolean (True, False) trait."""
937 evaluate = bool
947 evaluate = bool
938 default_value = False
948 default_value = False
939 info_text = 'a boolean'
949 info_text = 'a boolean'
@@ -945,7 +955,7 b' class Bool(TraitletType):'
945
955
946
956
947 class CBool(Bool):
957 class CBool(Bool):
948 """A casting version of the boolean traitlet."""
958 """A casting version of the boolean trait."""
949
959
950 def validate(self, obj, value):
960 def validate(self, obj, value):
951 try:
961 try:
@@ -954,7 +964,7 b' class CBool(Bool):'
954 self.error(obj, value)
964 self.error(obj, value)
955
965
956
966
957 class Enum(TraitletType):
967 class Enum(TraitType):
958 """An enum that whose value must be in a given sequence."""
968 """An enum that whose value must be in a given sequence."""
959
969
960 def __init__(self, values, default_value=None, allow_none=True, **metadata):
970 def __init__(self, values, default_value=None, allow_none=True, **metadata):
@@ -999,7 +1009,7 b' class List(Instance):'
999 """An instance of a Python list."""
1009 """An instance of a Python list."""
1000
1010
1001 def __init__(self, default_value=None, allow_none=True, **metadata):
1011 def __init__(self, default_value=None, allow_none=True, **metadata):
1002 """Create a list traitlet type from a list or tuple.
1012 """Create a list trait type from a list or tuple.
1003
1013
1004 The default value is created by doing ``list(default_value)``,
1014 The default value is created by doing ``list(default_value)``,
1005 which creates a copy of the ``default_value``.
1015 which creates a copy of the ``default_value``.
@@ -1008,6 +1018,8 b' class List(Instance):'
1008 args = ((),)
1018 args = ((),)
1009 elif isinstance(default_value, SequenceTypes):
1019 elif isinstance(default_value, SequenceTypes):
1010 args = (default_value,)
1020 args = (default_value,)
1021 else:
1022 raise TypeError('default value of List was %s' % default_value)
1011
1023
1012 super(List,self).__init__(klass=list, args=args,
1024 super(List,self).__init__(klass=list, args=args,
1013 allow_none=allow_none, **metadata)
1025 allow_none=allow_none, **metadata)
@@ -134,7 +134,7 b' traitlets for a number of other types.'
134 .. note::
134 .. note::
135
135
136 Underneath the hood, the :class:`Component` base class is a subclass of
136 Underneath the hood, the :class:`Component` base class is a subclass of
137 :class:`IPython.utils.traitlets.HasTraitlets`. The
137 :class:`IPython.utils.traitlets.HasTraits`. The
138 :mod:`IPython.utils.traitlets` module is a lightweight version of
138 :mod:`IPython.utils.traitlets` module is a lightweight version of
139 :mod:`enthought.traits`. Our implementation is a pure Python subset
139 :mod:`enthought.traits`. Our implementation is a pure Python subset
140 (mostly API compatible) of :mod:`enthought.traits` that does not have any
140 (mostly API compatible) of :mod:`enthought.traits` that does not have any
General Comments 0
You need to be logged in to leave comments. Login now