1.. index:: validation, using traits
2
3.. _defining-traits-initialization-and-validation:
4
5==============================================
6Defining Traits: Initialization and Validation
7==============================================
8
9Using the Traits package in a Python program involves the following steps:
10
11.. index:: importing Traits names, traits.api; importing from
12
131. Import the names you need from the Traits package traits.api.
14
152. Define the traits you want to use.
16
17.. index:: HasTraits class
18
193. Define classes derived from HasTraits (or a subclass of HasTraits), with
20   attributes that use the traits you have defined.
21
22In practice, steps 2 and 3 are often combined by defining traits in-line
23in an attribute definition. This strategy is used in many examples in this
24guide. However, you can also define traits independently, and reuse the trait
25definitions across multiple classes and attributes (see
26:ref:`reusing-trait-definitions`).
27
28In order to use trait attributes in a class, the class must inherit from the
29HasTraits class in the Traits package (or from a subclass of HasTraits). The
30following example defines a class called Person that has a single trait
31attribute **weight**, which is initialized to 150.0 and can only take floating
32point values.
33
34.. index::
35   single: examples; minimal
36
37::
38
39    # minimal.py --- Minimal example of using traits.
40
41    from traits.api import HasTraits, Float
42
43    class Person(HasTraits):
44        weight = Float(150.0)
45
46.. index:: attribute definition
47
48In this example, the attribute named **weight** specifies that the class has a
49corresponding trait called **weight**. The value associated with the attribute
50**weight** (i.e., ``Float(150.0)``) specifies a predefined trait provided with
51the Traits package, which requires that values assigned be of the standard
52Python type **float**. The value 150.0 specifies the default value of the
53trait.
54
55The value associated with each class-level attribute determines the
56characteristics of the instance attribute identified by the attribute name.
57For example::
58
59    >>> from minimal import Person
60    >>> # instantiate the class
61    >>> joe = Person()
62    >>> # Show the default value
63    >>> joe.weight
64    150.0
65    >>> # Assign new values
66    >>> joe.weight = 161.9     # OK to assign a float
67    >>> joe.weight = 162       # OK to assign an int
68    >>> joe.weight = 'average' # Error to assign a string
69    Traceback (most recent call last):
70        ...
71    traits.trait_errors.TraitError: The 'weight' trait of a Person instance
72    must be a float, but a value of 'average' <type 'str'> was specified.
73
74In this example, **joe** is an instance of the Person class defined in the
75previous example. The **joe** object has an instance attribute **weight**,
76whose initial value is the default value of the Person.weight trait (150.0),
77and whose assignment is governed by the Person.weight trait's validation
78rules. Assigning an integer to **weight** is acceptable because there is no
79loss of precision (but assigning a float to an Int trait would cause an error).
80
81The Traits package allows creation of a wide variety of trait types, ranging
82from very simple to very sophisticated. The following section presents some of
83the simpler, more commonly used forms.
84
85.. warning:: Unless otherwise stated as safe to do so, avoid naming
86   attributes with the prefix 'trait' or '_trait'. This avoids overshadowing
87   existing methods on HasTraits.
88
89
90A note about the Traits package structure
91-----------------------------------------
92
93We described above how trait type definitions and the :class:`~.HasTraits`
94class can be imported from the ``traits.api`` module. For example::
95
96    from traits.api import Float, HasTraits, Int
97
98In fact, the :class:`HasTraits` class and various trait type classes are
99defined in other modules nested inside the Traits package structure, but
100they're re-imported to ``traits.api`` for user convenience. In general,
101everything you need should be available in either ``traits.api`` or one of the
102other ``*.api`` modules inside the package structure (for example,
103``traits.adaptation.api`` or ``traits.observation.api``). As a matter of best
104practices, you should import the things you need directly from one of these
105``*.api`` modules. If you discover that there's something that you need that's
106not available from one of these modules, please discuss with the Traits
107development team (for example, by opening an issue on the `Traits bug
108tracker`_).
109
110
111.. index:: predefined traits
112
113.. _predefined-traits:
114
115Predefined Traits
116-----------------
117The Traits package includes a large number of predefined traits for commonly
118used Python data types. In the simplest case, you can assign the trait name
119to an attribute of a class derived from HasTraits; any instances of the class
120will have that attribute initialized to the built-in default value for the
121trait. For example::
122
123    account_balance = Float
124
125This statement defines an attribute whose value must be a floating point
126number, and whose initial value is 0.0 (the built-in default value for Floats).
127
128If you want to use an initial value other than the built-in default, you can
129pass it as an argument to the trait::
130
131    account_balance = Float(10.0)
132
133Most predefined traits are callable, [2]_ and can accept a default value and
134possibly other arguments; all that are callable can also accept metadata as
135keyword arguments. (See :ref:`other-predefined-traits` for information on trait
136signatures, and see :ref:`trait-metadata` for information on metadata
137arguments.)
138
139.. index:: simple types
140
141.. _predefined-traits-for-simple-types:
142
143Predefined Traits for Simple Types
144``````````````````````````````````
145There are two categories of predefined traits corresponding to Python simple
146types: those that coerce values, and those that cast values. These categories
147vary in the way that they handle assigned values that do not match the type
148explicitly defined for the trait. However, they are similar in terms of the
149Python types they correspond to, and their built-in default values, as listed
150in the following table.
151
152.. index::
153   pair: types; casting
154   pair: types; coercing
155   pair: type; string
156.. index:: Boolean type, Bool trait, CBool trait, Complex trait, CComplex trait
157.. index:: Float trait, CFloat trait, Int trait, CInt trait
158.. index:: integer type, floating point number type, complex number type
159.. index:: Str trait, CStr trait, Bytes trait, CBytes trait
160
161.. _predefined-defaults-for-simple-types-table:
162
163.. rubric:: Predefined defaults for simple types
164
165============== ============= ====================== ======================
166Coercing Trait Casting Trait Python Type            Built-in Default Value
167============== ============= ====================== ======================
168Bool           CBool         Boolean                False
169Complex        CComplex      Complex number         0+0j
170Float          CFloat        Floating point number  0.0
171Int            CInt          Integer                0
172Str            CStr          String                 ''
173Bytes          CBytes        Bytes                  b''
174============== ============= ====================== ======================
175
176.. index::
177   pair: types; coercing
178
179.. _trait-type-coercion:
180
181Trait Type Coercion
182:::::::::::::::::::
183For trait attributes defined using the predefined "coercing"
184traits, if a value is assigned to a trait attribute that is not of the type
185defined for the trait, but it can be coerced to the required type, then the
186coerced value is assigned to the attribute. If the value cannot be coerced to
187the required type, a TraitError exception is raised. Only widening coercions
188are allowed, to avoid any possible loss of precision. The following table
189lists traits that coerce values, and the types that each coerces.
190
191.. index::
192   pair: types; coercing
193
194.. _type-coercions-permitted-for-coercing-traits-table:
195
196.. rubric:: Type coercions permitted for coercing traits
197
198============= ===========================================
199Trait         Coercible Types
200============= ===========================================
201Complex       Floating point number, integer
202Float         Integer
203============= ===========================================
204
205.. index::
206   pair: types; casting
207
208.. _trait-type-casting:
209
210Trait Type Casting
211::::::::::::::::::
212For trait attributes defined using the predefined "casting"
213traits, if a value is assigned to a trait attribute that is not of the type
214defined for the trait, but it can be cast to the required type, then the cast
215value is assigned to the attribute. If the value cannot be cast to the required
216type, a TraitError exception is raised. Internally, casting is done using the
217Python built-in functions for type conversion:
218
219* bool()
220* complex()
221* float()
222* int()
223* str()
224* bytes()
225
226.. index::
227   single: examples; coercing vs. casting
228
229The following example illustrates the difference between coercing traits and
230casting traits::
231
232    >>> from traits.api import HasTraits, Float, CFloat
233    >>> class Person ( HasTraits ):
234    ...    weight  = Float
235    ...    cweight = CFloat
236    ...
237    >>> bill = Person()
238    >>> bill.weight  = 180    # OK, coerced to 180.0
239    >>> bill.cweight = 180    # OK, cast to float(180)
240    >>> bill.weight  = '180'  # Error, invalid coercion
241    Traceback (most recent call last):
242        ...
243    traits.trait_errors.TraitError: The 'weight' trait of a Person instance
244    must be a float, but a value of '180' <type 'str'> was specified.
245    >>> bill.cweight = '180'  # OK, cast to float('180')
246    >>> print(bill.cweight)
247    180.0
248
249
250.. _other-predefined-traits:
251
252Other Predefined Traits
253```````````````````````
254The Traits package provides a number of other predefined traits besides those
255for simple types, corresponding to other commonly used data types; these
256predefined traits are listed in the following table. Refer to  the
257*Traits API Reference*, in the section for the module traits.traits,
258for details. Most can be used either as simple names, which use their built-in
259default values, or as callables, which can take additional arguments. If the
260trait cannot be used as a simple name, it is omitted from the Name column of
261the table.
262
263.. index:: Any(), Array(), Button(), Callable(), CArray(), Code()
264.. index:: CSet(), Constant(), Dict()
265.. index:: Directory(), Disallow, Either(), Enum()
266.. index:: Event(), Expression(), false, File()
267.. index:: Instance(), List(), Method(), Module()
268.. index:: Password(), Property(), Python()
269.. index:: PythonValue(), Range(), ReadOnly(), Regex()
270.. index:: Set() String(), This,
271.. index:: ToolbarButton(), true, Tuple(), Type()
272.. index:: undefined, UUID(), ValidatedTuple(), WeakRef()
273
274.. _predefined-traits-beyond-simple-types-table:
275
276.. rubric:: Predefined traits beyond simple types
277
278+------------------+----------------------------------------------------------+
279| Name             | Callable Signature                                       |
280+==================+==========================================================+
281| Any              | Any( [*default_value* = None, \*,                        |
282|                  | *factory* = None, *args* = (), *kw* = {},                |
283|                  | \*\*\ *metadata* )                                       |
284+------------------+----------------------------------------------------------+
285| Array            | Array( [*dtype* = None, *shape* = None, *value* = None,  |
286|                  | *typecode* = None, \*\*\ *metadata*] )                   |
287+------------------+----------------------------------------------------------+
288| ArrayOrNone      | ArrayOrNone( [*dtype* = None, *shape* = None,            |
289|                  | *value* = None, *typecode* = None, \*\*\ *metadata*] )   |
290+------------------+----------------------------------------------------------+
291| Button           | Button( [*label* = '', *image* = None, *style* =         |
292|                  | 'button', *orientation* = 'vertical', *width_padding* =  |
293|                  | 7, *height_padding* = 5, \*\*\ *metadata*] )             |
294+------------------+----------------------------------------------------------+
295| Callable         | Callable( [*value* = None, \*\*\ *metadata*] )           |
296+------------------+----------------------------------------------------------+
297| CArray           | CArray( [*dtype* = None, *shape* = None, *value* = None, |
298|                  | *typecode* = None, \*\*\ *metadata*] )                   |
299+------------------+----------------------------------------------------------+
300| Code             | Code( [*value* = '', *minlen* = 0,                       |
301|                  | *maxlen* = sys.maxsize, *regex* = '',                    |
302|                  | \*\*\ *metadata*] )                                      |
303+------------------+----------------------------------------------------------+
304| CSet             | CSet( [*trait* = None, *value* = None, *items* = True,   |
305|                  | \*\*\ *metadata*] )                                      |
306+------------------+----------------------------------------------------------+
307| Constant         | Constant( *value*\ [, \*\*\ *metadata*] )                |
308+------------------+----------------------------------------------------------+
309| Dict             | Dict( [*key_trait* = None, *value_trait* = None,         |
310|                  | *value* = None, *items* = True, \*\*\ *metadata*] )      |
311+------------------+----------------------------------------------------------+
312| Directory        | Directory( [*value* = '', *auto_set* = False, *entries* =|
313|                  | 10, *exists* = False, \*\*\ *metadata*] )                |
314+------------------+----------------------------------------------------------+
315| Disallow         | n/a                                                      |
316+------------------+----------------------------------------------------------+
317| Either           | Either( *val1*\ [, *val2*, ..., *valN*,                  |
318|                  | \*\*\ *metadata*] )                                      |
319+------------------+----------------------------------------------------------+
320| Enum             | Enum( *values*\ [, \*\*\ *metadata*] )                   |
321+------------------+----------------------------------------------------------+
322| Event            | Event( [*trait* = None, \*\*\ *metadata*] )              |
323+------------------+----------------------------------------------------------+
324| Expression       | Expression( [*value* = '0', \*\*\ *metadata*] )          |
325+------------------+----------------------------------------------------------+
326| File             | File( [*value* = '', *filter* = None, *auto_set* = False,|
327|                  | *entries* = 10, *exists* = False,  \*\*\ *metadata* ] )  |
328+------------------+----------------------------------------------------------+
329| Function [3]_    | Function( [*value* = None, \*\*\ *metadata*] )           |
330+------------------+----------------------------------------------------------+
331| generic_trait    | n/a                                                      |
332+------------------+----------------------------------------------------------+
333| HTML             | HTML( [*value* = '', *minlen* = 0,                       |
334|                  | *maxlen* = sys.maxsize, *regex* = '',                    |
335|                  | \*\*\ *metadata* ] )                                     |
336+------------------+----------------------------------------------------------+
337| Instance         | Instance( [*klass* = None, *factory* = None, *args* =    |
338|                  | None, *kw* = None, *allow_none* = True, *adapt* = None,  |
339|                  | *module* = None, \*\*\ *metadata*] )                     |
340+------------------+----------------------------------------------------------+
341| List             | List( [*trait* = None, *value* = None, *minlen* = 0,     |
342|                  | *maxlen* = sys.maxsize, *items* = True,                  |
343|                  | \*\*\ *metadata*] )                                      |
344+------------------+----------------------------------------------------------+
345| Map              | Map( *map*\ [, \*\*\ *metadata*] )                       |
346+------------------+----------------------------------------------------------+
347| Method [3]_      | Method ([\*\*\ *metadata*] )                             |
348+------------------+----------------------------------------------------------+
349| Module           | Module ( [\*\*\ *metadata*] )                            |
350+------------------+----------------------------------------------------------+
351| Password         | Password( [*value* = '', *minlen* = 0, *maxlen* =        |
352|                  | sys.maxsize, *regex* = '', \*\*\ *metadata*] )           |
353+------------------+----------------------------------------------------------+
354| PrefixList       | PrefixList( *values*\ [, \*\*\ *metadata*] )             |
355+------------------+----------------------------------------------------------+
356| PrefixMap        | PrefixMap( *map*\ [, \*\*\ *metadata*] )                 |
357+------------------+----------------------------------------------------------+
358| Property         | Property( [*fget* = None, *fset* = None, *fvalidate* =   |
359|                  | None, *force* = False, *handler* = None, *trait* = None, |
360|                  | \*\*\ *metadata*] )                                      |
361|                  |                                                          |
362|                  | See :ref:`property-traits`, for details.                 |
363+------------------+----------------------------------------------------------+
364| Python           | Python ( [*value* = None, \*\*\ *metadata*] )            |
365+------------------+----------------------------------------------------------+
366| PythonValue      | PythonValue( [*value* = None, \*\*\ *metadata*] )        |
367+------------------+----------------------------------------------------------+
368| Range            | Range( [*low* = None, *high* = None, *value* = None,     |
369|                  | *exclude_low* = False, *exclude_high* = False,           |
370|                  | \*\ *metadata*] )                                        |
371+------------------+----------------------------------------------------------+
372| ReadOnly         | ReadOnly( [*value* = Undefined, \*\*\ *metadata*] )      |
373+------------------+----------------------------------------------------------+
374| Regex            | Regex( [*value* = '', *regex* = '.\*', \*\*\ *metadata*])|
375+------------------+----------------------------------------------------------+
376| self             | n/a                                                      |
377+------------------+----------------------------------------------------------+
378| Set              | Set( [*trait* = None, *value* = None, *items* = True,    |
379|                  | \*\*\ *metadata*] )                                      |
380+------------------+----------------------------------------------------------+
381| String           | String( [*value* = '', *minlen* = 0, *maxlen* =          |
382|                  | sys.maxsize, *regex* = '', \*\*\ *metadata*] )           |
383+------------------+----------------------------------------------------------+
384| Subclass         | Subclass( [*value* = None, *klass* = None, *allow_none* =|
385|                  | True, \*\*\ *metadata*] )                                |
386+------------------+----------------------------------------------------------+
387| This             | n/a                                                      |
388+------------------+----------------------------------------------------------+
389| ToolbarButton    | ToolbarButton( [*label* = '', *image* = None, *style* =  |
390|                  | 'toolbar', *orientation* = 'vertical', *width_padding* = |
391|                  | 2, *height_padding* = 2, \*\*\ *metadata*] )             |
392+------------------+----------------------------------------------------------+
393| Tuple            | Tuple( [\*\ *traits*, \*\*\ *metadata*] )                |
394+------------------+----------------------------------------------------------+
395| Type             | Type( [*value* = None, *klass* = None, *allow_none* =    |
396|                  | True, \*\*\ *metadata*] )                                |
397+------------------+----------------------------------------------------------+
398| Union            | Union( *val1*\ [, *val2*, ..., *valN*,                   |
399|                  | \*\*\ *metadata*] )                                      |
400+------------------+----------------------------------------------------------+
401| UUID [4]_        | UUID( [\*\*\ *metadata*] )                               |
402+------------------+----------------------------------------------------------+
403| ValidatedTuple   | ValidatedTuple( [\*\ *traits*, *fvalidate* = None,       |
404|                  | *fvalidate_info* = '' , \*\*\ *metadata*] )              |
405+------------------+----------------------------------------------------------+
406| WeakRef          | WeakRef( [*klass* = 'traits.HasTraits',                  |
407|                  | *allow_none* = False, *adapt* = 'yes', \*\*\ *metadata*])|
408+------------------+----------------------------------------------------------+
409
410.. index:: Instance trait
411
412.. _instance:
413
414Instance
415::::::::
416One of the most fundamental and useful predefined trait types is
417:class:`~.Instance`. Instance trait values are an instance of a particular class
418or its subclasses, as specified by the **klass** argument. **klass** can be
419either an instance of a class or a class itself (note this applies to all python
420classes, not necessarily just :class:`~.HasTraits` subclasses).  However, one should
421typically provide the type or interface they want an instance of, instead of
422providing an instance of a class.
423
424If **klass** is an instance or if it is a class and **args** and **kw** are not
425specified, the default value is ``None``. Otherwise, the default value is
426obtained by calling the callable **factory** argument (or **klass** if
427**factory** is None) with **args** and **kw**. Further, there is the
428**allow_none** argument which dictates whether the trait can take on a value of
429``None``. However, this does not include the default value for the trait. For
430example::
431
432    # instance_trait_defaults.py --- Example of Instance trait default values
433    from traits.api import HasTraits, Instance
434
435    class Parent(HasTraits):
436        pass
437
438    class Child(HasTraits):
439        # default value is None
440        father = Instance(Parent)
441        # default value is still None, but None can not be assigned
442        grandfather = Instance(Parent, allow_none=False)
443        # default value is Parent()
444        mother = Instance(Parent, args=())
445
446In the last case, the default ``Parent`` instance is not immediately
447created, but rather is lazily instantiated when the trait is first accessed.
448The default ``Parent`` will also be instantiated if the trait is assigned to
449and there is a change handler defined on the trait (to detect changes from the
450default value). For more details on change handlers and trait notification see
451:ref:`observe-notification`.
452
453Somewhat surprisingly, ``mother = Instance(Parent, ())`` will also yield a
454default value of ``Parent()``, even though in that case it is **factory** that
455is ``()`` not **args**.  This is a result of implementation details, however
456the recommended way of writing this code is to explicitly pass **args** by
457keyword like so ``mother = Instance(Parent, args=())``. Another common mistake
458is passing in another trait type to Instance. For example,
459``some_trait = Instance(Int)``. This will likely lead to unexpected behavior
460and potential errors. Instead simply do ``some_trait = Int()``.
461
462.. index:: This trait, self trait
463
464.. _this-and-self:
465
466This and self
467:::::::::::::
468A couple of predefined traits that merit special explanation are This and
469**self**. They are intended for attributes whose values must be of the same
470class (or a subclass) as the enclosing class. The default value of This is
471None; the default value of **self** is the object containing the attribute.
472
473.. index::
474   pair: This trait; examples
475
476The following is an example of using This::
477
478    # this.py --- Example of This predefined trait
479
480    from traits.api import HasTraits, This
481
482    class Employee(HasTraits):
483        manager = This
484
485This example defines an Employee class, which has a **manager** trait
486attribute, which accepts only other Employee instances as its value. It might
487be more intuitive to write the following::
488
489    # bad_self_ref.py --- Non-working example with self- referencing
490    #                     class definition
491    from traits.api import HasTraits, Instance
492    class Employee(HasTraits):
493        manager = Instance(Employee)
494
495However, the Employee class is not fully defined at the time that the
496**manager** attribute is defined. Handling this common design pattern is the
497main reason for providing the This trait.
498
499Note that if a trait attribute is defined using This on one class and is
500referenced on an instance of a subclass, the This trait verifies values based
501on the class on which it was defined. For example::
502
503    >>> from traits.api import HasTraits, This
504    >>> class Employee(HasTraits):
505    ...    manager = This
506    ...
507    >>> class Executive(Employee):
508    ...  pass
509    ...
510    >>> fred = Employee()
511    >>> mary = Executive()
512    >>> # The following is OK, because fred's manager can be an
513    >>> # instance of Employee or any subclass.
514    >>> fred.manager = mary
515    >>> # This is also OK, because mary's manager can be an Employee
516    >>> mary.manager = fred
517
518.. index:: Map trait
519
520.. _map:
521
522Map
523:::
524The map trait ensures that the value assigned to a trait attribute
525is a key of a specified dictionary, and also assigns the dictionary
526value corresponding to that key to a shadow attribute.
527
528.. index::
529   pair: Map trait; examples
530
531The following is an example of using Map::
532
533    # map.py --- Example of Map predefined trait
534
535    from traits.api import HasTraits, Map
536
537    class Person(HasTraits):
538        married = Map({'yes': 1, 'no': 0 }, default_value="yes")
539
540This example defines a Person class which has a **married** trait
541attribute which accepts values "yes" and "no". The default value
542is set to "yes". The name of the shadow attribute is the name of
543the Map attribute followed by an underscore, i.e ``married_``
544Instantiating the class produces the following::
545
546    >>> from traits.api import HasTraits, Map
547    >>> bob = Person()
548    >>> print(bob.married)
549    yes
550    >>> print(bob.married_)
551    1
552
553.. index:: PrefixMap trait
554
555.. _prefixmap:
556
557PrefixMap
558:::::::::
559Like Map, PrefixMap is created using a dictionary, but in this
560case, the keys of the dictionary must be strings. Like PrefixList,
561a string *v* is a valid value for the trait attribute if it is a prefix of
562one and only one key *k* in the dictionary. The actual values assigned to
563the trait attribute is *k*, and its corresponding mapped attribute is map[*k*].
564
565.. index::
566   pair: PrefixMap trait; examples
567
568The following is an example of using PrefixMap::
569
570    # prefixmap.py --- Example of PrefixMap predefined trait
571
572    from traits.api import HasTraits, PrefixMap
573
574    class Person(HasTraits):
575        married = PrefixMap({'yes': 1, 'no': 0 }, default_value="yes")
576
577This example defines a Person class which has a **married** trait
578attribute which accepts values "yes" and "no" or any unique
579prefix. The default value is set to "yes". The name of the shadow attribute
580is the name of the PrefixMap attribute followed by an underscore, i.e ``married_``
581Instantiating the class produces the following::
582
583    >>> bob = Person()
584    >>> print(bob.married)
585    yes
586    >>> print(bob.married_)
587    1
588    >>> bob.married = "n" # Setting a prefix
589    >>> print(bob.married)
590    no
591    >>> print(bob.married_)
592    0
593
594.. index:: PrefixList trait
595
596.. _prefixlist:
597
598PrefixList
599::::::::::
600Ensures that a value assigned to the attribute is a member of a list of
601specified string values, or is a unique prefix of one of those values.
602The values that can be assigned to a trait attribute of type PrefixList
603is the set of all strings supplied to the PrefixList constructor, as well
604as any unique prefix of those strings. The actual value assigned to the
605trait is limited to the set of complete strings assigned to the
606PrefixList constructor.
607
608.. index::
609   pair: PrefixList trait; examples
610
611The following is an example of using PrefixList::
612
613    # prefixlist.py --- Example of PrefixList predefined trait
614
615    from traits.api import HasTraits, PrefixList
616
617    class Person(HasTraits):
618        married = PrefixList(["yes", "no"])
619
620This example defines a Person class which has a **married** trait
621attribute which accepts values "yes" and "no" or any unique
622prefix. Instantiating the class produces the following::
623
624    >>> bob = Person()
625    >>> print(bob.married)
626    yes
627    >>> bob.married = "n" # Setting a prefix
628    >>> print(bob.married)
629    no
630
631.. index:: Either trait
632
633.. _either:
634
635Either
636::::::
637Another predefined trait that merits special explanation is Either. The
638Either trait is intended for attributes that may take a value of more than
639a single trait type, including None. The default value of Either is None, even
640if None is not one of the types the user explicitly defines in the constructor,
641but a different default value can be provided using the ``default`` argument.
642
643.. index::
644   pair: Either trait; examples
645
646The following is an example of using Either::
647
648    # either.py --- Example of Either predefined trait
649
650    from traits.api import HasTraits, Either, Str
651
652    class Employee(HasTraits):
653        manager_name = Either(Str, None)
654
655This example defines an Employee class, which has a **manager_name** trait
656attribute, which accepts either an Str instance or None as its value, and
657will raise a TraitError if a value of any other type is assigned. For example::
658
659    >>> from traits.api import HasTraits, Either, Str
660    >>> class Employee(HasTraits):
661    ...     manager_name = Either(Str, None)
662    ...
663    >>> steven = Employee(manager_name="Jenni")
664    >>> # Here steven's manager is named "Jenni"
665    >>> steven.manager_name
666    'Jenni'
667    >>> eric = Employee(manager_name=None)
668    >>> # Eric is the boss, so he has no manager.
669    >>> eric.manager_name is None
670    True
671    >>> # Assigning a value that is neither a string nor None will fail.
672    >>> steven.manager_name = 5
673    traits.trait_errors.TraitError: The 'manager_name' trait of an Employee instance must be a string or None, but a value of 5 <type 'int'> was specified.
674
675.. index:: Union trait
676
677.. _union:
678
679Union
680::::::
681The Union trait accepts a value that is considered valid by at least one
682of the traits in its definition. It is a simpler and therefore less error-prone
683alternative to the `Either` trait, which allows more complex constructs and
684may sometimes exhibit mysterious validation behaviour. The Union trait however,
685validates the value assigned to it against each of the traits in its definition
686in the order they are defined. Union only accepts trait types or trait type
687instances or None in its definition. Prefer to use Union over `Either` to
688remain future proof.
689
690.. index::
691   pair: Union trait; examples
692
693The following is an example of using Union::
694
695    # union.py --- Example of Union predefined trait
696
697    from traits.api import HasTraits, Union, Int, Float, Instance
698
699    class Salary(HasTraits):
700        basic = Float
701        bonus = Float
702
703    class Employee(HasTraits):
704        manager_name = Union(Str, None)
705        pay = Union(Instance(Salary), Float)
706
707This example defines an Employee class, which has a **manager_name** trait
708attribute, which accepts either an Str instance or None as its value, a
709**salary** trait that accepts an instance of Salary or Float and will raise a
710TraitError if a value of any other type is assigned. For example::
711
712    >>> from traits.api import HasTraits, Either, Str
713    >>> class Employee(HasTraits):
714    ...     manager_name = Union(Str, None)
715    ...
716    >>> steven = Employee(manager_name="Jenni")
717    >>> # Here steven's manager is named "Jenni"
718    >>> # Assigning a value that is neither a string nor None will fail.
719    >>> steven.manager_name = 5
720    traits.trait_errors.TraitError: The 'manager_name' trait of an Employee instance must be a string or a None type, but a value of 5 <class 'int'> was specified.
721
722The following example illustrates the difference between `Either` and `Union`::
723
724    >>> from traits.api import HasTraits, Either, Union, Str
725    >>> class IntegerClass(HasTraits):
726    ...     primes = Either([2], None, {'3':6}, 5, 7, 11)
727    ...
728    >>> i = IntegerClass(primes=2) # Acceptable value, no error
729    >>> i = IntegerClass(primes=4)
730    traits.trait_errors.TraitError: The 'primes' trait of an IntegerClass instance must be 2 or None or 5 or 7 or 11 or '3', but a value of 4 <class 'int'> was specified.
731    >>>
732    >>> # But Union does not allow such declarations.
733    >>> class IntegerClass(HasTraits):
734    ...     primes = Union([2], None, {'3':6}, 5, 7, 11)
735    ValueError: Union trait declaration expects a trait type or an instance of trait type or None, but got [2] instead
736
737
738.. _migration_either_to_union:
739
740.. rubric:: Migration from Either to Union
741
742* Static default values are defined on Union via the **default_value**
743  attribute, whereas Either uses the **default** attribute. The naming of
744  **default_value** is consistent with other trait types.
745  For example::
746
747      Either(None, Str(), default="unknown")
748
749  would be changed to::
750
751      Union(None, Str(), default_value="unknown")
752
753* If a default value is not defined, Union uses the default value from the
754  first trait in its definition, whereas Either uses None.
755
756  For example::
757
758      Either(Int(), Float())
759
760  has a default value of None. However None is not one of the allowed values.
761  If the trait is later set to None from a non-None value, a validation error
762  will occur.
763
764  If the trait definition is changed to::
765
766      Union(Int(), Float())
767
768  Then the default value will be 0, which is the default value of the first
769  trait.
770
771  To keep None as the default, use None as the first item::
772
773      Union(None, Int(), Float())
774
775  With this, None also becomes one of the allowed values.
776
777.. index:: multiple values, defining trait with
778
779.. _list-of-possibl-values:
780
781List of Possible Values
782:::::::::::::::::::::::
783You can define a trait whose possible values include disparate types. To do
784this, use the predefined Enum trait, and pass it a list of all possible values.
785The values must all be of simple Python data types, such as strings, integers,
786and floats, but they do not have to be all of the same type. This list of
787values can be a typical parameter list, an explicit (bracketed) list, or a
788variable whose type is list. The first item in the list is used as the default
789value.
790
791.. index:: examples; list of values
792
793A trait defined in this fashion can accept only values that are contained in
794the list of permitted values. The default value is the first value specified;
795it is also a valid value for assignment.
796::
797
798    >>> from traits.api import Enum, HasTraits, Str
799    >>> class InventoryItem(HasTraits):
800    ...    name  = Str # String value, default is ''
801    ...    stock = Enum(None, 0, 1, 2, 3, 'many')
802    ...            # Enumerated list, default value is
803    ...            #'None'
804    ...
805    >>> hats = InventoryItem()
806    >>> hats.name = 'Stetson'
807
808    >>> print('%s: %s' % (hats.name, hats.stock))
809    Stetson: None
810
811    >>> hats.stock = 2      # OK
812    >>> hats.stock = 'many' # OK
813    >>> hats.stock = 4      # Error, value is not in \
814    >>>                     # permitted list
815    Traceback (most recent call last):
816        ...
817    traits.trait_errors.TraitError: The 'stock' trait of an InventoryItem
818    instance must be None or 0 or 1 or 2 or 3 or 'many', but a value of 4
819    <type 'int'> was specified.
820
821
822This defines an :py:class:`InventoryItem` class, with two trait attributes,
823**name**, and **stock**. The name attribute is simply a string. The **stock**
824attribute has an initial value of None, and can be assigned the values None, 0,
8251, 2, 3, and 'many'. The example then creates an instance of the InventoryItem
826class named **hats**, and assigns values to its attributes.
827
828When the list of possible values can change during the lifetime of the object,
829one can specify **another trait** that holds the list of possible values::
830
831    >>> from traits.api import Enum, HasTraits, List
832    >>> class InventoryItem(HasTraits):
833    ...    possible_stock_states = List([None, 0, 1, 2, 3, 'many'])
834    ...    stock = Enum(0, values="possible_stock_states")
835    ...            # Enumerated list, default value is 0. The list of
836    ...            # allowed values is whatever possible_stock_states holds
837    ...
838
839    >>> hats = InventoryItem()
840    >>> hats.stock
841    0
842    >>> hats.stock = 2      # OK
843    >>> hats.stock = 4      # TraitError like above
844    Traceback (most recent call last):
845        ...
846    traits.trait_errors.TraitError: The 'stock' trait of an InventoryItem
847    instance must be None or 0 or 1 or 2 or 3 or 'many', but a value of 4
848    <type 'int'> was specified.
849
850    >>> hats.possible_stock_states.append(4)  # Add 4 to list of allowed values
851    >>> hats.stock = 4      # OK
852
853
854.. index:: metadata attributes; on traits
855
856.. _trait-metadata:
857
858Trait Metadata
859--------------
860Trait objects can contain metadata attributes, which fall into three categories:
861
862* Internal attributes, which you can query but not set.
863* Recognized attributes, which you can set to determine the behavior of the
864  trait.
865* Arbitrary attributes, which you can use for your own purposes.
866
867You can specify values for recognized or arbitrary metadata attributes by
868passing them as keyword arguments to callable traits. The value of each
869keyword argument becomes bound to the resulting trait object as the value
870of an attribute having the same name as the keyword.
871
872.. index:: metadata attributes; internal
873
874.. _internal-metadata-attributes:
875
876Internal Metadata Attributes
877````````````````````````````
878The following metadata attributes are used internally by the Traits package,
879and can be queried:
880
881.. index:: array metadata attribute, default metadata attribute
882.. index:: default_kind metadata attribute, delegate; metadata attribute
883.. index:: inner_traits metadata attribute, parent metadata attribute
884.. index:: prefix metadata attribute, trait_type metadata attribute
885.. index:: type metadata attribute
886
887* **array**: Indicates whether the trait is an array.
888* **default**: Returns the default value for the trait, if known; otherwise it
889  returns Undefined.
890* **default_kind**: Returns a string describing the type of value returned by
891  the default attribute for the trait. The possible values are:
892
893  * ``value``: The default attribute returns the actual default value.
894  * ``list``: A copy of the list default value.
895  * ``dict``: A copy of the dictionary default value.
896  * ``self``: The default value is the object the trait is bound to; the
897    **default** attribute returns Undefined.
898  * ``factory``: The default value is created by calling a factory; the
899    **default** attribute returns Undefined.
900  * ``method``: The default value is created by calling a method on the object
901    the trait is bound to; the **default** attribute returns Undefined.
902
903* **delegate**: The name of the attribute on this object that references the
904  object that this object delegates to.
905* **inner_traits**: Returns a tuple containing the "inner" traits
906  for the trait. For most traits, this is empty, but for List and Dict traits,
907  it contains the traits that define the items in the list or the keys and
908  values in the dictionary.
909* **parent**: The trait from which this one is derived.
910* **prefix**: A prefix or substitution applied to the delegate attribute.
911  See :ref:`deferring-traits` for details.
912* **trait_type**: Returns the type of the trait, which is typically a handler
913  derived from TraitType.
914* **type**: One of the following, depending on the nature of the trait:
915
916  * ``constant``
917  * ``delegate``
918  * ``event``
919  * ``property``
920  * ``trait``
921
922.. index:: recognized metadata attributes, metadata attributes; recognized
923
924.. _recognized-metadata-attributes:
925
926Recognized Metadata Attributes
927``````````````````````````````
928The following metadata attributes are not predefined, but are recognized by
929HasTraits objects:
930
931.. index:: desc metadata attribute, editor metadata attribute
932.. index:: label; metadata attribute, comparison_mode metadata attribute
933.. index:: transient metadata attribute
934
935* **desc**: A string describing the intended meaning of the trait. It is used
936  in exception messages and fly-over help in user interface trait editors.
937* **editor**: Specifies an instance of a subclass of TraitEditor to use when
938  creating a user interface editor for the trait. Refer to the
939  `TraitsUI User Manual
940  <http://docs.enthought.com/traitsui/traitsui_user_manual/index.html>`_
941  for more information on trait editors.
942* **label**: A string providing a human-readable name for the trait. It is
943  used to label trait attribute values in user interface trait editors.
944* **comparison_mode**: Indicates when trait change notifications should be
945  generated based upon the result of comparing the old and new values of a
946  trait assignment. This should be a member of the
947  :class:`~traits.constants.ComparisonMode` enumeration class.
948* **transient**: A Boolean indicating that the trait value is not persisted
949  when the object containing it is persisted. The default value for most
950  predefined traits is False (the value will be persisted if its container is).
951  You can set it to True for traits whose values you know you do not want to
952  persist. Do not set it to True on traits where it is set internally to
953  False, as doing so is likely to create unintended consequences. See
954  :ref:`persistence` for more information.
955
956Other metadata attributes may be recognized by specific predefined traits.
957
958.. index:: metadata attributes; accessing
959
960.. _accessing-metadata-attributes:
961
962Accessing Metadata Attributes
963`````````````````````````````
964.. index::
965   pair: examples; metadata attributes
966
967Here is an example of setting trait metadata using keyword arguments::
968
969    # keywords.py --- Example of trait keywords
970    from traits.api import HasTraits, Str
971
972    class Person(HasTraits):
973        first_name = Str('',
974                         desc='first or personal name',
975                         label='First Name')
976        last_name =  Str('',
977                         desc='last or family name',
978                         label='Last Name')
979
980In this example, in a user interface editor for a Person object, the labels
981"First Name" and "Last Name" would be used for entry
982fields corresponding to the **first_name** and **last_name** trait attributes.
983If the user interface editor supports rollover tips, then the **first_name**
984field would display "first or personal name" when the user moves
985the mouse over it; the last_name field would display "last or family
986name" when moused over.
987
988To get the value of a trait metadata attribute, you can use the trait() method
989on a HasTraits object to get a reference to a specific trait, and then access
990the metadata attribute::
991
992    # metadata.py --- Example of accessing trait metadata attributes
993    from traits.api import HasTraits, Int, List, Float, Str, \
994                                     Instance, Any, TraitType
995
996    class Foo( HasTraits ): pass
997
998    class Test( HasTraits ):
999        i = Int(99)
1000        lf = List(Float)
1001        foo = Instance( Foo, () )
1002        any = Any( "123" )
1003
1004    t = Test()
1005
1006    print(t.trait( 'i' ).default)                      # 99
1007    print(t.trait( 'i' ).default_kind)                 # value
1008    print(t.trait( 'i' ).inner_traits)                 # ()
1009    print(t.trait( 'i' ).is_trait_type( Int ))         # True
1010    print(t.trait( 'i' ).is_trait_type( Float ))       # False
1011
1012    print(t.trait( 'lf' ).default)                     # []
1013    print(t.trait( 'lf' ).default_kind)                # list
1014    print(t.trait( 'lf' ).inner_traits)
1015             # (<traits.traits.CTrait object at 0x01B24138>,)
1016    print(t.trait( 'lf' ).is_trait_type( List ))       # True
1017    print(t.trait( 'lf' ).is_trait_type( TraitType ))  # True
1018    print(t.trait( 'lf' ).is_trait_type( Float ))      # False
1019    print(t.trait( 'lf' ).inner_traits[0].is_trait_type( Float )) # True
1020
1021    print(t.trait( 'foo' ).default)                    # <undefined>
1022    print(t.trait( 'foo' ).default_kind)               # factory
1023    print(t.trait( 'foo' ).inner_traits)               # ()
1024    print(t.trait( 'foo' ).is_trait_type( Instance ))  # True
1025    print(t.trait( 'foo' ).is_trait_type( List  ))     # False
1026
1027    print(t.trait( 'any' ).default)                    # 123
1028    print(t.trait( 'any' ).default_kind)               # value
1029    print(t.trait( 'any' ).inner_traits)               # ()
1030    print(t.trait( 'any' ).is_trait_type( Any ))       # True
1031    print(t.trait( 'any' ).is_trait_type( Str ))       # False
1032
1033.. rubric:: Footnotes
1034.. [2] Most callable predefined traits are classes, but a few are functions.
1035       The distinction does not make a difference unless you are trying to
1036       extend an existing predefined trait. See the *Traits API Reference* for
1037       details on particular traits, and see Chapter 5 for details on extending
1038       existing traits.
1039.. [3] The Function and Method trait types are now deprecated. See |Function|,
1040       |Method|
1041.. [4] Available in Python 2.5.
1042
1043..
1044   external urls
1045
1046.. _Traits bug tracker: https://github.com/enthought/traits/issues
1047
1048..
1049   # substitutions
1050
1051.. |Function| replace:: :class:`~traits.trait_types.Function`
1052.. |Method| replace:: :class:`~traits.trait_types.Method`
1053