【问题标题】:What type of error argparse.ArgumentParser raises for missing required argsargparse.ArgumentParser 因缺少必需的参数而引发什么类型的错误
【发布时间】:2021-09-04 05:14:19
【问题描述】:

鉴于以下情况,我需要确保使用 pytest 引发错误:

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('-x', required=True)
parser.parse_args()

调用时不向-x 标志传递一些东西,将导致:

usage: my_script.py [-h] -x X
my_script.py: error: the following arguments are required: -x

如果我故意尝试创建一个模棱两可的类型错误,我可能无法想出更好的错误。我需要指定一些要检查的错误类型,如下所示:

with pytest.raises(SomeError):
    test_condition()

即使在 tryexcept 块中包装东西也行不通,到目前为止,我尝试了 KeyErrorValueErrorSystemErrorSystemExitargparse.ArgumentErrorKeyError、@ 987654333@ ... 似乎没有任何效果。

【问题讨论】:

  • 我认为无法直接从“argparse implementation”的输出中捕获异常,因为它不会引发异常,而是在控制台中显示人类可读的消息。因此,我相信您必须自己获取输出并引发异常,因此稍后您将能够使用您的“pytest.raises”实现来捕获它
  • 为什么要简化事情,而我们可以像往常一样让它变得不可能具有挑战性。
  • 如果这是通过异常处理的,你也会得到一个回溯,这肯定不是你在 CLI 中想要的。它可能正在打印消息然后退出。因此,如果有的话,系统退出异常可能是您唯一可以捕获的。
  • 没有任何东西可以捕捉到它,即使是一个裸露的例外。我知道这可能是故意的,但我只是不明白为什么它不应该是一个例外,以及它与print('I am an error'); exit(1) 的不同之处
  • 查看argparse.py 文件。像这样的错误会通过parser.errorparser.exit。这是一个sys.exit。其他 [argparse] SO 问题讨论了测试。

标签: python error-handling argparse


【解决方案1】:

默认情况下,argparse 不会抛出异常,而是在发生错误时退出。从 python 3.9 开始,有一个 exit_on_error 参数,但它只在类型检查失败时引发异常。还是exit on unknown argument

不改变程序行为的更好方法是检查对sys.exit的调用:

>>> import argparse, mock
>>> parser = argparse.ArgumentParser()
>>> with mock.patch("sys.exit") as m:
...     parser.parse_args(("bad", "argument"))
...     print("sys.exit call count: %d" % m.call_count)
... 
usage: [-h]
: error: unrecognized arguments: bad argument
Namespace()
sys.exit call count: 1

【讨论】:

  • 谢谢,通过将SystemExit 传递给pytest.raises() 并进行其他修改,我能够通过曾经失败的测试。您的答案非常有用,但这是测试相同条件的另一种方法。
猜你喜欢
  • 1970-01-01
  • 2022-08-11
  • 1970-01-01
  • 2019-11-16
  • 2015-11-02
  • 2021-09-12
  • 2022-01-01
  • 2022-06-28
  • 2017-10-28
相关资源
最近更新 更多