如何为在存根文件中采用可变数量参数的 Python 函数编写类型注释?

问题描述 投票:0回答:1

我想在存根文件中为以下函数编写类型提示:

#foo.py
def foo(*args, bar="bar"): ...

我的要求如下:

  1. 如果没有给出
    args
    ,则返回类型为
    any
  2. 如果给定了一个类型为
    args
    _P
    ,则返回类型为
    _P
  3. 如果给定多个
    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')
python mypy python-typing
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, ...]: ...
© www.soinside.com 2019 - 2024. All rights reserved.