Skip to content

Commit 6f9ea46

Browse files
authored
compose_dataclasses is deprecated and will be removed in v5.0.0 (#796)
1 parent 49a2574 commit 6f9ea46

File tree

5 files changed

+53
-38
lines changed

5 files changed

+53
-38
lines changed

CHANGELOG.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ Deprecated
4444
- ``strip_meta`` is deprecated and will be removed in v5.0.0. Instead use
4545
``.clone(with_meta=False)`` (`#795
4646
<https://github.com/omni-us/jsonargparse/pull/795>`__).
47+
- ``compose_dataclasses`` is deprecated and will be removed in v5.0.0. There is
48+
no direct replacement, whoever is interested can copy the code (`#796
49+
<https://github.com/omni-us/jsonargparse/pull/796>`__).
4750

4851

4952
v4.42.0 (2025-10-14)

jsonargparse/_deprecated.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
"LoggerProperty",
2727
"ParserDeprecations",
2828
"ParserError",
29+
"compose_dataclasses",
2930
"get_config_read_mode",
3031
"namespace_to_dict",
3132
"null_logger",
@@ -774,3 +775,25 @@ def set_yaml_argument_comment(self, text: str, cfg: ruamelCommentedMap, key: str
774775
depth: The nested level of the argument.
775776
"""
776777
self._yaml_formatter.set_yaml_argument_comment(text, cfg, key, depth)
778+
779+
780+
@deprecated(
781+
"""
782+
compose_dataclasses is deprecated and will be removed in v5.0.0. There is
783+
no direct replacement, whoever is interested can copy the code from an old
784+
release.
785+
"""
786+
)
787+
def compose_dataclasses(*args):
788+
"""Returns a dataclass inheriting all given dataclasses and properly handling __post_init__."""
789+
790+
import dataclasses
791+
792+
@dataclasses.dataclass
793+
class ComposedDataclass(*args):
794+
def __post_init__(self):
795+
for arg in args:
796+
if hasattr(arg, "__post_init__"):
797+
arg.__post_init__(self)
798+
799+
return ComposedDataclass

jsonargparse/_signatures.py

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,7 @@
3131
from ._util import NoneType, get_import_path, get_private_kwargs, get_typehint_origin, iter_to_set_str
3232
from .typing import register_pydantic_type
3333

34-
__all__ = [
35-
"compose_dataclasses",
36-
"SignatureArguments",
37-
]
34+
__all__ = ["SignatureArguments"]
3835

3936

4037
kinds = inspect._ParameterKind
@@ -614,16 +611,3 @@ def convert_to_dict(value) -> dict:
614611
if is_not_subclass_type(value_type):
615612
return init_args
616613
return {"class_path": get_import_path(value_type), "init_args": init_args}
617-
618-
619-
def compose_dataclasses(*args):
620-
"""Returns a dataclass inheriting all given dataclasses and properly handling __post_init__."""
621-
622-
@dataclasses.dataclass
623-
class ComposedDataclass(*args):
624-
def __post_init__(self):
625-
for arg in args:
626-
if hasattr(arg, "__post_init__"):
627-
arg.__post_init__(self)
628-
629-
return ComposedDataclass

jsonargparse_tests/test_dataclasses.py

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
ArgumentError,
1313
ArgumentParser,
1414
Namespace,
15-
compose_dataclasses,
1615
set_parsing_settings,
1716
)
1817
from jsonargparse._namespace import NSKeyError
@@ -336,25 +335,6 @@ def test_dataclass_fail_untyped_false(parser):
336335
assert isinstance(init.data.a3, str)
337336

338337

339-
@dataclasses.dataclass
340-
class ComposeA:
341-
a: int = 1
342-
343-
def __post_init__(self):
344-
self.a += 1
345-
346-
347-
@dataclasses.dataclass
348-
class ComposeB:
349-
b: str = "1"
350-
351-
352-
def test_compose_dataclasses():
353-
ComposeAB = compose_dataclasses(ComposeA, ComposeB)
354-
assert 2 == len(dataclasses.fields(ComposeAB))
355-
assert {"a": 3, "b": "2"} == dataclasses.asdict(ComposeAB(a=2, b="2")) # pylint: disable=unexpected-keyword-arg
356-
357-
358338
@dataclasses.dataclass
359339
class NestedData:
360340
name: str = "name"

jsonargparse_tests/test_deprecated.py

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
ArgumentError,
1919
ArgumentParser,
2020
Namespace,
21+
compose_dataclasses,
2122
get_config_read_mode,
2223
set_config_read_mode,
2324
set_docstring_parse_options,
@@ -681,7 +682,6 @@ def test_import_from_deprecated():
681682
("link_arguments", "ArgumentLinking"),
682683
("loaders_dumpers", "set_loader"),
683684
("namespace", "Namespace"),
684-
("signatures", "compose_dataclasses"),
685685
("typehints", "lazy_instance"),
686686
("util", "Path"),
687687
("parameter_resolvers", "ParamData"),
@@ -802,3 +802,28 @@ def test_DefaultHelpFormatter_yaml_comments(parser):
802802
formatter.set_yaml_argument_comment("arg", cfg, "arg", 0)
803803
assert "set_yaml_argument_comment method is deprecated and will be removed in v5.0.0" in str(w[-1].message)
804804
assert "formatter.set_yaml_argument_comment(" in source[w[-1].lineno - 1]
805+
806+
807+
@dataclasses.dataclass
808+
class ComposeA:
809+
a: int = 1
810+
811+
def __post_init__(self):
812+
self.a += 1
813+
814+
815+
@dataclasses.dataclass
816+
class ComposeB:
817+
b: str = "1"
818+
819+
820+
def test_compose_dataclasses():
821+
with catch_warnings(record=True) as w:
822+
ComposeAB = compose_dataclasses(ComposeA, ComposeB)
823+
assert_deprecation_warn(
824+
w,
825+
message="compose_dataclasses is deprecated",
826+
code="ComposeAB = compose_dataclasses(ComposeA, ComposeB)",
827+
)
828+
assert 2 == len(dataclasses.fields(ComposeAB))
829+
assert {"a": 3, "b": "2"} == dataclasses.asdict(ComposeAB(a=2, b="2")) # pylint: disable=unexpected-keyword-arg

0 commit comments

Comments
 (0)