Repository: kedro-org/kedro
File: kedro/io/core.py (Python)

Code before:

        Decorates the `load` and `save` methods provided by the class.
        If `_load` or `_save` are defined, alias them as a prerequisite.

        """

        # Save the original __init__ method of the subclass
        init_func: Callable = cls.__init__

        def init_decorator(previous_init: Callable) -> Callable:
            """A decorator that wraps the original __init__ of the subclass.

            It ensures that after the original __init__ executes, the `__post_init__`
            method of the instance is called with the arguments used to initialize
            the object.
            """

            def new_init(self, *args, **kwargs) -> None:  # type: ignore[no-untyped-def]
                """The decorated __init__ method.

                Executes the original __init__, then calls __post_init__ with the arguments
                used to initialize the instance.
                """

                # Call the original __init__ method
                previous_init(self, *args, **kwargs)
                if type(self) is cls:
                    # Capture and process the arguments passed to the original __init__
                    call_args = getcallargs(init_func, self, *args, **kwargs)
                    # Call the custom post-initialization method to save captured arguments
                    self.__post_init__(call_args)

            return new_init

        # Replace the subclass's __init__ with the decorated version
        # A hook for subclasses to capture initialization arguments and save them
        # in the AbstractDataset._init_args field
        cls.__init__ = init_decorator(cls.__init__)  # type: ignore[method-assign]

        super().__init_subclass__(**kwargs)

        if hasattr(cls, "_load") and not cls._load.__qualname__.startswith("Abstract"):
            cls.load = cls._load  # type: ignore[method-assign]

        if hasattr(cls, "_save") and not cls._save.__qualname__.startswith("Abstract"):
            cls.save = cls._save  # type: ignore[method-assign]

        if hasattr(cls, "load") and not cls.load.__qualname__.startswith("Abstract"):
            cls.load = cls._load_wrapper(  # type: ignore[assignment]
                cls.load
                if not getattr(cls.load, "__loadwrapped__", False)

Review comment (suggestion):
```suggestion
                init_func(self, *args, **kwargs)
```

Code after:

        # Replace the subclass's __init__ with the new_init
        # A hook for subclasses to capture initialization arguments and save them
        # in the AbstractDataset._init_args field
        cls.__init__ = new_init  # type: ignore[method-assign]

        super().__init_subclass__(**kwargs)

        if hasattr(cls, "_load") and not cls._load.__qualname__.startswith("Abstract"):
            cls.load = cls._load  # type: ignore[method-assign]

        if hasattr(cls, "_save") and not cls._save.__qualname__.startswith("Abstract"):
            cls.save = cls._save  # type: ignore[method-assign]

        if hasattr(cls, "load") and not cls.load.__qualname__.startswith("Abstract"):
            cls.load = cls._load_wrapper(  # type: ignore[assignment]
                cls.load
                if not getattr(cls.load, "__loadwrapped__", False)
                else cls.load.__wrapped__  # type: ignore[attr-defined]
            )

        if hasattr(cls, "save") and not cls.save.__qualname__.startswith("Abstract"):
            cls.save = cls._save_wrapper(  # type: ignore[assignment]
                cls.save
                if not getattr(cls.save, "__savewrapped__", False)
                else cls.save.__wrapped__  # type: ignore[attr-defined]
            )

    def _pretty_repr(self, object_description: dict[str, Any]) -> str:
        str_keys = []
        for arg_name, arg_descr in object_description.items():
            if arg_descr is not None:
                descr = pprint.pformat(
                    arg_descr,
                    sort_dicts=False,
                    compact=True,
                    depth=2,
                    width=sys.maxsize,
                )
                str_keys.append(f"{arg_name}={descr}")

        return f"{type(self).__module__}.{type(self).__name__}({', '.join(str_keys)})"

    def __repr__(self) -> str:
        object_description = self._describe()
        if isinstance(object_description, dict) and all(
            isinstance(key, str) for key in object_description
        ):
            return self._pretty_repr(object_description)

        self._logger.warning(