Source code for qblox_scheduler.helpers.validators

# Repository: https://gitlab.com/qblox/packages/software/qblox-scheduler
# Licensed according to the LICENSE file on the main branch
#
# Copyright 2020-2025, Quantify Consortium
# Copyright 2025, Qblox B.V.
"""Module containing pydantic validators."""

from collections.abc import Hashable

import numpy as np
from qcodes.utils import validators
from qcodes.utils.validators import Validator
from qcodes.validators.validators import numbertypes


# this is a custom qcodes Numbers validator that allows for nan values.
[docs] class Numbers(validators.Numbers): """ A custom qcodes Numbers validator that allows for nan values. Requires a number of type int, float, numpy.integer or numpy.floating. Parameters ---------- min_value: Minimal value allowed, default -inf. max_value: Maximal value allowed, default inf. allow_nan: if nan values are allowed, default False. Raises ------ TypeError: If min or max value not a number. Or if min_value is larger than the max_value. """ def __init__( self, min_value: numbertypes = -np.inf, max_value: numbertypes = np.inf, allow_nan: bool = False, ) -> None: super().__init__(min_value, max_value)
[docs] self._allow_nan = allow_nan
[docs] def validate(self, value: numbertypes, context: str = "") -> None: """ Validate if number else raises error. Parameters ---------- value: A number. context: Context for validation. Raises ------ TypeError: If not int or float. ValueError: If number is not between the min and the max value. """ if not isinstance(value, self.validtypes): raise TypeError(f"{value!r} is not an int or float; {context}") if self._allow_nan and np.isnan(value): # return early as the next statement will otherwise trigger return if not (self._min_value <= value <= self._max_value): raise ValueError( f"{value!r} is invalid: must be between " f"{self._min_value} and {self._max_value} inclusive; {context}" )
[docs] class _Durations(Numbers): """Validator used for durations. It allows all numbers greater than or equal to 0.""" def __init__( self, ) -> None: super().__init__(min_value=0, allow_nan=False)
[docs] class _Amplitudes(Numbers): """Validator used for amplitudes. It allows all numbers and nan.""" def __init__( self, ) -> None: super().__init__(allow_nan=True)
[docs] class _NonNegativeFrequencies(Numbers): """Validator used for frequencies. It allows positive numbers and nan.""" def __init__( self, ) -> None: super().__init__(min_value=0, allow_nan=True)
[docs] class _Delays(Numbers): """Validator used for delays. It allows all numbers.""" def __init__( self, ) -> None: super().__init__(allow_nan=False)
[docs] class _Hashable(Validator[Hashable]): """Validator used for hashables.""" def __init__(self) -> None:
[docs] self._valid_values = (0, "str")
[docs] def validate(self, value: Hashable, context: str = "") -> None: """ Validates if hashable else raises error. Parameters ---------- value Value to validate context Context for validation. Raises ------ TypeError If value is not hashable. """ if not isinstance(value, Hashable): raise TypeError(f"{value!r} is not Hashable; {context}")
def __repr__(self) -> str: return "<Hashable>"