We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
ModuleNotFoundError: No module named 'botocore' when using OpenFile
Need to rewrite this so that this dependency is imported only when the S3 store is being used.
Thereby making it optional like s3fs.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `modin/core/io/file_dispatcher.py`
Content:
```
1 # Licensed to Modin Development Team under one or more contributor license agreements.
2 # See the NOTICE file distributed with this work for additional information regarding
3 # copyright ownership.  The Modin Development Team licenses this file to you under the
4 # Apache License, Version 2.0 (the "License"); you may not use this file except in
5 # compliance with the License.  You may obtain a copy of the License at
6 #
7 #     http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software distributed under
10 # the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
11 # ANY KIND, either express or implied. See the License for the specific language
12 # governing permissions and limitations under the License.
13 
14 """
15 Module houses `FileDispatcher` class.
16 
17 `FileDispatcher` can be used as abstract base class for dispatchers of specific file formats or
18 for direct files processing.
19 """
20 
21 import fsspec
22 import os
23 import re
24 from modin.config import Backend
25 import numpy as np
26 
27 S3_ADDRESS_REGEX = re.compile("[sS]3://(.*?)/(.*)")
28 NOT_IMPLEMENTED_MESSAGE = "Implement in children classes!"
29 
30 
31 class OpenFile:
32     """
33     OpenFile is a context manager for an input file.
34 
35     OpenFile uses fsspec to open files on __enter__. On __exit__, it closes the
36     fsspec file. This class exists to encapsulate the special behavior in
37     __enter__ around anon=False and anon=True for s3 buckets.
38 
39     Parameters
40     ----------
41     file_path : str
42         String that represents the path to the file (paths to S3 buckets
43         are also acceptable).
44     mode : str, default: "rb"
45         String, which defines which mode file should be open.
46     compression : str, default: "infer"
47         File compression name.
48 
49     Attributes
50     ----------
51     file_path : str
52         String that represents the path to the file
53     mode : str
54         String that defines which mode the file should be opened in.
55     compression : str
56         File compression name.
57     file : fsspec.core.OpenFile
58         The opened file.
59     """
60 
61     def __init__(self, file_path, mode="rb", compression="infer"):
62         self.file_path = file_path
63         self.mode = mode
64         self.compression = compression
65 
66     def __enter__(self):
67         """
68         Open the file with fsspec and return the opened file.
69 
70         Returns
71         -------
72         fsspec.core.OpenFile
73             The opened file.
74         """
75         from botocore.exceptions import NoCredentialsError
76 
77         try:
78             self.file = fsspec.open(
79                 self.file_path, self.mode, self.compression, anon=False
80             )
81             return self.file.open()
82         except NoCredentialsError:
83             self.file = fsspec.open(
84                 self.file_path, self.mode, self.compression, anon=True
85             )
86             return self.file.open()
87 
88     def __exit__(self, *args):
89         """
90         Close the file.
91 
92         Parameters
93         ----------
94         *args : any type
95             Variable positional arguments, all unused.
96         """
97         self.file.close()
98 
99 
100 class FileDispatcher:
101     """
102     Class handles util functions for reading data from different kinds of files.
103 
104     Notes
105     -----
106     `_read`, `deploy`, `parse` and `materialize` are abstract methods and should be
107     implemented in the child classes (functions signatures can differ between child
108     classes).
109     """
110 
111     frame_cls = None
112     frame_partition_cls = None
113     query_compiler_cls = None
114 
115     @classmethod
116     def read(cls, *args, **kwargs):
117         """
118         Read data according passed `args` and `kwargs`.
119 
120         Parameters
121         ----------
122         *args : iterable
123             Positional arguments to be passed into `_read` function.
124         **kwargs : dict
125             Keywords arguments to be passed into `_read` function.
126 
127         Returns
128         -------
129         query_compiler : BaseQueryCompiler
130             Query compiler with imported data for further processing.
131 
132         Notes
133         -----
134         `read` is high-level function that calls specific for defined backend, engine and
135         dispatcher class `_read` function with passed parameters and performs some
136         postprocessing work on the resulting query_compiler object.
137         """
138         query_compiler = cls._read(*args, **kwargs)
139         # TODO (devin-petersohn): Make this section more general for non-pandas kernel
140         # implementations.
141         if Backend.get() == "Pandas":
142             import pandas as kernel_lib
143         elif Backend.get() == "Cudf":
144             import cudf as kernel_lib
145         else:
146             raise NotImplementedError("FIXME")
147 
148         if hasattr(query_compiler, "dtypes") and any(
149             isinstance(t, kernel_lib.CategoricalDtype) for t in query_compiler.dtypes
150         ):
151             dtypes = query_compiler.dtypes
152             return query_compiler.astype(
153                 {
154                     t: dtypes[t]
155                     for t in dtypes.index
156                     if isinstance(dtypes[t], kernel_lib.CategoricalDtype)
157                 }
158             )
159         return query_compiler
160 
161     @classmethod
162     def _read(cls, *args, **kwargs):
163         """
164         Perform reading of the data from file.
165 
166         Should be implemented in the child class.
167 
168         Parameters
169         ----------
170         *args : iterable
171             Positional arguments of the function.
172         **kwargs : dict
173             Keywords arguments of the function.
174         """
175         raise NotImplementedError(NOT_IMPLEMENTED_MESSAGE)
176 
177     @classmethod
178     def get_path(cls, file_path):
179         """
180         Process `file_path` in accordance to it's type.
181 
182         Parameters
183         ----------
184         file_path : str
185             String that represents the path to the file (paths to S3 buckets
186             are also acceptable).
187 
188         Returns
189         -------
190         str
191             Updated or verified `file_path` parameter.
192 
193         Notes
194         -----
195         if `file_path` is an S3 bucket, parameter will be returned as is, otherwise
196         absolute path will be returned.
197         """
198         if S3_ADDRESS_REGEX.search(file_path):
199             return file_path
200         else:
201             return os.path.abspath(file_path)
202 
203     @classmethod
204     def file_size(cls, f):
205         """
206         Get the size of file associated with file handle `f`.
207 
208         Parameters
209         ----------
210         f : file-like object
211             File-like object, that should be used to get file size.
212 
213         Returns
214         -------
215         int
216             File size in bytes.
217         """
218         cur_pos = f.tell()
219         f.seek(0, os.SEEK_END)
220         size = f.tell()
221         f.seek(cur_pos, os.SEEK_SET)
222         return size
223 
224     @classmethod
225     def file_exists(cls, file_path):
226         """
227         Check if `file_path` exists.
228 
229         Parameters
230         ----------
231         file_path : str
232             String that represents the path to the file (paths to S3 buckets
233             are also acceptable).
234 
235         Returns
236         -------
237         bool
238             Whether file exists or not.
239         """
240         if isinstance(file_path, str):
241             match = S3_ADDRESS_REGEX.search(file_path)
242             if match is not None:
243                 if file_path[0] == "S":
244                     file_path = "{}{}".format("s", file_path[1:])
245                 import s3fs as S3FS
246                 from botocore.exceptions import NoCredentialsError
247 
248                 s3fs = S3FS.S3FileSystem(anon=False)
249                 exists = False
250                 try:
251                     exists = s3fs.exists(file_path) or exists
252                 except NoCredentialsError:
253                     pass
254                 s3fs = S3FS.S3FileSystem(anon=True)
255                 return exists or s3fs.exists(file_path)
256         return os.path.exists(file_path)
257 
258     @classmethod
259     def deploy(cls, func, args, num_returns):  # noqa: PR01
260         """
261         Deploy remote task.
262 
263         Should be implemented in the task class (for example in the `RayTask`).
264         """
265         raise NotImplementedError(NOT_IMPLEMENTED_MESSAGE)
266 
267     def parse(self, func, args, num_returns):  # noqa: PR01
268         """
269         Parse file's data in the worker process.
270 
271         Should be implemented in the parser class (for example in the `PandasCSVParser`).
272         """
273         raise NotImplementedError(NOT_IMPLEMENTED_MESSAGE)
274 
275     @classmethod
276     def materialize(cls, obj_id):  # noqa: PR01
277         """
278         Get results from worker.
279 
280         Should be implemented in the task class (for example in the `RayTask`).
281         """
282         raise NotImplementedError(NOT_IMPLEMENTED_MESSAGE)
283 
284     @classmethod
285     def build_partition(cls, partition_ids, row_lengths, column_widths):
286         """
287         Build array with partitions of `cls.frame_partition_cls` class.
288 
289         Parameters
290         ----------
291         partition_ids : list
292             Array with references to the partitions data.
293         row_lengths : list
294             Partitions rows lengths.
295         column_widths : list
296             Number of columns in each partition.
297 
298         Returns
299         -------
300         np.ndarray
301             array with shape equals to the shape of `partition_ids` and
302             filed with partition objects.
303         """
304         return np.array(
305             [
306                 [
307                     cls.frame_partition_cls(
308                         partition_ids[i][j],
309                         length=row_lengths[i],
310                         width=column_widths[j],
311                     )
312                     for j in range(len(partition_ids[i]))
313                 ]
314                 for i in range(len(partition_ids))
315             ]
316         )
317
```
--- 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/modin/core/io/file_dispatcher.py b/modin/core/io/file_dispatcher.py
--- a/modin/core/io/file_dispatcher.py
+++ b/modin/core/io/file_dispatcher.py
@@ -72,18 +72,21 @@
         fsspec.core.OpenFile
             The opened file.
         """
-        from botocore.exceptions import NoCredentialsError
+        try:
+            from botocore.exceptions import NoCredentialsError
+
+            credential_error_type = (NoCredentialsError,)
+        except ModuleNotFoundError:
+            credential_error_type = ()
+
+        args = (self.file_path, self.mode, self.compression)
 
+        self.file = fsspec.open(*args, anon=False)
         try:
-            self.file = fsspec.open(
-                self.file_path, self.mode, self.compression, anon=False
-            )
-            return self.file.open()
-        except NoCredentialsError:
-            self.file = fsspec.open(
-                self.file_path, self.mode, self.compression, anon=True
-            )
             return self.file.open()
+        except credential_error_type:
+            self.file = fsspec.open(*args, anon=True)
+        return self.file.open()
 
     def __exit__(self, *args):
         """

{"golden_diff": "diff --git a/modin/core/io/file_dispatcher.py b/modin/core/io/file_dispatcher.py\n--- a/modin/core/io/file_dispatcher.py\n+++ b/modin/core/io/file_dispatcher.py\n@@ -72,18 +72,21 @@\n         fsspec.core.OpenFile\n             The opened file.\n         \"\"\"\n-        from botocore.exceptions import NoCredentialsError\n+        try:\n+            from botocore.exceptions import NoCredentialsError\n+\n+            credential_error_type = (NoCredentialsError,)\n+        except ModuleNotFoundError:\n+            credential_error_type = ()\n+\n+        args = (self.file_path, self.mode, self.compression)\n \n+        self.file = fsspec.open(*args, anon=False)\n         try:\n-            self.file = fsspec.open(\n-                self.file_path, self.mode, self.compression, anon=False\n-            )\n-            return self.file.open()\n-        except NoCredentialsError:\n-            self.file = fsspec.open(\n-                self.file_path, self.mode, self.compression, anon=True\n-            )\n             return self.file.open()\n+        except credential_error_type:\n+            self.file = fsspec.open(*args, anon=True)\n+        return self.file.open()\n \n     def __exit__(self, *args):\n         \"\"\"\n", "issue": "ModuleNotFoundError: No module named 'botocore' when using OpenFile\nNeed to rewrite this so that this dependency is imported only when the S3 store is being used.\r\nThereby making it optional like s3fs.\n", "before_files": [{"content": "# Licensed to Modin Development Team under one or more contributor license agreements.\n# See the NOTICE file distributed with this work for additional information regarding\n# copyright ownership.  The Modin Development Team licenses this file to you under the\n# Apache License, Version 2.0 (the \"License\"); you may not use this file except in\n# compliance with the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under\n# the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF\n# ANY KIND, either express or implied. See the License for the specific language\n# governing permissions and limitations under the License.\n\n\"\"\"\nModule houses `FileDispatcher` class.\n\n`FileDispatcher` can be used as abstract base class for dispatchers of specific file formats or\nfor direct files processing.\n\"\"\"\n\nimport fsspec\nimport os\nimport re\nfrom modin.config import Backend\nimport numpy as np\n\nS3_ADDRESS_REGEX = re.compile(\"[sS]3://(.*?)/(.*)\")\nNOT_IMPLEMENTED_MESSAGE = \"Implement in children classes!\"\n\n\nclass OpenFile:\n    \"\"\"\n    OpenFile is a context manager for an input file.\n\n    OpenFile uses fsspec to open files on __enter__. On __exit__, it closes the\n    fsspec file. This class exists to encapsulate the special behavior in\n    __enter__ around anon=False and anon=True for s3 buckets.\n\n    Parameters\n    ----------\n    file_path : str\n        String that represents the path to the file (paths to S3 buckets\n        are also acceptable).\n    mode : str, default: \"rb\"\n        String, which defines which mode file should be open.\n    compression : str, default: \"infer\"\n        File compression name.\n\n    Attributes\n    ----------\n    file_path : str\n        String that represents the path to the file\n    mode : str\n        String that defines which mode the file should be opened in.\n    compression : str\n        File compression name.\n    file : fsspec.core.OpenFile\n        The opened file.\n    \"\"\"\n\n    def __init__(self, file_path, mode=\"rb\", compression=\"infer\"):\n        self.file_path = file_path\n        self.mode = mode\n        self.compression = compression\n\n    def __enter__(self):\n        \"\"\"\n        Open the file with fsspec and return the opened file.\n\n        Returns\n        -------\n        fsspec.core.OpenFile\n            The opened file.\n        \"\"\"\n        from botocore.exceptions import NoCredentialsError\n\n        try:\n            self.file = fsspec.open(\n                self.file_path, self.mode, self.compression, anon=False\n            )\n            return self.file.open()\n        except NoCredentialsError:\n            self.file = fsspec.open(\n                self.file_path, self.mode, self.compression, anon=True\n            )\n            return self.file.open()\n\n    def __exit__(self, *args):\n        \"\"\"\n        Close the file.\n\n        Parameters\n        ----------\n        *args : any type\n            Variable positional arguments, all unused.\n        \"\"\"\n        self.file.close()\n\n\nclass FileDispatcher:\n    \"\"\"\n    Class handles util functions for reading data from different kinds of files.\n\n    Notes\n    -----\n    `_read`, `deploy`, `parse` and `materialize` are abstract methods and should be\n    implemented in the child classes (functions signatures can differ between child\n    classes).\n    \"\"\"\n\n    frame_cls = None\n    frame_partition_cls = None\n    query_compiler_cls = None\n\n    @classmethod\n    def read(cls, *args, **kwargs):\n        \"\"\"\n        Read data according passed `args` and `kwargs`.\n\n        Parameters\n        ----------\n        *args : iterable\n            Positional arguments to be passed into `_read` function.\n        **kwargs : dict\n            Keywords arguments to be passed into `_read` function.\n\n        Returns\n        -------\n        query_compiler : BaseQueryCompiler\n            Query compiler with imported data for further processing.\n\n        Notes\n        -----\n        `read` is high-level function that calls specific for defined backend, engine and\n        dispatcher class `_read` function with passed parameters and performs some\n        postprocessing work on the resulting query_compiler object.\n        \"\"\"\n        query_compiler = cls._read(*args, **kwargs)\n        # TODO (devin-petersohn): Make this section more general for non-pandas kernel\n        # implementations.\n        if Backend.get() == \"Pandas\":\n            import pandas as kernel_lib\n        elif Backend.get() == \"Cudf\":\n            import cudf as kernel_lib\n        else:\n            raise NotImplementedError(\"FIXME\")\n\n        if hasattr(query_compiler, \"dtypes\") and any(\n            isinstance(t, kernel_lib.CategoricalDtype) for t in query_compiler.dtypes\n        ):\n            dtypes = query_compiler.dtypes\n            return query_compiler.astype(\n                {\n                    t: dtypes[t]\n                    for t in dtypes.index\n                    if isinstance(dtypes[t], kernel_lib.CategoricalDtype)\n                }\n            )\n        return query_compiler\n\n    @classmethod\n    def _read(cls, *args, **kwargs):\n        \"\"\"\n        Perform reading of the data from file.\n\n        Should be implemented in the child class.\n\n        Parameters\n        ----------\n        *args : iterable\n            Positional arguments of the function.\n        **kwargs : dict\n            Keywords arguments of the function.\n        \"\"\"\n        raise NotImplementedError(NOT_IMPLEMENTED_MESSAGE)\n\n    @classmethod\n    def get_path(cls, file_path):\n        \"\"\"\n        Process `file_path` in accordance to it's type.\n\n        Parameters\n        ----------\n        file_path : str\n            String that represents the path to the file (paths to S3 buckets\n            are also acceptable).\n\n        Returns\n        -------\n        str\n            Updated or verified `file_path` parameter.\n\n        Notes\n        -----\n        if `file_path` is an S3 bucket, parameter will be returned as is, otherwise\n        absolute path will be returned.\n        \"\"\"\n        if S3_ADDRESS_REGEX.search(file_path):\n            return file_path\n        else:\n            return os.path.abspath(file_path)\n\n    @classmethod\n    def file_size(cls, f):\n        \"\"\"\n        Get the size of file associated with file handle `f`.\n\n        Parameters\n        ----------\n        f : file-like object\n            File-like object, that should be used to get file size.\n\n        Returns\n        -------\n        int\n            File size in bytes.\n        \"\"\"\n        cur_pos = f.tell()\n        f.seek(0, os.SEEK_END)\n        size = f.tell()\n        f.seek(cur_pos, os.SEEK_SET)\n        return size\n\n    @classmethod\n    def file_exists(cls, file_path):\n        \"\"\"\n        Check if `file_path` exists.\n\n        Parameters\n        ----------\n        file_path : str\n            String that represents the path to the file (paths to S3 buckets\n            are also acceptable).\n\n        Returns\n        -------\n        bool\n            Whether file exists or not.\n        \"\"\"\n        if isinstance(file_path, str):\n            match = S3_ADDRESS_REGEX.search(file_path)\n            if match is not None:\n                if file_path[0] == \"S\":\n                    file_path = \"{}{}\".format(\"s\", file_path[1:])\n                import s3fs as S3FS\n                from botocore.exceptions import NoCredentialsError\n\n                s3fs = S3FS.S3FileSystem(anon=False)\n                exists = False\n                try:\n                    exists = s3fs.exists(file_path) or exists\n                except NoCredentialsError:\n                    pass\n                s3fs = S3FS.S3FileSystem(anon=True)\n                return exists or s3fs.exists(file_path)\n        return os.path.exists(file_path)\n\n    @classmethod\n    def deploy(cls, func, args, num_returns):  # noqa: PR01\n        \"\"\"\n        Deploy remote task.\n\n        Should be implemented in the task class (for example in the `RayTask`).\n        \"\"\"\n        raise NotImplementedError(NOT_IMPLEMENTED_MESSAGE)\n\n    def parse(self, func, args, num_returns):  # noqa: PR01\n        \"\"\"\n        Parse file's data in the worker process.\n\n        Should be implemented in the parser class (for example in the `PandasCSVParser`).\n        \"\"\"\n        raise NotImplementedError(NOT_IMPLEMENTED_MESSAGE)\n\n    @classmethod\n    def materialize(cls, obj_id):  # noqa: PR01\n        \"\"\"\n        Get results from worker.\n\n        Should be implemented in the task class (for example in the `RayTask`).\n        \"\"\"\n        raise NotImplementedError(NOT_IMPLEMENTED_MESSAGE)\n\n    @classmethod\n    def build_partition(cls, partition_ids, row_lengths, column_widths):\n        \"\"\"\n        Build array with partitions of `cls.frame_partition_cls` class.\n\n        Parameters\n        ----------\n        partition_ids : list\n            Array with references to the partitions data.\n        row_lengths : list\n            Partitions rows lengths.\n        column_widths : list\n            Number of columns in each partition.\n\n        Returns\n        -------\n        np.ndarray\n            array with shape equals to the shape of `partition_ids` and\n            filed with partition objects.\n        \"\"\"\n        return np.array(\n            [\n                [\n                    cls.frame_partition_cls(\n                        partition_ids[i][j],\n                        length=row_lengths[i],\n                        width=column_widths[j],\n                    )\n                    for j in range(len(partition_ids[i]))\n                ]\n                for i in range(len(partition_ids))\n            ]\n        )\n", "path": "modin/core/io/file_dispatcher.py"}], "after_files": [{"content": "# Licensed to Modin Development Team under one or more contributor license agreements.\n# See the NOTICE file distributed with this work for additional information regarding\n# copyright ownership.  The Modin Development Team licenses this file to you under the\n# Apache License, Version 2.0 (the \"License\"); you may not use this file except in\n# compliance with the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software distributed under\n# the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF\n# ANY KIND, either express or implied. See the License for the specific language\n# governing permissions and limitations under the License.\n\n\"\"\"\nModule houses `FileDispatcher` class.\n\n`FileDispatcher` can be used as abstract base class for dispatchers of specific file formats or\nfor direct files processing.\n\"\"\"\n\nimport fsspec\nimport os\nimport re\nfrom modin.config import Backend\nimport numpy as np\n\nS3_ADDRESS_REGEX = re.compile(\"[sS]3://(.*?)/(.*)\")\nNOT_IMPLEMENTED_MESSAGE = \"Implement in children classes!\"\n\n\nclass OpenFile:\n    \"\"\"\n    OpenFile is a context manager for an input file.\n\n    OpenFile uses fsspec to open files on __enter__. On __exit__, it closes the\n    fsspec file. This class exists to encapsulate the special behavior in\n    __enter__ around anon=False and anon=True for s3 buckets.\n\n    Parameters\n    ----------\n    file_path : str\n        String that represents the path to the file (paths to S3 buckets\n        are also acceptable).\n    mode : str, default: \"rb\"\n        String, which defines which mode file should be open.\n    compression : str, default: \"infer\"\n        File compression name.\n\n    Attributes\n    ----------\n    file_path : str\n        String that represents the path to the file\n    mode : str\n        String that defines which mode the file should be opened in.\n    compression : str\n        File compression name.\n    file : fsspec.core.OpenFile\n        The opened file.\n    \"\"\"\n\n    def __init__(self, file_path, mode=\"rb\", compression=\"infer\"):\n        self.file_path = file_path\n        self.mode = mode\n        self.compression = compression\n\n    def __enter__(self):\n        \"\"\"\n        Open the file with fsspec and return the opened file.\n\n        Returns\n        -------\n        fsspec.core.OpenFile\n            The opened file.\n        \"\"\"\n        try:\n            from botocore.exceptions import NoCredentialsError\n\n            credential_error_type = (NoCredentialsError,)\n        except ModuleNotFoundError:\n            credential_error_type = ()\n\n        args = (self.file_path, self.mode, self.compression)\n\n        self.file = fsspec.open(*args, anon=False)\n        try:\n            return self.file.open()\n        except credential_error_type:\n            self.file = fsspec.open(*args, anon=True)\n        return self.file.open()\n\n    def __exit__(self, *args):\n        \"\"\"\n        Close the file.\n\n        Parameters\n        ----------\n        *args : any type\n            Variable positional arguments, all unused.\n        \"\"\"\n        self.file.close()\n\n\nclass FileDispatcher:\n    \"\"\"\n    Class handles util functions for reading data from different kinds of files.\n\n    Notes\n    -----\n    `_read`, `deploy`, `parse` and `materialize` are abstract methods and should be\n    implemented in the child classes (functions signatures can differ between child\n    classes).\n    \"\"\"\n\n    frame_cls = None\n    frame_partition_cls = None\n    query_compiler_cls = None\n\n    @classmethod\n    def read(cls, *args, **kwargs):\n        \"\"\"\n        Read data according passed `args` and `kwargs`.\n\n        Parameters\n        ----------\n        *args : iterable\n            Positional arguments to be passed into `_read` function.\n        **kwargs : dict\n            Keywords arguments to be passed into `_read` function.\n\n        Returns\n        -------\n        query_compiler : BaseQueryCompiler\n            Query compiler with imported data for further processing.\n\n        Notes\n        -----\n        `read` is high-level function that calls specific for defined backend, engine and\n        dispatcher class `_read` function with passed parameters and performs some\n        postprocessing work on the resulting query_compiler object.\n        \"\"\"\n        query_compiler = cls._read(*args, **kwargs)\n        # TODO (devin-petersohn): Make this section more general for non-pandas kernel\n        # implementations.\n        if Backend.get() == \"Pandas\":\n            import pandas as kernel_lib\n        elif Backend.get() == \"Cudf\":\n            import cudf as kernel_lib\n        else:\n            raise NotImplementedError(\"FIXME\")\n\n        if hasattr(query_compiler, \"dtypes\") and any(\n            isinstance(t, kernel_lib.CategoricalDtype) for t in query_compiler.dtypes\n        ):\n            dtypes = query_compiler.dtypes\n            return query_compiler.astype(\n                {\n                    t: dtypes[t]\n                    for t in dtypes.index\n                    if isinstance(dtypes[t], kernel_lib.CategoricalDtype)\n                }\n            )\n        return query_compiler\n\n    @classmethod\n    def _read(cls, *args, **kwargs):\n        \"\"\"\n        Perform reading of the data from file.\n\n        Should be implemented in the child class.\n\n        Parameters\n        ----------\n        *args : iterable\n            Positional arguments of the function.\n        **kwargs : dict\n            Keywords arguments of the function.\n        \"\"\"\n        raise NotImplementedError(NOT_IMPLEMENTED_MESSAGE)\n\n    @classmethod\n    def get_path(cls, file_path):\n        \"\"\"\n        Process `file_path` in accordance to it's type.\n\n        Parameters\n        ----------\n        file_path : str\n            String that represents the path to the file (paths to S3 buckets\n            are also acceptable).\n\n        Returns\n        -------\n        str\n            Updated or verified `file_path` parameter.\n\n        Notes\n        -----\n        if `file_path` is an S3 bucket, parameter will be returned as is, otherwise\n        absolute path will be returned.\n        \"\"\"\n        if S3_ADDRESS_REGEX.search(file_path):\n            return file_path\n        else:\n            return os.path.abspath(file_path)\n\n    @classmethod\n    def file_size(cls, f):\n        \"\"\"\n        Get the size of file associated with file handle `f`.\n\n        Parameters\n        ----------\n        f : file-like object\n            File-like object, that should be used to get file size.\n\n        Returns\n        -------\n        int\n            File size in bytes.\n        \"\"\"\n        cur_pos = f.tell()\n        f.seek(0, os.SEEK_END)\n        size = f.tell()\n        f.seek(cur_pos, os.SEEK_SET)\n        return size\n\n    @classmethod\n    def file_exists(cls, file_path):\n        \"\"\"\n        Check if `file_path` exists.\n\n        Parameters\n        ----------\n        file_path : str\n            String that represents the path to the file (paths to S3 buckets\n            are also acceptable).\n\n        Returns\n        -------\n        bool\n            Whether file exists or not.\n        \"\"\"\n        if isinstance(file_path, str):\n            match = S3_ADDRESS_REGEX.search(file_path)\n            if match is not None:\n                if file_path[0] == \"S\":\n                    file_path = \"{}{}\".format(\"s\", file_path[1:])\n                import s3fs as S3FS\n                from botocore.exceptions import NoCredentialsError\n\n                s3fs = S3FS.S3FileSystem(anon=False)\n                exists = False\n                try:\n                    exists = s3fs.exists(file_path) or exists\n                except NoCredentialsError:\n                    pass\n                s3fs = S3FS.S3FileSystem(anon=True)\n                return exists or s3fs.exists(file_path)\n        return os.path.exists(file_path)\n\n    @classmethod\n    def deploy(cls, func, args, num_returns):  # noqa: PR01\n        \"\"\"\n        Deploy remote task.\n\n        Should be implemented in the task class (for example in the `RayTask`).\n        \"\"\"\n        raise NotImplementedError(NOT_IMPLEMENTED_MESSAGE)\n\n    def parse(self, func, args, num_returns):  # noqa: PR01\n        \"\"\"\n        Parse file's data in the worker process.\n\n        Should be implemented in the parser class (for example in the `PandasCSVParser`).\n        \"\"\"\n        raise NotImplementedError(NOT_IMPLEMENTED_MESSAGE)\n\n    @classmethod\n    def materialize(cls, obj_id):  # noqa: PR01\n        \"\"\"\n        Get results from worker.\n\n        Should be implemented in the task class (for example in the `RayTask`).\n        \"\"\"\n        raise NotImplementedError(NOT_IMPLEMENTED_MESSAGE)\n\n    @classmethod\n    def build_partition(cls, partition_ids, row_lengths, column_widths):\n        \"\"\"\n        Build array with partitions of `cls.frame_partition_cls` class.\n\n        Parameters\n        ----------\n        partition_ids : list\n            Array with references to the partitions data.\n        row_lengths : list\n            Partitions rows lengths.\n        column_widths : list\n            Number of columns in each partition.\n\n        Returns\n        -------\n        np.ndarray\n            array with shape equals to the shape of `partition_ids` and\n            filed with partition objects.\n        \"\"\"\n        return np.array(\n            [\n                [\n                    cls.frame_partition_cls(\n                        partition_ids[i][j],\n                        length=row_lengths[i],\n                        width=column_widths[j],\n                    )\n                    for j in range(len(partition_ids[i]))\n                ]\n                for i in range(len(partition_ids))\n            ]\n        )\n", "path": "modin/core/io/file_dispatcher.py"}]}