# Buggy code
def _read(cls, path, engine, columns, **kwargs):
    """Load a parquet object from the file path, returning a Modin DataFrame.

    Modin only supports pyarrow engine for now.

    Parameters
    ----------
    path: str
        The filepath of the parquet file in local filesystem or hdfs.
    engine: 'pyarrow'
        Parquet library to use
    columns: list or None
        If not None, only these columns will be read from the file.
    kwargs: dict
        Keyword arguments.

    Returns
    -------
    PandasQueryCompiler
        A new Query Compiler.

    Notes
    -----
    ParquetFile API is used. Please refer to the documentation here
    https://arrow.apache.org/docs/python/parquet.html
    """
    from pyarrow.parquet import ParquetFile, ParquetDataset
    from modin.pandas.io import PQ_INDEX_REGEX

    if os.path.isdir(path):
        partitioned_columns = set()
        directory = True
        # We do a tree walk of the path directory because partitioned
        # parquet directories have a unique column at each directory level.
        # Thus, we can use os.walk(), which does a dfs search, to walk
        # through the different columns that the data is partitioned on
        for root, dir_names, files in os.walk(path):
            if dir_names:
                partitioned_columns.add(dir_names[0].split("=")[0])
            if files:
                # Metadata files, git files, .DSStore
                if files[0][0] == ".":
                    continue
                break
        partitioned_columns = list(partitioned_columns)
        if len(partitioned_columns):
            ErrorMessage.default_to_pandas("Mixed Partitioning Columns in Parquet")
            return cls.single_worker_read(
                path, engine=engine, columns=columns, **kwargs
            )
    else:
        directory = False
    if not columns:
        if directory:
            # Path of the sample file that we will read to get the remaining columns
            pd = ParquetDataset(path)
            meta = pd.metadata
            column_names = pd.schema.names
        elif isinstance(path, str) and path.startswith("hdfs://"):
            import fsspec.core

            fs, path = fsspec.core.url_to_fs(path)
            pd = ParquetDataset(path, filesystem=fs)
            meta = pd.metadata
            column_names = pd.schema.names
        else:
            meta = ParquetFile(path).metadata
            column_names = meta.schema.names
        if meta is not None:
            # This is how we convert the metadata from pyarrow to a python
            # dictionary, from which we then get the index columns.
            # We use these to filter out from the columns in the metadata since
            # the pyarrow storage has no concept of row labels/index.
            # This ensures that our metadata lines up with the partitions without
            # extra communication steps once we `have done all the remote
            # computation.
            index_columns = eval(
                meta.metadata[b"pandas"].replace(b"null", b"None")
            ).get("index_columns", [])
            column_names = [c for c in column_names if c not in index_columns]
        columns = [name for name in column_names if not PQ_INDEX_REGEX.match(name)]
    return cls.build_query_compiler(path, columns, **kwargs)


# Traceback (FileNotFoundError)
---------------------------------------------------------------------------
FileNotFoundError                         Traceback (most recent call last)
<ipython-input-14-814dc08ef229> in <module>
----> 1 df2 = mpd.read_parquet(path)

/opt/anaconda3/envs/myenv/lib/python3.7/site-packages/modin/pandas/io.py in read_parquet(path, engine, columns, **kwargs)
40     return DataFrame(
41         query_compiler=EngineDispatcher.read_parquet(
---> 42             path=path, columns=columns, engine=engine, **kwargs
43         )
44     )

/opt/anaconda3/envs/myenv/lib/python3.7/site-packages/modin/data_management/dispatcher.py in read_parquet(cls, **kwargs)
105     @classmethod
106     def read_parquet(cls, **kwargs):
--> 107         return cls.__engine._read_parquet(**kwargs)
108
109     @classmethod

/opt/anaconda3/envs/myenv/lib/python3.7/site-packages/modin/data_management/factories.py in _read_parquet(cls, **kwargs)
46     @classmethod
47     def _read_parquet(cls, **kwargs):
---> 48         return cls.io_cls.read_parquet(**kwargs)
49
50     @classmethod

/opt/anaconda3/envs/myenv/lib/python3.7/site-packages/modin/engines/base/io/file_reader.py in read(cls, *args, **kwargs)
27     @classmethod
28     def read(cls, *args, **kwargs):
---> 29         query_compiler = cls._read(*args, **kwargs)
30         # TODO (devin-petersohn): Make this section more general for non-pandas kernel
31         # implementations.

/opt/anaconda3/envs/myenv/lib/python3.7/site-packages/modin/engines/base/io/column_stores/parquet_reader.py in _read(cls, path, engine, columns, **kwargs)
68                 column_names = pd.schema.names
69             else:
---> 70                 meta = ParquetFile(path).metadata
71                 column_names = meta.schema.names
72             if meta is not None:

/opt/anaconda3/envs/myenv/lib/python3.7/site-packages/pyarrow/parquet.py in __init__(self, source, metadata, common_metadata, read_dictionary, memory_map, buffer_size)
135         self.reader.open(source, use_memory_map=memory_map,
136                          buffer_size=buffer_size,
--> 137                          read_dictionary=read_dictionary, metadata=metadata)
138         self.common_metadata = common_metadata
139         self._nested_paths_by_prefix = self._build_nested_paths()

/opt/anaconda3/envs/myenv/lib/python3.7/site-packages/pyarrow/_parquet.pyx in pyarrow._parquet.ParquetReader.open()

/opt/anaconda3/envs/myenv/lib/python3.7/site-packages/pyarrow/io.pxi in pyarrow.lib.get_reader()

/opt/anaconda3/envs/myenv/lib/python3.7/site-packages/pyarrow/io.pxi in pyarrow.lib._get_native_file()

/opt/anaconda3/envs/myenv/lib/python3.7/site-packages/pyarrow/io.pxi in pyarrow.lib.OSFile.__cinit__()

/opt/anaconda3/envs/myenv/lib/python3.7/site-packages/pyarrow/io.pxi in pyarrow.lib.OSFile._open_readable()

/opt/anaconda3/envs/myenv/lib/python3.7/site-packages/pyarrow/error.pxi in pyarrow.lib.pyarrow_internal_check_status()

/opt/anaconda3/envs/myenv/lib/python3.7/site-packages/pyarrow/error.pxi in pyarrow.lib.check_status()

FileNotFoundError: [Errno 2] Failed to open local file s3://bucket_name/data/dataframe.snappy.parquet'. Detail: [errno 2] No such file or directory

# Fixed code
def _read(cls, path, engine, columns, **kwargs):
    """Load a parquet object from the file path, returning a Modin DataFrame.

    Modin only supports pyarrow engine for now.

    Parameters
    ----------
    path: str
        The filepath of the parquet file in local filesystem or hdfs.
    engine: 'pyarrow'
        Parquet library to use
    columns: list or None
        If not None, only these columns will be read from the file.
    kwargs: dict
        Keyword arguments.

    Returns
    -------
    PandasQueryCompiler
        A new Query Compiler.

    Notes
    -----
    ParquetFile API is used. Please refer to the documentation here
    https://arrow.apache.org/docs/python/parquet.html
    """
    from pyarrow.parquet import ParquetFile, ParquetDataset
    from modin.pandas.io import PQ_INDEX_REGEX

    if isinstance(path, str) and os.path.isdir(path):
        partitioned_columns = set()
        directory = True
        # We do a tree walk of the path directory because partitioned
        # parquet directories have a unique column at each directory level.
        # Thus, we can use os.walk(), which does a dfs search, to walk
        # through the different columns that the data is partitioned on
        for root, dir_names, files in os.walk(path):
            if dir_names:
                partitioned_columns.add(dir_names[0].split("=")[0])
            if files:
                # Metadata files, git files, .DSStore
                if files[0][0] == ".":
                    continue
                break
        partitioned_columns = list(partitioned_columns)
        if len(partitioned_columns):
            ErrorMessage.default_to_pandas("Mixed Partitioning Columns in Parquet")
            return cls.single_worker_read(
                path, engine=engine, columns=columns, **kwargs
            )
    else:
        directory = False
    if not columns:
        if directory:
            # Path of the sample file that we will read to get the remaining columns
            pd = ParquetDataset(path)
            meta = pd.metadata
            column_names = pd.schema.names
        elif isinstance(path, str) and path.startswith("hdfs://"):
            import fsspec.core

            fs, path = fsspec.core.url_to_fs(path)
            pd = ParquetDataset(path, filesystem=fs)
            meta = pd.metadata
            column_names = pd.schema.names
        elif isinstance(path, s3fs.S3File) or (
            isinstance(path, str) and path.startswith("s3://")
        ):
            from botocore.exceptions import NoCredentialsError

            if isinstance(path, s3fs.S3File):
                bucket_path = path.url().split(".s3.amazonaws.com")
                path = "s3://" + bucket_path[0].split("://")[1] + bucket_path[1]
            try:
                fs = s3fs.S3FileSystem()
                pd = ParquetDataset(path, filesystem=fs)
            except NoCredentialsError:
                fs = s3fs.S3FileSystem(anon=True)
                pd = ParquetDataset(path, filesystem=fs)
            meta = pd.metadata
            column_names = pd.schema.names
        else:
            meta = ParquetFile(path).metadata
            column_names = meta.schema.names
        if meta is not None:
            # This is how we convert the metadata from pyarrow to a python
            # dictionary, from which we then get the index columns.
            # We use these to filter out from the columns in the metadata since
            # the pyarrow storage has no concept of row labels/index.
            # This ensures that our metadata lines up with the partitions without
            # extra communication steps once we `have done all the remote
            # computation.
            index_columns = eval(
                meta.metadata[b"pandas"].replace(b"null", b"None")
            ).get("index_columns", [])
            column_names = [c for c in column_names if c not in index_columns]
        columns = [name for name in column_names if not PQ_INDEX_REGEX.match(name)]
    return cls.build_query_compiler(path, columns, **kwargs)