validation_utils.py 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. from __future__ import annotations
  2. from typing import Type
  3. class MissingAttributeException(Exception):
  4. pass
  5. class WrongTypeAttributeException(Exception):
  6. pass
  7. def check_required_attributes(
  8. sensor: "Sensor", # noqa: F821
  9. attributes: list[str | tuple[str, Type | tuple[Type, ...]]],
  10. ):
  11. """Raises if any attribute in the list of attributes is missing on the Sensor, or has the wrong type.
  12. :param sensor: Sensor object to check for attributes
  13. :param attributes: List of either an attribute name or a tuple of an attribute name and its allowed type
  14. (the allowed type may also be a tuple of several allowed types)
  15. """
  16. missing_attributes: list[str] = []
  17. wrong_type_attributes: list[tuple[str, Type, Type]] = []
  18. for attribute_field in attributes:
  19. if isinstance(attribute_field, str):
  20. attribute_name = attribute_field
  21. expected_attribute_type = None
  22. elif isinstance(attribute_field, tuple) and len(attribute_field) == 2:
  23. attribute_name = attribute_field[0]
  24. expected_attribute_type = attribute_field[1]
  25. else:
  26. raise ValueError("Unexpected declaration of attributes")
  27. # Check attribute exists
  28. if not sensor.has_attribute(attribute_name):
  29. missing_attributes.append(attribute_name)
  30. # Check attribute is of the expected type
  31. if expected_attribute_type is not None:
  32. attribute = sensor.get_attribute(attribute_name)
  33. if not isinstance(attribute, expected_attribute_type):
  34. wrong_type_attributes.append(
  35. (attribute_name, type(attribute), expected_attribute_type)
  36. )
  37. if missing_attributes:
  38. raise MissingAttributeException(
  39. f"Sensor is missing required attributes: {', '.join(missing_attributes)}"
  40. )
  41. if wrong_type_attributes:
  42. error_message = ""
  43. for (
  44. attribute_name,
  45. attribute_type,
  46. expected_attribute_type,
  47. ) in wrong_type_attributes:
  48. error_message += f"- attribute '{attribute_name}' is a {attribute_type} instead of a {expected_attribute_type}\n"
  49. raise WrongTypeAttributeException(
  50. f"Sensor attributes are not of the required type:\n {error_message}"
  51. )