Skip to content

Commit 6ef9ce1

Browse files
committed
[refactor] Avoid if-else def by suffixing different FUSE version implementations
1 parent 5a1914c commit 6ef9ce1

File tree

1 file changed

+54
-73
lines changed

1 file changed

+54
-73
lines changed

mfusepy.py

Lines changed: 54 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1123,7 +1123,7 @@ class FUSE:
11231123
('nothreads', '-s'),
11241124
)
11251125

1126-
def __init__(self, operations, mountpoint, raw_fi=False, encoding='utf-8', **kwargs):
1126+
def __init__(self, operations, mountpoint: str, raw_fi: bool = False, encoding: str = 'utf-8', **kwargs) -> None:
11271127
'''
11281128
Setting raw_fi to True will cause FUSE to pass the fuse_file_info
11291129
class as is to Operations, instead of just the fh field.
@@ -1164,8 +1164,8 @@ class as is to Operations, instead of just the fh field.
11641164
args.append(','.join(self._normalize_fuse_options(**kwargs)))
11651165
args.append(mountpoint)
11661166

1167-
args = [arg.encode(encoding) for arg in args]
1168-
argv = (ctypes.c_char_p * len(args))(*args)
1167+
argsb = [arg.encode(encoding) for arg in args]
1168+
argv = (ctypes.c_char_p * len(argsb))(*argsb)
11691169

11701170
fuse_ops = fuse_operations()
11711171
callbacks_to_always_add = {'init'}
@@ -1187,9 +1187,22 @@ class as is to Operations, instead of just the fh field.
11871187

11881188
# Wrap functions into try-except statements.
11891189
if is_function:
1190-
method = getattr(self, name, None)
1190+
method: Optional[Any] = None
1191+
if fuse_version_major == 2:
1192+
method = getattr(self, name + '_fuse_2', None)
1193+
elif fuse_version_major == 3:
1194+
method = getattr(self, name + '_fuse_3', None)
1195+
1196+
if method is not None and hasattr(self, name):
1197+
raise RuntimeError(
1198+
"Internal Error: Only either suffixed or non-suffixed methods must exist!"
1199+
f"Found both for '{name}'."
1200+
)
1201+
11911202
if method is None:
1192-
raise RuntimeError(f"Internal Error: Method wrapper for FUSE callback '{name}' is missing!")
1203+
method = getattr(self, name, None)
1204+
if method is None:
1205+
raise RuntimeError(f"Internal Error: Method wrapper for FUSE callback '{name}' is missing!")
11931206

11941207
log.debug("Set libFUSE callback for '%s' to wrapped %s wrapping %s", name, method, value)
11951208
value = prototype(functools.partial(self._wrapper, method))
@@ -1203,7 +1216,7 @@ class as is to Operations, instead of just the fh field.
12031216
except ValueError:
12041217
old_handler = SIG_DFL
12051218

1206-
err = fuse_main_real(len(args), argv, ctypes.pointer(fuse_ops), ctypes.sizeof(fuse_ops), None)
1219+
err = fuse_main_real(len(argsb), argv, ctypes.pointer(fuse_ops), ctypes.sizeof(fuse_ops), None)
12071220

12081221
try:
12091222
signal(SIGINT, old_handler)
@@ -1272,15 +1285,11 @@ def _wrapper(self, func, *args, **kwargs):
12721285
fuse_exit()
12731286
return -errno.EFAULT
12741287

1275-
if fuse_version_major == 2:
1276-
1277-
def getattr(self, path: bytes, buf):
1278-
return self.fgetattr(path, buf, None)
1288+
def getattr_fuse_2(self, path: bytes, buf):
1289+
return self.fgetattr(path, buf, None)
12791290

1280-
elif fuse_version_major == 3:
1281-
1282-
def getattr(self, path: bytes, buf, fip): # type: ignore
1283-
return self.fgetattr(path, buf, None)
1291+
def getattr_fuse_3(self, path: bytes, buf, fip):
1292+
return self.fgetattr(path, buf, None)
12841293

12851294
def readlink(self, path: bytes, buf, bufsize: int) -> int:
12861295
ret = self.operations.readlink(path.decode(self.encoding)).encode(self.encoding)
@@ -1308,30 +1317,22 @@ def symlink(self, source: bytes, target: bytes) -> int:
13081317

13091318
return self.operations.symlink(target.decode(self.encoding), source.decode(self.encoding))
13101319

1311-
def _rename(self, old: bytes, new: bytes) -> int:
1320+
def rename_fuse_2(self, old: bytes, new: bytes) -> int:
13121321
return self.operations.rename(old.decode(self.encoding), new.decode(self.encoding))
13131322

1314-
if fuse_version_major == 2:
1315-
rename = _rename
1316-
elif fuse_version_major == 3:
1317-
1318-
def rename(self, old: bytes, new: bytes, flags: int) -> int: # type: ignore
1319-
return self._rename(old, new)
1323+
def rename_fuse_3(self, old: bytes, new: bytes, flags: int) -> int:
1324+
return self.rename_fuse_2(old, new)
13201325

13211326
def link(self, source: bytes, target: bytes):
13221327
'creates a hard link `target -> source` (e.g. ln source target)'
13231328

13241329
return self.operations.link(target.decode(self.encoding), source.decode(self.encoding))
13251330

1326-
if fuse_version_major == 2:
1331+
def chmod_fuse_2(self, path: Optional[bytes], mode: int) -> int:
1332+
return self.operations.chmod(None if path is None else path.decode(self.encoding), mode)
13271333

1328-
def chmod(self, path: Optional[bytes], mode: int) -> int:
1329-
return self.operations.chmod(None if path is None else path.decode(self.encoding), mode)
1330-
1331-
elif fuse_version_major == 3:
1332-
1333-
def chmod(self, path: Optional[bytes], mode: int, fip) -> int: # type: ignore
1334-
return self.operations.chmod(None if path is None else path.decode(self.encoding), mode)
1334+
def chmod_fuse_3(self, path: Optional[bytes], mode: int, fip) -> int:
1335+
return self.operations.chmod(None if path is None else path.decode(self.encoding), mode)
13351336

13361337
def _chown(self, path: Optional[bytes], uid: int, gid: int) -> int:
13371338
# Check if any of the arguments is a -1 that has overflowed
@@ -1342,25 +1343,17 @@ def _chown(self, path: Optional[bytes], uid: int, gid: int) -> int:
13421343

13431344
return self.operations.chown(None if path is None else path.decode(self.encoding), uid, gid)
13441345

1345-
if fuse_version_major == 2:
1346-
1347-
def chown(self, path: Optional[bytes], uid: int, gid: int) -> int:
1348-
return self._chown(path, uid, gid)
1349-
1350-
elif fuse_version_major == 3:
1346+
def chown_fuse_2(self, path: Optional[bytes], uid: int, gid: int) -> int:
1347+
return self._chown(path, uid, gid)
13511348

1352-
def chown(self, path: Optional[bytes], uid: int, gid: int, fip) -> int: # type: ignore
1353-
return self._chown(path, uid, gid)
1349+
def chown_fuse_3(self, path: Optional[bytes], uid: int, gid: int, fip) -> int:
1350+
return self._chown(path, uid, gid)
13541351

1355-
if fuse_version_major == 2:
1352+
def truncate_fuse_2(self, path: Optional[bytes], length: int) -> int:
1353+
return self.operations.truncate(None if path is None else path.decode(self.encoding), length)
13561354

1357-
def truncate(self, path: Optional[bytes], length: int) -> int:
1358-
return self.operations.truncate(None if path is None else path.decode(self.encoding), length)
1359-
1360-
elif fuse_version_major == 3:
1361-
1362-
def truncate(self, path: Optional[bytes], length: int, fip) -> int: # type: ignore
1363-
return self.operations.truncate(None if path is None else path.decode(self.encoding), length)
1355+
def truncate_fuse_3(self, path: Optional[bytes], length: int, fip) -> int:
1356+
return self.operations.truncate(None if path is None else path.decode(self.encoding), length)
13641357

13651358
def open(self, path: bytes, fip) -> int:
13661359
fi = fip.contents
@@ -1548,18 +1541,14 @@ def _readdir(self, path: Optional[bytes], buf, filler, offset: int, fip) -> int:
15481541

15491542
return 0
15501543

1551-
if fuse_version_major == 2:
1552-
1553-
def readdir(self, path: Optional[bytes], buf, filler, offset, fip) -> int:
1554-
return self._readdir(path, buf, filler, offset, fip)
1544+
def readdir_fuse_2(self, path: Optional[bytes], buf, filler, offset, fip) -> int:
1545+
return self._readdir(path, buf, filler, offset, fip)
15551546

1556-
elif fuse_version_major == 3:
1557-
1558-
def readdir(self, path: Optional[bytes], buf, filler, offset, fip, flags) -> int: # type: ignore
1559-
# TODO if bit 0 (FUSE_READDIR_PLUS) is set in flags, then we might want to gather more metadata
1560-
# and return it in "filler" with bit 1 (FUSE_FILL_DIR_PLUS) being set.
1561-
# Ignore raw_fi
1562-
return self._readdir(path, buf, filler, offset, fip)
1547+
def readdir_fuse_3(self, path: Optional[bytes], buf, filler, offset, fip, flags) -> int:
1548+
# TODO if bit 0 (FUSE_READDIR_PLUS) is set in flags, then we might want to gather more metadata
1549+
# and return it in "filler" with bit 1 (FUSE_FILL_DIR_PLUS) being set.
1550+
# Ignore raw_fi
1551+
return self._readdir(path, buf, filler, offset, fip)
15631552

15641553
def releasedir(self, path: Optional[bytes], fip) -> int:
15651554
# Ignore raw_fi
@@ -1577,17 +1566,13 @@ def _init(self, conn, config) -> None:
15771566
elif hasattr(self.operations, "init") and not getattr(self.operations.init, "libfuse_ignore", False):
15781567
self.operations.init("/")
15791568

1580-
if fuse_version_major == 2:
1569+
def init_fuse_2(self, conn) -> None:
1570+
self._init(conn, fuse_config())
15811571

1582-
def init(self, conn) -> None:
1583-
self._init(conn, fuse_config())
1584-
1585-
else:
1586-
1587-
def init(self, conn, config) -> None: # type: ignore
1588-
if getattr(self.operations, 'flag_nopath', False) and getattr(self.operations, 'flag_nullpath_ok', False):
1589-
config.contents.nullpath_ok = True
1590-
self._init(conn, config)
1572+
def init_fuse_3(self, conn, config) -> None:
1573+
if getattr(self.operations, 'flag_nopath', False) and getattr(self.operations, 'flag_nullpath_ok', False):
1574+
config.contents.nullpath_ok = True
1575+
self._init(conn, config)
15911576

15921577
def destroy(self, private_data) -> None:
15931578
return self.operations.destroy('/')
@@ -1625,7 +1610,7 @@ def lock(self, path: Optional[bytes], fip, cmd: int, lock) -> int:
16251610
fh = fip.contents if self.raw_fi else fip.contents.fh
16261611
return self.operations.lock(None if path is None else path.decode(self.encoding), fh, cmd, lock)
16271612

1628-
def _utimens(self, path: Optional[bytes], buf) -> int:
1613+
def utimens_fuse_2(self, path: Optional[bytes], buf) -> int:
16291614
if buf:
16301615
atime = time_of_timespec(buf.contents.actime, use_ns=self.use_ns)
16311616
mtime = time_of_timespec(buf.contents.modtime, use_ns=self.use_ns)
@@ -1635,12 +1620,8 @@ def _utimens(self, path: Optional[bytes], buf) -> int:
16351620

16361621
return self.operations.utimens(None if path is None else path.decode(self.encoding), times)
16371622

1638-
if fuse_version_major == 2:
1639-
utimens = _utimens
1640-
elif fuse_version_major == 3:
1641-
1642-
def utimens(self, path: Optional[bytes], buf, fip) -> int: # type: ignore
1643-
return self._utimens(path, buf)
1623+
def utimens_fuse_3(self, path: Optional[bytes], buf, fip) -> int:
1624+
return self.utimens_fuse_2(path, buf)
16441625

16451626
def bmap(self, path: bytes, blocksize: int, idx) -> int:
16461627
return self.operations.bmap(path.decode(self.encoding), blocksize, idx)

0 commit comments

Comments
 (0)