From 48168faa350ca37d9f251fbe8e30278f424a5a99 Mon Sep 17 00:00:00 2001 From: mvdbeek Date: Tue, 16 Apr 2024 17:41:27 +0200 Subject: [PATCH] Don't fail if reporting invalid parameter values which can contain None values. Fixes the following traceback: ``` TypeError: sequence item 0: expected str instance, NoneType found File "galaxy/web/framework/decorators.py", line 346, in decorator rval = func(self, trans, *args, **kwargs) File "galaxy/webapps/galaxy/api/tools.py", line 247, in build return tool.to_json(trans, kwd.get("inputs", kwd), history=history) File "galaxy/tools/__init__.py", line 2509, in to_json populate_state(request_context, self.inputs, params.__dict__, state_inputs, state_errors) File "galaxy/tools/parameters/__init__.py", line 412, in populate_state _populate_state_legacy( File "galaxy/tools/parameters/__init__.py", line 625, in _populate_state_legacy check_param(request_context, input, param_value, context, simple_errors=simple_errors) File "galaxy/tools/parameters/__init__.py", line 246, in check_param value = param.from_json(value, trans, param_values) File "galaxy/tools/parameters/basic.py", line 1045, in from_json f"invalid options ({','.join(set(value) - set(legal_values))!r}) were selected (valid options: {','.join(legal_values)})", ``` Where `None` was in values. Note also that pyright underlined these lines, not sure why mypy has ignored this error. --- lib/galaxy/tools/parameters/basic.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/galaxy/tools/parameters/basic.py b/lib/galaxy/tools/parameters/basic.py index 18924a618d84..e24904731aec 100644 --- a/lib/galaxy/tools/parameters/basic.py +++ b/lib/galaxy/tools/parameters/basic.py @@ -892,6 +892,11 @@ def to_dict(self, trans, other_values=None): return d +def iter_to_string(iterable: typing.Iterable[typing.Any]) -> typing.Generator[str, None, None]: + for item in iterable: + yield str(item) + + class SelectToolParameter(ToolParameter): """ Parameter that takes on one (or many) or a specific set of values. @@ -1041,8 +1046,9 @@ def from_json(self, value, trans, other_values=None, require_legal_value=True): elif set(value).issubset(set(fallback_values.keys())): return [fallback_values[v] for v in value] else: + invalid_options = iter_to_string(set(value) - set(legal_values)) raise ParameterValueError( - f"invalid options ({','.join(set(value) - set(legal_values))!r}) were selected (valid options: {','.join(legal_values)})", + f"invalid options ({','.join(invalid_options)!r}) were selected (valid options: {','.join(iter_to_string(legal_values))})", self.name, is_dynamic=self.is_dynamic, ) @@ -1066,7 +1072,7 @@ def from_json(self, value, trans, other_values=None, require_legal_value=True): return value else: raise ParameterValueError( - f"an invalid option ({value!r}) was selected (valid options: {','.join(legal_values)})", + f"an invalid option ({value!r}) was selected (valid options: {','.join(iter_to_string(legal_values))})", self.name, value, is_dynamic=self.is_dynamic,