Skip to content

Commit 18cfc1e

Browse files
Small speedup for dataclass __eq__ and __repr__ (#104904)
Faster __repr__ with str.__add__ moved inside the f-string. For __eq__ comp;are field by field instead of building temporary tuples. Co-authored-by: Shantanu <[email protected]>
1 parent c8c1e73 commit 18cfc1e

File tree

1 file changed

+12
-8
lines changed

1 file changed

+12
-8
lines changed

Lib/dataclasses.py

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -627,7 +627,7 @@ def _init_fn(fields, std_fields, kw_only_fields, frozen, has_post_init,
627627
def _repr_fn(fields, globals):
628628
fn = _create_fn('__repr__',
629629
('self',),
630-
['return self.__class__.__qualname__ + f"(' +
630+
['return f"{self.__class__.__qualname__}(' +
631631
', '.join([f"{f.name}={{self.{f.name}!r}}"
632632
for f in fields]) +
633633
')"'],
@@ -1085,13 +1085,17 @@ def _process_class(cls, init, repr, eq, order, unsafe_hash, frozen,
10851085
if eq:
10861086
# Create __eq__ method. There's no need for a __ne__ method,
10871087
# since python will call __eq__ and negate it.
1088-
flds = [f for f in field_list if f.compare]
1089-
self_tuple = _tuple_str('self', flds)
1090-
other_tuple = _tuple_str('other', flds)
1091-
_set_new_attribute(cls, '__eq__',
1092-
_cmp_fn('__eq__', '==',
1093-
self_tuple, other_tuple,
1094-
globals=globals))
1088+
cmp_fields = (field for field in field_list if field.compare)
1089+
terms = [f'self.{field.name}==other.{field.name}' for field in cmp_fields]
1090+
field_comparisons = ' and '.join(terms) or 'True'
1091+
body = [f'if other.__class__ is self.__class__:',
1092+
f' return {field_comparisons}',
1093+
f'return NotImplemented']
1094+
func = _create_fn('__eq__',
1095+
('self', 'other'),
1096+
body,
1097+
globals=globals)
1098+
_set_new_attribute(cls, '__eq__', func)
10951099

10961100
if order:
10971101
# Create and set the ordering methods.

0 commit comments

Comments
 (0)