Source code for pinttr.validators

from ._metadata import MetadataKey
from .exceptions import UnitsError
from .util import units_compatible


[docs] def has_compatible_units(instance, attribute, value): """ Validate if ``value`` has units compatible (in the sense of :func:`~pinttr.units_compatible`) with ``attribute``. This validator checks that a Pint quantity has units compatible with the units declared for an attribute. It raises :class:`~pinttrs.exceptions.UnitsError` if the units are incompatible or if a unitless value is provided. Only works with unit-enabled fields created with :func:`pinttrs.field` or :func:`pinttr.attrib`. :param instance: The class instance being validated. :param attribute: The attrs attribute being validated (must have units metadata). :param value: The value to validate (should be a Pint quantity). :raises UnitsError: If units are incompatible or if a unitless value is provided. """ compatible_units = attribute.metadata[MetadataKey.UNITS]() try: if not units_compatible(value.units, compatible_units): raise UnitsError( units1=value.units, units2=compatible_units, extra_msg=f": incompatible units '{value.units}' " f"used to set field '{attribute.name}' " f"(allowed: '{compatible_units}').", ) except AttributeError: # value.units doesn't exist raise UnitsError( units1=None, units2=compatible_units, extra_msg=f": unitless value '{value}' " f"used to set field '{attribute.name}' " f"(requires units '{compatible_units}').", )