From 88a816de967749a2cc689bbb22f0a059cf6383fc Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Sun, 14 May 2023 17:36:43 -0500 Subject: [PATCH 1/3] Faster __repr__ with str.__add__ moved inside the f-string. --- Lib/dataclasses.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/dataclasses.py b/Lib/dataclasses.py index 3eacba840db426..5154ef8230bee6 100644 --- a/Lib/dataclasses.py +++ b/Lib/dataclasses.py @@ -627,7 +627,7 @@ def _init_fn(fields, std_fields, kw_only_fields, frozen, has_post_init, def _repr_fn(fields, globals): fn = _create_fn('__repr__', ('self',), - ['return self.__class__.__qualname__ + f"(' + + ['return f"{self.__class__.__qualname__}(' + ', '.join([f"{f.name}={{self.{f.name}!r}}" for f in fields]) + ')"'], From bce2e722df899c8e7e70772fb6eeeeee00afef91 Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Wed, 24 May 2023 17:15:44 -0500 Subject: [PATCH 2/3] Almost there --- Lib/dataclasses.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/Lib/dataclasses.py b/Lib/dataclasses.py index 5154ef8230bee6..b1f8ec5305ec44 100644 --- a/Lib/dataclasses.py +++ b/Lib/dataclasses.py @@ -1085,13 +1085,17 @@ def _process_class(cls, init, repr, eq, order, unsafe_hash, frozen, if eq: # Create __eq__ method. There's no need for a __ne__ method, # since python will call __eq__ and negate it. - flds = [f for f in field_list if f.compare] - self_tuple = _tuple_str('self', flds) - other_tuple = _tuple_str('other', flds) - _set_new_attribute(cls, '__eq__', - _cmp_fn('__eq__', '==', - self_tuple, other_tuple, - globals=globals)) + cmp_fields = (field for field in field_list if f.compare) + terms = [f'self.{field.name}==other.{field.name}' for field in cmp_fields] + field_comparisons = ' and '.join(terms) or 'True' + body = [f'if other.__class__ is self.__class__:', + f' return { field_comparisons}', + f'return NotImplemented'] + func = _create_fn('__eq__', + ('self', 'other'), + body, + globals=globals) + _set_new_attribute(cls, '__eq__', func) if order: # Create and set the ordering methods. From cfa5a06f863c278eafa6de8d18057ef8edbf617c Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Wed, 24 May 2023 17:36:25 -0500 Subject: [PATCH 3/3] Faster __eq__ --- Lib/dataclasses.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/dataclasses.py b/Lib/dataclasses.py index b1f8ec5305ec44..e766a7b554afe1 100644 --- a/Lib/dataclasses.py +++ b/Lib/dataclasses.py @@ -1085,11 +1085,11 @@ def _process_class(cls, init, repr, eq, order, unsafe_hash, frozen, if eq: # Create __eq__ method. There's no need for a __ne__ method, # since python will call __eq__ and negate it. - cmp_fields = (field for field in field_list if f.compare) + cmp_fields = (field for field in field_list if field.compare) terms = [f'self.{field.name}==other.{field.name}' for field in cmp_fields] field_comparisons = ' and '.join(terms) or 'True' body = [f'if other.__class__ is self.__class__:', - f' return { field_comparisons}', + f' return {field_comparisons}', f'return NotImplemented'] func = _create_fn('__eq__', ('self', 'other'),