Skip to content

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

Closed

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.

Activity

  1. julianpryde commented on Feb 28, 2023

    @julianpryde

    This is because np.ArrayLike assumes that possible compatible types are one of the following:

    1. a numpy ndarray of numpy dtypes (_SupportsArray[_DType])
    2. a python sequence (_NestedSequence) of numpy dtypes (_NestedSequence[_SupportsArray[np.dtype[Any]]])
    3. a python sequence with python numeric type constituents (_NestedSequence[bool, int, float, ...])
    4. a bare python numeric type. (bool, int, float, ...)

    None of these capture the possibility of a python list which could have python numeric types or numpy dtypes since it crosses two cases.

    I'm working on fixing this by adding a separate case that would cover both situations such as _NestedSequence[Union[dtype[Any], bool, int, float, ...]].

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions