Skip to content

Auto Eq

auto_eq

Auto-eq decorator for generating __eq__ on class instances.

Provides the auto_eq decorator that generates __eq__ based on
class fields. Works on plain classes with
__slots__ or __annotations__.

Can be used as @auto_eq, @auto_eq(), or
@auto_eq(fields=[...]) to compare only specific attributes.

Does NOT generate __hash__ — use auto_hash when
hashability is required.

Useful for: Plain data classes and any type that requires
structural equality comparisons.

Example
@auto_eq
class Point:
    __slots__ = ("x", "y")

    def __init__(self, x: int, y: int) -> None:
        self.x = x
        self.y = y


p1 = Point(1, 2)
p2 = Point(1, 2)
p3 = Point(3, 4)
assert p1 == p2
assert p1 != p3

With selective fields:

@auto_eq(fields=["x"])
class Point:
    __slots__ = ("x", "y")

    def __init__(self, x: int, y: int) -> None:
        self.x = x
        self.y = y


assert Point(1, 2) == Point(1, 999)

auto_eq(class_: type[T] | None = None, *, fields: Sequence[str] | None = None) -> type[T] | Callable[[type[T]], type[T]]

auto_eq(class_: type[T]) -> type[T]
auto_eq(
    class_: type[T], *, fields: Sequence[str] | None = None
) -> type[T]
auto_eq(
    class_: None = None,
    *,
    fields: Sequence[str] | None = None,
) -> Callable[[type[T]], type[T]]

Generate __eq__ for a class based on its fields.

Can be used as @auto_eq, @auto_eq(), or
@auto_eq(fields=[...]). Generates __eq__ only — does NOT
generate __hash__. Use auto_hash when hashability
is required.

Field names are resolved from __slots__ (across the MRO) or
__annotations__ keys when fields is None.

Parameters:

Name Type Description Default
class_ type[T] | None

The target class (when used directly as @auto_eq).
None when used with parentheses (@auto_eq() or
@auto_eq(fields=...)).

None
fields Sequence[str] | None

Optional sequence of field names to include in equality.
When None, field names are resolved from __slots__
(across the MRO) or __annotations__ keys.

None

Returns:

Type Description
type[T] | Callable[[type[T]], type[T]]

The decorated class if class_ is provided; otherwise a callable

type[T] | Callable[[type[T]], type[T]]

that can be used as a decorator.

Raises:

Type Description
TypeError

If no field names can be determined automatically and
fields is None.

Source code in src/forging_blocks/foundation/autoeq/auto_eq.py
def auto_eq[T](
    class_: type[T] | None = None,
    *,
    fields: Sequence[str] | None = None,
) -> type[T] | Callable[[type[T]], type[T]]:
    """Generate ``__eq__`` for a class based on its fields.

    Can be used as ``@auto_eq``, ``@auto_eq()``, or
    ``@auto_eq(fields=[...])``. Generates ``__eq__`` only — does NOT
    generate ``__hash__``. Use `auto_hash` when hashability
    is required.

    Field names are resolved from ``__slots__`` (across the MRO) or
    ``__annotations__`` keys when *fields* is ``None``.

    Args:
        class_: The target class (when used directly as ``@auto_eq``).
            ``None`` when used with parentheses (``@auto_eq()`` or
            ``@auto_eq(fields=...)``).
        fields: Optional sequence of field names to include in equality.
            When ``None``, field names are resolved from ``__slots__``
            (across the MRO) or ``__annotations__`` keys.

    Returns:
        The decorated class if *class_* is provided; otherwise a callable
        that can be used as a decorator.

    Raises:
        TypeError: If no field names can be determined automatically and
            *fields* is ``None``.

    """
    decorator = _AutoEqDecorator(fields=fields)

    if class_ is not None:
        return decorator(class_)
    return decorator