setters.py 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. # SPDX-License-Identifier: MIT
  2. """
  3. Commonly used hooks for on_setattr.
  4. """
  5. from . import _config
  6. from .exceptions import FrozenAttributeError
  7. def pipe(*setters):
  8. """
  9. Run all *setters* and return the return value of the last one.
  10. .. versionadded:: 20.1.0
  11. """
  12. def wrapped_pipe(instance, attrib, new_value):
  13. rv = new_value
  14. for setter in setters:
  15. rv = setter(instance, attrib, rv)
  16. return rv
  17. return wrapped_pipe
  18. def frozen(_, __, ___):
  19. """
  20. Prevent an attribute to be modified.
  21. .. versionadded:: 20.1.0
  22. """
  23. raise FrozenAttributeError()
  24. def validate(instance, attrib, new_value):
  25. """
  26. Run *attrib*'s validator on *new_value* if it has one.
  27. .. versionadded:: 20.1.0
  28. """
  29. if _config._run_validators is False:
  30. return new_value
  31. v = attrib.validator
  32. if not v:
  33. return new_value
  34. v(instance, attrib, new_value)
  35. return new_value
  36. def convert(instance, attrib, new_value):
  37. """
  38. Run *attrib*'s converter -- if it has one -- on *new_value* and return the
  39. result.
  40. .. versionadded:: 20.1.0
  41. """
  42. c = attrib.converter
  43. if c:
  44. return c(new_value)
  45. return new_value
  46. # Sentinel for disabling class-wide *on_setattr* hooks for certain attributes.
  47. # autodata stopped working, so the docstring is inlined in the API docs.
  48. NO_OP = object()