SelectParameters: allow to choose legal options by name

this change will allow choose a legal option by name.

use case: data table with 2 columns: name and value (e.g. mothur data tables and probably many other old ones).
tools using such data tables can not be tested since one needs to specify the value .. which is a path that changes with the test environment.

this has been tested for one mothur tool
This commit is contained in:
Matthias Bernt
2021-01-12 13:43:55 +01:00
parent 7053b1a00c
commit e87245b325
+29 -5
View File
@@ -878,6 +878,9 @@ class SelectToolParameter(ToolParameter):
return self.static_options
def get_legal_values(self, trans, other_values):
"""
determine the set of values of legal options
"""
if self.options:
return {v for _, v, _ in self.options.get_options(trans, other_values)}
elif self.dynamic_options:
@@ -890,12 +893,23 @@ class SelectToolParameter(ToolParameter):
else:
return self.legal_values
def get_legal_names(self, trans, other_values):
"""
determine a mapping from names to values for all legal options
"""
return {n: v for n, v, _ in self.get_options(trans, other_values)}
def from_json(self, value, trans, other_values=None, require_legal_value=True):
other_values = other_values or {}
try:
legal_values = self.get_legal_values(trans, other_values)
except ImplicitConversionRequired:
return value
# if the given value is not found in the set of values of the legal
# options we fall back to check if the value is in the set of names of
# the legal options. this is done with the fallback_values dict which
# allows to determine the corresponding legal values
fallback_values = self.get_legal_names(trans, other_values)
if (not legal_values or not require_legal_value) and is_runtime_context(trans, other_values):
if self.multiple:
# While it is generally allowed that a select value can be '',
@@ -926,9 +940,14 @@ class SelectToolParameter(ToolParameter):
raise ParameterValueError("multiple values provided but parameter is not expecting multiple values", self.name, is_dynamic=self.is_dynamic)
rval = []
for v in value:
if v not in legal_values:
raise ParameterValueError("an invalid option ({!r}) was selected (valid options: {})".format(v, ",".join(legal_values)), self.name, v, is_dynamic=self.is_dynamic)
rval.append(v)
if v in legal_values:
rval.append(v)
if len(rval) == 0:
for v in value:
if v in fallback_values:
rval.append(fallback_values[v])
if len(rval) == 0:
raise ParameterValueError("an invalid option ({!r}) was selected (valid options: {})".format(v, ",".join(legal_values)), self.name, v, is_dynamic=self.is_dynamic)
return rval
else:
value_is_none = (value == "None" and "None" not in legal_values)
@@ -940,9 +959,14 @@ class SelectToolParameter(ToolParameter):
raise ParameterValueError("no option was selected for non optional parameter", self.name, is_dynamic=self.is_dynamic)
if is_runtime_value(value):
return None
if value not in legal_values and require_legal_value:
if value in legal_values:
return value
elif value in fallback_values:
return fallback_values[value]
elif not require_legal_value:
return value
else:
raise ParameterValueError("an invalid option ({!r}) was selected (valid options: {})".format(value, ",".join(legal_values)), self.name, value, is_dynamic=self.is_dynamic)
return value
def to_param_dict_string(self, value, other_values=None):
if value in (None, []):