IntelliJ Python 3检查"Expected a dictionary, got a dict"对于带有**kwargs的超级函数是误报吗?

25

我使用Python 3,希望用一个自定义类来包装argparse.ArgumentParser,并默认设置formatter_class=argparse.RawDescriptionHelpFormatter。我可以成功地做到这一点,但是IntelliJ IDEA 2017.1与Python插件(PyCharm)对以下代码发出了警告:

class CustomParser(argparse.ArgumentParser):
def __init__(self, formatter_class=argparse.RawDescriptionHelpFormatter, **kwargs):
    # noinspection PyArgumentList
    super().__init__(formatter_class=formatter_class, **kwargs)  # warning in this line for the last argument if suppression comment above removed

如果使用IntelliJ的抑制命令去掉kwargs的注释,那么"Expected a dictionary, got a dict"警告就会消失,但是这段代码仍然有效。这是一个误报警告吗?还是有更好的方法可以避免这个警告?这个警告背后是否存在真正的问题?
另外一个问题:使用
formatter_class = kwargs.pop('formatter_class', argparse.RawDescriptionHelpFormatter)与在签名中明确定义命名参数有什么区别吗?根据PEP20,在签名中更加明确是更好的,对吗?

现在我看到另一个警告,如果我想使用CustomParser(formatter_class=argparse.HelpFormatter)更改默认格式化程序,我会收到警告“预期类型为'Type[RawDescriptionHelpFormatter]',而实际得到的是'Type[HelpFormatter]'”,可以通过# noinspection PyTypeChecker来抑制。这也是误报吗? - jan
3个回答

17

是的,那似乎是一个错误的阳性结果。

你问到了 formatter_class=kwargs.pop('formatter_class', argparse.RawDescriptionHelpFormatter)。请不要这样做。改变 kwargs,它似乎是下一个参数,看起来很糟糕。此外,默认关键字参数应该设置为一个简单的常量,而不是一些可变数据结构,因为在导入时和运行时评估之间有很大的区别。例如,参见 http://www.effbot.org/zone/default-values.htm 。通常的惯用语是在签名中使用 formatter_class=None ,然后在主体中测试是否为 None 并且您可以任意更改 kwargs。


你知道一个方便的例子,可以说明这个警告是真正的问题而不是误报吗?自从上次提问以来,我在Python方面没有做过太多的工作,这看起来是一个非常简单的错误,对吧? - jan
4
一周前,Pavel Karateev在https://youtrack.jetbrains.com/issue/PY-27935中解释说这只是一个错误,并且现在在pycharm 2017.3.3 RC中已经修复;请参考基本错误https://youtrack.jetbrains.com/issue/PY-27686中的简单重复方式。 - J_H
看起来你的链接错误只涉及到Python 2,你确定这个Python 3的误报警告已经在这个版本中解决了吗?如果我有时间,我会更新并验证一下。 - jan
没错,那是纯粹的Python2问题。你可能需要为Python3提交一个新的错误报告。 - J_H

2
将存储在项目中的所有虚拟环境目录(例如./venv)标记为排除的,这对我在PyCharm 2020.2.3中解决了问题。
操作步骤:右键单击项目树中的虚拟环境目录,选择:标记目录为 -> 排除。解决方案来自https://youtrack.jetbrains.com/issue/PY-39715

1

是的,那似乎是一个误报。正如@J_H所说。

我通过Chat-gpt得到了最好的建议。在字符串末尾添加注释# type: ignore

class Price(ItemBase):
def __init__(self, *args, **kwargs):
    super(Price, self).__init__(*args, **kwargs)  # type: ignore

这正是我正在寻找的:# type: ignore。谢谢! - Mihai-Cristian

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接