Skip to content

Commit c634a88

Browse files
authored
Fix dict types not correctly forwarding previous nested values when parsing (#559)
1 parent 74c169b commit c634a88

File tree

3 files changed

+40
-1
lines changed

3 files changed

+40
-1
lines changed

CHANGELOG.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,15 @@ The semantic versioning only considers the public API as described in
1212
paths are considered internals and can change in minor and patch releases.
1313

1414

15+
v4.32.1 (2024-08-??)
16+
--------------------
17+
18+
Fixed
19+
^^^^^
20+
- ``dict`` types not correctly forwarding previous nested values when parsing
21+
(`#559 <https://github.com/omni-us/jsonargparse/pull/559>`__).
22+
23+
1524
v4.32.0 (2024-07-19)
1625
--------------------
1726

jsonargparse/_typehints.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -904,7 +904,12 @@ def adapt_typehints(
904904
for t in sub_add_kwargs["linked_targets"]
905905
}
906906
else:
907-
kwargs = adapt_kwargs
907+
kwargs = adapt_kwargs.copy()
908+
if kwargs.get("prev_val"):
909+
if isinstance(kwargs["prev_val"], dict):
910+
kwargs["prev_val"] = kwargs["prev_val"].get(k)
911+
else:
912+
kwargs["prev_val"] = None
908913
val[k] = adapt_typehints(v, subtypehints[1], **kwargs)
909914
if get_import_path(typehint.__class__) == "typing._TypedDictMeta":
910915
if typehint.__total__:

jsonargparse_tests/test_dataclass_like.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from __future__ import annotations
22

33
import dataclasses
4+
import json
45
from typing import Any, Dict, Generic, List, Optional, Tuple, TypeVar, Union
56
from unittest.mock import patch
67

@@ -684,6 +685,13 @@ class OptionalPydantic:
684685
def __init__(self, a: Optional[PydanticModel] = None):
685686
self.a = a
686687

688+
class NestedModel(pydantic.BaseModel):
689+
inputs: List[str]
690+
outputs: List[str]
691+
692+
class PydanticNestedDict(pydantic.BaseModel):
693+
nested: Optional[Dict[str, NestedModel]] = None
694+
687695

688696
def none(x):
689697
return x
@@ -817,6 +825,23 @@ def test_optional_pydantic_model(self, parser):
817825
assert cfg.b.class_path == f"{__name__}.OptionalPydantic"
818826
assert cfg.b.init_args == Namespace(a=Namespace(p1="x", p2=3))
819827

828+
def test_nested_dict(self, parser):
829+
parser.add_argument("--config", action="config")
830+
parser.add_argument("--model", type=PydanticNestedDict)
831+
model = {
832+
"nested": {
833+
"key": {
834+
"inputs": ["a", "b"],
835+
"outputs": ["x", "y"],
836+
}
837+
}
838+
}
839+
cfg = parser.parse_args(["--model", json.dumps(model)])
840+
assert cfg.model.nested["key"] == Namespace(inputs=["a", "b"], outputs=["x", "y"])
841+
init = parser.instantiate_classes(cfg)
842+
assert isinstance(init.model, PydanticNestedDict)
843+
assert isinstance(init.model.nested["key"], NestedModel)
844+
820845

821846
# attrs tests
822847

0 commit comments

Comments
 (0)