traits.py 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. """Trait types for events."""
  2. from __future__ import annotations
  3. import logging
  4. import typing as t
  5. from traitlets import TraitError, TraitType
  6. baseclass = TraitType
  7. if t.TYPE_CHECKING:
  8. baseclass = TraitType[t.Any, t.Any] # type:ignore[misc]
  9. class Handlers(baseclass): # type:ignore[type-arg]
  10. """A trait that takes a list of logging handlers and converts
  11. it to a callable that returns that list (thus, making this
  12. trait pickleable).
  13. """
  14. info_text = "a list of logging handlers"
  15. def validate_elements(self, obj: t.Any, value: t.Any) -> None:
  16. """Validate the elements of an object."""
  17. if len(value) > 0:
  18. # Check that all elements are logging handlers.
  19. for el in value:
  20. if isinstance(el, logging.Handler) is False:
  21. self.element_error(obj)
  22. def element_error(self, obj: t.Any) -> None:
  23. """Raise an error for bad elements."""
  24. msg = f"Elements in the '{self.name}' trait of an {obj.__class__.__name__} instance must be Python `logging` handler instances."
  25. raise TraitError(msg)
  26. def validate(self, obj: t.Any, value: t.Any) -> t.Any:
  27. """Validate an object."""
  28. # If given a callable, call it and set the
  29. # value of this trait to the returned list.
  30. # Verify that the callable returns a list
  31. # of logging handler instances.
  32. if callable(value):
  33. out = value()
  34. self.validate_elements(obj, out)
  35. return out
  36. # If a list, check it's elements to verify
  37. # that each element is a logging handler instance.
  38. if isinstance(value, list):
  39. self.validate_elements(obj, value)
  40. return value
  41. self.error(obj, value)
  42. return None # type:ignore[unreachable]