-
Notifications
You must be signed in to change notification settings - Fork 1
/
parser.py
73 lines (61 loc) · 2.05 KB
/
parser.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
import argparse
import copy
from argparse import Namespace
def dict2ns(dict_obj):
"""
Convert recursively dict to Namespace object.
"""
dict_obj = copy.deepcopy(dict_obj)
temp = Namespace(**dict_obj)
for k, v in dict_obj.items():
if isinstance(v, dict):
temp.__setattr__(k, dict2ns(v))
return temp
def ns2dict(namespace):
"""
Convert recursively Namespace object to dict.
"""
namespace = copy.deepcopy(namespace)
temp = vars(namespace)
for k, v in temp.items():
if isinstance(v, Namespace):
temp[k] = ns2dict(v)
return temp
class NestedParser:
def __init__(self, parser, names, prefixes):
self.parser = parser
self.names = names
self.prefixes = prefixes
def add_argument(self, name, **kwargs):
if name.startswith('--'):
name, dashes = name[2:], '--'
elif name.startswith('-'):
name, dashes = name[1:], '-'
else:
dashes = ''
return self.parser.add_argument(dashes + '.'.join(list(self.prefixes) + [name]),
dest='.'.join(list(self.names) + [name]), **kwargs)
def parse_args(self):
def recursive(dt, names, val):
name0 = names[0]
if len(names) == 1:
dt[name0] = val
return
else:
if name0 not in dt:
dt[name0] = {}
recursive(dt[name0], names[1:], val)
dict_in = vars(self.parser.parse_args())
# print(dict_in)
dict_out = {}
for k, v in dict_in.items():
name_list = k.split('.')
recursive(dict_out, name_list, v)
return dict2ns(dict_out)
def get_child(self, name, prefix=None):
names = list(self.names) + [name]
prefixes = list(self.prefixes) + [name if prefix is None else prefix]
return NestedParser(self.parser, names, prefixes)
@staticmethod
def new():
return NestedParser(argparse.ArgumentParser(), (), ())