Skip to content

Commit 7795c9b

Browse files
committed
Remove references to original class from fields and annotate functions
1 parent a4fe18a commit 7795c9b

File tree

1 file changed

+40
-2
lines changed

1 file changed

+40
-2
lines changed

Lib/dataclasses.py

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -509,7 +509,10 @@ def add_fns_to_class(self, cls):
509509
for name, fn in zip(self.names, fns):
510510
fn.__qualname__ = f"{cls.__qualname__}.{fn.__name__}"
511511
if annotations := self.method_annotations.get(name):
512-
fn.__annotate__ = _make_annotate_function(cls, annotations)
512+
annotate_fn = _make_annotate_function(cls, annotations)
513+
annotate_fn.__qualname__ = f"{cls.__qualname__}.{fn.__name__}.__annotate__"
514+
515+
fn.__annotate__ = annotate_fn
513516

514517
if self.unconditional_adds.get(name, False):
515518
setattr(cls, name, fn)
@@ -533,7 +536,7 @@ def _make_annotate_function(cls, annotations):
533536

534537
# annotations should be in FORWARDREF format at this stage
535538

536-
def __annotate__(format):
539+
def __annotate__(format, /):
537540
match format:
538541
case annotationlib.Format.VALUE | annotationlib.Format.FORWARDREF:
539542
return {
@@ -1380,6 +1383,41 @@ def _add_slots(cls, is_frozen, weakref_slot, defined_fields):
13801383
or _update_func_cell_for__class__(member.fdel, cls, newcls)):
13811384
break
13821385

1386+
# Get new annotations to remove references to the original class
1387+
# in forward references
1388+
newcls_ann = annotationlib.get_annotations(
1389+
newcls, format=annotationlib.Format.FORWARDREF)
1390+
1391+
# Fix references in dataclass Fields
1392+
for f in getattr(newcls, _FIELDS).values():
1393+
try:
1394+
ann = newcls_ann[f.name]
1395+
except KeyError:
1396+
pass
1397+
else:
1398+
f.type = ann
1399+
1400+
# Fix references in generated __annotate__ methods
1401+
method = getattr(newcls, "__init__")
1402+
update_annotations = getattr(method.__annotate__, "__generated_by_dataclasses", False)
1403+
1404+
if update_annotations:
1405+
new_annotations = {}
1406+
1407+
# Get the previous annotations to know what to replace
1408+
old_annotations = method.__annotate__(annotationlib.Format.FORWARDREF)
1409+
1410+
for k, v in old_annotations.items():
1411+
try:
1412+
new_annotations[k] = newcls_ann[k]
1413+
except KeyError:
1414+
new_annotations[k] = v
1415+
1416+
new_annotate = _make_annotate_function(newcls, new_annotations)
1417+
new_annotate.__qualname__ = f"{newcls.__qualname__}.__init__.__annotate__"
1418+
1419+
setattr(method, "__annotate__", new_annotate)
1420+
13831421
return newcls
13841422

13851423

0 commit comments

Comments
 (0)