diff --git a/Lib/dataclasses.py b/Lib/dataclasses.py index bd317aa9b0f2f3..5ec91cddaa3e10 100644 --- a/Lib/dataclasses.py +++ b/Lib/dataclasses.py @@ -806,7 +806,11 @@ def _get_type_from_annotation(annotation, cls): path = match[1].split(".") root = sys.modules.get(cls.__module__) for path_item in path: - root = getattr(root, path_item.strip(), None) + try: + root = getattr(root, path_item.strip(), None) + except Exception: + # Like annotationlib, ignore lazy imports that cannot be resolved. + return None if root is None: return None diff --git a/Lib/test/test_dataclasses/__init__.py b/Lib/test/test_dataclasses/__init__.py index a89999bb97938c..2b4defe35f8a33 100644 --- a/Lib/test/test_dataclasses/__init__.py +++ b/Lib/test/test_dataclasses/__init__.py @@ -4525,6 +4525,11 @@ def test_classvar_module_level_import(self): # won't exist on the instance. self.assertNotIn('not_iv4', c.__dict__) + def test_lazy_import_annotations(self): + from test.test_dataclasses import dataclass_lazy_str as m + self.assertEqual([f.name for f in fields(m.C)], ['x', 'y']) + self.assertNotIsInstance(vars(m)['t'], types.LazyImportType) + def test_text_annotations(self): from test.test_dataclasses import dataclass_textanno diff --git a/Lib/test/test_dataclasses/dataclass_lazy_broken.py b/Lib/test/test_dataclasses/dataclass_lazy_broken.py new file mode 100644 index 00000000000000..d9d29834fe1276 --- /dev/null +++ b/Lib/test/test_dataclasses/dataclass_lazy_broken.py @@ -0,0 +1 @@ +raise RuntimeError("module fails to import") diff --git a/Lib/test/test_dataclasses/dataclass_lazy_str.py b/Lib/test/test_dataclasses/dataclass_lazy_str.py new file mode 100644 index 00000000000000..cd600fb6f38071 --- /dev/null +++ b/Lib/test/test_dataclasses/dataclass_lazy_str.py @@ -0,0 +1,12 @@ +from __future__ import annotations + +import dataclasses +lazy import typing as t +lazy from _dataclass_test_missing_module import Missing +lazy from test.test_dataclasses.dataclass_lazy_broken import Broken + +@dataclasses.dataclass +class C: + x: Missing | None = None + y: Broken | None = None + cv: t.ClassVar[int] = 0 diff --git a/Misc/NEWS.d/next/Library/2026-10-06-20-33-52.gh-issue-158936.flCm_m.rst b/Misc/NEWS.d/next/Library/2026-10-06-20-33-52.gh-issue-158936.flCm_m.rst new file mode 100644 index 00000000000000..5b023af8b1b91b --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-10-06-20-33-52.gh-issue-158936.flCm_m.rst @@ -0,0 +1,3 @@ +:func:`~dataclasses.dataclass` no longer fails when a string annotation names a +:ref:`lazy import ` that cannot be resolved, matching the +behavior for non-string annotations.