Skip to content

0.2 to 0.3

This page explains how to migrate from coola 0.2 to 0.3 because coola 0.3 introduces several non-backward compatible changes due to the redesign of the equality mechanism.

objects_are_equal/allclose

The signature of the objects_are_equal and objects_are_allclose function were updated and only the first two arguments can be provided as positional arguments. All the other arguments had to be provided as keyword arguments. Both functions take a BaseEqualityTester as tester argument.

objects_are_equal

coola 0.3 also introduces a new parameter equal_nan to objects_are_equal to indicate whether to compare NaN’s as equal. To keep the behavior similar as coola 0.2, the default value of equal_nan is False.

coola 0.2 (old)
>>> from coola import objects_are_equal
>>> objects_are_equal(float("nan"), float("nan"))
False
coola 0.3 (new)
>>> from coola import objects_are_equal
>>> objects_are_equal(float("nan"), float("nan"))
False
>>> objects_are_equal(float("nan"), float("nan"), equal_nan=True)
True

Equality mechanism

The equality mechanism was fully redesigned in coola 0.3 to merge the two existing equality mechanisms. In coola 0.2, there were two equality mechanisms:

  • a mechanism to check if two objects are equal (mechanism behind objects_are_equal)
  • a mechanism to check if two objects are equal within tolerance (mechanism behind objects_are_allclose)

This approach was not scalable because there were a lot of overlap and duplicate code between the two mechanisms. For each new type to support, it was necessary to implement two comparators: one inheriting from BaseEqualityOperator and another one inheriting from BaseAllCloseOperator. In the long term, fusing the two mechanisms will make the code easier to maintain and extend. The new equality mechanism combines two previous equality mechanisms in a single equality mechanism so it is necessary to implement only a single comparator for each type.

BaseEqualityOperator has a new interface which is similar but not directly compatible with the old interface. The new interface introduces a new data structure EqualityConfig to keep the interface simpler and to make the fusion easier. EqualityConfig stores all the parameters that controls the equality mechanism, like the absolute or relative tolerance thresholds. Below is a simplified version of the interface. Please check the code to see all the details.

coola 0.3 (new interface)
from abc import ABC, abstractmethod
from typing import Any, Generic, TypeVar

from coola.equality.config import EqualityConfig

T = TypeVar("T")


class BaseEqualityComparator(ABC, Generic[T]):
    @abstractmethod
    def equal(self, object1: T, object2: Any, config: EqualityConfig) -> bool:
        pass

Note that in most of the cases, it will not be necessary to change the overall logic inside the equal method.

The redesign of the equality mechanism introduces the following main changes:

  • The class BaseAllCloseOperator has been removed as well as all its child classes.
  • coola.comparators has been removed and an equivalent package has been added coola.equality.comparators. Please note that coola.equality.comparators is not a direct replacement of coola.comparators because BaseEqualityOperator has new interface.
  • coola.testers has been removed and an equivalent package has been added coola.equality.testers. Please note that coola.equality.testers is not a direct replacement of coola.testers because BaseEqualityOperator has new interface.