我遇到了这种静态类型的提示不匹配(与Pyright):
from __future__ import annotations
from typing import AnyStr, Iterable
def foo(i: Iterable[AnyStr]):
return i
def bar(i: Iterable[str] | Iterable[bytes]):
return i
def baz(i: Iterable[str | bytes]):
return i
def main():
s = ['a']
# makes sense to me
baz(foo(s)) # allowed
foo(baz(s)) # not allowed
# makes sense to me
baz(bar(s)) # allowed
bar(baz(s)) # not allowed
bar(foo(s)) # allowed
foo(bar(s)) # nope -- why?Iterable[AnyStr]和Iterable[str] | Iterable[bytes]有什么区别?
难道它们不应该是“等同的”吗?(对于引用上下文中单个一致类型的AnyStr除外)
更具体地说:键入以下提示的正确方法是什么?
import random
from typing import Iterable, AnyStr
def foo(i: Iterable[AnyStr]):
return i
def exclusive_bytes_or_str(): # type-inferred to be Iterator[bytes] | Iterator[str]
if random.randrange(2) == 0:
return iter([b'bytes'])
else:
return iter(['str'])
foo(iter([b'bytes'])) # fine
foo(iter(['str'])) # fine
foo(exclusive_bytes_or_str()) # same error发布于 2021-08-23 23:56:57
从回答到erictraut@github的释义
这实际上并不是受约束的TypeVar的预期用途。我建议使用
@overload来代替: @重载def foo(i: Iterablestr) -> Iterablestr:.@重载def foo(i: Iterable字节) -> Iterablestr字节:.def foo(i: IterableAnyStr) -> IterableAnyStr:返回i
因为:
类型Iterablestr \Iterablestr字节不能分配给IterableAnyStr类型。约束类型变量需要与其约束之一相匹配,而不是多个约束。当一个类型变量被“解决”时,它需要被另一个(通常是具体的)类型替换。如果foo(bar(s))被允许,AnyType@foo类型变量将解析到什么类型?如果它被解析为str \字节类型,那么foo的具体返回类型将是Iterablestr \字节。这显然是错误的。
https://stackoverflow.com/questions/68869110
复制相似问题