此函数的类型标注正确吗?
import subprocess
from os import PathLike
from typing import Union, Sequence, Any
def run(shell_command: Union[bytes, str, Sequence[Union[bytes, str, PathLike]]], **subprocess_run_kwargs: Any) -> int:
return subprocess.run(shell_command, check=True, shell=True, **subprocess_run_kwargs).returncode
我猜不是,因为我得到:
he\other.py:6: error: Missing type parameters for generic type
要获取相同的错误,请将上面的代码保存在other.py
中,然后:
$ pip install mypy
$ mypy --strict other.py
答案 0 :(得分:1)
PathLike
是通用类型,因此您需要将其与类型参数一起使用(例如AnyStr
):
import subprocess
from os import PathLike
from typing import Union, Sequence, Any, AnyStr
def run(shell_command: Union[bytes, str, Sequence[Union[bytes, str, PathLike[AnyStr]]]], **subprocess_run_kwargs: Any) -> int:
return subprocess.run(shell_command, check=True, shell=True, **subprocess_run_kwargs).returncode
相关问题:
更新
对不起,我没有在运行时检查此代码。通过一些技巧,可以编写解决方法:
import subprocess
from os import PathLike as BasePathLike
from typing import Union, Sequence, Any, AnyStr, TYPE_CHECKING
import abc
if TYPE_CHECKING:
PathLike = BasePathLike
else:
class FakeGenericMeta(abc.ABCMeta):
def __getitem__(self, item):
return self
class PathLike(BasePathLike, metaclass=FakeGenericMeta):
pass
def run(shell_command: Union[bytes, str, Sequence[Union[bytes, str, PathLike[AnyStr]]]], **subprocess_run_kwargs: Any) -> int:
return subprocess.run(shell_command, check=True, shell=True, **subprocess_run_kwargs).returncode
与此变通办法相关的问题:
答案 1 :(得分:1)
如sanyash的答案所述,os.PathLike
被定义为通用类型。您可以查看stub in the typeshed repo。但是,os.PathLike
仅在存根文件中是通用的,从os
导入的实现不是。
不指定类型var参数(path: PathLike
)会导致mypy错误。指定类型var参数(path: PathLike[Any]
)会导致Python解释器(运行时)错误。
在mypy仓库中已提出此确切问题{{3}}。结果,#5667扩展了mypy文档:
添加的部分指出了两种处理方法:
使用typing.TYPE_CHECKING
提供不同的注释,具体取决于类型检查器还是Python解释器(运行时)来解释文件。
from os import PathLike
import subprocess
from typing import Any, Sequence, TYPE_CHECKING, Union
if TYPE_CHECKING:
BasePathLike = PathLike[Any]
else:
BasePathLike = PathLike
def run(shell_command: Union[bytes, str, Sequence[Union[bytes, str, BasePathLike]]], **subprocess_run_kwargs: Any) -> int:
return subprocess.run(shell_command, check=True, shell=True, **subprocess_run_kwargs).returncode
将注释作为字符串提供。 Python解释器(运行时)不会解释注释,但mypy会选择正确的含义。
import subprocess
from typing import Any, Sequence, Union
def run(shell_command: Union[bytes, str, Sequence[Union[bytes, str, 'PathLike[Any]']]], **subprocess_run_kwargs: Any) -> int:
return subprocess.run(shell_command, check=True, shell=True, **subprocess_run_kwargs).returncode