Skip to content

Pyright not narrowing list comprehension. #11385

@njz-cvm

Description

@njz-cvm

Describe the bug
When using a function to change a type inside list comprehension, if the exactly function is unknown statically, pyright says the result of the list comprehensions is a list with a mix of types from the possible functions. However, only one function will end up being selected at runtime, so the type should be a list of types from one function, or a list of types from another function.

Code or Screenshots
Code sample in pyright playground

from typing import Any

class VerifyType[T]:

    def __init__(self, v_type: type[T]): ...

    def verify(self, obj: Any) -> T: ...


def ensure_typed[T](array: list[Any], v_type: type[T] | None = None) -> list[str] | list[T]:
    if v_type is not None:
        adapter = VerifyType[v_type](v_type)
    else:
        adapter = VerifyType[str](str)

    return [adapter.verify(val) for val in array]
    # ^ Type "list[T@ensure_typed | str]" is not assignable to return type "list[str] | list[T@ensure_typed]"  (reportReturnType)

Pyright should say the list comprehension lines up with the function signature in this example.

VS Code extension or command-line
I'm using basedpyright, but I was able to reproduce this issue in the pyright playground.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions