![](/img/trans.png)
[英]Can docopt generate an argument parsing class that doesn't depend on docopt?
[英]docopt parsing doesn't return the expected dictionary
我想做同样的cli工具并试过docopt但我多次挣扎:
这是我的文档字符串:
"""
usage:
wplan [--progress] [--forced] [--path DIR]
[--verbosity VMODE]
wplan -h
options:
--progress show progress bar
--forced force overwrite
--path DIR ddsfwefafef [default: /path/to/file]
--verbosity VMODE asdfasdf [default: 1]
-h some help
"""
但是以下cli字符串中没有一个产生docopt字典:
好的 - 我用这个文件测试docopt东西:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sys
import os
# to run docopt.docopt in a test: replace DocoptExit in docopt
# func
from docopt import \
DocoptExit, printable_usage, parse_defaults, parse_pattern, \
formal_usage, TokenStream, parse_argv, Option, Dict, \
AnyOptions, extras
def pseudo_docopt(doc, argv=None, help=True, version=None,
options_first=False):
"""Thats a copy of docopt.docopt function. Only the last line
the "DocoptExit()" statement ist replaced by "raise RuntimeError".
"""
if argv is None:
argv = sys.argv[1:]
DocoptExit.usage = printable_usage(doc)
options = parse_defaults(doc)
pattern = parse_pattern(formal_usage(DocoptExit.usage), options)
argv = parse_argv(TokenStream(argv, DocoptExit), list(options),
options_first)
pattern_options = set(pattern.flat(Option))
for ao in pattern.flat(AnyOptions):
doc_options = parse_defaults(doc)
ao.children = list(set(doc_options) - pattern_options)
extras(help, version, argv, doc)
matched, left, collected = pattern.fix().match(argv)
if matched and left == []: # better error message if left?
return Dict((a.name, a.value)
for a in (pattern.flat() + collected))
# if code goes here no dict is sent
raise RuntimeError()
# some command line tests
cltests = [
[],
# 1 arg
["--progress"],
["--forced"],
# 2 args
["--progress", "--forced"],
["--forced", "--progress"],
["--path /path/to/file"],
["--verbosity", "2"],
# 3 args
["--progress", "--path", "/path/to/file"],
["--forced", "--path", "/path/to/file"],
["--progress", "--verbosity", "2"],
["--forced", "--verbosity", "2"],
# 4 args
["--forced", "--progress", "--path", "/path/to/file"],
["--progress", "--forced", "--path", "/path/to/file"],
["--forced", "--progress", "--verbosity", "2"],
["--progress", "--forced", "--verbosity", "2"],
]
# the __doc__ fake
doc = """
usage:
wplan [--progress] [--forced] [--path DIR]
[--verbosity VMODE]
wplan -h
options:
--progress show progress bar
--forced force overwrite
--path DIR ddsfwefafef [default: /path/to/file]
--verbosity VMODE asdfasdf [default: 1]
-h some help
"""
for args in cltests:
cmd = ["wplan", ] + args
info = "run {}".format(cmd)
print(info + os.linesep + "-" * len(info))
try:
data = pseudo_docopt(doc=doc, argv=cmd)
assert isinstance(data, dict)
assert "--progress" in data
assert "--progress" in data
assert "--forced" in data
assert "--path" in data
assert "--verbosity" in data
print("... OK there is a docopt dict")
except RuntimeError:
print("... ERROR: no docopt dict for: {}".format(cmd))
print()
所以如果我运行这个docoptest.py文件(“python3.7 docopttest.py”),只会出现错误信息!
前两个实际工作,这里是现场演示:
最后需要修改以匹配使用模式,例如:
阅读你的代码,我认为这将避免使用pseudo_docopt
函数,允许使用真正的docopt:
for args in cltests:
... # same
try:
data = docopt.docopt(doc=doc, argv=cmd)
... # assert, print... same
except DocoptExit:
print("... ERROR: no docopt dict for: {}".format(cmd))
需要注意的是DocoptExit
从继承SystemExit
它继承形成BaseException
,所以仅使用except Exception
将无法正常工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.