Skip to content

Commit c57adeb

Browse files
authored
Merge pull request #95 from DavidCEllis/fix-comparison-tuples
Make the other comparison methods match eq
2 parents abff2b7 + 020742c commit c57adeb

4 files changed

Lines changed: 47 additions & 15 deletions

File tree

docs/code_examples/outputs/docs_ex08_converters.output

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
ConverterEx(unconverted='42', converted=42)
22
Source:
33
def __eq__(self, other):
4+
if self is other:
5+
return True
46
return (
57
self.unconverted == other.unconverted
68
and self.converted == other.converted

docs/code_examples/outputs/docs_ex09_annotated.output

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ Slots: {'x': None, 'a': None, 'b': None, 'c': None, 'd': None, 'e': None, 'f': N
1515

1616
Source:
1717
def __eq__(self, other):
18+
if self is other:
19+
return True
1820
return (
1921
self.x == other.x
2022
and self.a == other.a

src/ducktools/classbuilder/__init__.py

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,8 @@ def eq_generator(cls, funcname="__eq__"):
486486
# fmt: off
487487
code = (
488488
f"def {funcname}(self, other):\n"
489+
f" if self is other:\n"
490+
f" return True\n"
489491
f" return (\n"
490492
f" {instance_comparison}\n"
491493
f" ) if {class_comparison} else NotImplemented\n"
@@ -497,20 +499,36 @@ def eq_generator(cls, funcname="__eq__"):
497499

498500

499501
def get_order_generator(cls, funcname, *, operator):
502+
class_comparison = "self.__class__ is other.__class__"
500503
field_names = [
501504
name
502505
for name, attrib in get_fields(cls).items()
503506
if attrib.compare
504507
]
505508

506-
self_tuple = ", ".join(f"self.{name}" for name in field_names)
507-
other_tuple = self_tuple.replace("self.", "other.")
509+
# Equal objects should be False for gt/lt comparisons
510+
eq_return = "True" if "=" in operator else "False"
511+
512+
instance_comparisons = [
513+
(
514+
f" if self.{name} != other.{name}:\n"
515+
f" return self.{name} {operator} other.{name}\n"
516+
)
517+
for name in field_names
518+
]
519+
instance_comparisons.append(
520+
f" return {eq_return}"
521+
)
522+
523+
instance_comparison = "".join(instance_comparisons)
508524

509525
# fmt: off
510526
code = (
511527
f"def {funcname}(self, other):\n"
512-
f" if self.__class__ is other.__class__:\n"
513-
f" return ({self_tuple}) {operator} ({other_tuple})\n"
528+
f" if self is other:\n"
529+
f" return {eq_return}\n"
530+
f" if {class_comparison}:\n"
531+
f"{instance_comparison}\n"
514532
f" return NotImplemented\n"
515533
)
516534
# fmt: on
@@ -1057,7 +1075,7 @@ def __init__(
10571075

10581076
def __init_subclass__(cls, frozen=False, ignore_annotations=False):
10591077
# Subclasses of Field can be created as if they are dataclasses
1060-
field_methods = {_field_init_maker, repr_maker, eq_maker}
1078+
field_methods = {_field_init_maker, repr_maker, eq_maker, replace_maker}
10611079
if frozen or _UNDER_TESTING:
10621080
field_methods |= {frozen_setattr_maker, frozen_delattr_maker}
10631081

src/ducktools/classbuilder/prefab.py

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -36,23 +36,33 @@
3636
except ImportError:
3737
from types import GenericAlias, NoneType
3838

39+
#fmt: off
3940
from . import (
41+
# Constants
4042
NOTHING, FIELD_NOTHING,
43+
44+
# Classes
4145
Field, MethodMaker, GatheredFields, GeneratedCode, SlotMakerMeta,
42-
builder, get_flags, get_fields,
43-
make_unified_gatherer,
46+
47+
# Builder
48+
builder,
49+
50+
# Internals Retrieval
51+
build_completed,
52+
get_flags, get_fields, get_methods,
53+
54+
# Method Makers
4455
eq_maker,
45-
lt_maker,
46-
le_maker,
47-
gt_maker,
48-
ge_maker,
49-
frozen_setattr_maker,
50-
frozen_delattr_maker,
56+
frozen_delattr_maker, frozen_setattr_maker,
57+
get_repr_generator,
58+
ge_maker, gt_maker, le_maker, lt_maker,
5159
hash_maker,
5260
replace_maker,
53-
get_repr_generator,
54-
build_completed,
61+
62+
# Gatherer
63+
make_unified_gatherer,
5564
)
65+
#fmt: on
5666

5767
from .annotations import get_func_annotations, is_type, replace_generic_with_arg
5868

0 commit comments

Comments
 (0)