Skip to content

gh-89687: fix get_type_hints with dataclasses __init__ generation#137168

Open
Tishka17 wants to merge 2 commits intopython:mainfrom
Tishka17:issue-45524
Open

gh-89687: fix get_type_hints with dataclasses __init__ generation#137168
Tishka17 wants to merge 2 commits intopython:mainfrom
Tishka17:issue-45524

Conversation

@Tishka17
Copy link
Copy Markdown

@Tishka17 Tishka17 commented Jul 28, 2025

@Tishka17 Tishka17 requested a review from ericvsmith as a code owner July 28, 2025 14:18
@python-cla-bot
Copy link
Copy Markdown

python-cla-bot Bot commented Jul 28, 2025

All commit authors signed the Contributor License Agreement.

CLA signed

@bedevere-app
Copy link
Copy Markdown

bedevere-app Bot commented Jul 28, 2025

Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool.

If this change has little impact on Python users, wait for a maintainer to apply the skip news label instead.

@Tishka17
Copy link
Copy Markdown
Author

As I see at this point:

  1. annotationlib.get_annotations does not resolve ForwardRef at all
  2. typing.get_type_hints ignores module in ForwardRef

@Tishka17 Tishka17 requested a review from JelleZijlstra as a code owner July 28, 2025 15:58
Comment thread Lib/annotationlib.py

arg = self.__forward_arg__
if arg.isidentifier() and not keyword.iskeyword(arg):
if self.__forward_module__ is not None:
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is correct, since we infer globals from __forward_module__ if no explicit globals are given. And if explicit globals are given, we shouldn't be using __forward_module__.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think current behavior is correct. Was there any discussion?

Comment thread Lib/dataclasses.py
# Return the text of the line in the body of __init__ that will
# initialize this field.

if f.init and isinstance(f.type, str):
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something like this is good, but I'd do it like this:

diff --git a/Lib/dataclasses.py b/Lib/dataclasses.py
index 53b3b54cfb3..e3d25fb0840 100644
--- a/Lib/dataclasses.py
+++ b/Lib/dataclasses.py
@@ -789,7 +789,10 @@ def _get_field(cls, a_name, a_type, default_kw_only):
 
     # Only at this point do we know the name and the type.  Set them.
     f.name = a_name
-    f.type = a_type
+    if isinstance(a_type, str):
+        f.type = annotationlib.ForwardRef(a_type, owner=cls)
+    else:
+        f.type = a_type
 
     # Assume it's a normal field until proven otherwise.  We're next
     # going to decide if it's a ClassVar or InitVar, everything else

ForwardRef now lives in annotationlib, not typing. There's no need to catch SyntaxError as it doesn't parse its input in the constructor.

@github-actions
Copy link
Copy Markdown

This PR is stale because it has been open for 30 days with no activity.

@github-actions github-actions Bot added the stale Stale PR or inactive for long period of time. label Apr 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

awaiting review stale Stale PR or inactive for long period of time.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants