You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

传递泛型类作为值时类型提示异常,是代码问题还是pyright Bug?

Pyright泛型类条件选择后的类型提示问题

当使用条件表达式(a = cls1 if cond else cls2)或字典映射选择泛型类时,pyright无法正确推断实例化后方法的TypeVar类型,导致参数提示为Any,但mypy能正确检查类型错误。示例代码如下:

from typing import Generic, TypeVar

T = TypeVar("T")
class Foo(Generic[T]): 
    def __init__(self, t: T):
        self.t = t
    
    def print(self, t: T): 
        print(t, self.t)

class Foo2(Foo[T]): 
    def print(self, t: T):
        if t == self.t: 
            print("equal")
        else: 
            Foo.print(self, t)

check_equal: bool
printer = Foo2 if check_equal else Foo

a = printer(3)
a.print(...)  # pyright提示参数为Any,mypy能检查非int类型错误

问题分析

你的代码本身没有错误,这是pyright在处理泛型类的联合类型赋值时的类型推断限制:

  • pyright会将printer推断为Type[Foo[T]] | Type[Foo2[T]],但在实例化printer(3)后,未能将T的具体类型(int)绑定到实例的方法参数上,导致提示为Any。
  • mypy的泛型推断逻辑更完善,能够追踪到实例化时传入的int类型,进而正确校验print方法的参数类型。

解决方案

1. 显式标注printer的类型

通过明确指定泛型类型,帮助pyright绑定TypeVar:

from typing import Type, Union

# 方式1:用Union标注具体的类类型
printer: Union[Type[Foo[T]], Type[Foo2[T]]] = Foo2 if check_equal else Foo

# 方式2:利用子类兼容性,直接标注为父类的泛型类型
printer: Type[Foo[T]] = Foo2 if check_equal else Foo

2. 实例化时显式指定泛型参数

直接给类指定泛型类型,强制pyright识别参数类型:

a = printer[int](3)
a.print(...)  # 此时会正确提示参数为int

内容的提问来源于stack exchange,提问作者LibrarristShalinward

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 06:22:08