根据您的回答,我假设您希望 linter 传递 bar 的定义,并且您愿意为此目的对 bar 的实现/声明进行更改。
对我来说,根本问题是 bar 的实现是错误的 - 如果 *args 不为空,那么调用 foo(biz=ness, *args, **kwargs) 将失败,并与 mypy 报告的错误完全相同。
def foo(biz: str = 'biz',baz: str = 'baz', *args:Any, **kwargs:Any)-> str:
return biz + baz
def bar_from_question(ness: str = 'ness', *args, **kwargs):
return foo(biz=ness, *args, **kwargs)
>>> bar_from_question("1")
1baz
>>> bar_from_question("1", "2")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/jean/Projects/python/test-mypy/test.py", line 7, in bar_from_question
return foo(biz=ness, *args, **kwargs)
TypeError: foo() got multiple values for argument 'biz'
对我来说,你有三个选择:
-
通过不再传递 args 来修复对 foo 的调用。这样的更改不会导致功能损失,因为在bar 中有一个非空的args 无论如何都会引发TypeError。在这种情况下,您还可以从 bar 的签名中删除 args(同样,不会丢失功能 - 您只需将调用 foo 触发的 TypeError 替换为 @ 调用中的 TypeError 987654338@)
def bar_do_not_pass_args_to_foo(ness: str = 'ness', *args, **kwargs):
return foo(biz=ness, **kwargs)
def bar_remove_args_from_signature(ness: str = 'ness', **kwargs):
return foo(biz=ness, **kwargs)
-
通过将biz 作为位置参数而不是命名参数传递来修复对foo 的调用:
def bar_pass_biz_as_positional(ness: str = 'ness', *args, **kwargs):
return foo(ness, *args, **kwargs)
-
向 mypy 隐藏问题(我从您的回答中了解到)
def bar_hide_from_mypy(ness: str = 'ness', *args, **kwargs):
kwargs['biz'] = ness
return foo(*args, **kwargs)
但是,如果目标只是防止 mypy 报告错误,则有以下语法:
def bar_suppress_mypy(ness: str = 'ness', *args, **kwargs):
return foo(biz=ness, *args, **kwargs) # type: ignore
现在,如果我在运行时解释器中比较每个提案的结果:
>>> bar_do_not_pass_args_to_foo("1")
'1baz'
>>> bar_do_not_pass_args_to_foo("1", "2")
'1baz'
>>> bar_remove_args_from_signature("1")
'1baz'
>>> bar_remove_args_from_signature("1", "2")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: bar_remove_args_from_signature() takes from 0 to 1 positional arguments but 2 were given
>>> bar_pass_biz_as_positional("1")
'1baz'
>>> bar_pass_biz_as_positional("1", "2")
'12'
>>> bar_hide_from_mypy("1")
'1baz'
>>> bar_hide_from_mypy("1", "2")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/jean/Projects/python/test-mypy/test.py", line 20, in bar_hide_from_mypy
return foo(*args, **kwargs)
TypeError: foo() got multiple values for argument 'biz'
>>> bar_suppress_mypy("1")
'1baz'
>>> bar_suppress_mypy("1", "2")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/jean/Projects/python/test-mypy/test.py", line 23, in bar_suppress_mypy
return foo(biz=ness, *args, **kwargs) # type: ignore
TypeError: foo() got multiple values for argument 'biz'
你可以看到:
- 对于
bar_from_question 返回结果的每种情况,所有其他bar_... 实现都返回相同的结果;
- 除了
bar_from_question 之外的所有实现都对 mypy 保持沉默,我认为这就是您想要的;
在您的情况下,我会寻求解决根本问题的方法(即应用要点 1 或 2),而不是仅仅试图强制 mypy(要点 3)。