Repository: ManimCommunity/manim
File: manim/utils/hashing.py (Python)

Code before:

    @classmethod
    def _handle_already_processed(
        cls, obj, default_function: typing.Callable[[Any], Any]
    ):
        if (
            isinstance(
                obj,
                (
                    int,
                    float,
                    str,
                    complex,
                ),
            )
            and obj not in [None, cls.ALREADY_PROCESSED_PLACEHOLDER]
        ):
            # It makes no sense (and it'd slower) to memoize objects of these primitive types.
            # Hence, we simply return the object.
            return obj
        if isinstance(obj, collections.abc.Hashable):
            try:
                return cls._return(obj, hash, default_function)
            except TypeError:
                # In case of an error with the hash (eg an object is marked as hashable but contains a non hashable within it)
                # Fallback to use id instead.
                pass
        return cls._return(obj, id, default_function)

    @classmethod
    def _return(
        cls,
        obj: typing.Any,
        obj_to_membership_sign: typing.Callable[[Any], int],
        default_func,
        memoizing=True,
    ) -> typing.Union[str, Any]:

        obj_membership_sign = obj_to_membership_sign(obj)
        if obj_membership_sign in cls._already_processed:
            return cls.ALREADY_PROCESSED_PLACEHOLDER
        if memoizing:
            cls._already_processed.add(obj_membership_sign)
        return default_func(obj)


class _CustomEncoder(json.JSONEncoder):
    def default(self, obj):
        """
        This method is used to serialize objects to JSON format.


Review comment (suggestion):
```suggestion
                # Fallback to use the built-in function id instead.
```

Code after:

    @classmethod
    def _handle_already_processed(
        cls, obj, default_function: typing.Callable[[Any], Any]
    ):
        if (
            isinstance(
                obj,
                (
                    int,
                    float,
                    str,
                    complex,
                ),
            )
            and obj not in [None, cls.ALREADY_PROCESSED_PLACEHOLDER]
        ):
            # It makes no sense (and it'd slower) to memoize objects of these primitive types.
            # Hence, we simply return the object.
            return obj
        if isinstance(obj, collections.abc.Hashable):
            try:
                return cls._return(obj, hash, default_function)
            except TypeError:
                # In case of an error with the hash (eg an object is marked as hashable but contains a non hashable within it)
                # Fallback to use the built-in function id instead.
                pass
        return cls._return(obj, id, default_function)

    @classmethod
    def _return(
        cls,
        obj: typing.Any,
        obj_to_membership_sign: typing.Callable[[Any], int],
        default_func,
        memoizing=True,
    ) -> typing.Union[str, Any]:

        obj_membership_sign = obj_to_membership_sign(obj)
        if obj_membership_sign in cls._already_processed:
            return cls.ALREADY_PROCESSED_PLACEHOLDER
        if memoizing:
            cls._already_processed.add(obj_membership_sign)
        return default_func(obj)


class _CustomEncoder(json.JSONEncoder):
    def default(self, obj):
        """
        This method is used to serialize objects to JSON format.