Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,15 @@ The semantic versioning only considers the public API as described in
paths are considered internals and can change in minor and patch releases.


v4.32.0 (2024-07-??)
--------------------

Added
^^^^^
- Support for ``MappingProxyType`` as a type and as default for mapping types
(`#540 <https://github.com/omni-us/jsonargparse/pull/540>`__).


v4.31.0 (2024-06-27)
--------------------

Expand Down
5 changes: 3 additions & 2 deletions DOCUMENTATION.rst
Original file line number Diff line number Diff line change
Expand Up @@ -400,8 +400,9 @@ Some notes about this support are:
:ref:`restricted-strings` and paths and URLs as explained in sections
:ref:`parsing-paths` and :ref:`parsing-urls`.

- ``Dict``, ``Mapping``, ``MutableMapping``, and ``TypedDict`` are supported but
only with ``str`` or ``int`` keys. For more details see :ref:`dict-items`.
- ``Dict``, ``Mapping``, ``MutableMapping``, ``MappingProxyType``, and
``TypedDict`` are supported but only with ``str`` or ``int`` keys. For more
details see :ref:`dict-items`.

- ``Tuple``, ``Set`` and ``MutableSet`` are supported even though they can't be
represented in json distinguishable from a list. Each ``Tuple`` element
Expand Down
8 changes: 6 additions & 2 deletions jsonargparse/_typehints.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from copy import deepcopy
from enum import Enum
from functools import partial
from types import FunctionType
from types import FunctionType, MappingProxyType
from typing import (
Any,
Callable,
Expand Down Expand Up @@ -145,7 +145,7 @@
abc.Sequence,
abc.MutableSequence,
}
mapping_origin_types = {Dict, dict, Mapping, MutableMapping, abc.Mapping, abc.MutableMapping}
mapping_origin_types = {Dict, dict, Mapping, MappingProxyType, MutableMapping, abc.Mapping, abc.MutableMapping}
callable_origin_types = {Callable, abc.Callable}

literal_types = {Literal}
Expand Down Expand Up @@ -872,6 +872,8 @@ def adapt_typehints(
val = {**prev_val, val.key: val.val}
else:
val = {val.key: val.val}
elif isinstance(val, MappingProxyType):
val = dict(val)
elif not isinstance(val, dict):
raise_unexpected_value(f"Expected a {typehint_origin}", val)
if subtypehints is not None:
Expand Down Expand Up @@ -902,6 +904,8 @@ def adapt_typehints(
raise_unexpected_value(f"Unexpected keys: {extra_keys}", val)
for k, v in val.items():
val[k] = adapt_typehints(v, typehint.__annotations__[k], **adapt_kwargs)
if typehint_origin == MappingProxyType and not serialize:
val = MappingProxyType(val)

# Callable
elif typehint_origin in callable_origin_types or typehint in callable_origin_types:
Expand Down
18 changes: 18 additions & 0 deletions jsonargparse_tests/test_typehints.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from calendar import Calendar, TextCalendar
from enum import Enum
from pathlib import Path
from types import MappingProxyType
from typing import (
Any,
Callable,
Expand Down Expand Up @@ -545,6 +546,23 @@ def test_typeddict_with_args_ntotal(parser):
ctx.match("Expected a <class 'dict'>")


def test_mapping_proxy_type(parser):
parser.add_argument("--mapping", type=MappingProxyType)
cfg = parser.parse_args(['--mapping={"x":1}'])
assert isinstance(cfg.mapping, MappingProxyType)
assert cfg.mapping == {"x": 1}
assert parser.dump(cfg, format="json") == '{"mapping":{"x":1}}'


def test_mapping_default_mapping_proxy_type(parser):
mapping_proxy = MappingProxyType({"x": 1})
parser.add_argument("--mapping", type=Mapping[str, int], default=mapping_proxy)
cfg = parser.parse_args([])
assert isinstance(cfg.mapping, Mapping)
assert mapping_proxy == cfg.mapping
assert parser.dump(cfg, format="json") == '{"mapping":{"x":1}}'


# union tests


Expand Down