pio*_*tec 6 python type-hinting python-3.x mypy python-typing
我有一个具有以下签名的函数:
def wait_for_namespaced_objects_condition(
obj_type: Type[NamespacedAPIObject],
obj_condition_fun: Callable[[NamespacedAPIObject], bool],
) -> List[NamespacedAPIObject]:
...
Run Code Online (Sandbox Code Playgroud)
这里的重要部分是NamespacedAPIObject参数。此函数采用obj_typeas 类型规范,然后创建该类型(类)的对象(实例)。然后将该类型的其他一些对象添加到列表中,然后使用mypy`obj_condition_fun类型List[NamespacedAPIObject]. This works fine and also evaluates OK with 对其进行过滤并返回。
现在,我想让这个函数通用,以便NamespacedAPIObject可以使用它的任何子类型。我的尝试是这样做的:
T = TypeVar("T", bound=NamespacedAPIObject)
def wait_for_namespaced_objects_condition(
obj_type: Type[T],
obj_condition_fun: Callable[[T], bool],
) -> List[T]:
Run Code Online (Sandbox Code Playgroud)
但是Type[T]是TypeVar,所以这不是要走的路。问题是:应该使用什么类型的obj_type参数才能使这项工作起作用?我试过Generic[T],这对我来说似乎是最合理的,但它不起作用。如果我把它放在那里obj_type: T,mypy评估这可以,但对我来说似乎是错误的。在我看来,这意味着它obj_type是一个子类型的类的实例NamespacedAPIObject,而我想说的是“T 是一个表示 子类型的类变量NamespacedAPIObject。如何解决这个问题?
[编辑] 为了更好地解释(请参阅下面的评论)为什么Type[T]对我不起作用:在我的情况下, T 的所有子类型都实现了 class method objects(),但是当我尝试像这样编写代码时:
obj_type.objects()
Run Code Online (Sandbox Code Playgroud)
mypy 返回:
pytest_helm_charts/utils.py:36: error: "Type[T]" has no attribute "objects"
Run Code Online (Sandbox Code Playgroud)
但 Type[T] 是 TypeVar,所以这不是正确的方法。
不,你走在正确的道路上——这TypeVar绝对是正确的道路。这里的问题在于类被包装在尚无法处理的pykube.objects.APIObject装饰器中。mypy添加类型存根 forpykube.objects将解决该问题。创建一个目录_typeshed/pykube并添加最小类型存根pykube:
_typeshed/pykube/__init__.pyi:
from typing import Any
def __getattr__(name: str) -> Any: ... # incomplete
Run Code Online (Sandbox Code Playgroud)
_typeshed/pykube/objects.pyi:
from typing import Any, ClassVar, Optional
from pykube.query import Query
def __getattr__(name: str) -> Any: ... # incomplete
class ObjectManager:
def __getattr__(self, name: str) -> Any: ... # incomplete
def __call__(self, api: Any, namespace: Optional[Any] = None) -> Query: ...
class APIObject:
objects: ClassVar[ObjectManager]
def __getattr__(self, name: str) -> Any: ... # incomplete
class NamespacedAPIObject(APIObject): ...
Run Code Online (Sandbox Code Playgroud)
正在运行
$ MYPYPATH=_typeshed mypy pytest_helm_charts/
Run Code Online (Sandbox Code Playgroud)
正确解析obj_type.objects:
T = TypeVar('T', bound=NamespacedAPIObject)
def wait_for_namespaced_objects_condition(obj_type: Type[T]) -> List[T]:
reveal_type(obj_type.objects)
Run Code Online (Sandbox Code Playgroud)
输出:
pytest_helm_charts/utils.py:29: note: Revealed type is 'pykube.objects.ObjectManager'
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
912 次 |
| 最近记录: |