0
# Core Trait System
1
2
The foundational trait system providing HasTraits base class, TraitType descriptors, and change notification mechanisms. This forms the core of traitlets' typed attribute functionality with validation, metadata, and observer patterns.
3
4
## Capabilities
5
6
### HasTraits Base Class
7
8
The main base class that provides trait functionality to objects. Any class inheriting from HasTraits can use trait descriptors and benefit from change notifications, validation, and metadata features.
9
10
```python { .api }
11
class HasTraits:
12
"""
13
Base class for objects with traits.
14
15
Provides trait functionality including initialization, observation,
16
and metadata access for trait attributes.
17
"""
18
19
def __init__(self, **kwargs):
20
"""
21
Initialize with trait values from kwargs.
22
23
Parameters:
24
- **kwargs: Trait name-value pairs for initialization
25
"""
26
27
def observe(self, handler, names=All, type='change'):
28
"""
29
Setup dynamic trait change handler.
30
31
Parameters:
32
- handler: callable(change) - Function to call on trait changes
33
- names: str|list - Trait names to observe or All for all traits
34
- type: str - Type of change to observe ('change', etc.)
35
"""
36
37
def unobserve(self, handler, names=All, type='change'):
38
"""
39
Remove trait change handler.
40
41
Parameters:
42
- handler: callable - Handler function to remove
43
- names: str|list - Trait names or All
44
- type: str - Type of change handler
45
"""
46
47
def unobserve_all(self, name=All):
48
"""
49
Remove all handlers for given trait name.
50
51
Parameters:
52
- name: str - Trait name or All for all traits
53
"""
54
55
def on_trait_change(self, handler, name=None, remove=False):
56
"""
57
Deprecated observer method.
58
59
Parameters:
60
- handler: callable - Handler function
61
- name: str - Trait name
62
- remove: bool - Whether to remove handler
63
"""
64
65
def add_traits(self, **traits):
66
"""
67
Dynamically add trait attributes to instance.
68
69
Parameters:
70
- **traits: TraitType instances to add as attributes
71
"""
72
73
def set_trait(self, name, value):
74
"""
75
Forcibly set trait value, bypassing read-only restrictions.
76
77
Parameters:
78
- name: str - Trait name
79
- value: any - Value to set
80
"""
81
82
def has_trait(self, name):
83
"""
84
Check if object has trait with given name.
85
86
Parameters:
87
- name: str - Trait name
88
89
Returns:
90
bool - True if trait exists
91
"""
92
93
def traits(self, **metadata):
94
"""
95
Get dict of all traits matching metadata filter.
96
97
Parameters:
98
- **metadata: Metadata key-value pairs to filter by
99
100
Returns:
101
dict - {trait_name: TraitType} mapping
102
"""
103
104
def trait_names(self, **metadata):
105
"""
106
Get list of trait names matching metadata filter.
107
108
Parameters:
109
- **metadata: Metadata key-value pairs to filter by
110
111
Returns:
112
list - List of trait names
113
"""
114
115
def trait_metadata(self, traitname, key, default=None):
116
"""
117
Get metadata value for specific trait.
118
119
Parameters:
120
- traitname: str - Name of trait
121
- key: str - Metadata key
122
- default: any - Default value if key not found
123
124
Returns:
125
any - Metadata value
126
"""
127
128
def hold_trait_notifications(self):
129
"""
130
Context manager to bundle trait notifications.
131
132
Returns:
133
context manager - Bundles notifications until exit
134
"""
135
136
@classmethod
137
def class_traits(cls, **metadata):
138
"""
139
Get dict of class traits matching metadata filter.
140
141
Parameters:
142
- **metadata: Metadata key-value pairs to filter by
143
144
Returns:
145
dict - {trait_name: TraitType} mapping
146
"""
147
148
@classmethod
149
def class_trait_names(cls, **metadata):
150
"""
151
Get list of class trait names matching metadata filter.
152
153
Parameters:
154
- **metadata: Metadata key-value pairs to filter by
155
156
Returns:
157
list - List of trait names
158
"""
159
160
@classmethod
161
def class_own_traits(cls, **metadata):
162
"""
163
Get traits defined on this class only (not inherited).
164
165
Parameters:
166
- **metadata: Metadata key-value pairs to filter by
167
168
Returns:
169
dict - {trait_name: TraitType} mapping
170
"""
171
172
@classmethod
173
def trait_events(cls, name=None):
174
"""
175
Get event handlers for trait.
176
177
Parameters:
178
- name: str - Trait name or None for all
179
180
Returns:
181
dict - Event handler mapping
182
"""
183
```
184
185
### TraitType Base Descriptor
186
187
The base class for all trait types, providing validation, metadata, and descriptor functionality. All specific trait types inherit from TraitType.
188
189
```python { .api }
190
class TraitType:
191
"""
192
Base class for all trait types.
193
194
Provides validation, metadata, defaults, and descriptor protocol
195
implementation for typed attributes.
196
"""
197
198
def __init__(self, default_value=Undefined, allow_none=False, read_only=None, help=None, config=None, **kwargs):
199
"""
200
Initialize trait type.
201
202
Parameters:
203
- default_value: any - Default value or Undefined
204
- allow_none: bool - Whether None is allowed as value
205
- read_only: bool - Whether trait is read-only after set
206
- help: str - Help text description
207
- config: bool - Whether trait is configurable
208
- **kwargs: Additional metadata
209
"""
210
211
def tag(self, **metadata):
212
"""
213
Set metadata and return self for chaining.
214
215
Parameters:
216
- **metadata: Metadata key-value pairs
217
218
Returns:
219
TraitType - Self for method chaining
220
"""
221
222
def validate(self, obj, value):
223
"""
224
Validate a value for this trait type.
225
Override in subclasses for specific validation.
226
227
Parameters:
228
- obj: HasTraits - Object containing the trait
229
- value: any - Value to validate
230
231
Returns:
232
any - Validated/coerced value
233
234
Raises:
235
TraitError - If validation fails
236
"""
237
238
def error(self, obj, value):
239
"""
240
Raise TraitError with appropriate message.
241
242
Parameters:
243
- obj: HasTraits - Object containing the trait
244
- value: any - Invalid value
245
246
Raises:
247
TraitError - Always raised with descriptive message
248
"""
249
250
def info(self):
251
"""
252
Return description string for this trait type.
253
254
Returns:
255
str - Human-readable description
256
"""
257
258
def get_metadata(self, key, default=None):
259
"""
260
Get metadata value (deprecated, use .metadata dict).
261
262
Parameters:
263
- key: str - Metadata key
264
- default: any - Default if key not found
265
266
Returns:
267
any - Metadata value
268
"""
269
270
def set_metadata(self, key, value):
271
"""
272
Set metadata value (deprecated, use .metadata dict).
273
274
Parameters:
275
- key: str - Metadata key
276
- value: any - Metadata value
277
"""
278
279
def default_value_repr(self):
280
"""
281
Return representation of default value.
282
283
Returns:
284
str - String representation of default
285
"""
286
```
287
288
### Base Descriptor Classes
289
290
Foundation descriptor classes that TraitType builds upon.
291
292
```python { .api }
293
class BaseDescriptor:
294
"""
295
Base class for all descriptors in traitlets.
296
297
Provides the foundation for trait descriptors with
298
class and instance initialization hooks.
299
"""
300
301
def class_init(self, cls, name):
302
"""
303
Part of initialization depending on HasDescriptors class.
304
305
Parameters:
306
- cls: type - Class that declared the trait
307
- name: str - Name of the attribute
308
"""
309
310
def instance_init(self, obj):
311
"""
312
Part of initialization depending on HasDescriptors instance.
313
314
Parameters:
315
- obj: HasDescriptors - Instance being initialized
316
"""
317
318
class HasDescriptors:
319
"""
320
Base class for all classes that have descriptors.
321
322
Provides setup_instance method for descriptor initialization.
323
"""
324
325
def setup_instance(self, *args, **kwargs):
326
"""
327
Called before __init__ to setup descriptors.
328
329
Parameters:
330
- *args: Positional arguments
331
- **kwargs: Keyword arguments
332
"""
333
```
334
335
### Metaclasses
336
337
Metaclasses that enable the trait system's functionality.
338
339
```python { .api }
340
class MetaHasDescriptors(type):
341
"""
342
Metaclass for HasDescriptors that instantiates TraitType class attributes.
343
344
Automatically calls class_init on TraitType descriptors and
345
manages descriptor setup at class creation time.
346
"""
347
348
class MetaHasTraits(MetaHasDescriptors):
349
"""
350
Metaclass for HasTraits, extends MetaHasDescriptors.
351
352
Provides additional trait-specific metaclass functionality.
353
"""
354
```
355
356
## Usage Examples
357
358
### Basic HasTraits Usage
359
360
```python
361
from traitlets import HasTraits, Unicode, Int
362
363
class Person(HasTraits):
364
name = Unicode()
365
age = Int(min=0)
366
367
person = Person(name="Alice", age=30)
368
print(person.name) # "Alice"
369
print(person.age) # 30
370
371
# Access trait metadata
372
traits = person.traits()
373
trait_names = person.trait_names()
374
```
375
376
### Custom Trait Type
377
378
```python
379
from traitlets import TraitType, TraitError
380
381
class PositiveInt(TraitType):
382
info_text = 'a positive integer'
383
384
def validate(self, obj, value):
385
if isinstance(value, int) and value > 0:
386
return value
387
self.error(obj, value)
388
389
class MyClass(HasTraits):
390
count = PositiveInt()
391
392
obj = MyClass(count=5) # Valid
393
# obj.count = -1 # Would raise TraitError
394
```
395
396
### Trait Metadata
397
398
```python
399
class Example(HasTraits):
400
value = Int(help="An important value").tag(category="core", units="meters")
401
402
example = Example()
403
metadata = example.trait_metadata('value', 'category') # "core"
404
help_text = example.trait_metadata('value', 'help') # "An important value"
405
```