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>"