---
title: "filelock Breaking Changes on PyPI | Since.dev"
description: "What each filelock release removed, renamed or changed: 76 breaking changes in 20 versions on PyPI, each with its source."
canonical_url: https://since.dev/packages/pypi/filelock
last_updated: 2026-10-17
---

# filelock breaking changes

Every breaking API change we have recorded in filelock on PyPI: 76 breaking changes in 20 versions. Below are its newest 6 versions, removals and renames first, each with its source.

Newest change October 17, 2026

## 4.2.1

9 breaking changes, first published October 17, 2026.

- **Removed** `filelock.ReadWriteLock.__del__`  

ReadWriteLock.\_\_del\_\_ was removed in filelock 4.2.1 [pypi.org](https://pypi.org/project/filelock/4.2.1/)
- **Behavior changed** `AsyncReadWriteLock`  

Holds are recorded under a task owner, so synchronous code on the executor thread can no longer re-enter or release a hold taken by an async task. [github.com](https://github.com/tox-dev/filelock/releases/tag/4.2.1)
- **Behavior changed** `AsyncSoftReadWriteLock.release`  

Each release now gives back one level rather than the whole hold, so callers that expected a full release must release once per acquire. [github.com](https://github.com/tox-dev/filelock/releases/tag/4.2.1)
- **Behavior changed** `ReadWriteLock`  

Where an account other than the locking account can change names in the database directory and hard links are unavailable, the lock now raises OSError. Keep the database in a directory other accounts cannot write. [github.com](https://github.com/tox-dev/filelock/releases/tag/4.2.1)
- **Behavior changed** `SoftReadWriteLock.release`  

Read levels are now tracked per thread, so calling release() from a thread that holds none raises RuntimeError. Code that released from another thread must be changed to release from the thread that acquired. [github.com](https://github.com/tox-dev/filelock/releases/tag/4.2.1)
- **Behavior changed** `StrictSoftFileLock`  

Under a sticky parent such as /tmp the lock now refuses a coordination directory owned by another account. Leftover directories of other accounts must be removed by hand. [github.com](https://github.com/tox-dev/filelock/releases/tag/4.2.1)
- **Behavior changed** `UnixFileLock`  

The lock no longer truncates a lock file it did not create and no longer applies mode to it. Code that relied on truncation or mode for such files must set them itself. [github.com](https://github.com/tox-dev/filelock/releases/tag/4.2.1)
- **Signature changed** `filelock.LeaseCompromise.__init__`  

Was def \_\_init\_\_(self, lock_file: str, token: str, reason: CompromiseReason, error: OSError | None = None) -> None; now def \_\_init\_\_(self, lock_file: str, token: str, reason: CompromiseReason, error: Exception | None = None) -> None. [pypi.org](https://pypi.org/project/filelock/4.2.1/)
- **Signature changed** `filelock.LeaseCompromise.error`  

Was error: OSError | None; now error: Exception | None. [pypi.org](https://pypi.org/project/filelock/4.2.1/)

## 4.1.1

1 breaking change, first published October 11, 2026.

- **Behavior changed**  

To avoid a macOS kernel panic, SQLite is opened through a hard link. The database directory must be writable and support hard links, and alias creation failure raises OSError. [github.com](https://github.com/tox-dev/filelock/releases/tag/4.1.1)

## 4.1.0

14 breaking changes, first published October 9, 2026.

- **Behavior changed** `BaseAsyncFileLock`  

When the executor shuts down with a call still queued, BaseAsyncFileLock now raises RuntimeError instead of CancelledError. Code catching CancelledError must catch RuntimeError. [github.com](https://github.com/tox-dev/filelock/releases/tag/4.1.0)
- **Behavior changed** `BaseFileLock`  

Passing a bool or string timeout, an out-of-range mode, or a non-bool blocking value to BaseFileLock now fails, and unknown options on a singleton cache hit are rejected. Pass numeric seconds and valid options. [github.com](https://github.com/tox-dev/filelock/releases/tag/4.1.0)
- **Behavior changed** `ReadWriteLock`  

ReadWriteLock and SoftReadWriteLock options given in seconds now refuse bool or string values that were previously accepted. Pass a number. [github.com](https://github.com/tox-dev/filelock/releases/tag/4.1.0)
- **Behavior changed** `ReadWriteLock.release`  

Calling ReadWriteLock.release() from a thread holding no read level now raises RuntimeError instead of silently ending another thread's read lock. [github.com](https://github.com/tox-dev/filelock/releases/tag/4.1.0)
- **Behavior changed** `SoftFileLock`  

SoftFileLock now applies an explicit mode past the umask, as UnixFileLock already does, so created marker file permissions can differ from before. [github.com](https://github.com/tox-dev/filelock/releases/tag/4.1.0)
- **Behavior changed** `SoftFileLockLifetimeWarning`  

SoftFileLockLifetimeWarning now derives from FutureWarning, so code that filters or catches DeprecationWarning for it will no longer match. [github.com](https://github.com/tox-dev/filelock/releases/tag/4.1.0)
- **Behavior changed** `SoftReadWriteLock.close`  

An acquire still waiting in another thread when SoftReadWriteLock.close() runs now raises RuntimeError instead of taking the lock on the closed instance. [github.com](https://github.com/tox-dev/filelock/releases/tag/4.1.0)
- **Signature changed** `filelock.AcquireReturnProxy`  

Was class AcquireReturnProxy; now class AcquireReturnProxy(Generic\[\_LockT\]). [pypi.org](https://pypi.org/project/filelock/4.1.0/)
- **Signature changed** `filelock.AcquireReturnProxy.__enter__`  

Was def \_\_enter\_\_(self) -> BaseFileLock | ReadWriteLock | SoftReadWriteLock; now def \_\_enter\_\_(self) -> \_LockT. [pypi.org](https://pypi.org/project/filelock/4.1.0/)
- **Signature changed** `filelock.AcquireReturnProxy.__init__`  

Was def \_\_init\_\_(self, lock: BaseFileLock | ReadWriteLock | SoftReadWriteLock) -> None; now def \_\_init\_\_(self, lock: \_LockT) -> None. [pypi.org](https://pypi.org/project/filelock/4.1.0/)

And 4 more in this version.

## 4.0.10

3 breaking changes, first published October 3, 2026.

- **Behavior changed** `AsyncFileLock`  

Reusing a singleton AsyncFileLock with another loop, executor or run_in_executor now raises ValueError instead of returning the lock with its original options. Code that reuses it with changed options must be updated. [github.com](https://github.com/tox-dev/filelock/releases/tag/4.0.10)
- **Behavior changed** `SoftFileLease`  

Reusing a singleton SoftFileLease with another lease_duration, heartbeat_interval or on_compromise now raises ValueError instead of returning the lease with its original options. Code that reuses it with changed options must be updated. [github.com](https://github.com/tox-dev/filelock/releases/tag/4.0.10)
- **Signature changed** `filelock.SoftFileLease.__init__`  

Was def \_\_init\_\_(self, lock_file: str | os.PathLike\[str\], \*, lease_duration: float = 30.0, heartbeat_interval: float | None = None, on_compromise: Callable\[\[LeaseCompromise\], None\] | None = None, \*\*kwargs: Unpack\[LockOptions\]) -> None; now... [pypi.org](https://pypi.org/project/filelock/4.0.10/)

## 4.0.9

2 breaking changes, first published October 1, 2026.

- **Behavior changed** `AsyncReadWriteLock`  

AsyncReadWriteLock no longer follows a symlink at the database path and refuses it instead. Code that relied on a symlinked lock database path must point the lock at a real file. [github.com](https://github.com/tox-dev/filelock/releases/tag/4.0.9)
- **Behavior changed** `ReadWriteLock`  

ReadWriteLock no longer follows a symlink at the database path and refuses it instead. Code that relied on a symlinked lock database path must point the lock at a real file. [github.com](https://github.com/tox-dev/filelock/releases/tag/4.0.9)

## 4.0.8

2 breaking changes, first published October 1, 2026.

- **Behavior changed** `ReadWriteLock.release`  

ReadWriteLock.release() called from a thread that does not hold the write lock now raises RuntimeError instead of silently releasing the holder's lock. Code that relied on the old silent behavior must be changed. [github.com](https://github.com/tox-dev/filelock/releases/tag/4.0.8)
- **Behavior changed** `SoftReadWriteLock.release`  

SoftReadWriteLock.release() called from a thread that does not hold the write lock now raises RuntimeError instead of silently releasing the holder's lock. Code that relied on the old silent behavior must be changed. [github.com](https://github.com/tox-dev/filelock/releases/tag/4.0.8)

## Check your code

These are the changes. To see which of them reach your code, [scan a public repository](https://since.dev/scan.md), or have your coding agent call `check_code` with your manifest or lockfile over [MCP](https://since.dev/docs.md#mcp). [The API](https://since.dev/docs.md#api) reads every change in every version, not only the newest. On Team and up, a fix pull request opens for the changes that reach a connected repository. Nothing merges or deploys.

## Put your code on continuous management.

Scan a public repository now, or give your agent one line.

### See how out of date your code is.

[Scan a repository](https://since.dev/scan.md). Any public GitHub repository. No sign-in.

### Tell your agent what changed since it was trained.

`claude mcp add --transport http since https://api.since.dev/mcp`

---

Every page on this site as Markdown: https://since.dev/sitemap.md. For agents: https://since.dev/llms.txt.
