Loading lib/galaxy/tools/__init__.py +5 −2 Original line number Diff line number Diff line Loading @@ -120,7 +120,10 @@ from galaxy.util.bunch import Bunch from galaxy.util.dictifiable import Dictifiable from galaxy.util.expressions import ExpressionContext from galaxy.util.form_builder import SelectField from galaxy.util.json import safe_loads from galaxy.util.json import ( safe_loads, swap_inf_nan, ) from galaxy.util.rules_dsl import RuleSet from galaxy.util.template import ( fill_template, Loading Loading @@ -2459,7 +2462,7 @@ class Tool(Dictifiable): "enctype": self.enctype, } ) return tool_model return swap_inf_nan(tool_model) def populate_model(self, request_context, inputs, state_inputs, group_inputs, other_values=None): """ Loading lib/galaxy/util/json.py +8 −4 Original line number Diff line number Diff line Loading @@ -9,6 +9,7 @@ from collections.abc import ( Mapping, Sequence, ) from decimal import Decimal from ..util import unicodify Loading @@ -22,7 +23,8 @@ from_json_string = json.loads def swap_inf_nan(val): """ This takes an arbitrary object and preps it for jsonifying safely, templating Inf/NaN. This takes an arbitrary object and preps it for jsonifying safely, templating Inf/NaN and casting Decimal instances as strings. """ if isinstance(val, str): # basestring first, because it's a sequence and would otherwise get caught below. Loading @@ -40,6 +42,8 @@ def swap_inf_nan(val): return "__-Infinity__" else: return val elif isinstance(val, Decimal): return str(val) else: return val Loading @@ -63,12 +67,12 @@ def safe_dumps(obj, **kwargs): """ This is a wrapper around dumps that encodes Infinity and NaN values. It's a fairly rare case (which will be low in request volume). Basically, we tell json.dumps to blow up if it encounters Infinity/NaN, and we 'fix' it before re-encoding. json.dumps to blow up if it encounters Infinity/NaN, or Decimal values and we 'fix' it before re-encoding. """ try: dumped = json.dumps(obj, allow_nan=False, **kwargs) except ValueError: except (ValueError, TypeError): obj = swap_inf_nan(obj) dumped = json.dumps(obj, allow_nan=False, **kwargs) if kwargs.get("escape_closing_tags", True): Loading test/unit/util/test_json.py 0 → 100644 +25 −0 Original line number Diff line number Diff line from decimal import Decimal import pytest from galaxy.util.json import ( safe_dumps, swap_inf_nan, ) @pytest.mark.parametrize( "val,expected_val", [ (float("inf"), "__Infinity__"), (float("-inf"), "__-Infinity__"), (float("NaN"), "__NaN__"), (Decimal("1"), "1"), ], ) def test_swap_inf_nan(val, expected_val): assert swap_inf_nan(val) == expected_val def test_safe_dumps(): assert safe_dumps({"a": Decimal("0.1")}) == """{"a": "0.1"}""" Loading
lib/galaxy/tools/__init__.py +5 −2 Original line number Diff line number Diff line Loading @@ -120,7 +120,10 @@ from galaxy.util.bunch import Bunch from galaxy.util.dictifiable import Dictifiable from galaxy.util.expressions import ExpressionContext from galaxy.util.form_builder import SelectField from galaxy.util.json import safe_loads from galaxy.util.json import ( safe_loads, swap_inf_nan, ) from galaxy.util.rules_dsl import RuleSet from galaxy.util.template import ( fill_template, Loading Loading @@ -2459,7 +2462,7 @@ class Tool(Dictifiable): "enctype": self.enctype, } ) return tool_model return swap_inf_nan(tool_model) def populate_model(self, request_context, inputs, state_inputs, group_inputs, other_values=None): """ Loading
lib/galaxy/util/json.py +8 −4 Original line number Diff line number Diff line Loading @@ -9,6 +9,7 @@ from collections.abc import ( Mapping, Sequence, ) from decimal import Decimal from ..util import unicodify Loading @@ -22,7 +23,8 @@ from_json_string = json.loads def swap_inf_nan(val): """ This takes an arbitrary object and preps it for jsonifying safely, templating Inf/NaN. This takes an arbitrary object and preps it for jsonifying safely, templating Inf/NaN and casting Decimal instances as strings. """ if isinstance(val, str): # basestring first, because it's a sequence and would otherwise get caught below. Loading @@ -40,6 +42,8 @@ def swap_inf_nan(val): return "__-Infinity__" else: return val elif isinstance(val, Decimal): return str(val) else: return val Loading @@ -63,12 +67,12 @@ def safe_dumps(obj, **kwargs): """ This is a wrapper around dumps that encodes Infinity and NaN values. It's a fairly rare case (which will be low in request volume). Basically, we tell json.dumps to blow up if it encounters Infinity/NaN, and we 'fix' it before re-encoding. json.dumps to blow up if it encounters Infinity/NaN, or Decimal values and we 'fix' it before re-encoding. """ try: dumped = json.dumps(obj, allow_nan=False, **kwargs) except ValueError: except (ValueError, TypeError): obj = swap_inf_nan(obj) dumped = json.dumps(obj, allow_nan=False, **kwargs) if kwargs.get("escape_closing_tags", True): Loading
test/unit/util/test_json.py 0 → 100644 +25 −0 Original line number Diff line number Diff line from decimal import Decimal import pytest from galaxy.util.json import ( safe_dumps, swap_inf_nan, ) @pytest.mark.parametrize( "val,expected_val", [ (float("inf"), "__Infinity__"), (float("-inf"), "__-Infinity__"), (float("NaN"), "__NaN__"), (Decimal("1"), "1"), ], ) def test_swap_inf_nan(val, expected_val): assert swap_inf_nan(val) == expected_val def test_safe_dumps(): assert safe_dumps({"a": Decimal("0.1")}) == """{"a": "0.1"}"""