BUG: modelling various integer types as a specialized version of the generic class breaks type-checking in pyright #23007
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.