PyType对合法类方法返回bad-concrete-type错误,求正确注解方案
解决PyType泛型类实例化的类型检查错误
我来帮你排查这个PyType报错的问题——你遇到的Invalid instantiation of generic class [bad-concrete-type]错误,核心原因是前向引用的类属性注解在PyType的类型推导流程中没被正确识别,导致它没法确认cls._things[id_]的类型确实是Thing,进而认为你传给Container的参数不符合泛型要求。另外你提到的.pyi文件里类属性和实例属性表现类似,这其实是PyType生成存根文件的正常行为,问题根源还是类型注解的解析问题。
下面是几个实用的修复方案,按推荐优先级排序:
方案1:启用延迟注解(最推荐)
给文件顶部加上from __future__ import annotations(Python 3.7及以上版本支持),这个语法会让所有类型注解以字符串形式保留,PyType能更顺畅地解析前向引用。同时保持你的原有注解结构即可:
from __future__ import annotations from typing import List, Generic, TypeVar T = TypeVar('T') class Container(Generic[T]): def __init__(self, item: T) -> None: self.item = item class Thing: _things: List['Thing'] = [] @classmethod def get(cls, id_: int) -> Container['Thing']: return Container(cls._things[id_])
方案2:显式指定泛型实例化参数
有时候PyType需要更明确的提示,你可以在实例化Container的时候显式声明泛型参数,帮类型检查器锁定类型:
@classmethod def get(cls, id_: int) -> Container['Thing']: # 显式指定Container的泛型参数为Thing return Container[Thing](cls._things[id_])
方案3:使用类内部类型别名
如果上面两种方法都不生效,可以给Thing定义一个内部类型别名,用别名来做注解,降低PyType解析前向引用的难度:
class Thing: # 定义内部类型别名指向自身 _Self = 'Thing' _things: List[_Self] = [] @classmethod def get(cls, id_: int) -> Container[_Self]: return Container(cls._things[id_])
验证修复
修改完成后,运行PyType检查命令确认报错消失:
pytype your_module.py
内容的提问来源于stack exchange,提问作者Bruno Kim
相关产品推荐
相关产品推荐

