Repository: konradhalas/dacite

Issue:
"AttributeError: readonly attribute" for dataclasses containing iterables with dacite `1.9.0`
**Describe the bug**
When trying to instantiate a dataclass, which contains an iterable (tested with `list` and `tuple`), using `dacite.from_dict` in version `1.9.0`, `AttributeError: readonly attribute` is raised.

**To Reproduce**
```python3
#!/usr/bin/env python3

import dataclasses

import dacite


@dataclasses.dataclass
class Foo:
    bar: list[str]


def main():
    dacite.from_dict(
        data_class=Foo,
        data={
            'bar': ['foo', 'bar'],
        },
    )


if __name__ == '__main__':
    main()
```

**Expected behavior**
No exception.

**Environment**
- Python version: 3.12.8 as well as 3.13.1
- `dacite` version: 1.9.0

**Additional context**
stracktrace (Python 3.12.8 + homebrew):
```
Traceback (most recent call last):
  File "reproducer.py", line 23, in <module>
    main()
  File "reproducer.py", line 14, in main
    dacite.from_dict(
  File "/opt/homebrew/lib/python3.12/site-packages/dacite/core.py", line 53, in from_dict
    data_class_hints = cache(get_concrete_type_hints)(data_class, localns=config.hashable_forward_references)
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/lib/python3.12/site-packages/dacite/generics.py", line 92, in get_concrete_type_hints
    hints[key] = __concretize(hint, generics, data_class)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/lib/python3.12/site-packages/dacite/generics.py", line 59, in __concretize
    hint.__args__ = tuple(__concretize(a, generics, data_class) for a in hint_args)
    ^^^^^^^^^^^^^
AttributeError: readonly attribute
```

stacktrace (Python 3.13.1 + apk):
```
Traceback (most recent call last):
  File "reproducer.py", line 23, in <module>
    main()
    ~~~~^^
  File "reproducer.py", line 14, in main
    dacite.from_dict(
    ~~~~~~~~~~~~~~~~^
        data_class=Foo,
        ^^^^^^^^^^^^^^^
    ...<2 lines>...
        },
        ^^
    )
    ^
  File "/usr/local/lib/python3.13/site-packages/dacite/core.py", line 53, in from_dict
    data_class_hints = cache(get_concrete_type_hints)(data_class, localns=config.hashable_forward_references)
  File "/usr/local/lib/python3.13/site-packages/dacite/generics.py", line 92, in get_concrete_type_hints
    hints[key] = __concretize(hint, generics, data_class)
                 ~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.13/site-packages/dacite/generics.py", line 59, in __concretize
    hint.__args__ = tuple(__concretize(a, generics, data_class) for a in hint_args)
    ^^^^^^^^^^^^^
AttributeError: readonly attribute
```

Discussion:

Patch:
diff --git a/dacite/generics.py b/dacite/generics.py
index 9a44c19..30ef0eb 100644
--- a/dacite/generics.py
+++ b/dacite/generics.py
@@ -56,7 +56,12 @@ def __concretize(
     hint_origin = get_origin(hint)
     hint_args = get_args(hint)
     if hint_origin and hint_args and hint_origin is not Literal:
-        hint.__args__ = tuple(__concretize(a, generics, data_class) for a in hint_args)
+        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
 
     return hint
 


Test patch:
diff --git a/tests/common.py b/tests/common.py
index bfb7c81..29e743a 100644
--- a/tests/common.py
+++ b/tests/common.py
@@ -4,6 +4,6 @@ import pytest
 
 literal_support = init_var_type_support = pytest.mark.skipif(sys.version_info < (3, 8), reason="requires Python 3.8")
 pep_604_support = pytest.mark.skipif(sys.version_info < (3, 10), reason="requires Python 3.10")
-type_hints_with_generic_collections_support = pytest.mark.skipif(
+type_hints_with_generic_collections_support = type_hinting_using_standard_collections = pytest.mark.skipif(
     sys.version_info < (3, 9), reason="requires Python 3.9"
 )
diff --git a/tests/core/test_base.py b/tests/core/test_base.py
index 89e67c6..2e690b1 100644
--- a/tests/core/test_base.py
+++ b/tests/core/test_base.py
@@ -4,6 +4,26 @@ from typing import Any, NewType, Optional, List
 import pytest
 
 from dacite import from_dict, MissingValueError, WrongTypeError
+from tests.common import type_hinting_using_standard_collections
+
+
+def test_from_dict_iterables_with_typing_list():
+    @dataclass
+    class Foo:
+        bar: List[str]
+
+    result = from_dict(Foo, {"bar": ["foo", "bar"]})
+    assert result == Foo(bar=["foo", "bar"])
+
+
+@type_hinting_using_standard_collections
+def test_from_dict_iterables():
+    @dataclass
+    class Foo:
+        bar: list[str]
+
+    result = from_dict(Foo, {"bar": ["foo", "bar"]})
+    assert result == Foo(bar=["foo", "bar"])
 
 
 def test_from_dict_with_correct_data():