[Python] Why does all(isinstance(x, str) for x in value) not help Pyright infer Iterable[str]...

Discussão em 'Python' iniciado por Stack, Maio 19, 2025.

  1. Stack

    Stack Membro Participativo

    I'm working with Pyright in strict mode and want to check if a function parameter value of type object is an Iterable[str]. I tried using:

    if isinstance(value, Iterable) and all(isinstance(v, str) for v in value):
    # Pyright complains: 'Type of "v" is unknown'


    However, looking at the elements, Pyright complains that the type of v is still Unknown, even after the isinstance check on each element. Why doesn't all(isinstance(...)) refine the type of value to Iterable[str]?

    For context: I'm implementing __contains__ in a class that inherits from collections.abc.MutableSequence.
    Therefore, the method signature must remain def __contains__(self, value: object) -> bool, I can't change the type annotation of value to Iterable[str].

    Here's my current implementation:

    def __contains__(self, value: object) -> bool:
    if isinstance(value, Iterable) and all(isinstance(v, str) for v in value):
    value = "".join(value).upper()
    return value in "".join(self.sequence) # self.sequence is an Iterable[str]
    return False


    Is there a way to get Pyright to properly infer the type of value here without using an explicit cast() or defining a separate TypeGuard function?
    It seems to me that a separate TypeGuard should make no difference.

    Alternatively: am I looking at this the wrong way? Should I try to avoid implementing __contains__ myself, because of the object type?

    Continue reading...

Compartilhe esta Página