Разбор docopt не возвращает ожидаемый словарь - PullRequest
0 голосов
/ 24 июня 2019

Я хочу использовать те же инструменты 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
""" 

Но ни одна из следующих строк не приводит к словарю docopt:

  • "wplan --progress" -> без словаря -> экран использования
  • "wplan --forced" -> без словаря -> экран использования
  • "wplan --verbose" -> нет словаря -> экран использования

Хорошо - я проверяю документацию с этим файлом:

#!/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()

Так что, если я запущу этот документ-тест.В файле py ("python3.7 docopttest.py") отображается только информация об ОШИБКЕ!

...