We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
pickle.PickleDataSet docstring examples are incorrect
## Description
Kind of a small issue but the "advanced" example in the [pickle.PickleDataSet API docs](https://kedro.readthedocs.io/en/stable/kedro.extras.datasets.pickle.PickleDataSet.html) is wrong.
`compression` is not a valid [`joblib.dump`](https://joblib.readthedocs.io/en/latest/generated/joblib.dump.html) parameter (it should simply be `compress`) and [`joblib.load`](https://joblib.readthedocs.io/en/latest/generated/joblib.load.html) does not require a `compression` kwarg at all since it can automagically discover the correct compression algorithm used.


## Context
Even if it's a trivial issue I stumbled upon it and I hope to fix it so that future users will not have to go the joblib docs to find the problem.


## Possible Alternatives
I'a m working on a trivial fix, I'm going to open a PR as soon as possible.


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `kedro/extras/datasets/pickle/pickle_dataset.py`
Content:
```
1 """``PickleDataSet`` loads/saves data from/to a Pickle file using an underlying
2 filesystem (e.g.: local, S3, GCS). The underlying functionality is supported by
3 the specified backend library passed in (defaults to the ``pickle`` library), so it
4 supports all allowed options for loading and saving pickle files.
5 """
6 import importlib
7 from copy import deepcopy
8 from pathlib import PurePosixPath
9 from typing import Any, Dict
10 
11 import fsspec
12 
13 from kedro.io.core import (
14     AbstractVersionedDataSet,
15     DataSetError,
16     Version,
17     get_filepath_str,
18     get_protocol_and_path,
19 )
20 
21 
22 class PickleDataSet(AbstractVersionedDataSet[Any, Any]):
23     """``PickleDataSet`` loads/saves data from/to a Pickle file using an underlying
24     filesystem (e.g.: local, S3, GCS). The underlying functionality is supported by
25     the specified backend library passed in (defaults to the ``pickle`` library), so it
26     supports all allowed options for loading and saving pickle files.
27 
28     Example adding a catalog entry with
29     `YAML API <https://kedro.readthedocs.io/en/stable/data/\
30         data_catalog.html#use-the-data-catalog-with-the-yaml-api>`_:
31 
32     .. code-block:: yaml
33 
34         >>> test_model: # simple example without compression
35         >>>   type: pickle.PickleDataSet
36         >>>   filepath: data/07_model_output/test_model.pkl
37         >>>   backend: pickle
38         >>>
39         >>> final_model: # example with load and save args
40         >>>   type: pickle.PickleDataSet
41         >>>   filepath: s3://your_bucket/final_model.pkl.lz4
42         >>>   backend: joblib
43         >>>   credentials: s3_credentials
44         >>>   save_args:
45         >>>     compression: lz4
46         >>>   load_args:
47         >>>     compression: lz4
48 
49     Example using Python API:
50     ::
51 
52         >>> from kedro.extras.datasets.pickle import PickleDataSet
53         >>> import pandas as pd
54         >>>
55         >>> data = pd.DataFrame({'col1': [1, 2], 'col2': [4, 5],
56         >>>                      'col3': [5, 6]})
57         >>>
58         >>> # data_set = PickleDataSet(filepath="gcs://bucket/test.pkl")
59         >>> data_set = PickleDataSet(filepath="test.pkl", backend="pickle")
60         >>> data_set.save(data)
61         >>> reloaded = data_set.load()
62         >>> assert data.equals(reloaded)
63         >>>
64         >>> # Add "compress_pickle[lz4]" to requirements.txt
65         >>> data_set = PickleDataSet(filepath="test.pickle.lz4",
66         >>>                          backend="compress_pickle",
67         >>>                          load_args={"compression":"lz4"},
68         >>>                          save_args={"compression":"lz4"})
69         >>> data_set.save(data)
70         >>> reloaded = data_set.load()
71         >>> assert data.equals(reloaded)
72     """
73 
74     DEFAULT_LOAD_ARGS = {}  # type: Dict[str, Any]
75     DEFAULT_SAVE_ARGS = {}  # type: Dict[str, Any]
76 
77     # pylint: disable=too-many-arguments,too-many-locals
78     def __init__(
79         self,
80         filepath: str,
81         backend: str = "pickle",
82         load_args: Dict[str, Any] = None,
83         save_args: Dict[str, Any] = None,
84         version: Version = None,
85         credentials: Dict[str, Any] = None,
86         fs_args: Dict[str, Any] = None,
87     ) -> None:
88         """Creates a new instance of ``PickleDataSet`` pointing to a concrete Pickle
89         file on a specific filesystem. ``PickleDataSet`` supports custom backends to
90         serialise/deserialise objects.
91 
92         Example backends that are compatible (non-exhaustive):
93             * `pickle`
94             * `joblib`
95             * `dill`
96             * `compress_pickle`
97 
98         Example backends that are incompatible:
99             * `torch`
100 
101         Args:
102             filepath: Filepath in POSIX format to a Pickle file prefixed with a protocol like
103                 `s3://`. If prefix is not provided, `file` protocol (local filesystem) will be used.
104                 The prefix should be any protocol supported by ``fsspec``.
105                 Note: `http(s)` doesn't support versioning.
106             backend: Backend to use, must be an import path to a module which satisfies the
107                 ``pickle`` interface. That is, contains a `load` and `dump` function.
108                 Defaults to 'pickle'.
109             load_args: Pickle options for loading pickle files.
110                 You can pass in arguments that the backend load function specified accepts, e.g:
111                 pickle.load: https://docs.python.org/3/library/pickle.html#pickle.load
112                 joblib.load: https://joblib.readthedocs.io/en/latest/generated/joblib.load.html
113                 dill.load: https://dill.readthedocs.io/en/latest/dill.html#dill._dill.load
114                 compress_pickle.load:
115                 https://lucianopaz.github.io/compress_pickle/html/api/compress_pickle.html#compress_pickle.compress_pickle.load
116                 All defaults are preserved.
117             save_args: Pickle options for saving pickle files.
118                 You can pass in arguments that the backend dump function specified accepts, e.g:
119                 pickle.dump: https://docs.python.org/3/library/pickle.html#pickle.dump
120                 joblib.dump: https://joblib.readthedocs.io/en/latest/generated/joblib.dump.html
121                 dill.dump: https://dill.readthedocs.io/en/latest/dill.html#dill._dill.dump
122                 compress_pickle.dump:
123                 https://lucianopaz.github.io/compress_pickle/html/api/compress_pickle.html#compress_pickle.compress_pickle.dump
124                 All defaults are preserved.
125             version: If specified, should be an instance of
126                 ``kedro.io.core.Version``. If its ``load`` attribute is
127                 None, the latest version will be loaded. If its ``save``
128                 attribute is None, save version will be autogenerated.
129             credentials: Credentials required to get access to the underlying filesystem.
130                 E.g. for ``GCSFileSystem`` it should look like `{"token": None}`.
131             fs_args: Extra arguments to pass into underlying filesystem class constructor
132                 (e.g. `{"project": "my-project"}` for ``GCSFileSystem``), as well as
133                 to pass to the filesystem's `open` method through nested keys
134                 `open_args_load` and `open_args_save`.
135                 Here you can find all available arguments for `open`:
136                 https://filesystem-spec.readthedocs.io/en/latest/api.html#fsspec.spec.AbstractFileSystem.open
137                 All defaults are preserved, except `mode`, which is set to `wb` when saving.
138 
139         Raises:
140             ValueError: If ``backend`` does not satisfy the `pickle` interface.
141             ImportError: If the ``backend`` module could not be imported.
142         """
143         # We do not store `imported_backend` as an attribute to be used in `load`/`save`
144         # as this would mean the dataset cannot be deepcopied (module objects cannot be
145         # pickled). The import here is purely to raise any errors as early as possible.
146         # Repeated imports in the `load` and `save` methods should not be a significant
147         # performance hit as Python caches imports.
148         try:
149             imported_backend = importlib.import_module(backend)
150         except ImportError as exc:
151             raise ImportError(
152                 f"Selected backend '{backend}' could not be imported. "
153                 "Make sure it is installed and importable."
154             ) from exc
155 
156         if not (
157             hasattr(imported_backend, "load") and hasattr(imported_backend, "dump")
158         ):
159             raise ValueError(
160                 f"Selected backend '{backend}' should satisfy the pickle interface. "
161                 "Missing one of 'load' and 'dump' on the backend."
162             )
163 
164         _fs_args = deepcopy(fs_args) or {}
165         _fs_open_args_load = _fs_args.pop("open_args_load", {})
166         _fs_open_args_save = _fs_args.pop("open_args_save", {})
167         _credentials = deepcopy(credentials) or {}
168 
169         protocol, path = get_protocol_and_path(filepath, version)
170         if protocol == "file":
171             _fs_args.setdefault("auto_mkdir", True)
172 
173         self._protocol = protocol
174         self._fs = fsspec.filesystem(self._protocol, **_credentials, **_fs_args)
175 
176         super().__init__(
177             filepath=PurePosixPath(path),
178             version=version,
179             exists_function=self._fs.exists,
180             glob_function=self._fs.glob,
181         )
182 
183         self._backend = backend
184 
185         # Handle default load and save arguments
186         self._load_args = deepcopy(self.DEFAULT_LOAD_ARGS)
187         if load_args is not None:
188             self._load_args.update(load_args)
189         self._save_args = deepcopy(self.DEFAULT_SAVE_ARGS)
190         if save_args is not None:
191             self._save_args.update(save_args)
192 
193         _fs_open_args_save.setdefault("mode", "wb")
194         self._fs_open_args_load = _fs_open_args_load
195         self._fs_open_args_save = _fs_open_args_save
196 
197     def _describe(self) -> Dict[str, Any]:
198         return dict(
199             filepath=self._filepath,
200             backend=self._backend,
201             protocol=self._protocol,
202             load_args=self._load_args,
203             save_args=self._save_args,
204             version=self._version,
205         )
206 
207     def _load(self) -> Any:
208         load_path = get_filepath_str(self._get_load_path(), self._protocol)
209 
210         with self._fs.open(load_path, **self._fs_open_args_load) as fs_file:
211             imported_backend = importlib.import_module(self._backend)
212             return imported_backend.load(fs_file, **self._load_args)  # type: ignore
213 
214     def _save(self, data: Any) -> None:
215         save_path = get_filepath_str(self._get_save_path(), self._protocol)
216 
217         with self._fs.open(save_path, **self._fs_open_args_save) as fs_file:
218             try:
219                 imported_backend = importlib.import_module(self._backend)
220                 imported_backend.dump(data, fs_file, **self._save_args)  # type: ignore
221             except Exception as exc:
222                 raise DataSetError(
223                     f"{data.__class__} was not serialised due to: {exc}"
224                 ) from exc
225 
226         self._invalidate_cache()
227 
228     def _exists(self) -> bool:
229         try:
230             load_path = get_filepath_str(self._get_load_path(), self._protocol)
231         except DataSetError:
232             return False
233 
234         return self._fs.exists(load_path)
235 
236     def _release(self) -> None:
237         super()._release()
238         self._invalidate_cache()
239 
240     def _invalidate_cache(self) -> None:
241         """Invalidate underlying filesystem caches."""
242         filepath = get_filepath_str(self._filepath, self._protocol)
243         self._fs.invalidate_cache(filepath)
244
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/kedro/extras/datasets/pickle/pickle_dataset.py b/kedro/extras/datasets/pickle/pickle_dataset.py
--- a/kedro/extras/datasets/pickle/pickle_dataset.py
+++ b/kedro/extras/datasets/pickle/pickle_dataset.py
@@ -42,9 +42,7 @@
         >>>   backend: joblib
         >>>   credentials: s3_credentials
         >>>   save_args:
-        >>>     compression: lz4
-        >>>   load_args:
-        >>>     compression: lz4
+        >>>     compress: lz4
 
     Example using Python API:
     ::

{"golden_diff": "diff --git a/kedro/extras/datasets/pickle/pickle_dataset.py b/kedro/extras/datasets/pickle/pickle_dataset.py\n--- a/kedro/extras/datasets/pickle/pickle_dataset.py\n+++ b/kedro/extras/datasets/pickle/pickle_dataset.py\n@@ -42,9 +42,7 @@\n         >>>   backend: joblib\n         >>>   credentials: s3_credentials\n         >>>   save_args:\n-        >>>     compression: lz4\n-        >>>   load_args:\n-        >>>     compression: lz4\n+        >>>     compress: lz4\n \n     Example using Python API:\n     ::\n", "issue": "pickle.PickleDataSet docstring examples are incorrect\n## Description\r\nKind of a small issue but the \"advanced\" example in the [pickle.PickleDataSet API docs](https://kedro.readthedocs.io/en/stable/kedro.extras.datasets.pickle.PickleDataSet.html) is wrong.\r\n`compression` is not a valid [`joblib.dump`](https://joblib.readthedocs.io/en/latest/generated/joblib.dump.html) parameter (it should simply be `compress`) and [`joblib.load`](https://joblib.readthedocs.io/en/latest/generated/joblib.load.html) does not require a `compression` kwarg at all since it can automagically discover the correct compression algorithm used.\r\n\r\n\r\n## Context\r\nEven if it's a trivial issue I stumbled upon it and I hope to fix it so that future users will not have to go the joblib docs to find the problem.\r\n\r\n\r\n## Possible Alternatives\r\nI'a m working on a trivial fix, I'm going to open a PR as soon as possible.\r\n\n", "before_files": [{"content": "\"\"\"``PickleDataSet`` loads/saves data from/to a Pickle file using an underlying\nfilesystem (e.g.: local, S3, GCS). The underlying functionality is supported by\nthe specified backend library passed in (defaults to the ``pickle`` library), so it\nsupports all allowed options for loading and saving pickle files.\n\"\"\"\nimport importlib\nfrom copy import deepcopy\nfrom pathlib import PurePosixPath\nfrom typing import Any, Dict\n\nimport fsspec\n\nfrom kedro.io.core import (\n    AbstractVersionedDataSet,\n    DataSetError,\n    Version,\n    get_filepath_str,\n    get_protocol_and_path,\n)\n\n\nclass PickleDataSet(AbstractVersionedDataSet[Any, Any]):\n    \"\"\"``PickleDataSet`` loads/saves data from/to a Pickle file using an underlying\n    filesystem (e.g.: local, S3, GCS). The underlying functionality is supported by\n    the specified backend library passed in (defaults to the ``pickle`` library), so it\n    supports all allowed options for loading and saving pickle files.\n\n    Example adding a catalog entry with\n    `YAML API <https://kedro.readthedocs.io/en/stable/data/\\\n        data_catalog.html#use-the-data-catalog-with-the-yaml-api>`_:\n\n    .. code-block:: yaml\n\n        >>> test_model: # simple example without compression\n        >>>   type: pickle.PickleDataSet\n        >>>   filepath: data/07_model_output/test_model.pkl\n        >>>   backend: pickle\n        >>>\n        >>> final_model: # example with load and save args\n        >>>   type: pickle.PickleDataSet\n        >>>   filepath: s3://your_bucket/final_model.pkl.lz4\n        >>>   backend: joblib\n        >>>   credentials: s3_credentials\n        >>>   save_args:\n        >>>     compression: lz4\n        >>>   load_args:\n        >>>     compression: lz4\n\n    Example using Python API:\n    ::\n\n        >>> from kedro.extras.datasets.pickle import PickleDataSet\n        >>> import pandas as pd\n        >>>\n        >>> data = pd.DataFrame({'col1': [1, 2], 'col2': [4, 5],\n        >>>                      'col3': [5, 6]})\n        >>>\n        >>> # data_set = PickleDataSet(filepath=\"gcs://bucket/test.pkl\")\n        >>> data_set = PickleDataSet(filepath=\"test.pkl\", backend=\"pickle\")\n        >>> data_set.save(data)\n        >>> reloaded = data_set.load()\n        >>> assert data.equals(reloaded)\n        >>>\n        >>> # Add \"compress_pickle[lz4]\" to requirements.txt\n        >>> data_set = PickleDataSet(filepath=\"test.pickle.lz4\",\n        >>>                          backend=\"compress_pickle\",\n        >>>                          load_args={\"compression\":\"lz4\"},\n        >>>                          save_args={\"compression\":\"lz4\"})\n        >>> data_set.save(data)\n        >>> reloaded = data_set.load()\n        >>> assert data.equals(reloaded)\n    \"\"\"\n\n    DEFAULT_LOAD_ARGS = {}  # type: Dict[str, Any]\n    DEFAULT_SAVE_ARGS = {}  # type: Dict[str, Any]\n\n    # pylint: disable=too-many-arguments,too-many-locals\n    def __init__(\n        self,\n        filepath: str,\n        backend: str = \"pickle\",\n        load_args: Dict[str, Any] = None,\n        save_args: Dict[str, Any] = None,\n        version: Version = None,\n        credentials: Dict[str, Any] = None,\n        fs_args: Dict[str, Any] = None,\n    ) -> None:\n        \"\"\"Creates a new instance of ``PickleDataSet`` pointing to a concrete Pickle\n        file on a specific filesystem. ``PickleDataSet`` supports custom backends to\n        serialise/deserialise objects.\n\n        Example backends that are compatible (non-exhaustive):\n            * `pickle`\n            * `joblib`\n            * `dill`\n            * `compress_pickle`\n\n        Example backends that are incompatible:\n            * `torch`\n\n        Args:\n            filepath: Filepath in POSIX format to a Pickle file prefixed with a protocol like\n                `s3://`. If prefix is not provided, `file` protocol (local filesystem) will be used.\n                The prefix should be any protocol supported by ``fsspec``.\n                Note: `http(s)` doesn't support versioning.\n            backend: Backend to use, must be an import path to a module which satisfies the\n                ``pickle`` interface. That is, contains a `load` and `dump` function.\n                Defaults to 'pickle'.\n            load_args: Pickle options for loading pickle files.\n                You can pass in arguments that the backend load function specified accepts, e.g:\n                pickle.load: https://docs.python.org/3/library/pickle.html#pickle.load\n                joblib.load: https://joblib.readthedocs.io/en/latest/generated/joblib.load.html\n                dill.load: https://dill.readthedocs.io/en/latest/dill.html#dill._dill.load\n                compress_pickle.load:\n                https://lucianopaz.github.io/compress_pickle/html/api/compress_pickle.html#compress_pickle.compress_pickle.load\n                All defaults are preserved.\n            save_args: Pickle options for saving pickle files.\n                You can pass in arguments that the backend dump function specified accepts, e.g:\n                pickle.dump: https://docs.python.org/3/library/pickle.html#pickle.dump\n                joblib.dump: https://joblib.readthedocs.io/en/latest/generated/joblib.dump.html\n                dill.dump: https://dill.readthedocs.io/en/latest/dill.html#dill._dill.dump\n                compress_pickle.dump:\n                https://lucianopaz.github.io/compress_pickle/html/api/compress_pickle.html#compress_pickle.compress_pickle.dump\n                All defaults are preserved.\n            version: If specified, should be an instance of\n                ``kedro.io.core.Version``. If its ``load`` attribute is\n                None, the latest version will be loaded. If its ``save``\n                attribute is None, save version will be autogenerated.\n            credentials: Credentials required to get access to the underlying filesystem.\n                E.g. for ``GCSFileSystem`` it should look like `{\"token\": None}`.\n            fs_args: Extra arguments to pass into underlying filesystem class constructor\n                (e.g. `{\"project\": \"my-project\"}` for ``GCSFileSystem``), as well as\n                to pass to the filesystem's `open` method through nested keys\n                `open_args_load` and `open_args_save`.\n                Here you can find all available arguments for `open`:\n                https://filesystem-spec.readthedocs.io/en/latest/api.html#fsspec.spec.AbstractFileSystem.open\n                All defaults are preserved, except `mode`, which is set to `wb` when saving.\n\n        Raises:\n            ValueError: If ``backend`` does not satisfy the `pickle` interface.\n            ImportError: If the ``backend`` module could not be imported.\n        \"\"\"\n        # We do not store `imported_backend` as an attribute to be used in `load`/`save`\n        # as this would mean the dataset cannot be deepcopied (module objects cannot be\n        # pickled). The import here is purely to raise any errors as early as possible.\n        # Repeated imports in the `load` and `save` methods should not be a significant\n        # performance hit as Python caches imports.\n        try:\n            imported_backend = importlib.import_module(backend)\n        except ImportError as exc:\n            raise ImportError(\n                f\"Selected backend '{backend}' could not be imported. \"\n                \"Make sure it is installed and importable.\"\n            ) from exc\n\n        if not (\n            hasattr(imported_backend, \"load\") and hasattr(imported_backend, \"dump\")\n        ):\n            raise ValueError(\n                f\"Selected backend '{backend}' should satisfy the pickle interface. \"\n                \"Missing one of 'load' and 'dump' on the backend.\"\n            )\n\n        _fs_args = deepcopy(fs_args) or {}\n        _fs_open_args_load = _fs_args.pop(\"open_args_load\", {})\n        _fs_open_args_save = _fs_args.pop(\"open_args_save\", {})\n        _credentials = deepcopy(credentials) or {}\n\n        protocol, path = get_protocol_and_path(filepath, version)\n        if protocol == \"file\":\n            _fs_args.setdefault(\"auto_mkdir\", True)\n\n        self._protocol = protocol\n        self._fs = fsspec.filesystem(self._protocol, **_credentials, **_fs_args)\n\n        super().__init__(\n            filepath=PurePosixPath(path),\n            version=version,\n            exists_function=self._fs.exists,\n            glob_function=self._fs.glob,\n        )\n\n        self._backend = backend\n\n        # Handle default load and save arguments\n        self._load_args = deepcopy(self.DEFAULT_LOAD_ARGS)\n        if load_args is not None:\n            self._load_args.update(load_args)\n        self._save_args = deepcopy(self.DEFAULT_SAVE_ARGS)\n        if save_args is not None:\n            self._save_args.update(save_args)\n\n        _fs_open_args_save.setdefault(\"mode\", \"wb\")\n        self._fs_open_args_load = _fs_open_args_load\n        self._fs_open_args_save = _fs_open_args_save\n\n    def _describe(self) -> Dict[str, Any]:\n        return dict(\n            filepath=self._filepath,\n            backend=self._backend,\n            protocol=self._protocol,\n            load_args=self._load_args,\n            save_args=self._save_args,\n            version=self._version,\n        )\n\n    def _load(self) -> Any:\n        load_path = get_filepath_str(self._get_load_path(), self._protocol)\n\n        with self._fs.open(load_path, **self._fs_open_args_load) as fs_file:\n            imported_backend = importlib.import_module(self._backend)\n            return imported_backend.load(fs_file, **self._load_args)  # type: ignore\n\n    def _save(self, data: Any) -> None:\n        save_path = get_filepath_str(self._get_save_path(), self._protocol)\n\n        with self._fs.open(save_path, **self._fs_open_args_save) as fs_file:\n            try:\n                imported_backend = importlib.import_module(self._backend)\n                imported_backend.dump(data, fs_file, **self._save_args)  # type: ignore\n            except Exception as exc:\n                raise DataSetError(\n                    f\"{data.__class__} was not serialised due to: {exc}\"\n                ) from exc\n\n        self._invalidate_cache()\n\n    def _exists(self) -> bool:\n        try:\n            load_path = get_filepath_str(self._get_load_path(), self._protocol)\n        except DataSetError:\n            return False\n\n        return self._fs.exists(load_path)\n\n    def _release(self) -> None:\n        super()._release()\n        self._invalidate_cache()\n\n    def _invalidate_cache(self) -> None:\n        \"\"\"Invalidate underlying filesystem caches.\"\"\"\n        filepath = get_filepath_str(self._filepath, self._protocol)\n        self._fs.invalidate_cache(filepath)\n", "path": "kedro/extras/datasets/pickle/pickle_dataset.py"}], "after_files": [{"content": "\"\"\"``PickleDataSet`` loads/saves data from/to a Pickle file using an underlying\nfilesystem (e.g.: local, S3, GCS). The underlying functionality is supported by\nthe specified backend library passed in (defaults to the ``pickle`` library), so it\nsupports all allowed options for loading and saving pickle files.\n\"\"\"\nimport importlib\nfrom copy import deepcopy\nfrom pathlib import PurePosixPath\nfrom typing import Any, Dict\n\nimport fsspec\n\nfrom kedro.io.core import (\n    AbstractVersionedDataSet,\n    DataSetError,\n    Version,\n    get_filepath_str,\n    get_protocol_and_path,\n)\n\n\nclass PickleDataSet(AbstractVersionedDataSet[Any, Any]):\n    \"\"\"``PickleDataSet`` loads/saves data from/to a Pickle file using an underlying\n    filesystem (e.g.: local, S3, GCS). The underlying functionality is supported by\n    the specified backend library passed in (defaults to the ``pickle`` library), so it\n    supports all allowed options for loading and saving pickle files.\n\n    Example adding a catalog entry with\n    `YAML API <https://kedro.readthedocs.io/en/stable/data/\\\n        data_catalog.html#use-the-data-catalog-with-the-yaml-api>`_:\n\n    .. code-block:: yaml\n\n        >>> test_model: # simple example without compression\n        >>>   type: pickle.PickleDataSet\n        >>>   filepath: data/07_model_output/test_model.pkl\n        >>>   backend: pickle\n        >>>\n        >>> final_model: # example with load and save args\n        >>>   type: pickle.PickleDataSet\n        >>>   filepath: s3://your_bucket/final_model.pkl.lz4\n        >>>   backend: joblib\n        >>>   credentials: s3_credentials\n        >>>   save_args:\n        >>>     compress: lz4\n\n    Example using Python API:\n    ::\n\n        >>> from kedro.extras.datasets.pickle import PickleDataSet\n        >>> import pandas as pd\n        >>>\n        >>> data = pd.DataFrame({'col1': [1, 2], 'col2': [4, 5],\n        >>>                      'col3': [5, 6]})\n        >>>\n        >>> # data_set = PickleDataSet(filepath=\"gcs://bucket/test.pkl\")\n        >>> data_set = PickleDataSet(filepath=\"test.pkl\", backend=\"pickle\")\n        >>> data_set.save(data)\n        >>> reloaded = data_set.load()\n        >>> assert data.equals(reloaded)\n        >>>\n        >>> # Add \"compress_pickle[lz4]\" to requirements.txt\n        >>> data_set = PickleDataSet(filepath=\"test.pickle.lz4\",\n        >>>                          backend=\"compress_pickle\",\n        >>>                          load_args={\"compression\":\"lz4\"},\n        >>>                          save_args={\"compression\":\"lz4\"})\n        >>> data_set.save(data)\n        >>> reloaded = data_set.load()\n        >>> assert data.equals(reloaded)\n    \"\"\"\n\n    DEFAULT_LOAD_ARGS = {}  # type: Dict[str, Any]\n    DEFAULT_SAVE_ARGS = {}  # type: Dict[str, Any]\n\n    # pylint: disable=too-many-arguments,too-many-locals\n    def __init__(\n        self,\n        filepath: str,\n        backend: str = \"pickle\",\n        load_args: Dict[str, Any] = None,\n        save_args: Dict[str, Any] = None,\n        version: Version = None,\n        credentials: Dict[str, Any] = None,\n        fs_args: Dict[str, Any] = None,\n    ) -> None:\n        \"\"\"Creates a new instance of ``PickleDataSet`` pointing to a concrete Pickle\n        file on a specific filesystem. ``PickleDataSet`` supports custom backends to\n        serialise/deserialise objects.\n\n        Example backends that are compatible (non-exhaustive):\n            * `pickle`\n            * `joblib`\n            * `dill`\n            * `compress_pickle`\n\n        Example backends that are incompatible:\n            * `torch`\n\n        Args:\n            filepath: Filepath in POSIX format to a Pickle file prefixed with a protocol like\n                `s3://`. If prefix is not provided, `file` protocol (local filesystem) will be used.\n                The prefix should be any protocol supported by ``fsspec``.\n                Note: `http(s)` doesn't support versioning.\n            backend: Backend to use, must be an import path to a module which satisfies the\n                ``pickle`` interface. That is, contains a `load` and `dump` function.\n                Defaults to 'pickle'.\n            load_args: Pickle options for loading pickle files.\n                You can pass in arguments that the backend load function specified accepts, e.g:\n                pickle.load: https://docs.python.org/3/library/pickle.html#pickle.load\n                joblib.load: https://joblib.readthedocs.io/en/latest/generated/joblib.load.html\n                dill.load: https://dill.readthedocs.io/en/latest/dill.html#dill._dill.load\n                compress_pickle.load:\n                https://lucianopaz.github.io/compress_pickle/html/api/compress_pickle.html#compress_pickle.compress_pickle.load\n                All defaults are preserved.\n            save_args: Pickle options for saving pickle files.\n                You can pass in arguments that the backend dump function specified accepts, e.g:\n                pickle.dump: https://docs.python.org/3/library/pickle.html#pickle.dump\n                joblib.dump: https://joblib.readthedocs.io/en/latest/generated/joblib.dump.html\n                dill.dump: https://dill.readthedocs.io/en/latest/dill.html#dill._dill.dump\n                compress_pickle.dump:\n                https://lucianopaz.github.io/compress_pickle/html/api/compress_pickle.html#compress_pickle.compress_pickle.dump\n                All defaults are preserved.\n            version: If specified, should be an instance of\n                ``kedro.io.core.Version``. If its ``load`` attribute is\n                None, the latest version will be loaded. If its ``save``\n                attribute is None, save version will be autogenerated.\n            credentials: Credentials required to get access to the underlying filesystem.\n                E.g. for ``GCSFileSystem`` it should look like `{\"token\": None}`.\n            fs_args: Extra arguments to pass into underlying filesystem class constructor\n                (e.g. `{\"project\": \"my-project\"}` for ``GCSFileSystem``), as well as\n                to pass to the filesystem's `open` method through nested keys\n                `open_args_load` and `open_args_save`.\n                Here you can find all available arguments for `open`:\n                https://filesystem-spec.readthedocs.io/en/latest/api.html#fsspec.spec.AbstractFileSystem.open\n                All defaults are preserved, except `mode`, which is set to `wb` when saving.\n\n        Raises:\n            ValueError: If ``backend`` does not satisfy the `pickle` interface.\n            ImportError: If the ``backend`` module could not be imported.\n        \"\"\"\n        # We do not store `imported_backend` as an attribute to be used in `load`/`save`\n        # as this would mean the dataset cannot be deepcopied (module objects cannot be\n        # pickled). The import here is purely to raise any errors as early as possible.\n        # Repeated imports in the `load` and `save` methods should not be a significant\n        # performance hit as Python caches imports.\n        try:\n            imported_backend = importlib.import_module(backend)\n        except ImportError as exc:\n            raise ImportError(\n                f\"Selected backend '{backend}' could not be imported. \"\n                \"Make sure it is installed and importable.\"\n            ) from exc\n\n        if not (\n            hasattr(imported_backend, \"load\") and hasattr(imported_backend, \"dump\")\n        ):\n            raise ValueError(\n                f\"Selected backend '{backend}' should satisfy the pickle interface. \"\n                \"Missing one of 'load' and 'dump' on the backend.\"\n            )\n\n        _fs_args = deepcopy(fs_args) or {}\n        _fs_open_args_load = _fs_args.pop(\"open_args_load\", {})\n        _fs_open_args_save = _fs_args.pop(\"open_args_save\", {})\n        _credentials = deepcopy(credentials) or {}\n\n        protocol, path = get_protocol_and_path(filepath, version)\n        if protocol == \"file\":\n            _fs_args.setdefault(\"auto_mkdir\", True)\n\n        self._protocol = protocol\n        self._fs = fsspec.filesystem(self._protocol, **_credentials, **_fs_args)\n\n        super().__init__(\n            filepath=PurePosixPath(path),\n            version=version,\n            exists_function=self._fs.exists,\n            glob_function=self._fs.glob,\n        )\n\n        self._backend = backend\n\n        # Handle default load and save arguments\n        self._load_args = deepcopy(self.DEFAULT_LOAD_ARGS)\n        if load_args is not None:\n            self._load_args.update(load_args)\n        self._save_args = deepcopy(self.DEFAULT_SAVE_ARGS)\n        if save_args is not None:\n            self._save_args.update(save_args)\n\n        _fs_open_args_save.setdefault(\"mode\", \"wb\")\n        self._fs_open_args_load = _fs_open_args_load\n        self._fs_open_args_save = _fs_open_args_save\n\n    def _describe(self) -> Dict[str, Any]:\n        return dict(\n            filepath=self._filepath,\n            backend=self._backend,\n            protocol=self._protocol,\n            load_args=self._load_args,\n            save_args=self._save_args,\n            version=self._version,\n        )\n\n    def _load(self) -> Any:\n        load_path = get_filepath_str(self._get_load_path(), self._protocol)\n\n        with self._fs.open(load_path, **self._fs_open_args_load) as fs_file:\n            imported_backend = importlib.import_module(self._backend)\n            return imported_backend.load(fs_file, **self._load_args)  # type: ignore\n\n    def _save(self, data: Any) -> None:\n        save_path = get_filepath_str(self._get_save_path(), self._protocol)\n\n        with self._fs.open(save_path, **self._fs_open_args_save) as fs_file:\n            try:\n                imported_backend = importlib.import_module(self._backend)\n                imported_backend.dump(data, fs_file, **self._save_args)  # type: ignore\n            except Exception as exc:\n                raise DataSetError(\n                    f\"{data.__class__} was not serialised due to: {exc}\"\n                ) from exc\n\n        self._invalidate_cache()\n\n    def _exists(self) -> bool:\n        try:\n            load_path = get_filepath_str(self._get_load_path(), self._protocol)\n        except DataSetError:\n            return False\n\n        return self._fs.exists(load_path)\n\n    def _release(self) -> None:\n        super()._release()\n        self._invalidate_cache()\n\n    def _invalidate_cache(self) -> None:\n        \"\"\"Invalidate underlying filesystem caches.\"\"\"\n        filepath = get_filepath_str(self._filepath, self._protocol)\n        self._fs.invalidate_cache(filepath)\n", "path": "kedro/extras/datasets/pickle/pickle_dataset.py"}]}