From 996479f938b13d28988dfe6d5df2f1bf24b89bb0 Mon Sep 17 00:00:00 2001 From: "arne.vanlondersele" Date: Thu, 30 Jan 2025 10:08:42 +0100 Subject: [PATCH] fix readonly __args__ --- dacite/config.py | 2 +- dacite/generics.py | 15 +++++++++------ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/dacite/config.py b/dacite/config.py index 78359da..78723d3 100644 --- a/dacite/config.py +++ b/dacite/config.py @@ -4,7 +4,7 @@ from dacite.frozen_dict import FrozenDict -if sys.version_info.minor >= 8: +if sys.version_info >= (3, 8): from functools import cached_property # type: ignore # pylint: disable=no-name-in-module else: # Remove when we drop support for Python<3.8 diff --git a/dacite/generics.py b/dacite/generics.py index 30ef0eb..ede42fa 100644 --- a/dacite/generics.py +++ b/dacite/generics.py @@ -56,12 +56,15 @@ def __concretize( hint_origin = get_origin(hint) hint_args = get_args(hint) if hint_origin and hint_args and hint_origin is not Literal: - concretized = tuple(__concretize(a, generics, data_class) for a in hint_args) - if concretized != hint_args: - try: - hint.__args__ = concretized - except AttributeError as err: - raise DaciteError(f"Could not set __args__ on {hint} [original error: {err}]") from None + concrete_hint_args = tuple(__concretize(a, generics, data_class) for a in hint_args) + if concrete_hint_args != hint_args: + if sys.version_info >= (3, 9): + return hint_origin[concrete_hint_args] + # It's generally not a good practice to overwrite __args__, + # and it even has become impossible starting from python 3.13 (read-only), + # but changing the output of get_type_hints is harmless (see unit test) + # and at least this way, we get it working for python 3.8. + hint.__args__ = concrete_hint_args return hint