Completed
Push — master ( ca146f...1b2584 )
by
unknown
53s
created

DocOptParse   A

Complexity

Total Complexity 37

Size/Duplication

Total Lines 82
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 0
loc 82
rs 9.44
c 1
b 0
f 0
wmc 37

8 Methods

Rating   Name   Duplication   Size   Complexity  
A _err() 0 3 1
A __init__() 0 4 3
A _chk_docopt_exit() 0 11 4
B _get_docargs() 0 18 8
A get_docargs() 0 7 3
B _chk_docunknown() 0 16 8
B _chk_docopt_kws() 0 7 7
A _set_intvals() 0 6 3
1
"""Run docopt in GOATOOLS."""
2
3
from __future__ import print_function
4
5
__copyright__ = "Copyright (C) 2016-2018, DV Klopfenstein, H Tang, All rights reserved."
6
__author__ = "DV Klopfenstein"
7
8
import sys
9
import re
10
from docopt import docopt
11
from goatools.gosubdag.utils import get_kwargs
12
13
14
class DocOptParse(object):
15
    """Run docopt in GOATOOLS."""
16
17
    def __init__(self, doc, exp_keys, exp_elems):
18
        self.doc = doc
19
        self.exp_keys = exp_keys if exp_keys else set()     # Expected dictionary keys
20
        self.exp_elems = exp_elems if exp_elems else set()  # Expected set elements (True/False)
21
22
    def get_docargs(self, args=None, prt=None, **kws):
23
        """Pare down docopt. Return a minimal dictionary and a set containing runtime arg values."""
24
        args_user = sys.argv[1:] if args is None else args
25
        arg_kws = self._get_docargs(args_user, prt)
26
        if 'intvals' in kws:
27
            self._set_intvals(arg_kws, kws['intvals'])
28
        return arg_kws
29
30
    def _get_docargs(self, args_user, prt):
31
        """Pare down docopt. Return a minimal dictionary and a set containing runtime arg values."""
32
        if prt is not None:
33
            print("DocOptParse BEFORE docopt: {}".format(args_user))
34
        docargs = docopt(self.doc, args_user)
35
        if prt is not None:
36
            print("DocOptParse AFTER  docopt: {}".format(docargs))
37
        kwargs_doc = {re.sub(r'^-{1,2}', '', k):v for k, v in docargs.items()}
38
        self._chk_docopt_kws(kwargs_doc, args_user)
39
        kwargs_usr = get_kwargs(kwargs_doc, self.exp_keys, self.exp_elems)
40
        if prt is not None:
41
            print("DocOptParse AFTER  pared: {}".format(kwargs_usr))
42
        for key in ['taxid']:
43
            if key in kwargs_usr:
44
                kwargs_usr[key] = int(kwargs_usr[key])
45
        if prt is not None:
46
            print("DocOptParse AFTER  edited/checked: {}".format(kwargs_usr))
47
        return kwargs_usr
48
49
    @staticmethod
50
    def _set_intvals(kws, keys):
51
        """Convert keyword values to int."""
52
        for key in keys:
53
            if key in kws:
54
                kws[key] = int(kws[key])
55
56
    def _chk_docopt_exit(self, args, exp_letters):
57
        """Check if docopt exit was for an unknown argument."""
58
        if args is None:
59
            args = sys.argv[1:]
60
        keys_all = self.exp_keys.union(self.exp_elems)
61
        if exp_letters:
62
            keys_all |= exp_letters
63
        unknown_args = self._chk_docunknown(args, keys_all)
64
        if unknown_args:
65
            raise RuntimeError("{USAGE}\n    **FATAL: UNKNOWN ARGS: {UNK}".format(
66
                USAGE=self.doc, UNK=" ".join(unknown_args)))
67
68
    def _chk_docopt_kws(self, docdict, exp):
69
        """Check for common user errors when running from the command-line."""
70
        for key, val in docdict.items():
71
            if isinstance(val, str):
72
                assert '=' not in val, self._err("'=' FOUND IN VALUE", key, val, exp)
73
            elif key != 'help' and key not in self.exp_keys and key not in self.exp_elems:
74
                raise RuntimeError(self._err("UNKNOWN KEY", key, val, exp))
75
76
    def _err(self, msg, key, val, exp):
77
        return "{DOC}\n{MSG}: KEY({K}) VAL({V}): {EXP}".format(
78
            DOC=self.doc, MSG=msg, K=key, V=val, EXP=" ".join(exp))
79
80
    @staticmethod
81
    def _chk_docunknown(args, exp):
82
        """Return any unknown args."""
83
        unknown = []
84
        for arg in args:
85
            if arg[:2] == '--':
86
                val = arg[2:]
87
                if val not in exp:
88
                    unknown.append(arg)
89
            elif arg[:1] == '-':
90
                val = arg[1:]
91
                if val not in exp:
92
                    unknown.append(arg)
93
        if '-h' in unknown or '--help' in unknown:
94
            return []
95
        return unknown
96
97
98
# Copyright (C) 2016-2018, DV Klopfenstein, H Tang, All rights reserved.
99