Wrong type interference for inheritance with statements
I'm developing a proprietary python plugin using pyo3 to ease software testing for embedded deviced. It's somewhat like the ctypes plugin but provides more capabilites for our specific needs.
For array creation i can use ctypes like:
For both variants the inherited type is properly interfered as type[Array[c_ubytes]].
When trying to do the same with my plugin:
The first variant works as the type of BaseClass2 is properly interfered as U8Array. The second variant seems to inerhit from U8 instead of U8Array so the __get_item__ method is apparently not available.
The runtime works as expected. The error both appears with the vscode pylance plugin and when running pyright 1.1.405 from the commandline.
While most of the classes is defined in rust, the metaclass logic inside the __init__.py file looks like this (_types.U8 being the rust class):
class _ArrayAble(Protocol):
@classmethod
def __make_array__[C](cls: type[C], size: int) -> Any: ...
class _U8ArrayMeta(type):
def __getitem__[C: _ArrayAble](cls: type[C], size: int) -> type[U8Array]:
return cls.__make_array__(size)
class U8(_types.U8, metaclass=_U8ArrayMeta): ...
I also provide a stub file (__init__.pyi), which is what pyright seems to use for its type interference:
class _NonGeneric:
def __class_getitem__(cls, index: int) -> None: ...
class _ArrayAble(Protocol):
@classmethod
def __make_array__[C](cls: type[C], size: int) -> Any: ...
class U8Array(ArrayType):
"""
8-Bit Unsigned Integer implementing `pymat.types.protocols.ArrayType` and
`pymat.types.protocols.MeterVariable`
"""
class _U8ArrayMeta(type):
def __getitem__[C: _ArrayAble](cls: type[C], size: int) -> type[U8Array]: ...
class U8(PrimitiveType, _NonGeneric, metaclass=_U8ArrayMeta):
"""
8-Bit Unsigned Integer implementing `pymat.types.protocols.PrimitiveType` and
`pymat.types.protocols.MeterVariable`
"""
The ArrayType class provides the inherited __get_item__ method:
class ArrayType(MeterVariable):
def __getitem__(self, idx: int) -> PrimitiveTypeProtocol:
....
Could you provide a self-contained minimal reproducible example (MRE)? You code sample above references undefined symbols like PrimitiveType, ArrayType and MeterVariable — preferably something that you can paste into the pyright playground.
You are correct in assuming that pyright will use a stub file, if present, to resolve an import. That behavior is dictated by the typing standard.
Sure, the example doesn't make much sense but it demonstrates the inconsistence: https://pyright-play.net/?code=MYGwhgzhAECqAcBBATssBPAXAWAFDQOgBMBTAM2gH1KBLAOxoBdqAKCEkMgGmgDcwQAVxKZoIGhEYBteowC6AShz5Cq9pwB09OiWTQAvHwHC8q04VIVqAcxKMmJALat13aDSIAPUbIXQAtAB87nSMyqqqyHaCyHTQrlp0OsgyXnJ4eKCQMJQIKGjoALJ2YCyM6AAOJErmBJZUlLb2jE6soBCi5VU8EDQAXiIhjH5B0F0kUnmoGHLhEQRRjDFxUwUZuFlQVAByAPZ0AOIkyTTAc3XkDZsQjXYOzpQs7Tz0pN5DI8F7OqIaf%2BvXODwFiUb5HE7AHiOErXfS5JDTIolGoqC5WWgMZiPVw8fhCQa%2Bc4RBLaXQGIz49aFdAASToAAtdExyQgpAAmdIbcBban5DBsljUumM5BMFGqP4aKnoPnoAVSACMXDZXAAzIoAdyYLzESxWRzxYRJdLZSxFTwVdB1Qp1usgA