Traitlite¶
Traitlite is a package which provides simple descriptors which you can use as class attributes to provide functionality such as type checking, variable validation, callbacks, making a variable read-only, etc. It does not require you to subclass anything in order to start using it.
Basic Example¶
In order to use a trait, simply define it as a class attribute for your variable.
from traitlite import TypeChecked
class Foo:
bar = TypeChecked(int)
def __init__(self, bar):
self.bar = bar
Foo(3) # Is fine
Foo(3.0) # Raises exception
Accessing your variable is done just like with any normal variable.
foo = Foo(3)
print(foo.bar) # 3
To get the actual traitlite instance, access the class attribute (capital F in Foo).
print(Foo.bar) # <traitlite.traits.TypeChecked object at 0x10f1334a8>
To use different properties at the same time, simply add the traits to your variable.
from traitlite import ReadOnly, TypeChecked
class Foo:
bar = TypeChecked(int) + ReadOnly()
def __init__(self, bar):
self.bar = bar
Foo(3.0) # Raises exception
foo = Foo(3) # Okay
foo.b = 2 # Raises exception because of read-only
Traits Documentation¶
-
class
traitlite.
ReadOnly
¶ A trait which makes an attribute read-only after it has been set for the first time.
from traitlite import ReadOnly class Foo: bar = ReadOnly() def __init__(self, bar): self.bar = bar # Setting it the first time is allowed foo = Foo(3) foo.bar = 4 # This raises an exception
-
class
traitlite.
TypeChecked
(type_: Type[object])¶ A trait which performs a type check whenever the attribute is given a new value.
from traitlite import TypeChecked class Foo: bar = TypeChecked(int) def __init__(self, bar): self.bar = bar foo = Foo(3) # This is okay foo = Foo(3.0) # This raises an exception
-
class
traitlite.
HasCallback
(callbacks: Optional[List[Callable[Value, None]]] = None)¶ A trait which introduces callbacks which are called after the given attribute has been given a new value. The callbacks are callable objects which take the new value as an argument.
from traitlite import HasCallback class Foo: bar = HasCallback() def print_value(value): print('New value is:', value) foo = Foo() # We have to use the class here instead of the instance, and the # instance is passed as the first argument. Foo.bar.add_callback(foo, print_value) foo.bar = 3 # New value is: 3
Additionally, a list of default callbacks can be passed to the constructor:
from traitlite import HasCallback def print_value(value): print('New value is:', value) class Foo: bar = HasCallback([print_value]) foo = Foo() foo.bar = 3 # New value is: 3
-
add_callback
(obj: Owner, func: Callable[Value, None]) → None¶ Adds a callback to be called after the value is changed. The callback must be a callable object which takes the new value as its argument.
For example, a callback which prints the new value would be:
def print_value(value): print('New value:', value) ObjClass.add_callback(obj, print_value)
Note: The callable passed to
add_callback()
must have a signature, i.e. builtin functions likemax
cannot be used directly, but must be wrapped in a lambda.
-
static
check_callback
(func: Callable[Value, None]) → None¶ Raises an exception if the given callback function is not compatible with this trait.
Parameters: func (Callable[[Value], None]) – A compatible callback function.
-
-
class
traitlite.
HasCallbackDelta
(callbacks: Optional[List[Callable[[Value, Value], None]]] = None)¶ A trait which introduces callbacks which are called after the given attribute has been given a new value. The callbacks are callable objects which take the old and new values as an argument.
from traitlite import HasCallbackDelta class Foo: bar = HasCallbackDelta() def print_value(old_value, new_value): print('Old value: {}, New value: {}'.format( old_value, new_value)) foo = Foo() # We have to use the class here instead of the instance, and the # instance is passed as the first argument. Foo.bar.add_callback(foo, print_value) foo.bar = 3 # Old value: None, New value: 3 foo.bar = 4 # Old value: 3, New value: 4
Additionally, a list of default callbacks can be passed to the constructor:
from traitlite import HasCallbackDelta def print_value(old_value, new_value): print('Old value: {}, New value: {}'.format( old_value, new_value)) class Foo: bar = HasCallbackDelta([print_value]) foo = Foo() foo.bar = 3 # Old value: None, New value: 3 foo.bar = 4 # Old value: 3, New value: 4
-
add_callback
(obj: Owner, func: Callable[[Value, Value], None]) → None¶ Adds a callback to be called after the value is changed. The callback must be a callable object which takes the new and old values as its arguments.
For example, a callback which prints the old and new values would be:
def print_value(old_value, new_value): print('Old value:', old_value) print('New value:', new_value) ObjClass.add_callback(obj, print_value)
Note: The callable passed to
add_callback()
must have a signature, i.e. builtin functions likemax
cannot be used directly, but must be wrapped in a lambda.
-
static
check_callback
(func: Callable[[Value, Value], None]) → None¶ Raises an exception if the given callback function is not compatible with this trait.
Parameters: func (Callable[[Value, Value], None]) – A compatible callback function.
-
-
class
traitlite.
HasValidator
(validators: Optional[List[Callable[Value, Value]]] = None)¶ A trait which introduces validators which are called before the given attribute is given a new value. The validators take the new value as a single argument and must return the value which should be used.
from traitlite import HasValidator class Foo: bar = HasValidator() foo = Foo() # We have to use the class here instead of the instance, and the # instance is passed as the first argument. Foo.bar.add_validator(foo, lambda x: max(0, x)) Foo.bar.add_validator(foo, lambda x: min(10, x)) foo.bar = 3 print(foo.bar) # 3 foo.bar = -1 print(foo.bar) # 0 foo.bar = 11 print(foo.bar) # 10
Additionally, a list of default validators can be passed to the constructor:
from traitlite import HasValidator class Foo: bar = HasValidator([lambda x: max(0, x)]) foo = Foo() foo.bar = 3 print(foo.bar) # 3 foo.bar = -1 print(foo.bar) # 0
-
add_validator
(obj: Owner, func: Callable[Value, Value]) → None¶ Adds a validator to be called before the value is changed. The validator must be a callable object which takes the new value as its argument and must return the value which should be used.
For example, a validator which makes sure that the value is always greater or equal to zero would be:
ObjClass.add_validator(obj, lambda x: max(0, x))
Note: The callable passed to
add_validator()
must have a signature, i.e. builtin functions likemax
cannot be used directly, but must be wrapped in a lambda.
-
static
check_validator
(func: Callable[Value, Value])¶ Raises an exception if the given validator function is not compatible with this trait.
Parameters: func (Callable[[Value], Value]) – A compatible validator function.
-
-
class
traitlite.
HasValidatorDelta
(validators: Optional[List[Callable[[Value, Value], Value]]] = None)¶ A trait which introduces validators which are called before the given attribute is given a new value. The validators take the new value as a single argument and must return the value which should be used.
from traitlite import HasValidatorDelta class Foo: bar = HasValidatorDelta() def __init__(self): self.bar = 0 foo = Foo() # We have to use the class here instead of the instance, and the # instance is passed as the first argument. Foo.bar.add_validator(foo, lambda x, y: max(x, y)) foo.bar = 3 print(foo.bar) # 3 foo.bar = 2 print(foo.bar) # 3 foo.bar = 4 print(foo.bar) # 4
Additionally, a list of default validators can be passed to the constructor:
from traitlite import HasValidatorDelta class Foo: bar = HasValidatorDelta([lambda old, new: max(old or 0, new)]) foo = Foo() foo.bar = 3 print(foo.bar) # 3 foo.bar = -1 print(foo.bar) # 3
-
add_validator
(obj: Owner, func: Callable[[Value, Value], Value]) → None¶ Adds a validator to be called before the value is changed. The validator must be a callable object which takes the old and new values as its arguments and must return the value which should be used.
For example, a validator which only accepts increases in value would be:
ObjClass.add_validator(obj, lambda x, y: max(x, y))
Note: The callable passed to
add_validator()
must have a signature, i.e. builtin functions likemax
cannot be used directly, but must be wrapped in a lambda.
-
static
check_validator
(func: Callable[[Value, Value], Value])¶ Raises an exception if the given validator function is not compatible with this trait.
Parameters: func (Callable[[Value], Value]) – A compatible validator function.
-
Debug Traits¶
-
class
traitlite.debug.
BreakOnChange
(callback: Callable[Value, bool])¶ A trait which starts the debugger when its value causes the specified callback to return True. The method called to start the debugger is the one set in the PYTHONBREAKPOINT environment variable, or
pdb.set_trace
if the variable is not defined.from traitlite import BreakOnChange class Foo: bar = BreakOnChange(lambda value: value < 0) def __init__(self, bar): self.bar = bar foo = Foo(3) foo.bar = 2 # breakpoint() is NOT called here. foo.bar = -1 # breakpoint() is called here.
-
class
traitlite.debug.
BreakOnChangeDelta
(callback: Callable[[Value, Value], bool])¶ A trait which starts the debugger when its old and new values cause the specified callback to return True. The method called to start the debugger is the one set in the PYTHONBREAKPOINT environment variable, or
pdb.set_trace
if the variable is not defined.from traitlite import BreakOnChangeDelta class Foo: bar = BreakOnChangeDelta(lambda old, new: old is not None and new < old) def __init__(self, bar): self.bar = bar foo = Foo(3) foo.bar = 5 # The new value is higher, so breakpoint is NOT called. foo.bar = 4 # The new value is lower, so breakpoint is called.
-
class
traitlite.debug.
BreakOnRead
¶ A trait which starts the debugger when it is accessed. The method called to start the debugger is the one set in the PYTHONBREAKPOINT environment variable, or
pdb.set_trace
if the variable is not defined.from traitlite import BreakOnRead class Foo: bar = BreakOnRead() def __init__(self, bar): self.bar = bar foo = Foo(3) print(foo.bar) # breakpoint() is called here.
-
class
traitlite.debug.
BreakOnWrite
(ignore_initial: bool = False)¶ A trait which starts the debugger when it is accessed. The method called to start the debugger is the one set in the PYTHONBREAKPOINT environment variable, or
pdb.set_trace
if the variable is not defined.from traitlite import BreakOnWrite class Foo: bar = BreakOnWrite(ignore_initial=True) def __init__(self, bar): self.bar = bar foo = Foo(3) # breakpoint is not called because of ignore_initial=True foo.bar = 4 # breakpoint() is called here.