diff --git a/astropy/units/core.py b/astropy/units/core.py index ee40591599a..5297436d044 100644 --- a/astropy/units/core.py +++ b/astropy/units/core.py @@ -38,7 +38,7 @@ from .format import Base from .physical import PhysicalType from .quantity import Quantity - from .typing import Complex, Real, UnitPower, UnitScale + from .typing import UnitPower, UnitPowerLike, UnitScale, UnitScaleLike __all__ = [ "CompositeUnit", @@ -774,7 +774,7 @@ def _normalize_equivalencies(equivalencies): return normalized - def __pow__(self, p: Real) -> CompositeUnit: + def __pow__(self, p: UnitPowerLike) -> CompositeUnit: try: # Handling scalars should be as quick as possible return CompositeUnit(1, [self], [sanitize_power(p)], _error_check=False) except Exception: @@ -2081,9 +2081,9 @@ def __call__( _error_check=False, ) - from .typing import Complex + from .typing import UnitScaleLike - if isinstance(s, Complex): # same as the annotation in sanitize_scale_type() + if isinstance(s, UnitScaleLike): return CompositeUnit(s, [], []) if isinstance(s, tuple): @@ -2261,9 +2261,9 @@ class CompositeUnit(UnitBase): @overload def __init__( self, - scale: Complex, + scale: UnitScaleLike, bases: Sequence[UnitBase], - powers: Sequence[Real], + powers: Sequence[UnitPowerLike], decompose: bool = False, decompose_bases: Collection[UnitBase] = (), _error_check: Literal[True] = True, diff --git a/astropy/units/typing.py b/astropy/units/typing.py index b45d5ae7835..3edfb2ea0a5 100644 --- a/astropy/units/typing.py +++ b/astropy/units/typing.py @@ -68,12 +68,7 @@ """ -# The classes from the standard library `numbers` module are not suitable for -# type checking (https://github.com/python/mypy/issues/3186). For now we define -# our own number types, but if a good definition becomes available upstream -# then we should switch to that. -Real: TypeAlias = int | float | Fraction | np.integer | np.floating -Complex: TypeAlias = Real | complex | np.complexfloating - UnitPower: TypeAlias = int | float | Fraction +UnitPowerLike: TypeAlias = UnitPower | np.integer | np.floating UnitScale: TypeAlias = int | float | Fraction | complex +UnitScaleLike: TypeAlias = UnitScale | np.number diff --git a/astropy/units/utils.py b/astropy/units/utils.py index 25c336f95ba..1bd76b88e80 100644 --- a/astropy/units/utils.py +++ b/astropy/units/utils.py @@ -26,7 +26,7 @@ from .core import UnitBase from .quantity import Quantity - from .typing import Complex, Real, UnitPower, UnitScale + from .typing import UnitPower, UnitPowerLike, UnitScale, UnitScaleLike DType = TypeVar("DType", bound=np.generic) FloatLike = TypeVar("FloatLike", bound=SupportsFloat) @@ -181,7 +181,7 @@ def generate_prefixonly_unit_summary(namespace: dict[str, object]) -> str: return docstring.getvalue() -def is_effectively_unity(value: Complex) -> bool: +def is_effectively_unity(value: UnitScaleLike) -> bool: # value is *almost* always real, except, e.g., for u.mag**0.5, when # it will be complex. Use try/except to ensure normal case is fast try: @@ -193,7 +193,7 @@ def is_effectively_unity(value: Complex) -> bool: ) -def sanitize_scale_type(scale: Complex) -> UnitScale: +def sanitize_scale_type(scale: UnitScaleLike) -> UnitScale: if not scale: raise UnitScaleError("cannot create a unit with a scale of 0.") @@ -226,7 +226,7 @@ def sanitize_scale_value(scale: UnitScale) -> UnitScale: return scale.real -def maybe_simple_fraction(p: Real, max_denominator: int = 100) -> UnitPower: +def maybe_simple_fraction(p: UnitPowerLike, max_denominator: int = 100) -> UnitPower: """Fraction very close to x with denominator at most max_denominator. The fraction has to be such that fraction/x is unity to within 4 ulp. @@ -257,7 +257,7 @@ def maybe_simple_fraction(p: Real, max_denominator: int = 100) -> UnitPower: return float(p) -def sanitize_power(p: Real) -> UnitPower: +def sanitize_power(p: UnitPowerLike) -> UnitPower: """Convert the power to a float, an integer, or a Fraction. If a fractional power can be represented exactly as a floating point @@ -297,7 +297,9 @@ def sanitize_power(p: Real) -> UnitPower: return p -def resolve_fractions(a: Real, b: Real) -> tuple[Real, Real]: +def resolve_fractions( + a: UnitPowerLike, b: UnitPowerLike +) -> tuple[UnitPowerLike, UnitPowerLike]: """ If either input is a Fraction, convert the other to a Fraction (at least if it does not have a ridiculous denominator). diff --git a/docs/nitpick-exceptions b/docs/nitpick-exceptions index 219e23bf572..09f99a48f69 100644 --- a/docs/nitpick-exceptions +++ b/docs/nitpick-exceptions @@ -94,10 +94,10 @@ py:class np.ma.MaskedArray # locally defined type variable for ndarray dtype py:class DT # type aliases -py:class Complex -py:class Real py:class UnitPower +py:class UnitPowerLike py:class UnitScale +py:class UnitScaleLike # Classes from `astropy.extern` that are nonetheless exposed in documentation py:class Lexer