Repository URL to install this package:
|
Version:
6.4.1 ▾
|
# (C) Copyright 2005-2022 Enthought, Inc., Austin, TX
# All rights reserved.
#
# This software is provided without warranty under the terms of the BSD
# license included in LICENSE.txt and may be redistributed only under
# the conditions described in the aforementioned license. The license
# is also available online at http://www.enthought.com/licenses/BSD.txt
#
# Thanks for using Enthought open source!
""" Module for HasTraits and CTrait specific utility functions for observers.
"""
from traits.constants import ComparisonMode, TraitKind
from traits.ctraits import CHasTraits
from traits.observation._observe import add_or_remove_notifiers
from traits.observation.exceptions import NotifierNotFound
from traits.trait_base import Undefined, Uninitialized
#: List of values not to be passed onto the next observers because they are
#: filled values for uninitialized/undefined traits, and no observables
#: can be derived from them.
UNOBSERVABLE_VALUES = [
Undefined,
Uninitialized,
None,
]
def object_has_named_trait(object, name):
""" Return true if a trait with the given name is defined on the object.
Parameters
----------
object : any
Any object
name : str
Trait name to look for.
Returns
-------
boolean
"""
return (
isinstance(object, CHasTraits) and object._trait(name, 0) is not None
)
def iter_objects(object, name):
""" Yield the object referenced by the named trait, unless the value is not
defined or is one of the few unobservable filled values.
This function should not introduce side-effect (e.g. evaluating default)
on the given object.
Parameters
----------
object : HasTraits
Object from which the trait value will be obtained.
name : str
Name of the trait.
Yields
------
value : any
The value of the trait, if it is defined and is not one of those
skipped values.
"""
value = object.__dict__.get(name, Undefined)
if all(value is not skipped for skipped in UNOBSERVABLE_VALUES):
yield value
def observer_change_handler(event, graph, handler, target, dispatcher):
""" Maintain downstream notifiers when the trait changes.
Parameters
----------
event : TraitChangeEvent
The event that triggers this function.
graph : ObserverGraph
Description for the *downstream* observers, i.e. excluding the observer
that contributed this maintainer function.
handler : callable
User handler.
target : object
Object seen by the user as the owner of the observer.
dispatcher : callable
Callable for dispatching the handler.
"""
if all(event.old is not skipped for skipped in UNOBSERVABLE_VALUES):
try:
add_or_remove_notifiers(
object=event.old,
graph=graph,
handler=handler,
target=target,
dispatcher=dispatcher,
remove=True,
)
except NotifierNotFound:
# The old value could be a default value that does not have any
# notifier.
pass
if all(event.new is not skipped for skipped in UNOBSERVABLE_VALUES):
add_or_remove_notifiers(
object=event.new,
graph=graph,
handler=handler,
target=target,
dispatcher=dispatcher,
remove=False,
)
def ctrait_prevent_event(event):
""" Return true if the CTrait change event should be skipped.
Parameters
----------
event : TraitChangeEvent
Returns
-------
skipped : bool
Whether the event should be skipped
"""
if event.old is Uninitialized:
return True
ctrait = event.object.trait(event.name)
if (ctrait.type == TraitKind.trait.name
and ctrait.comparison_mode == ComparisonMode.equality):
try:
return bool(event.old == event.new)
except Exception:
# Maybe do something else about the exception
# enthought/traits#1230
pass
return False