-
Notifications
You must be signed in to change notification settings - Fork 1
/
parsers.py
153 lines (123 loc) · 4.11 KB
/
parsers.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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
"""
See https://medium.com/analytics-vidhya/my-parser-module-429ed1457718 for documentation.
"""
import logging
logger = logging.getLogger(__name__)
from collections import OrderedDict
from configparser import ConfigParser
from argparse import ArgumentParser
import sys
import ast
def _as_dict(parser):
"""
Go over all sections in the parser,
convert's there's key/value as dictionary that
for every section in the parser has dictionary
with key/value pairs (both str).
:param parser: (self)
:return: dict with key/value as str
"""
d = OrderedDict()
for section in parser.sections():
d[section] = OrderedDict()
for key in parser.options(section):
d[section][key] = parser.get(section, key)
return d
ConfigParser.as_dict = _as_dict
#inspired by
#https://stackoverflow.com/questions/21920989/parse-non-pre-defined-argument
#https://stackoverflow.com/questions/51267814/argparse-for-unknown-number-of-arguments-and-unknown-names
def _args_as_dict(parser, args=None):
"""
Go over source for arguments, takes argument of the form --key=value.
Create dictionary.
Strip out '--' prefix from the key and put key/value (as str) to dict.
If args is None, sys.argv[1:] will be used as source for arguments.
Note: sys.argv[0] is ignored as it contain the name of main .py file to run.
:param parser: ArgumentParser (self)
:param args: if is not None, will be used as source for arguments.
:return:
"""
#see #argumentParser.parse_known_args()
if args is None:
# args default to the system args
args = sys.argv[1:]
else:
# make sure that args are mutable
args = list(args)
d = OrderedDict()
key = None
value = None
for arg in args:
if arg.startswith('--') and '=' in arg:
key, value = arg.rsplit("=", 1)
else:
key = arg
value = None
if key.startswith('--'):
key = key[2:]
d[key] = value
return d
ArgumentParser.as_dict = _args_as_dict
#insipred by https://stackoverflow.com/a/14258151/1137529
#
def safe_eval(value):
'''
The purpose of this function is convert numbers from str to correct type.
This function support convertion of built-in Python number to correct type (int, float)
This function doesn't support decimal.Decimal or datetime.datetime or numpy types.
'''
try:
ret = ast.literal_eval(value)
except (SyntaxError, ValueError):
ret = value
return ret
def is_empty(value):
'''
if value is None returns True.
if value is empty iterable (for example, empty str or emptry list),
returns true
otherwise false
Note: For not iterable values, behaivour is undefined.
:param value:
:return:
'''
if value is None:
return True
if value:
ret = False
else:
ret = True
return ret
def parse_boolean(value):
'''
if value is None returns None.
if value is boolean, it is returned as it is.
if value is str and value is equals ignoring case to "True", True is returned.
if value is str and value is equals ignoring case to "False", False is returned.
For every other value, the answer is undefined.
:param value:
:return:
'''
if value is None:
return None
if value in (True, False):
return value
try:
return {"true": True, "false": False}[value.casefold()]
except (AttributeError, KeyError):
raise ValueError(f"unknown string for bool: {value!r}")
def parse_sys_args(argumentParser=None, args=None):
"""
This function parses command line arguments.
:param argumentParser:
:param args: if not None, suppresses sys.args
:return:
"""
if argumentParser is None:
argumentParser = ArgumentParser()
argumentParser.add_argument("--general.config.file", nargs='?', dest='config_file', default='config.yml',
const='config.yml')
params, unknown_arg = argumentParser.parse_known_args(args=args)
sys_d = argumentParser.as_dict(args=unknown_arg)
return params, sys_d