Skip to content

BUG: modelling various integer types as a specialized version of the generic class breaks type-checking in pyright #23007

Open
@ischurov

Description

Describe the issue:

I want to make sure that some variable is an instance of np.uint64. To this end, I use the following:

assert isinstance(idx, np.uint64)

However, in that case I have the following error on that line during type-checking with pyright:

Second argument to "isinstance" must be a class or tuple of classes
  TypeVar or generic type with type arguments not allowed

As the developers of pyright explained, this is due to fact that type stubs model np.uint64 as a specialized version of the generic class unsignedinteger (uint64 = unsignedinteger[_64Bit]), while in fact it is a proper subclass of unsignedinteger. As specialized versions of a class (like list[int]) are not allowed in isinstance, the type-checker reports an error, making it impossible to use this assert at all.

Are there any reasons to model these types (like np.uint64, np.uint32, etc) in this way (as a specialized versions) instead of making separate types?

Reproduce the code example:

import numpy as np
import pandas as pd

def foo(x: np.uint64):
    pass
series = pd.Series([1, 2, 3], index=np.array([10, 20, 30], dtype='uint64'))
idx = series.index[0]
assert isinstance(idx, np.uint64)
foo(idx)

Error message:

(type alias) uint64: Type[unsignedinteger[_64Bit]]
Second argument to "isinstance" must be a class or tuple of classes
  TypeVar or generic type with type arguments not allowed

Runtime information:

1.24.1
3.10.8 | packaged by conda-forge | (main, Nov 22 2022, 08:26:04) [GCC 10.4.0]
[{'simd_extensions': {'baseline': ['SSE', 'SSE2', 'SSE3'],
'found': ['SSSE3',
'SSE41',
'POPCNT',
'SSE42',
'AVX',
'F16C',
'FMA3',
'AVX2'],
'not_found': ['AVX512F',
'AVX512CD',
'AVX512_KNL',
'AVX512_KNM',
'AVX512_SKX',
'AVX512_CLX',
'AVX512_CNL',
'AVX512_ICL']}},
{'architecture': 'Haswell',
'filepath': '/vol/tcm10/ischurov/.conda/envs/latsym2/lib/libopenblasp-r0.3.21.so',
'internal_api': 'openblas',
'num_threads': 1,
'prefix': 'libopenblas',
'threading_layer': 'pthreads',
'user_api': 'blas',
'version': '0.3.21'}]
None

Context for the issue:

Initially, I had a code that looked like the following:

def foo(x: np.uint64):
    pass
series = pd.Series([1, 2, 3], index=np.array([10, 20, 30], dtype='uint64'))
idx = series.index[0]
foo(idx)

On the type-checking, I have an error: Argument of type "Scalar | Unknown" cannot be assigned to parameter "x" of type "uint64" in function "foo". That's because the type-checker cannot infer that index of pd.Series has dtype uint64. Due to open issue in pandas, it is not yet possible to specify pd.Series.index's dtype using type hints. To give the type-checker information that idx has type np.uint64, I want to add the following assert before running foo:

assert isinstance(idx, np.uint64)

And that leads to type-checker error, as explained above.

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