Skip to content

Dataclass __init__ annotation eagerly evaluated #128184

Description

@nickdrozd

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

Linked PRs

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

3.14bugs and security fixesstdlibStandard Library Python modules in the Lib/ directorytopic-dataclassestopic-typingtype-bugAn unexpected behavior, bug, or error

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions