diff --git a/src/debugpy/common/json.py b/src/debugpy/common/json.py index d5bd12daa..6f3e2b214 100644 --- a/src/debugpy/common/json.py +++ b/src/debugpy/common/json.py @@ -7,6 +7,7 @@ import builtins import json +import numbers import operator @@ -92,6 +93,16 @@ def __format__(self, format_spec): # some substitutions - e.g. replacing () with some default value. +def _converter(value, classinfo): + """Convert value (str) to number, otherwise return None if is not possible""" + for one_info in classinfo: + if issubclass(one_info, numbers.Number): + try: + return one_info(value) + except ValueError: + pass + + def of_type(*classinfo, **kwargs): """Returns a validator for a JSON property that requires it to have a value of the specified type. If optional=True, () is also allowed. @@ -107,6 +118,10 @@ def validate(value): if (optional and value == ()) or isinstance(value, classinfo): return value else: + converted_value = _converter(value, classinfo) + if converted_value: + return converted_value + if not optional and value == (): raise ValueError("must be specified") raise TypeError("must be " + " or ".join(t.__name__ for t in classinfo)) diff --git a/tests/debugpy/common/test_messaging.py b/tests/debugpy/common/test_messaging.py index 7ba88e886..335a5ead8 100644 --- a/tests/debugpy/common/test_messaging.py +++ b/tests/debugpy/common/test_messaging.py @@ -656,3 +656,21 @@ def _send_requests_and_events(self, channel): assert fuzzer2.sent == fuzzer1.received assert fuzzer1.responses_sent == fuzzer2.responses_received assert fuzzer2.responses_sent == fuzzer1.responses_received + + +class TestTypeConversion(object): + def test_str_to_num(self): + + # test conversion that are expected to work + correct_trials = [("1.0", float), ("1", int), ("1", bool)] + for val_trial, type_trial in correct_trials: + assert isinstance( + json.of_type(type_trial)(val_trial), type_trial + ), "Wrong type coversion" + + # test conversion that are not expected to work + try: + json.of_type(int)("1.0") + raise ValueError("This test should have failed") + except TypeError: + pass