gridparse 1.5.0__tar.gz → 1.5.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {gridparse-1.5.0/gridparse.egg-info → gridparse-1.5.2}/PKG-INFO +1 -1
- {gridparse-1.5.0 → gridparse-1.5.2}/gridparse/grid_argument_parser.py +358 -20
- {gridparse-1.5.0 → gridparse-1.5.2/gridparse.egg-info}/PKG-INFO +1 -1
- {gridparse-1.5.0 → gridparse-1.5.2}/pyproject.toml +1 -2
- {gridparse-1.5.0 → gridparse-1.5.2}/setup.py +1 -1
- {gridparse-1.5.0 → gridparse-1.5.2}/LICENSE +0 -0
- {gridparse-1.5.0 → gridparse-1.5.2}/MANIFEST.in +0 -0
- {gridparse-1.5.0 → gridparse-1.5.2}/README.md +0 -0
- {gridparse-1.5.0 → gridparse-1.5.2}/gridparse/__init__.py +0 -0
- {gridparse-1.5.0 → gridparse-1.5.2}/gridparse/utils.py +0 -0
- {gridparse-1.5.0 → gridparse-1.5.2}/gridparse.egg-info/SOURCES.txt +0 -0
- {gridparse-1.5.0 → gridparse-1.5.2}/gridparse.egg-info/dependency_links.txt +0 -0
- {gridparse-1.5.0 → gridparse-1.5.2}/gridparse.egg-info/requires.txt +0 -0
- {gridparse-1.5.0 → gridparse-1.5.2}/gridparse.egg-info/top_level.txt +0 -0
- {gridparse-1.5.0 → gridparse-1.5.2}/setup.cfg +0 -0
@@ -8,6 +8,328 @@ from omegaconf import OmegaConf
|
|
8
8
|
from gridparse.utils import list_as_dashed_str, strbool
|
9
9
|
|
10
10
|
|
11
|
+
class AuxArgumentParser(argparse.ArgumentParser):
|
12
|
+
"""Overwritten only to collect the argument names that
|
13
|
+
are specified in the command line."""
|
14
|
+
|
15
|
+
def parse_known_args(
|
16
|
+
self, args=None, namespace=None
|
17
|
+
) -> Tuple[argparse.Namespace, List[str]]:
|
18
|
+
"""Overwritten to collect the argument names that
|
19
|
+
are specified in the command line."""
|
20
|
+
if args is None:
|
21
|
+
# args default to the system args
|
22
|
+
args = argparse._sys.argv[1:]
|
23
|
+
else:
|
24
|
+
# make sure that args are mutable
|
25
|
+
args = list(args)
|
26
|
+
|
27
|
+
# default Namespace built from parser defaults
|
28
|
+
if namespace is None:
|
29
|
+
namespace = argparse.Namespace()
|
30
|
+
|
31
|
+
if not hasattr(namespace, "___specified_args___"):
|
32
|
+
setattr(namespace, "___specified_args___", set())
|
33
|
+
|
34
|
+
# add any action defaults that aren't present
|
35
|
+
for action in self._actions:
|
36
|
+
if action.dest is not argparse.SUPPRESS:
|
37
|
+
if not hasattr(namespace, action.dest):
|
38
|
+
if action.default is not argparse.SUPPRESS:
|
39
|
+
setattr(namespace, action.dest, action.default)
|
40
|
+
|
41
|
+
# add any parser defaults that aren't present
|
42
|
+
for dest in self._defaults:
|
43
|
+
if not hasattr(namespace, dest):
|
44
|
+
setattr(namespace, dest, self._defaults[dest])
|
45
|
+
|
46
|
+
# parse the arguments and exit if there are any errors
|
47
|
+
if self.exit_on_error:
|
48
|
+
try:
|
49
|
+
namespace, args = self._parse_known_args(args, namespace)
|
50
|
+
except argparse.ArgumentError:
|
51
|
+
err = argparse._sys.exc_info()[1]
|
52
|
+
self.error(str(err))
|
53
|
+
else:
|
54
|
+
namespace, args = self._parse_known_args(args, namespace)
|
55
|
+
|
56
|
+
if hasattr(namespace, argparse._UNRECOGNIZED_ARGS_ATTR):
|
57
|
+
args.extend(getattr(namespace, argparse._UNRECOGNIZED_ARGS_ATTR))
|
58
|
+
delattr(namespace, argparse._UNRECOGNIZED_ARGS_ATTR)
|
59
|
+
|
60
|
+
return namespace, args
|
61
|
+
|
62
|
+
def _parse_known_args(
|
63
|
+
self, arg_strings, namespace
|
64
|
+
) -> Tuple[List[argparse.Namespace], List[str]]:
|
65
|
+
"""Overwritten to collect the argument names that
|
66
|
+
are specified in the command line."""
|
67
|
+
|
68
|
+
# replace arg strings that are file references
|
69
|
+
if self.fromfile_prefix_chars is not None:
|
70
|
+
arg_strings = self._read_args_from_files(arg_strings)
|
71
|
+
|
72
|
+
# map all mutually exclusive arguments to the other arguments
|
73
|
+
# they can't occur with
|
74
|
+
action_conflicts = {}
|
75
|
+
for mutex_group in self._mutually_exclusive_groups:
|
76
|
+
group_actions = mutex_group._group_actions
|
77
|
+
for i, mutex_action in enumerate(mutex_group._group_actions):
|
78
|
+
conflicts = action_conflicts.setdefault(mutex_action, [])
|
79
|
+
conflicts.extend(group_actions[:i])
|
80
|
+
conflicts.extend(group_actions[i + 1 :])
|
81
|
+
|
82
|
+
# find all option indices, and determine the arg_string_pattern
|
83
|
+
# which has an 'O' if there is an option at an index,
|
84
|
+
# an 'A' if there is an argument, or a '-' if there is a '--'
|
85
|
+
option_string_indices = {}
|
86
|
+
arg_string_pattern_parts = []
|
87
|
+
arg_strings_iter = iter(arg_strings)
|
88
|
+
for i, arg_string in enumerate(arg_strings_iter):
|
89
|
+
|
90
|
+
# all args after -- are non-options
|
91
|
+
if arg_string == '--':
|
92
|
+
arg_string_pattern_parts.append('-')
|
93
|
+
for arg_string in arg_strings_iter:
|
94
|
+
arg_string_pattern_parts.append('A')
|
95
|
+
|
96
|
+
# otherwise, add the arg to the arg strings
|
97
|
+
# and note the index if it was an option
|
98
|
+
else:
|
99
|
+
option_tuple = self._parse_optional(arg_string)
|
100
|
+
if option_tuple is None:
|
101
|
+
pattern = 'A'
|
102
|
+
else:
|
103
|
+
option_string_indices[i] = option_tuple
|
104
|
+
pattern = 'O'
|
105
|
+
arg_string_pattern_parts.append(pattern)
|
106
|
+
|
107
|
+
# join the pieces together to form the pattern
|
108
|
+
arg_strings_pattern = ''.join(arg_string_pattern_parts)
|
109
|
+
|
110
|
+
# converts arg strings to the appropriate and then takes the action
|
111
|
+
seen_actions = set()
|
112
|
+
seen_non_default_actions = set()
|
113
|
+
|
114
|
+
def take_action(action, argument_strings, option_string=None):
|
115
|
+
seen_actions.add(action)
|
116
|
+
argument_values = self._get_values(action, argument_strings)
|
117
|
+
|
118
|
+
# error if this argument is not allowed with other previously
|
119
|
+
# seen arguments, assuming that actions that use the default
|
120
|
+
# value don't really count as "present"
|
121
|
+
if argument_values is not action.default:
|
122
|
+
seen_non_default_actions.add(action)
|
123
|
+
for conflict_action in action_conflicts.get(action, []):
|
124
|
+
if conflict_action in seen_non_default_actions:
|
125
|
+
msg = argparse._('not allowed with argument %s')
|
126
|
+
action_name = argparse._get_action_name(conflict_action)
|
127
|
+
raise argparse.ArgumentError(action, msg % action_name)
|
128
|
+
|
129
|
+
# take the action if we didn't receive a SUPPRESS value
|
130
|
+
# (e.g. from a default)
|
131
|
+
if argument_values is not argparse.SUPPRESS:
|
132
|
+
action(self, namespace, argument_values, option_string)
|
133
|
+
namespace.___specified_args___.add(action.dest)
|
134
|
+
|
135
|
+
# function to convert arg_strings into an optional action
|
136
|
+
def consume_optional(start_index):
|
137
|
+
|
138
|
+
# get the optional identified at this index
|
139
|
+
option_tuple = option_string_indices[start_index]
|
140
|
+
action, option_string, explicit_arg = option_tuple
|
141
|
+
|
142
|
+
# identify additional optionals in the same arg string
|
143
|
+
# (e.g. -xyz is the same as -x -y -z if no args are required)
|
144
|
+
match_argument = self._match_argument
|
145
|
+
action_tuples = []
|
146
|
+
while True:
|
147
|
+
|
148
|
+
# if we found no optional action, skip it
|
149
|
+
if action is None:
|
150
|
+
extras.append(arg_strings[start_index])
|
151
|
+
return start_index + 1
|
152
|
+
|
153
|
+
# if there is an explicit argument, try to match the
|
154
|
+
# optional's string arguments to only this
|
155
|
+
if explicit_arg is not None:
|
156
|
+
arg_count = match_argument(action, 'A')
|
157
|
+
|
158
|
+
# if the action is a single-dash option and takes no
|
159
|
+
# arguments, try to parse more single-dash options out
|
160
|
+
# of the tail of the option string
|
161
|
+
chars = self.prefix_chars
|
162
|
+
if (
|
163
|
+
arg_count == 0
|
164
|
+
and option_string[1] not in chars
|
165
|
+
and explicit_arg != ''
|
166
|
+
):
|
167
|
+
action_tuples.append((action, [], option_string))
|
168
|
+
char = option_string[0]
|
169
|
+
option_string = char + explicit_arg[0]
|
170
|
+
new_explicit_arg = explicit_arg[1:] or None
|
171
|
+
optionals_map = self._option_string_actions
|
172
|
+
if option_string in optionals_map:
|
173
|
+
action = optionals_map[option_string]
|
174
|
+
explicit_arg = new_explicit_arg
|
175
|
+
else:
|
176
|
+
msg = argparse._('ignored explicit argument %r')
|
177
|
+
raise argparse.ArgumentError(
|
178
|
+
action, msg % explicit_arg
|
179
|
+
)
|
180
|
+
|
181
|
+
# if the action expect exactly one argument, we've
|
182
|
+
# successfully matched the option; exit the loop
|
183
|
+
elif arg_count == 1:
|
184
|
+
stop = start_index + 1
|
185
|
+
args = [explicit_arg]
|
186
|
+
action_tuples.append((action, args, option_string))
|
187
|
+
break
|
188
|
+
|
189
|
+
# error if a double-dash option did not use the
|
190
|
+
# explicit argument
|
191
|
+
else:
|
192
|
+
msg = argparse._('ignored explicit argument %r')
|
193
|
+
raise argparse.ArgumentError(action, msg % explicit_arg)
|
194
|
+
|
195
|
+
# if there is no explicit argument, try to match the
|
196
|
+
# optional's string arguments with the following strings
|
197
|
+
# if successful, exit the loop
|
198
|
+
else:
|
199
|
+
start = start_index + 1
|
200
|
+
selected_patterns = arg_strings_pattern[start:]
|
201
|
+
arg_count = match_argument(action, selected_patterns)
|
202
|
+
stop = start + arg_count
|
203
|
+
args = arg_strings[start:stop]
|
204
|
+
action_tuples.append((action, args, option_string))
|
205
|
+
break
|
206
|
+
|
207
|
+
# add the Optional to the list and return the index at which
|
208
|
+
# the Optional's string args stopped
|
209
|
+
assert action_tuples
|
210
|
+
for action, args, option_string in action_tuples:
|
211
|
+
take_action(action, args, option_string)
|
212
|
+
return stop
|
213
|
+
|
214
|
+
# the list of Positionals left to be parsed; this is modified
|
215
|
+
# by consume_positionals()
|
216
|
+
positionals = self._get_positional_actions()
|
217
|
+
|
218
|
+
# function to convert arg_strings into positional actions
|
219
|
+
def consume_positionals(start_index):
|
220
|
+
# match as many Positionals as possible
|
221
|
+
match_partial = self._match_arguments_partial
|
222
|
+
selected_pattern = arg_strings_pattern[start_index:]
|
223
|
+
arg_counts = match_partial(positionals, selected_pattern)
|
224
|
+
|
225
|
+
# slice off the appropriate arg strings for each Positional
|
226
|
+
# and add the Positional and its args to the list
|
227
|
+
for action, arg_count in zip(positionals, arg_counts):
|
228
|
+
args = arg_strings[start_index : start_index + arg_count]
|
229
|
+
start_index += arg_count
|
230
|
+
take_action(action, args)
|
231
|
+
|
232
|
+
# slice off the Positionals that we just parsed and return the
|
233
|
+
# index at which the Positionals' string args stopped
|
234
|
+
positionals[:] = positionals[len(arg_counts) :]
|
235
|
+
return start_index
|
236
|
+
|
237
|
+
# consume Positionals and Optionals alternately, until we have
|
238
|
+
# passed the last option string
|
239
|
+
extras = []
|
240
|
+
start_index = 0
|
241
|
+
if option_string_indices:
|
242
|
+
max_option_string_index = max(option_string_indices)
|
243
|
+
else:
|
244
|
+
max_option_string_index = -1
|
245
|
+
while start_index <= max_option_string_index:
|
246
|
+
|
247
|
+
# consume any Positionals preceding the next option
|
248
|
+
next_option_string_index = min(
|
249
|
+
[
|
250
|
+
index
|
251
|
+
for index in option_string_indices
|
252
|
+
if index >= start_index
|
253
|
+
]
|
254
|
+
)
|
255
|
+
if start_index != next_option_string_index:
|
256
|
+
positionals_end_index = consume_positionals(start_index)
|
257
|
+
|
258
|
+
# only try to parse the next optional if we didn't consume
|
259
|
+
# the option string during the positionals parsing
|
260
|
+
if positionals_end_index > start_index:
|
261
|
+
start_index = positionals_end_index
|
262
|
+
continue
|
263
|
+
else:
|
264
|
+
start_index = positionals_end_index
|
265
|
+
|
266
|
+
# if we consumed all the positionals we could and we're not
|
267
|
+
# at the index of an option string, there were extra arguments
|
268
|
+
if start_index not in option_string_indices:
|
269
|
+
strings = arg_strings[start_index:next_option_string_index]
|
270
|
+
extras.extend(strings)
|
271
|
+
start_index = next_option_string_index
|
272
|
+
|
273
|
+
# consume the next optional and any arguments for it
|
274
|
+
start_index = consume_optional(start_index)
|
275
|
+
|
276
|
+
# consume any positionals following the last Optional
|
277
|
+
stop_index = consume_positionals(start_index)
|
278
|
+
|
279
|
+
# if we didn't consume all the argument strings, there were extras
|
280
|
+
extras.extend(arg_strings[stop_index:])
|
281
|
+
|
282
|
+
# make sure all required actions were present and also convert
|
283
|
+
# action defaults which were not given as arguments
|
284
|
+
required_actions = []
|
285
|
+
for action in self._actions:
|
286
|
+
if action not in seen_actions:
|
287
|
+
if action.required:
|
288
|
+
required_actions.append(argparse._get_action_name(action))
|
289
|
+
else:
|
290
|
+
# Convert action default now instead of doing it before
|
291
|
+
# parsing arguments to avoid calling convert functions
|
292
|
+
# twice (which may fail) if the argument was given, but
|
293
|
+
# only if it was defined already in the namespace
|
294
|
+
if (
|
295
|
+
action.default is not None
|
296
|
+
and isinstance(action.default, str)
|
297
|
+
and hasattr(namespace, action.dest)
|
298
|
+
and action.default is getattr(namespace, action.dest)
|
299
|
+
):
|
300
|
+
setattr(
|
301
|
+
namespace,
|
302
|
+
action.dest,
|
303
|
+
self._get_value(action, action.default),
|
304
|
+
)
|
305
|
+
|
306
|
+
if required_actions:
|
307
|
+
self.error(
|
308
|
+
argparse._('the following arguments are required: %s')
|
309
|
+
% ', '.join(required_actions)
|
310
|
+
)
|
311
|
+
|
312
|
+
# make sure all required groups had one option present
|
313
|
+
for group in self._mutually_exclusive_groups:
|
314
|
+
if group.required:
|
315
|
+
for action in group._group_actions:
|
316
|
+
if action in seen_non_default_actions:
|
317
|
+
break
|
318
|
+
|
319
|
+
# if no actions were used, report the error
|
320
|
+
else:
|
321
|
+
names = [
|
322
|
+
argparse._get_action_name(action)
|
323
|
+
for action in group._group_actions
|
324
|
+
if action.help is not argparse.SUPPRESS
|
325
|
+
]
|
326
|
+
msg = argparse._('one of the arguments %s is required')
|
327
|
+
self.error(msg % ' '.join(names))
|
328
|
+
|
329
|
+
# return the updated namespace, the extra arguments, and the epxlicitly specified args
|
330
|
+
return namespace, extras
|
331
|
+
|
332
|
+
|
11
333
|
# overwritten to fix issue in __call__
|
12
334
|
class _GridSubparsersAction(argparse._SubParsersAction):
|
13
335
|
def __call__(
|
@@ -57,7 +379,13 @@ class _GridSubparsersAction(argparse._SubParsersAction):
|
|
57
379
|
subnamespaces, arg_strings = parser.parse_known_args(arg_strings, None)
|
58
380
|
for subnamespace in subnamespaces:
|
59
381
|
new_namespace = deepcopy(namespace)
|
382
|
+
new_namespace.___specified_args___.update(
|
383
|
+
subnamespace.___specified_args___
|
384
|
+
)
|
385
|
+
|
60
386
|
for key, value in vars(subnamespace).items():
|
387
|
+
if key == "___specified_args___":
|
388
|
+
continue
|
61
389
|
setattr(new_namespace, key, value)
|
62
390
|
namespaces.append(new_namespace)
|
63
391
|
|
@@ -81,7 +409,7 @@ class _GridActionsContainer(argparse._ActionsContainer):
|
|
81
409
|
self.register("action", "parsers", _GridSubparsersAction)
|
82
410
|
|
83
411
|
|
84
|
-
class GridArgumentParser(_GridActionsContainer,
|
412
|
+
class GridArgumentParser(_GridActionsContainer, AuxArgumentParser):
|
85
413
|
"""ArgumentParser that supports grid search.
|
86
414
|
|
87
415
|
It transforms the following arguments in the corresponding way:
|
@@ -163,7 +491,7 @@ class GridArgumentParser(_GridActionsContainer, argparse.ArgumentParser):
|
|
163
491
|
|
164
492
|
def __init__(self, retain_config_filename: bool = False, *args, **kwargs):
|
165
493
|
"""Initializes the GridArgumentParser.
|
166
|
-
|
494
|
+
|
167
495
|
Args:
|
168
496
|
retain_config_filename: whether to keep the `gridparse-config` argument
|
169
497
|
in the namespace or not.
|
@@ -180,9 +508,9 @@ class GridArgumentParser(_GridActionsContainer, argparse.ArgumentParser):
|
|
180
508
|
"Values will be used if not provided in the command line.",
|
181
509
|
)
|
182
510
|
|
183
|
-
|
184
511
|
def parse_args(self, *args, **kwargs):
|
185
512
|
vals = super().parse_args(*args, **kwargs)
|
513
|
+
|
186
514
|
# hacky way to return namespaces in subparser
|
187
515
|
if "___namespaces___" in vals[0]:
|
188
516
|
vals = [ns for subps_ns in vals for ns in subps_ns.___namespaces___]
|
@@ -220,21 +548,25 @@ class GridArgumentParser(_GridActionsContainer, argparse.ArgumentParser):
|
|
220
548
|
cfg = {}
|
221
549
|
if ns.gridparse_config is not None:
|
222
550
|
# reverse for priority to originally first configs
|
223
|
-
for potential_fn in reversed(
|
551
|
+
for potential_fn in reversed(
|
552
|
+
getattr(ns, "gridparse_config", [])
|
553
|
+
):
|
224
554
|
if os.path.isfile(potential_fn):
|
225
555
|
cfg = OmegaConf.merge(cfg, OmegaConf.load(potential_fn))
|
226
556
|
|
227
557
|
for arg in cfg:
|
228
558
|
if not hasattr(ns, arg):
|
229
559
|
continue
|
230
|
-
if
|
231
|
-
setattr(ns, arg,
|
560
|
+
if arg not in ns.___specified_args___:
|
561
|
+
setattr(ns, arg, cfg.get(arg))
|
232
562
|
|
233
563
|
if not self._retain_config_filename:
|
234
564
|
delattr(ns, "gridparse_config")
|
235
565
|
|
566
|
+
delattr(ns, "___specified_args___")
|
567
|
+
|
236
568
|
return vals
|
237
|
-
|
569
|
+
|
238
570
|
def _check_value(self, action, value):
|
239
571
|
"""Overwrites `_check_value` to support grid search with `None`s."""
|
240
572
|
# converted value must be one of the choices (if specified)
|
@@ -243,7 +575,7 @@ class GridArgumentParser(_GridActionsContainer, argparse.ArgumentParser):
|
|
243
575
|
): # allows value to be None without error
|
244
576
|
args = {
|
245
577
|
"value": value,
|
246
|
-
"choices": ", ".join(map(repr, action.choices))
|
578
|
+
"choices": ", ".join(map(repr, action.choices)),
|
247
579
|
}
|
248
580
|
msg = argparse._(
|
249
581
|
"invalid choice: %(value)r (choose from %(choices)s)"
|
@@ -263,12 +595,12 @@ class GridArgumentParser(_GridActionsContainer, argparse.ArgumentParser):
|
|
263
595
|
default == arg_string or arg_string is None
|
264
596
|
):
|
265
597
|
return default
|
266
|
-
|
598
|
+
|
267
599
|
# if arg_string is "args.X" value,
|
268
600
|
# then set up value so that X is grabbed from the same namespace later
|
269
601
|
if arg_string.startswith("args."):
|
270
602
|
return arg_string
|
271
|
-
|
603
|
+
|
272
604
|
# if arg_string is "_None_", then return None
|
273
605
|
if (
|
274
606
|
arg_string == "_None_"
|
@@ -304,16 +636,18 @@ class GridArgumentParser(_GridActionsContainer, argparse.ArgumentParser):
|
|
304
636
|
@staticmethod
|
305
637
|
def _add_split_in_arg(arg: str, split: str) -> str:
|
306
638
|
"""Adds the `split` to the name of the argument `arg`."""
|
307
|
-
|
639
|
+
|
308
640
|
if "_" in arg:
|
309
|
-
|
641
|
+
# if the user uses "_" as a delimiter, we use that
|
310
642
|
delim = "_"
|
311
643
|
else:
|
312
|
-
|
644
|
+
# otherwise, we use "-" (no necessary to check for it, e.g., could be CamelCase)
|
313
645
|
delim = "-"
|
314
646
|
return split + delim + arg
|
315
647
|
|
316
|
-
def add_argument(
|
648
|
+
def add_argument(
|
649
|
+
self, *args, **kwargs
|
650
|
+
) -> Union[argparse.Action, List[argparse.Action]]:
|
317
651
|
"""Augments `add_argument` to support grid search.
|
318
652
|
For parameters that are searchable, provide specification
|
319
653
|
for a single value, and set the new argument `searchable`
|
@@ -346,10 +680,14 @@ class GridArgumentParser(_GridActionsContainer, argparse.ArgumentParser):
|
|
346
680
|
while cp_args[0][i] in self.prefix_chars:
|
347
681
|
i += 1
|
348
682
|
|
349
|
-
cp_args[0] = cp_args[0][:i] + self._add_split_in_arg(
|
683
|
+
cp_args[0] = cp_args[0][:i] + self._add_split_in_arg(
|
684
|
+
cp_args[0][i:], split
|
685
|
+
)
|
350
686
|
|
351
687
|
else:
|
352
|
-
cp_kwargs["dest"] = self._add_split_in_arg(
|
688
|
+
cp_kwargs["dest"] = self._add_split_in_arg(
|
689
|
+
cp_kwargs["dest"], split
|
690
|
+
)
|
353
691
|
|
354
692
|
actions.append(self.add_argument(*cp_args, **cp_kwargs))
|
355
693
|
|
@@ -388,7 +726,7 @@ class GridArgumentParser(_GridActionsContainer, argparse.ArgumentParser):
|
|
388
726
|
self.subspaces = {}
|
389
727
|
self.cnt = 0
|
390
728
|
self.parent = parent
|
391
|
-
|
729
|
+
|
392
730
|
def add_arg(self, arg: str):
|
393
731
|
if arg == "{":
|
394
732
|
new_subspace = GridArgumentParser.Subspace(self)
|
@@ -401,7 +739,7 @@ class GridArgumentParser(_GridActionsContainer, argparse.ArgumentParser):
|
|
401
739
|
self.args[self.cnt] = arg
|
402
740
|
self.cnt += 1
|
403
741
|
return self
|
404
|
-
|
742
|
+
|
405
743
|
def parse_paths(self) -> List[List[str]]:
|
406
744
|
|
407
745
|
if not self.subspaces:
|
@@ -419,9 +757,9 @@ class GridArgumentParser(_GridActionsContainer, argparse.ArgumentParser):
|
|
419
757
|
this_subspace_args.append(self.args[i])
|
420
758
|
for path in cumulative_args:
|
421
759
|
path.append(self.args[i])
|
422
|
-
|
760
|
+
|
423
761
|
return cumulative_args
|
424
|
-
|
762
|
+
|
425
763
|
def __repr__(self) -> str:
|
426
764
|
repr = "Subspace("
|
427
765
|
for i in range(self.cnt):
|
@@ -1,6 +1,6 @@
|
|
1
1
|
[project]
|
2
2
|
name = "gridparse"
|
3
|
-
version = "1.5.
|
3
|
+
version = "1.5.2"
|
4
4
|
description = "Grid search directly from argparse"
|
5
5
|
readme = "README.md"
|
6
6
|
requires-python = ">=3.7"
|
@@ -31,7 +31,6 @@ classifiers = [
|
|
31
31
|
"Programming Language :: Python :: 3 :: Only",
|
32
32
|
]
|
33
33
|
|
34
|
-
|
35
34
|
dependencies = [
|
36
35
|
"omegaconf",
|
37
36
|
]
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|