Skip to content

Commit eaace32

Browse files
committed
abstract _requirements_met and use it to only store actual given_parameters in database
1 parent a2d953e commit eaace32

1 file changed

Lines changed: 47 additions & 37 deletions

File tree

common/lib/user_input.py

Lines changed: 47 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,13 @@ def parse_all(options, input, silently_correct=True):
109109
# ignored
110110
continue
111111

112-
elif settings.get("type") == UserInput.OPTION_DATERANGE:
112+
if settings.get("requires") and not UserInput.requirements_met(settings["requires"], parsed_input):
113+
# the option's condition is not met, so the user never saw it:
114+
# leave it out instead of storing a default for it. This holds
115+
# whether or not the (hidden) form field was submitted.
116+
continue
117+
118+
if settings.get("type") == UserInput.OPTION_DATERANGE:
113119
# special case, since it combines two inputs
114120
option_min = option + "-min"
115121
option_max = option + "-max"
@@ -234,6 +240,43 @@ def parse_all(options, input, silently_correct=True):
234240

235241
return parsed_input
236242

243+
@staticmethod
244+
def requirements_met(requires, other_input):
245+
"""
246+
Check whether an option's "requires" condition is satisfied
247+
248+
`requires` may be:
249+
- a single string: "field==value"
250+
- an &&-joined string: "field1==v1 && field2==v2" (all must be true)
251+
- a ||-joined string: "field1==v1 || field2==v2" (any must be true)
252+
- a list/tuple of strings: every requirement must be true
253+
254+
:param requires: The option's "requires" setting
255+
:param dict other_input: Values to check the condition against; a
256+
condition that refers to a field missing from this dictionary is
257+
not met
258+
:return bool: True if the condition is satisfied
259+
"""
260+
if isinstance(requires, (list, tuple)):
261+
# a list always means: every requirement must be satisfied
262+
req_list = list(requires)
263+
combine_and = True
264+
elif "||" in requires:
265+
# pipe-separated alternatives: any one is sufficient
266+
req_list = [r.strip() for r in requires.split("||")]
267+
combine_and = False
268+
elif "&&" in requires:
269+
# ampersand-separated conditions: all must hold
270+
req_list = [r.strip() for r in requires.split("&&")]
271+
combine_and = True
272+
else:
273+
# single requirement string
274+
req_list = [requires]
275+
combine_and = True
276+
277+
results = [UserInput._requirement_met(r, other_input) for r in req_list]
278+
return all(results) if combine_and else any(results)
279+
237280
@staticmethod
238281
def _requirement_met(req, other_input):
239282
"""
@@ -337,42 +380,9 @@ def parse_value(settings, choice, other_input=None, silently_correct=True):
337380
:return: Validated and parsed input
338381
"""
339382
# short-circuit if there is a requirement for the field to be parsed
340-
# and the requirement isn't met.
341-
# 'requires' may be:
342-
# - a single string: "field==value"
343-
# - an &&-joined string: "field1==v1 && field2==v2" (all must be true)
344-
# - a ||-joined string: "field1==v1 || field2==v2" (any must be true)
345-
# - a list/tuple of strings: AND semantics (all must be true)
346-
if settings.get("requires"):
347-
reqs = settings["requires"]
348-
349-
# normalise to a list of individual requirement strings plus a flag
350-
# indicating whether they combine with AND (True) or OR (False)
351-
if isinstance(reqs, (list, tuple)):
352-
# a list always uses AND semantics: every requirement must be satisfied
353-
req_list = list(reqs)
354-
combine_and = True
355-
elif "||" in reqs:
356-
# pipe-separated alternatives: any one is sufficient (OR)
357-
req_list = [r.strip() for r in reqs.split("||")]
358-
combine_and = False
359-
elif "&&" in reqs:
360-
# ampersand-separated conditions: all must hold (AND)
361-
req_list = [r.strip() for r in reqs.split("&&")]
362-
combine_and = True
363-
else:
364-
# single requirement string — original behaviour
365-
req_list = [reqs]
366-
combine_and = True
367-
368-
results = [UserInput._requirement_met(r, other_input) for r in req_list]
369-
370-
if combine_and and not all(results):
371-
# AND mode: every requirement must be satisfied
372-
raise RequirementsNotMetException()
373-
elif not combine_and and not any(results):
374-
# OR mode: at least one requirement must be satisfied
375-
raise RequirementsNotMetException()
383+
# and the requirement isn't met
384+
if settings.get("requires") and not UserInput.requirements_met(settings["requires"], other_input):
385+
raise RequirementsNotMetException()
376386

377387
input_type = settings.get("type", "")
378388
if input_type in UserInput.OPTIONS_COSMETIC:

0 commit comments

Comments
 (0)