本文介绍了Python:引发argparse.ArgumentError之后,argparse引发通用错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我为需要遵循精确格式的参数定义了自定义正则表达式类型.我使用了另一篇文章中的代码( regex自定义类型 )非常有用.我的问题是我正在编写单元测试,希望正则表达式失败,并试图断言argparse.ArgumentError被引发(assertRaises(argparse.ArgumentError, parser.parse_args(inargs.split()))).问题是argparse似乎正在捕获ArgumentError并抛出一般错误,使我无法验证失败原因.我想念什么吗?

I defined a custom regex type for an argument that needs to follow an exact format. I used code from another post (regex custom type) that has been super useful. My problem is that I'm writing unit tests where I expect the regex to fail and trying to assert that the argparse.ArgumentError is raised ( assertRaises(argparse.ArgumentError, parser.parse_args(inargs.split())) ). The problem is that argparse appears to be catching the ArgumentError and throwing a generic error, preventing me from verifying the cause of the failure. Am I missing something?

这是回溯:

Error
Traceback (most recent call last):
  File "/Users/markebbert/PyCharmProjects/newproject/unittests.py", line 203, in test_set_operation_parameter
    self.assertRaises(argparse.ArgumentError, parser.parse_args(inargs.split()))
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/argparse.py", line 1688, in parse_args
    args, argv = self.parse_known_args(args, namespace)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/argparse.py", line 1727, in parse_known_args
self.error(str(err))
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/argparse.py", line 2347, in error
    self.exit(2, _('%s: error: %s\n') % (self.prog, message))
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/argparse.py", line 2335, in exit
    _sys.exit(status)
SystemExit: 2

这是我定义的自定义类型和解析器代码:

Here is my defined custom type and the parser code:

class RegexValidator(object):
    """
    Performs regular expression match on value.
    If match fails an ArgumentError is raised
    """

    def __init__(self, pattern, statement=None):
        self.pattern = re.compile(pattern)
        self.statement = statement
        if not self.statement:
            self.statement = "must match pattern %s" % self.pattern

    def __call__(self, string):
        match = self.pattern.search(string)
        if not match:
            raise argparse.ArgumentError(None, self.statement)
        return string


operatorRV = RegexValidator(
    "^((\w+)=)?[iIuUcC]\[(\w+(\[\w+(,\w+)*\])?)(:\w+(\[\w+(,\w+)*\])?)*\]$",
    "Set operations must conform to...")

parser = argparse.ArgumentParser(
    description='Compare variants across individuals',
    formatter_class=argparse.ArgumentDefaultsHelpFormatter)

group.add_argument('-s', '--set-operation', dest='operation', nargs='+',
                   type=operatorRV,
                   help="blah.")

这是单元测试:

    # Fail for ending colon
    inargs = "-s out=i[one[id1]:]"
    self.assertRaises(argparse.ArgumentError, parser.parse_args(inargs.split()))

推荐答案

Argparse是一个命令行解析器,错误总是以argparse.exit()结尾,而argparse.exit()则依次以错误代码调用sys.exit().这是设计使然.

Argparse is a command line parser, and errors always end up calling argparse.exit(), which in turn calls sys.exit() with an error code. This is by design.

对于单元测试,您必须分析器的.error().exit()方法(可能使用模拟)来进行猴子补丁.会出现错误消息,调用.error()并打印使用情况消息,然后使用退出代码和错误消息调用.exit().

For a unit test, you'd have to monkeypatch (using mocking perhaps) the .error() or the .exit() methods of the parser. .error() is called with an error message and prints the usage message, then calls .exit() with an exit code and the error message.

他们当前的实现方式:

# ===============
# Exiting methods
# ===============
def exit(self, status=0, message=None):
    if message:
        self._print_message(message, _sys.stderr)
    _sys.exit(status)

def error(self, message):
    """error(message: string)

    Prints a usage message incorporating the message to stderr and
    exits.

    If you override this in a subclass, it should not return -- it
    should either exit or raise an exception.
    """
    self.print_usage(_sys.stderr)
    self.exit(2, _('%s: error: %s\n') % (self.prog, message))

这篇关于Python:引发argparse.ArgumentError之后,argparse引发通用错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-31 04:48