#8637·datasets

FileLock wrapper drops timeout and every other constructor argument

Author: behroozazarkhaliliCreated Sep 17, 2026Updated Sep 17, 2026

Describe the bug

datasets.utils._filelock.FileLock silently discards every keyword argument except lock_file. Passing timeout= has no effect, and is_singleton=True raises instead of returning the cached lock.

The wrapper declares a variadic signature:

# src/datasets/utils/_filelock.py
def __init__(self, lock_file, *args, **kwargs):

filelock inspects that signature to decide what to forward. From filelock/_api.py, FileLockMeta.__call__:

all_params = {"timeout": timeout, "mode": mode, "thread_local": thread_local,
              "blocking": blocking, "is_singleton": is_singleton,
              "poll_interval": poll_interval, "lifetime": lifetime, **kwargs}
present_params = inspect.signature(cls.__init__).parameters
init_params = {key: value for key, value in all_params.items() if key in present_params}
instance = super().__call__(lock_file, **init_params)

*args/**kwargs expose none of those names, so init_params is always empty and all seven are dropped before __init__ runs. Affected: timeout, mode, thread_local, blocking, is_singleton, poll_interval, lifetime.

The is_singleton failure is a knock-on effect. Our __init__ injects a umask-derived mode into the call it makes to super().__init__, so the cached instance ends up with mode=0o640, while the singleton check compares against the _UNSET_FILE_MODE sentinel (-1) that the caller never set. The parameters "differ" and the second construction raises.

Steps to reproduce the bug

import tempfile, os, filelock
from datasets.utils._filelock import FileLock

d = tempfile.mkdtemp()

print(FileLock(os.path.join(d, "a.lock"), timeout=5).timeout)           # -1
print(filelock.FileLock(os.path.join(d, "b.lock"), timeout=5).timeout)  # 5

p = os.path.join(d, "c.lock")
first = FileLock(p, is_singleton=True)
second = FileLock(p, is_singleton=True)                                  # ValueError
datasets 5.0.2.dev0, filelock 3.25.2
datasets FileLock timeout: -1
filelock FileLock timeout: 5
Traceback (most recent call last):
  File "<stdin>", line 9, in <module>
  File ".../filelock/_api.py", line 150, in __call__
    raise ValueError(msg)
ValueError: Singleton lock instances cannot be initialized with differing arguments
Non-matching arguments:
	mode (existing lock has 416 but -1 was passed)

Hold a reference to the first lock to see the is_singleton error: _instances is a WeakValueDictionary, so an unreferenced first lock is collected and the second call quietly succeeds.

Expected behavior

Arguments accepted by filelock.FileLock should reach it, and is_singleton=True should return the cached instance.

Impact

Nothing in datasets passes these arguments today, so internal behaviour is unaffected and there is no cache-correctness problem. It matters for anyone constructing this lock directly, where a timeout= that looks set is not, and a lock that should time out blocks indefinitely instead.

A fix means naming the parameters on __init__ so the signature inspection finds them, keeping the umask default expressed as filelock's _UNSET_FILE_MODE sentinel rather than a concrete mode, so the singleton comparison still matches. Happy to open a PR if that approach sounds right.

Environment info

  • datasets 5.0.2.dev0 (main, commit 3e2c1a6c3); reproduced identically on the released code path since the variadic signature arrived in #6445, first released in 2.16.0
  • filelock 3.25.2
  • Python 3.11.5, Linux