Closed
Description
Bug report
Bug description:
In 3.14, evaluation of annotations is deferred. Except, annotations for the __init__
method of a dataclass
are eagerly evaluated.
from dataclasses import dataclass
from typing import TYPE_CHECKING
if TYPE_CHECKING:
Z = int
@dataclass
class X:
def __init__(self, _: Z): # <-- NameError: name 'Z' is not defined
pass
def f(self, _: Z): # <-- no __init__, no problem
pass
class Y:
def __init__(self, _: Z): # <-- no dataclass, no problem
pass
Running this blows up with a scary stack trace:
Traceback (most recent call last):
File "/home/nick/test/annotation.py", line 7, in <module>
@dataclass
^^^^^^^^^
File "/usr/local/lib/python3.14/dataclasses.py", line 1365, in dataclass
return wrap(cls)
File "/usr/local/lib/python3.14/dataclasses.py", line 1355, in wrap
return _process_class(cls, init, repr, eq, order, unsafe_hash,
frozen, match_args, kw_only, slots,
weakref_slot)
File "/usr/local/lib/python3.14/dataclasses.py", line 1166, in _process_class
text_sig = str(inspect.signature(cls)).replace(' -> None', '')
~~~~~~~~~~~~~~~~~^^^^^
File "/usr/local/lib/python3.14/inspect.py", line 3281, in signature
return Signature.from_callable(obj, follow_wrapped=follow_wrapped,
~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
globals=globals, locals=locals, eval_str=eval_str,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
annotation_format=annotation_format)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.14/inspect.py", line 2999, in from_callable
return _signature_from_callable(obj, sigcls=cls,
follow_wrapper_chains=follow_wrapped,
globals=globals, locals=locals, eval_str=eval_str,
annotation_format=annotation_format)
File "/usr/local/lib/python3.14/inspect.py", line 2524, in _signature_from_callable
return _get_signature_of(init)
File "/usr/local/lib/python3.14/inspect.py", line 2421, in _signature_from_callable
sig = _get_signature_of(obj.__func__)
File "/usr/local/lib/python3.14/inspect.py", line 2492, in _signature_from_callable
return _signature_from_function(sigcls, obj,
skip_bound_arg=skip_bound_arg,
globals=globals, locals=locals, eval_str=eval_str,
annotation_format=annotation_format)
File "/usr/local/lib/python3.14/inspect.py", line 2315, in _signature_from_function
annotations = get_annotations(func, globals=globals, locals=locals, eval_str=eval_str,
format=annotation_format)
File "/usr/local/lib/python3.14/annotationlib.py", line 707, in get_annotations
ann = _get_dunder_annotations(obj)
File "/usr/local/lib/python3.14/annotationlib.py", line 847, in _get_dunder_annotations
ann = getattr(obj, "__annotations__", None)
File "/home/nick/test/annotation.py", line 9, in __annotate__
def __init__(self, _: Z): # <-- NameError: name 'Z' is not defined
^
NameError: name 'Z' is not defined
AFAICT, this behavior is specific to __init__
with dataclass
. I don't know what's intended, but as a user it feels like a bug.
Adding from __future__ import annotations
causes the problem to go away. But that shouldn't be required in 3.14.
CPython versions tested on:
3.14, CPython main branch
Operating systems tested on:
Linux