bpo-44649: Fix dataclasses(slots=True) with a field with a default, b… · python/cpython@d3062f6 (original) (raw)

`@@ -447,7 +447,7 @@ def _field_assign(frozen, name, value, self_name):

`

447

447

`return f'{self_name}.{name}={value}'

`

448

448

``

449

449

``

450

``

`-

def _field_init(f, frozen, globals, self_name):

`

``

450

`+

def _field_init(f, frozen, globals, self_name, slots):

`

451

451

`# Return the text of the line in the body of init that will

`

452

452

`# initialize this field.

`

453

453

``

`@@ -487,9 +487,15 @@ def _field_init(f, frozen, globals, self_name):

`

487

487

`globals[default_name] = f.default

`

488

488

`value = f.name

`

489

489

`else:

`

490

``

`-

This field does not need initialization. Signify that

`

491

``

`-

to the caller by returning None.

`

492

``

`-

return None

`

``

490

`+

If the class has slots, then initialize this field.

`

``

491

`+

if slots and f.default is not MISSING:

`

``

492

`+

globals[default_name] = f.default

`

``

493

`+

value = default_name

`

``

494

`+

else:

`

``

495

`+

This field does not need initialization: reading from it will

`

``

496

`+

just use the class attribute that contains the default.

`

``

497

`+

Signify that to the caller by returning None.

`

``

498

`+

return None

`

493

499

``

494

500

`# Only test this now, so that we can create variables for the

`

495

501

`# default. However, return None to signify that we're not going

`

`@@ -521,7 +527,7 @@ def _init_param(f):

`

521

527

``

522

528

``

523

529

`def _init_fn(fields, std_fields, kw_only_fields, frozen, has_post_init,

`

524

``

`-

self_name, globals):

`

``

530

`+

self_name, globals, slots):

`

525

531

`# fields contains both real fields and InitVar pseudo-fields.

`

526

532

``

527

533

`# Make sure we don't have fields without defaults following fields

`

`@@ -548,7 +554,7 @@ def _init_fn(fields, std_fields, kw_only_fields, frozen, has_post_init,

`

548

554

``

549

555

`body_lines = []

`

550

556

`for f in fields:

`

551

``

`-

line = _field_init(f, frozen, locals, self_name)

`

``

557

`+

line = _field_init(f, frozen, locals, self_name, slots)

`

552

558

`# line is None means that this field doesn't require

`

553

559

`# initialization (it's a pseudo-field). Just skip it.

`

554

560

`if line:

`

`@@ -1027,6 +1033,7 @@ def _process_class(cls, init, repr, eq, order, unsafe_hash, frozen,

`

1027

1033

`'dataclass_self' if 'self' in fields

`

1028

1034

`else 'self',

`

1029

1035

`globals,

`

``

1036

`+

slots,

`

1030

1037

` ))

`

1031

1038

``

1032

1039

`# Get the fields as a list, and include only real fields. This is

`