Skip to content

BUG: InstantCameraArray not an Iterable (type checking) #866

@danielkonecny

Description

@danielkonecny

Describe the issue:

I am working with an InstantCameraArray, but when for-looping over this array with addition of zip or enumerate, type checker complains that the variable is not an Iterable instance - which is not, it doesn't implement __iter__. Function like this require an Iterable on the input. Also, while we're at it, it doesn't implement the __len__ magic method either for "len()" to work and make it a Sized abstract base class, example also below.

Would it be possible to extend the InstantCameraArray with an __iter__ method or just register the class as Iterable? And the same for __len__ and Sized. I am not sure how the iteration works now without the __iter__ magic method, but it does.

I tested this with "ty" from Astral and also with integrated type checker in PyCharm - both consider this a type error.

Reproduce the code example:

from pypylon import pylon
cameras = pylon.InstantCameraArray(42)

for i, c in enumerate(cameras):
    print(i, c)

for i, c in zip(range(len(cameras)), cameras):
    print(i, c)

Error message:

error[invalid-argument-type]: Argument to function `__new__` is incorrect
for i, c in enumerate(cameras):
                      ^^^^^^^ Expected `Iterable[Unknown]`, found `InstantCameraArray`
info: Function defined here
    --> stdlib\builtins.pyi:3250:9
     |
3250 |     def __new__(cls, iterable: Iterable[_T], start: int = 0) -> Self: ...
     |         ^^^^^^^      ---------------------- Parameter declared here
3251 |     def __iter__(self) -> Self:
3252 |         """Implement iter(self)."""
     |
info: rule `invalid-argument-type` is enabled by default


error[not-iterable]: Object of type `_T_co@zip` is not iterable
for i, c in zip(range(len(cameras)), cameras):
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
info: It doesn't have an `__iter__` method or a `__getitem__` method
info: rule `not-iterable` is enabled by default


error[invalid-argument-type]: Argument to function `len` is incorrect
for i, c in zip(range(len(cameras)), cameras):
                          ^^^^^^^ Expected `Sized`, found `InstantCameraArray`
info: Function defined here
    --> stdlib\builtins.pyi:3777:5
     |
3777 | def len(obj: Sized, /) -> int:
     |     ^^^ ---------- Parameter declared here
3778 |     """Return the number of items in a container."""
     |
info: rule `invalid-argument-type` is enabled by default


error[invalid-argument-type]: Argument to function `__new__` is incorrect
for i, c in zip(range(len(cameras)), cameras):
                                     ^^^^^^^ Expected `Iterable[Unknown]`, found `InstantCameraArray`
info: Matching overload defined here
    --> stdlib\builtins.pyi:4402:13
     |
4400 |         def __new__(cls, iter1: Iterable[_T1], /, *, strict: bool = False) -> zip[tuple[_T1]]: ...
4401 |         @overload
4402 |         def __new__(cls, iter1: Iterable[_T1], iter2: Iterable[_T2], /, *, strict: bool = False) -> zip[tuple[_T1, _T2]]: ...
     |             ^^^^^^^                            -------------------- Parameter declared here
4403 |         @overload
4404 |         def __new__(
     |
info: Non-matching overloads for function `__new__`:
info:   (cls, *, strict: bool = False) -> zip[Any]
info:   [_T1](cls, iter1: Iterable[_T1], *, /, strict: bool = False) -> zip[tuple[_T1]]
info:   [_T1, _T2, _T3](cls, iter1: Iterable[_T1], iter2: Iterable[_T2], iter3: Iterable[_T3], *, /, strict: bool = False) -> zip[tuple[_T1, _T2, _T3]]
info:   [_T1, _T2, _T3, _T4](cls, iter1: Iterable[_T1], iter2: Iterable[_T2], iter3: Iterable[_T3], iter4: Iterable[_T4], *, /, strict: bool = False) -> zip[tuple[_T1, _T2, _T3, _T4]]
info:   [_T1, _T2, _T3, _T4, _T5](cls, iter1: Iterable[_T1], iter2: Iterable[_T2], iter3: Iterable[_T3], iter4: Iterable[_T4], iter5: Iterable[_T5], *, /, strict: bool = False) -> zip[tuple[_T1, _T2, _T3, _T4, _T5]]
info:   (cls, iter1: Iterable[Any], iter2: Iterable[Any], iter3: Iterable[Any], iter4: Iterable[Any], iter5: Iterable[Any], iter6: Iterable[Any], /, *iterables: Iterable[Any], *, strict: bool = False) -> zip[tuple[Any, ...]]
info: rule `invalid-argument-type` is enabled by default

Is your camera operational in Basler pylon viewer on your platform

Yes

Hardware setup & camera model(s) used

Not relevant

Runtime information:

python: 3.12.3 (tags/v3.12.3:f6650f9, Apr  9 2024, 14:05:25) [MSC v.1938 64 bit (AMD64)]
platform: win32/AMD64/11
pypylon: 26.03.1 / 11.4.0.1134

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions