Python Mypy不支持的类型[typeVarAlias]

Python Mypy不支持的类型[typeVarAlias],python,python-3.x,type-hinting,mypy,Python,Python 3.x,Type Hinting,Mypy,Mypy返回了一个我不理解的错误(我也不能以简化的形式重新创建)。用谷歌搜索错误被证明是困难的(考虑到问号) 有人知道这个错误是什么意思吗?特别是问号表示什么 不支持的类型[typeBasePage?] 有关守则: typeBasePage=TypeVar(“typeBasePage”,bind=“BasePage”)#BasePage的任何实例子类 typeNavCls=Type[typeBasePage]#此处发生错误-尝试创建别名 类别导航: 定义初始化(self,cls:typeNavC

Mypy返回了一个我不理解的错误(我也不能以简化的形式重新创建)。用谷歌搜索错误被证明是困难的(考虑到问号)

有人知道这个错误是什么意思吗?特别是问号表示什么

不支持的类型[typeBasePage?]

有关守则:

typeBasePage=TypeVar(“typeBasePage”,bind=“BasePage”)#BasePage的任何实例子类
typeNavCls=Type[typeBasePage]#此处发生错误-尝试创建别名
类别导航:
定义初始化(self,cls:typeNavCls):
self.cls:typeNavCls=cls
类基本页(基本):
...
#修改是因为它很大
同样,如果我尝试以非常简化的形式重新创建上述代码,mypy不会出错

typeB=TypeVar('typeB',bound='B')
tAlias=类型[typeB]
类别导航:
定义初始(自我,cls:tAlias):
self.cls:tAlias=cls
甲级:及格
B(A)级:及格

我相信我找到了问号,但我还没有弄清楚mypy中出现错误的原因

如果在
Final
中未提供显式类型,则
c
变得上下文敏感:mypy基本上会尝试“替换” 执行类型之前使用的原始赋值 检查。这就是为什么
c
的显示类型是
Literal[19]?
: 结尾的问号反映了这种上下文敏感的性质


如果没有一个完整的程序,我恐怕很难确定问题出在哪里。我认为这很可能是一个mypy错误:mypy可能会被代码中的一些循环弄糊涂。可能是一个导入周期,一些奇怪的模块和子模块的导入,你的mypy缓存不知怎么被破坏了

另一种可能性是,您的代码在某种程度上不是类型安全的,而这个错误只是mypy试图以任何方式前进的下游结果

为了帮助缩小问题范围,我建议在确保使用最新版本并删除
.mypy\u缓存
文件后重新运行mypy。如果问题仍然存在,那么可以尝试稳定地删除代码库中不相关的部分,以尝试重新编写代码


也就是说,在这里完全不使用类型别名也是值得的:在您的示例中使用别名/a类型变量实际上没有任何好处

简言之,如果在类型别名中使用任何类型变量,那么这些类型变量实际上始终是自由的:当您开始使用别名时,需要显式地将它们绑定到某个类型。因此,您不需要执行
def\uuu init\uuuuu(self,cls:typeNavCls)
,而是要执行
def\uu init\uuuuuu(self,cls:typeNavCls[SomeTypeHere])

否则,mypy会将您的签名视为与
def\uu init\uuuself(cls:typeNavCls[Any])
完全相同,就像
def foo(x:List)
的签名被视为
def foo(x:List[Any])
一样

您可以通过使用
--strict
标记或
--disallow any generics
标志运行mypy来配置mypy以警告您此问题:前者标志自动启用后者

相反,您可能应该执行以下操作之一:

#方法1:如果您不希望Nav具有固有的通用性
类别导航:
定义初始化(self,cls:Type[BasePage]):
self.cls=cls
#方法2:如果您希望Nav本质上是通用的
_TBasePage=TypeVar(“TBasePage”,bind='BasePage')
类导航(通用[\u TBasePage]):
定义初始化(self,cls:Type[\u TBasePage]):
self.cls=cls
#方法3:如果要确保两种或两种以上的类型相同,
#但是没有别的了
类别导航:
定义初始化(self,cls:Type[\u TBasePage],实例:\u TBasePage):
#…但您将无法在此处将“cls”保存为字段:您的
#如果需要,Nav类需要是关于_TBasePage的泛型
#希望“保留”绑定为字段的任何类型。
#方法4:如果您的别名在您想要的地方足够复杂
#强制别名中两个或多个类型之间的关系
MyAlias=元组[类型[\u-BasePage],\u-BasePage]
类别导航:
定义初始化(self,信息:MyAlias[BasePageSubtype]):
self.info=info
#方法5:……或者如果您希望导航也是通用的:
MyAlias=元组[类型[\u-BasePage],\u-BasePage]
类导航(通用[\u TBasePage]):
定义初始化(self,信息:MyAlias[\u TBasePage]):
self.info=info
#重要提示:前面的示例实际上是
#相当于做:
_T1=类型变量(“U T1”,绑定=基本页)
MyAlias=Tuple[类型[_T1],T1]
_T2=类型变量(“T2”,绑定=基本页)
类别导航(通用[_T2]):
定义初始化(self,信息:MyAlias[\u T2]):
self.info=info
方法1、2和3应该避开您原来的问题。如果这些方法与您实际想要做的类似,那么根本不使用别名就更简单/更简洁了。如果你没有使用别名,那么你就不会遇到这个bug

但是,如果您的实际代码更像方法4或5,那么不幸的是,可能需要进行更深入的调查


最后一点要注意的是:文档的这一部分提到的是在文本类型上下文中使用问号。但您没有使用文字类型,所以文档的这一部分在这里不相关

如果一个问题出现在一个常规实例之后,这意味着该类型实际上是一个“未绑定类型”。这是一种特殊的仅限内部的类型,mypy将其用作占位符,用于那些应该是类型但找不到相应定义的对象

这要么意味着mypy中存在一个bug,导致未绑定类型出现在它不应该出现的地方,要么意味着存在其他一些可能的合法错误