Skip to content

Commit 212ffb1

Browse files
Ensure reference FS wraps any sync filesystems (#1755)
Co-authored-by: Martin Durant <[email protected]>
1 parent 1372f87 commit 212ffb1

File tree

3 files changed

+13
-6
lines changed

3 files changed

+13
-6
lines changed

fsspec/implementations/asyn_wrapper.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,26 +45,27 @@ class AsyncFileSystemWrapper(AsyncFileSystem):
4545
def __init__(self, sync_fs, *args, **kwargs):
4646
super().__init__(*args, **kwargs)
4747
self.asynchronous = True
48-
self.fs = sync_fs
48+
self.sync_fs = sync_fs
49+
self.protocol = self.sync_fs.protocol
4950
self._wrap_all_sync_methods()
5051

5152
@property
5253
def fsid(self):
53-
return f"async_{self.fs.fsid}"
54+
return f"async_{self.sync_fs.fsid}"
5455

5556
def _wrap_all_sync_methods(self):
5657
"""
5758
Wrap all synchronous methods of the underlying filesystem with asynchronous versions.
5859
"""
59-
for method_name in dir(self.fs):
60+
for method_name in dir(self.sync_fs):
6061
if method_name.startswith("_"):
6162
continue
6263

63-
attr = inspect.getattr_static(self.fs, method_name)
64+
attr = inspect.getattr_static(self.sync_fs, method_name)
6465
if isinstance(attr, property):
6566
continue
6667

67-
method = getattr(self.fs, method_name)
68+
method = getattr(self.sync_fs, method_name)
6869
if callable(method) and not asyncio.iscoroutinefunction(method):
6970
async_method = async_wrapper(method, obj=self)
7071
setattr(self, f"_{method_name}", async_method)

fsspec/implementations/reference.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
from fsspec.asyn import AsyncFileSystem
2121
from fsspec.callbacks import DEFAULT_CALLBACK
2222
from fsspec.core import filesystem, open, split_protocol
23+
from fsspec.implementations.asyn_wrapper import AsyncFileSystemWrapper
2324
from fsspec.utils import isfilelike, merge_offset_ranges, other_paths
2425

2526
logger = logging.getLogger("fsspec.reference")
@@ -757,6 +758,10 @@ def __init__(
757758
self.fss[remote_protocol] = fs
758759

759760
self.fss[None] = fs or filesystem("file") # default one
761+
# Wrap any non-async filesystems to ensure async methods are available below
762+
for k, f in self.fss.items():
763+
if not f.async_impl:
764+
self.fss[k] = AsyncFileSystemWrapper(f)
760765

761766
def _cat_common(self, path, start=None, end=None):
762767
path = self._strip_protocol(path)

fsspec/implementations/tests/test_reference.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -458,7 +458,8 @@ def test_fss_has_defaults(m):
458458
assert fs.fss["memory"].protocol == "memory"
459459

460460
fs = fsspec.filesystem("reference", fs=m, fo={})
461-
assert fs.fss[None] is m
461+
# Default behavior here wraps synchronous filesystems to enable the async API
462+
assert fs.fss[None].sync_fs is m
462463

463464
fs = fsspec.filesystem("reference", fs={"memory": m}, fo={})
464465
assert fs.fss["memory"] is m

0 commit comments

Comments
 (0)