◐ Shell
clean mode source ↗

gh-89687: fix `get_type_hints` with dataclasses `__init__` generation by sobolevn · Pull Request #29158 · python/cpython

I found a corner case: when I define a proxy module, say dataclass_textanno2.py, with this content:

from __future__ import annotations

import dataclasses
from test import dataclass_textanno  # We need to be sure that `Foo` is not in scope


class Custom:
    pass


@dataclasses.dataclass
class Child(dataclass_textanno.Bar):
    custom: Custom


@dataclasses.dataclass(init=False)
class WithFutureInit(Child):
    def __init__(self, foo: dataclass_textanno.Foo, custom: Custom) -> None:
        pass

Then, this test does not pass:

def test_dataclass_from_proxy_module(self):
        from test import dataclass_textanno, dataclass_textanno2
        from dataclasses import dataclass

        @dataclass
        class Default(dataclass_textanno2.Child):
            pass

       self.assertEqual(
                    get_type_hints(Defualt.__init__),
                    {'foo': dataclass_textanno.Foo, 'custom': dataclass_textanno2.Custom,  'return': type(None)},
                )

Output:

======================================================================
ERROR: test_dataclass_from_proxy_module (test.test_typing.GetTypeHintTests) (klass=<class 'test.test_typing.GetTypeHintTests.test_dataclass_from_proxy_module.<locals>.Default'>)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/sobolev/Desktop/cpython/Lib/test/test_typing.py", line 3376, in test_dataclass_from_proxy_module
    get_type_hints(klass.__init__),
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/sobolev/Desktop/cpython/Lib/typing.py", line 1852, in get_type_hints
    value = _eval_type(value, globalns, localns)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/sobolev/Desktop/cpython/Lib/typing.py", line 334, in _eval_type
    return t._evaluate(globalns, localns, recursive_guard)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/sobolev/Desktop/cpython/Lib/typing.py", line 700, in _evaluate
    eval(self.__forward_code__, globalns, localns),
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<string>", line 1, in <module>
NameError: name 'Custom' is not defined

----------------------------------------------------------------------
Ran 1 test in 0.044s

FAILED (errors=1)
test test_typing failed
test_typing failed (1 error)

== Tests result: FAILURE ==

1 test failed:
    test_typing