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