Skip to content

Commit 5d0d9d9

Browse files
authored
Fix string parsing regressions (#674)
1 parent a23134f commit 5d0d9d9

File tree

5 files changed

+33
-20
lines changed

5 files changed

+33
-20
lines changed

CHANGELOG.rst

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,9 @@ Fixed
3131
<https://github.com/omni-us/jsonargparse/pull/668>`__)
3232
- Functions that create types now have ``TypeAlias`` return type to avoid mypy
3333
errors (`#671 <https://github.com/omni-us/jsonargparse/pull/671>`__).
34-
- Bug when parsing strings with digits and a starting or ending 'e' (`#672
35-
<https://github.com/omni-us/jsonargparse/pull/673>`__).
34+
- String parsing regressions (`#673
35+
<https://github.com/omni-us/jsonargparse/pull/673>`__, `#674
36+
<https://github.com/omni-us/jsonargparse/pull/674>`__).
3637

3738

3839
v4.36.0 (2025-01-17)

jsonargparse/_loaders_dumpers.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,15 @@ def load_basic(value):
2828
return False
2929
if value == "null":
3030
return None
31-
if value.isdigit() or (value.startswith("-") and value[1:].isdigit()):
32-
return int(value)
33-
if (
34-
not value.startswith("e")
35-
and not value.endswith("e")
36-
and value.replace(".", "", 1).replace("e", "", 1).replace("-", "", 2).isdigit()
37-
and ("e" in value or "." in value)
38-
):
39-
return float(value)
31+
try:
32+
if value.isdigit() or (value.startswith("-") and value[1:].isdigit()):
33+
return int(value)
34+
if value.replace(".", "", 1).replace("e", "", 1).replace("-", "", 2).isdigit() and (
35+
"e" in value or "." in value
36+
):
37+
return float(value)
38+
except ValueError:
39+
pass
4040
return not_loaded
4141

4242

jsonargparse/_typehints.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -602,11 +602,20 @@ def _check_type(self, value, append=False, cfg=None):
602602
val["__path__"] = config_path
603603
value[num] = val
604604
except (TypeError, ValueError) as ex:
605-
elem = "" if not islist else f" element {num+1}"
606-
error = indent_text(str(ex))
607-
raise TypeError(f'Parser key "{self.dest}"{elem}:\n{error}') from ex
605+
if self._is_valid_string(val):
606+
value[num] = val
607+
else:
608+
elem = "" if not islist else f" element {num+1}"
609+
error = indent_text(str(ex))
610+
raise TypeError(f'Parser key "{self.dest}"{elem}:\n{error}') from ex
608611
return value if islist else value[0]
609612

613+
def _is_valid_string(self, value):
614+
typehint = self._typehint
615+
return isinstance(value, str) and (
616+
typehint is str or (get_typehint_origin(typehint) == Union and str in typehint.__args__)
617+
)
618+
610619
def instantiate_classes(self, value):
611620
islist = _is_action_value_list(self)
612621
if not islist:

jsonargparse_tests/test_loaders_dumpers.py

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -91,12 +91,6 @@ def test_dump_header_invalid(parser):
9191
parser.dump_header = True
9292

9393

94-
def test_load_value_digits_and_e():
95-
with parser_context(load_value_mode="yaml"):
96-
assert "e123" == load_value("e123")
97-
assert "123e" == load_value("123e")
98-
99-
10094
@skip_if_no_pyyaml
10195
def test_load_value_dash():
10296
with parser_context(load_value_mode="yaml"):

jsonargparse_tests/test_typehints.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,15 @@ def test_str_yaml_constructor_error(parser):
109109
assert "{{something}}" == parser.parse_args(["--val={{something}}"]).val
110110

111111

112+
@parser_modes
113+
def test_str_edge_cases(parser):
114+
parser.add_argument("--val", type=str)
115+
assert parser.parse_args(["--val=e123"]).val == "e123"
116+
assert parser.parse_args(["--val=123e"]).val == "123e"
117+
val = "1" * 5000
118+
assert parser.parse_args([f"--val={val}"]).val == val
119+
120+
112121
def test_bool_parse(parser):
113122
parser.add_argument("--val", type=bool)
114123
assert None is parser.get_defaults().val

0 commit comments

Comments
 (0)