    async def _ls(self, path, detail=False, refresh=False, versions=False):
        """List files in given bucket, or list of buckets.

        Listing is cached unless `refresh=True`.

        Note: only your buckets associated with the login will be listed by
        `ls('')`, not any public buckets (even if already accessed).

        Parameters
        ----------
        path : string/bytes
            location at which to list files
        refresh : bool (=False)
            if False, look in local cache for file details first
        """
        path = self._strip_protocol(path).rstrip("/")
        if path in ["", "/"]:
            files = await self._lsbuckets(refresh)
        else:
            files = await self._lsdir(path, refresh, versions=versions)
            if not files and "/" in path:
                try:
                    files = await self._lsdir(
                        self._parent(path), refresh=refresh, versions=versions
                    )
                except IOError:
                    pass
                files = [
                    o
                    for o in files
                    if o["name"].rstrip("/") == path and o["type"] != "directory"
                ]
                if not files:
                    raise FileNotFoundError(path)
            if detail:
                return files
        return files if detail else sorted([o["name"] for o in files])
List files in given bucket, or list of buckets.

Listing is cached unless `refresh=True`.

Note: only your buckets associated with the login will be listed by
`ls('')`, not any public buckets (even if already accessed).

Parameters
----------
path : string/bytes
location at which to list files
refresh : bool (=False)
if False, look in local cache for file details first
s3fs/core.py