如何为一个接受可变数量参数的Python函数在存根文件中写类型注解?
我想在一个存根文件里为以下函数写类型提示:
#foo.py
def foo(*args, bar="bar"): ...
我的要求如下:
- 如果没有给出
args
,那么返回类型是any
。 - 如果给出一个类型为
_P
的args
,那么返回类型就是_P
。 - 如果给出多个
args
,它们必须都是同一种类型_P
,那么返回类型就是tuple[_P, ...]
。
我尝试了以下方法:
# foo.pyi
@overload
def foo(bar: str = ...) -> Any: ...
@overload
def foo(args: _P, bar: str = ...) -> _P: ...
@overload
def foo(arg1: _P, *args: _P, bar: str = ...) -> tuple[_P, ...]: ...
但是运行 python -m mypy.stubtest foo
时出现了错误 stub argument "bar" is not keyword-only
,而且通过在前面加上 *args
来让参数变成关键字参数,反而遮盖了下面的重载。
我还尝试了 foo(*, bar: str = ...)
,但这似乎并没有把 bar
标记为关键字参数。添加 *
后,错误信息从
error: foo.foo is inconsistent, stub argument "bar" is not keyword-only
Stub: in file /home/niklas/Desktop/test/foo.pyi:5
Overload(def (bar: builtins.str =) -> Any, def [_P] (args: _P`-1, bar: builtins.str =) -> _P`-1, def [_P] (arg1: _P`-1, *args: _P`-1, bar: builtins.str =) -> builtins.tuple[_P`-1, ...])
Inferred signature: def (arg1: _P`-1 = ..., bar: builtins.str = ..., *args)
Runtime: in file /home/niklas/Desktop/test/foo.py:1
def (*args, bar='bar')
变成了(注意第三行的星号 *
):
error: foo.foo is inconsistent, stub argument "bar" is not keyword-only
Stub: in file /home/niklas/Desktop/test/foo.pyi:5
Overload(def (*, bar: builtins.str =) -> Any, def [_P] (args: _P`-1, bar: builtins.str =) -> _P`-1, def [_P] (arg1: _P`-1, *args: _P`-1, bar: builtins.str =) -> builtins.tuple[_P`-1, ...])
Inferred signature: def (arg1: _P`-1 = ..., bar: builtins.str = ..., *args)
Runtime: in file /home/niklas/Desktop/test/foo.py:1
def (*args, bar='bar')
1 个回答
0
在评论中,@undefined 和 @chepner 提供了解决方案。请注意第一个和第二个签名中的星号 *
:
# foo.pyi
@overload
def foo(*, bar: str = ...) -> Any: ...
@overload
def foo(args: _P, *, bar: str = ...) -> _P: ...
@overload
def foo(arg1: _P, *args: _P, bar: str = ...) -> tuple[_P, ...]: ...