Skip to content

BUG: type checking np.isfinite() arguments fails for sequences of (np.number | float) #23081

@effigies

Description

@effigies

Describe the issue:

I'm trying to add type hints to an existing code base. I currently have a function (simplified):

def array_to_file(
    data,
    fileobj,
    out_dtype,
    intercept = 0.0,
    divslope = 1.0,
):
    if not np.all(np.isfinite((intercept, 1.0 if divslope is None else divslope))):
        raise ValueError('divslope and intercept must be finite')
    ...

We have written it to accept numpy or Python types. The general use case is Python types, but if someone wants to avoid doubling their memory by making sure all passed values are float32, they can. I want to make this:

Scalar = np.number | float

def array_to_file(
    data: npt.ArrayLike,
    fileobj: io.IOBase, 
    out_dtype: np.dtype | None = None,
    intercept: Scalar = 0.0,
    divslope: Scalar | None = 1.0,
):
    if not np.all(np.isfinite((intercept, 1.0 if divslope is None else divslope))):
        raise ValueError('divslope and intercept must be finite')
    ...

But I get the error below.

Reproduce the code example:

import numpy as np

Scalar = np.number | float

def check1(x: Scalar) -> np.bool_:
    return np.isfinite(x)

def check2(x: Scalar, y: Scalar) -> np.ndarray:
    return np.isfinite((x, y))

Error message:

$ mypy example.py
example.py:9: error: Argument 1 to "__call__" of "_UFunc_Nin1_Nout1" has incompatible type "Tuple[Union[number[Any], float]]"; expected "Union[_SupportsArray[dtype[Any]], _NestedSequence[_SupportsArray[dtype[Any]]], bool, int, float, complex, str, bytes, _NestedSequence[Union[bool, int, float, complex, str, bytes]]]"  [arg-type]
Found 1 error in 1 file (checked 1 source file)

Runtime information:

1.23.5
3.10.8 (main, Nov 24 2022, 14:13:03) [GCC 11.2.0]

Context for the issue:

This is not terribly high priority. I can rewrite this in a way that will type check, but it seems like a bug.

If numpy.typing has better ways of writing Scalar that I haven't seen, happy to switch to that.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions