Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Check for numeric type using numbers.Real #6802

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/qcodes/instrument_drivers/american_magnetics/AMI430.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

import collections.abc
import logging
import numbers
import time
import warnings
from collections import defaultdict
Expand All @@ -20,6 +19,7 @@
from qcodes.math_utils import FieldVector
from qcodes.parameters import Parameter
from qcodes.utils import QCoDeSDeprecationWarning
from qcodes.utils.types import NumberType
from qcodes.validators import Anything, Bool, Enum, Ints, Numbers

if TYPE_CHECKING:
Expand Down Expand Up @@ -635,7 +635,7 @@ def find_ami430_with_name(ami430_name: str) -> AMI430:
self._field_limit: float | Iterable[CartesianFieldLimitFunction]
if isinstance(field_limit, collections.abc.Iterable):
self._field_limit = field_limit
elif isinstance(field_limit, numbers.Real):
elif isinstance(field_limit, NumberType):
# Conversion to float makes related driver logic simpler
self._field_limit = float(field_limit)
else:
Expand Down Expand Up @@ -978,7 +978,7 @@ def _raise_if_not_same_field_and_ramp_rate_units(self) -> tuple[str, str]:
def _verify_safe_setpoint(
self, setpoint_values: tuple[float, float, float]
) -> bool:
if isinstance(self._field_limit, (int, float)):
if isinstance(self._field_limit, NumberType):
return bool(np.linalg.norm(setpoint_values) < self._field_limit)

answer = any(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from __future__ import annotations

import logging
import numbers
import time
import warnings
from collections import defaultdict
Expand All @@ -24,6 +23,7 @@
from qcodes.math_utils import FieldVector
from qcodes.parameters import Parameter
from qcodes.utils import QCoDeSDeprecationWarning
from qcodes.utils.types import NumberType
from qcodes.validators import Anything, Bool, Enum, Ints, Numbers

if TYPE_CHECKING:
Expand Down Expand Up @@ -730,7 +730,7 @@ def find_ami430_with_name(ami430_name: str) -> AMIModel430:
self._field_limit: float | Iterable[CartesianFieldLimitFunction]
if isinstance(field_limit, Iterable):
self._field_limit = field_limit
elif isinstance(field_limit, numbers.Real):
elif isinstance(field_limit, NumberType):
# Conversion to float makes related driver logic simpler
self._field_limit = float(field_limit)
else:
Expand Down Expand Up @@ -1073,7 +1073,7 @@ def _raise_if_not_same_field_and_ramp_rate_units(self) -> tuple[str, str]:
def _verify_safe_setpoint(
self, setpoint_values: tuple[float, float, float]
) -> bool:
if isinstance(self._field_limit, (int, float)):
if isinstance(self._field_limit, NumberType):
return bool(np.linalg.norm(setpoint_values) < self._field_limit)

answer = any(
Expand Down Expand Up @@ -1240,9 +1240,7 @@ def pause(self) -> None:
):
axis_instrument.pause()

def _request_field_change(
self, instrument: AMIModel430, value: numbers.Real
) -> None:
def _request_field_change(self, instrument: AMIModel430, value: NumberType) -> None:
"""
This method is called by the child x/y/z magnets if they are set
individually. It results in additional safety checks being
Expand Down
10 changes: 6 additions & 4 deletions src/qcodes/math_utils/field_vector.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

import numpy as np

from qcodes.utils.types import NumberType

if TYPE_CHECKING:
from collections.abc import Sequence

Expand Down Expand Up @@ -292,21 +294,21 @@ def __setitem__(self, component: str, value: float) -> None:
self.set_component(**{component: value})

def __mul__(self, other: Any) -> FieldVector:
if not isinstance(other, (float, int)):
if not isinstance(other, NumberType):
return NotImplemented

return FieldVector(
**{component: self[component] * other for component in "xyz"}
**{component: self[component] * float(other) for component in "xyz"}
)

def __rmul__(self, other: Any) -> FieldVector:
if not isinstance(other, (int, float)):
if not isinstance(other, NumberType):
return NotImplemented

return self * other

def __truediv__(self, other: Any) -> FieldVector:
if not isinstance(other, (int, float)):
if not isinstance(other, NumberType):
return NotImplemented

return self * (1.0 / other)
Expand Down
20 changes: 10 additions & 10 deletions src/qcodes/parameters/parameter_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from qcodes.utils import DelegateAttributes, full_class, qcodes_abstractmethod
from qcodes.validators import Enum, Ints, Validator

from ..utils.types import NumberType
from .cache import _Cache, _CacheProtocol
from .named_repr import named_repr
from .permissive_range import permissive_range
Expand Down Expand Up @@ -783,8 +784,8 @@ def set_wrapper(value: ParamDataType, **kwargs: Any) -> None:
return set_wrapper

def get_ramp_values(
self, value: float | Sized, step: float | None = None
) -> Sequence[float | Sized]:
self, value: NumberType | Sized, step: NumberType | None = None
) -> Sequence[NumberType | Sized]:
"""
Return values to sweep from current value to target value.
This method can be overridden to have a custom sweep behaviour.
Expand All @@ -809,8 +810,7 @@ def get_ramp_values(
self.get()
start_value = self.get_latest()
if not (
isinstance(start_value, (int, float))
and isinstance(value, (int, float))
isinstance(start_value, NumberType) and isinstance(value, NumberType)
):
# parameter is numeric but either one of the endpoints
# is not or the starting point is unknown. The later
Expand Down Expand Up @@ -859,7 +859,7 @@ def validate(self, value: ParamDataType) -> None:
validator.validate(value, self._validate_context)

@property
def step(self) -> float | None:
def step(self) -> NumberType | None:
"""
Stepsize that this Parameter uses during set operation.
Stepsize must be a positive number or None.
Expand All @@ -883,12 +883,12 @@ def step(self) -> float | None:
return self._step

@step.setter
def step(self, step: float | None) -> None:
def step(self, step: NumberType | None) -> None:
if step is None:
self._step: float | None = step
self._step: NumberType | None = step
elif not all(getattr(vals, "is_numeric", True) for vals in self._vals):
raise TypeError("you can only step numeric parameters")
elif not isinstance(step, (int, float)):
elif not isinstance(step, NumberType):
raise TypeError("step must be a number")
elif step == 0:
self._step = None
Expand Down Expand Up @@ -928,7 +928,7 @@ def post_delay(self) -> float:

@post_delay.setter
def post_delay(self, post_delay: float) -> None:
if not isinstance(post_delay, (int, float)):
if not isinstance(post_delay, NumberType):
raise TypeError(f"post_delay ({post_delay}) must be a number")
if post_delay < 0:
raise ValueError(f"post_delay ({post_delay}) must not be negative")
Expand Down Expand Up @@ -957,7 +957,7 @@ def inter_delay(self) -> float:

@inter_delay.setter
def inter_delay(self, inter_delay: float) -> None:
if not isinstance(inter_delay, (int, float)):
if not isinstance(inter_delay, NumberType):
raise TypeError(f"inter_delay ({inter_delay}) must be a number")
if inter_delay < 0:
raise ValueError(f"inter_delay ({inter_delay}) must not be negative")
Expand Down
9 changes: 6 additions & 3 deletions src/qcodes/parameters/permissive_range.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
from __future__ import annotations

import math
from typing import SupportsAbs
from typing import TYPE_CHECKING, SupportsAbs

if TYPE_CHECKING:
from qcodes.utils.types import NumberType


# could use numpy.arange here, but
# I'd like to be more flexible with the sign of step
def permissive_range(
start: float, stop: float, step: SupportsAbs[float]
) -> list[float]:
start: NumberType, stop: NumberType, step: SupportsAbs[NumberType]
) -> list[NumberType]:
"""
Returns a range (as a list of values) with floating point steps.
Always starts at start and moves toward stop, regardless of the
Expand Down
7 changes: 7 additions & 0 deletions src/qcodes/utils/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

from __future__ import annotations

from typing import TypeAlias

import numpy as np

complex_type_union = np.complex64 | np.complex128 | np.complexfloating | complex
Expand Down Expand Up @@ -82,3 +84,8 @@

concrete_complex_types = (*numpy_concrete_complex, complex)
complex_types = (*numpy_concrete_complex, complex)

NumberType: TypeAlias = int | float | np.integer | np.floating
"""
Python or NumPy real number.
"""