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

Code before:
        """
        try:
            class_obj, config = parse_dataset_definition(
                config, load_version, save_version
            )
        except Exception as exc:
            raise DatasetError(
                f"An exception occurred when parsing config "
                f"for dataset '{name}':\n{exc!s}"
            ) from exc

        try:
            dataset = class_obj(**config)
        except TypeError as err:
            raise DatasetError(
                f"\n{err}.\nDataset '{name}' must only contain arguments valid for the "
                f"constructor of '{class_obj.__module__}.{class_obj.__qualname__}'."
            ) from err
        except Exception as err:
            raise DatasetError(
                f"\n{err}.\nFailed to instantiate dataset '{name}' "
                f"of type '{class_obj.__module__}.{class_obj.__qualname__}'."
            ) from err
        return dataset

    def to_config(self) -> tuple[dict[str, Any], dict[str, str] | None, str | None]:
        return_config: dict[str, Any] = {
            f"{TYPE_KEY}": f"{type(self).__module__}.{type(self).__name__}"
        }
        load_versions: dict[str, str] | None = None
        save_version: str | None = None

        if self._init_args:
            return_config.update(self._init_args)

        if type(self).__name__ == "CachedDataset":
            cached_ds = return_config.pop("dataset")
            cached_ds_return_config: dict[str, Any] = {}
            if isinstance(cached_ds, dict):
                cached_ds_return_config = cached_ds
            elif isinstance(cached_ds, AbstractDataset):
                cached_ds_return_config, load_versions, save_version = (
                    cached_ds.to_config()
                )
            if VERSIONED_FLAG_KEY in cached_ds_return_config:
                return_config[VERSIONED_FLAG_KEY] = cached_ds_return_config.pop(
                    VERSIONED_FLAG_KEY
                )
            return_config["dataset"] = cached_ds_return_config

        version = return_config.pop(VERSION_KEY, None)

Review comment (refactor):
Why isn't this a classmethod like `from_config`? 

Does it have to do with:

> Use AbstractDataset.__init_subclass__ which allows to change the behavior of subclasses from inside the AbstractDataset

If so, could you explain this some more, because I don't quite understand it. 

Code after:
        Raises:
            DatasetError: When the function fails to create the dataset
                from its config.

        """
        try:
            class_obj, config = parse_dataset_definition(
                config, load_version, save_version
            )
        except Exception as exc:
            raise DatasetError(
                f"An exception occurred when parsing config "
                f"for dataset '{name}':\n{exc!s}"
            ) from exc

        try:
            dataset = class_obj(**config)
        except TypeError as err:
            raise DatasetError(
                f"\n{err}.\nDataset '{name}' must only contain arguments valid for the "
                f"constructor of '{class_obj.__module__}.{class_obj.__qualname__}'."
            ) from err
        except Exception as err:
            raise DatasetError(
                f"\n{err}.\nFailed to instantiate dataset '{name}' "
                f"of type '{class_obj.__module__}.{class_obj.__qualname__}'."
            ) from err
        return dataset

    def to_config(self) -> dict[str, Any]:
        """Converts the dataset instance into a dictionary-based configuration for
        serialization. Ensures that any subclass-specific details are handled, with
        additional logic for versioning and caching implemented for `CachedDataset`.

        Adds a key for the dataset's type using its module and class name and
        includes the initialization arguments.

        For `CachedDataset` it extracts the underlying dataset's configuration,
        handles the `versioned` flag and removes unnecessary metadata. It also
        ensures the embedded dataset's configuration is appropriately flattened
        or transformed.

        If the dataset has a version key, it sets the `versioned` flag in the
        configuration.

        Removes the `metadata` key from the configuration if present.

        Returns:
            A dictionary containing the dataset's type and initialization arguments.
        """
        return_config: dict[str, Any] = {