Skip to content

Commit

Permalink
pythongh-82129: Fix NameError on get_type_hints in dataclasses
Browse files Browse the repository at this point in the history
  • Loading branch information
sobolevn committed Jul 24, 2024
1 parent af4329e commit a96efef
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 6 deletions.
6 changes: 5 additions & 1 deletion Lib/dataclasses.py
Original file line number Diff line number Diff line change
Expand Up @@ -1530,7 +1530,11 @@ class C(Base):
for item in fields:
if isinstance(item, str):
name = item
tp = 'typing.Any'
typing = sys.modules.get('typing')
if typing:
tp = typing.Any
else:
tp = 'typing.Any'
elif len(item) == 2:
name, tp, = item
elif len(item) == 3:
Expand Down
23 changes: 18 additions & 5 deletions Lib/test/test_dataclasses/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import weakref
import traceback
import unittest
import sys
from unittest.mock import Mock
from typing import ClassVar, Any, List, Union, Tuple, Dict, Generic, TypeVar, Optional, Protocol, DefaultDict
from typing import get_type_hints
Expand All @@ -23,6 +24,7 @@
import dataclasses # Needed for the string "dataclasses.InitVar[int]" to work as an annotation.

from test import support
from test.support import import_helper

# Just any custom exception we can catch.
class CustomError(Exception): pass
Expand Down Expand Up @@ -4108,16 +4110,27 @@ def test_no_types(self):
C = make_dataclass('Point', ['x', 'y', 'z'])
c = C(1, 2, 3)
self.assertEqual(vars(c), {'x': 1, 'y': 2, 'z': 3})
self.assertEqual(C.__annotations__, {'x': 'typing.Any',
'y': 'typing.Any',
'z': 'typing.Any'})
self.assertEqual(C.__annotations__, {'x': typing.Any,
'y': typing.Any,
'z': typing.Any})

C = make_dataclass('Point', ['x', ('y', int), 'z'])
c = C(1, 2, 3)
self.assertEqual(vars(c), {'x': 1, 'y': 2, 'z': 3})
self.assertEqual(C.__annotations__, {'x': 'typing.Any',
self.assertEqual(C.__annotations__, {'x': typing.Any,
'y': int,
'z': 'typing.Any'})
'z': typing.Any})

def test_no_types_no_NameError(self):
C = make_dataclass('Point', ['x'])
self.assertEqual(C.__annotations__, {'x': typing.Any})
self.assertEqual(get_type_hints(C), {'x': typing.Any})

def test_no_types_no_typing_fallback(self):
with import_helper.isolated_modules():
del sys.modules['typing']
C = make_dataclass('Point', ['x'])
self.assertEqual(C.__annotations__, {'x': 'typing.Any'})

def test_module_attr(self):
self.assertEqual(ByMakeDataClass.__module__, __name__)
Expand Down

0 comments on commit a96efef

Please sign in to comment.