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

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

Open
effigies opened this issue Jan 24, 2023 · 1 comment

Comments

@effigies
Copy link
Contributor

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.

@julianpryde
Copy link

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
Projects
None yet
Development

No branches or pull requests

3 participants