or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

tessl/pypi-filelock

A platform independent file lock for cross-platform process synchronization.

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
pypipkg:pypi/filelock@3.19.x

To install, run

npx @tessl/cli install tessl/pypi-filelock@3.19.0

0

# Filelock

1

2

A platform-independent file lock that supports the with-statement for coordinating access to shared resources across processes. Filelock provides synchronous and asynchronous file locking with platform-specific optimizations for Unix (fcntl), Windows (msvcrt), and a fallback soft lock implementation.

3

4

## Package Information

5

6

- **Package Name**: filelock

7

- **Language**: Python

8

- **Installation**: `pip install filelock`

9

10

## Core Imports

11

12

```python

13

from filelock import FileLock

14

```

15

16

For async usage:

17

18

```python

19

from filelock import AsyncFileLock

20

```

21

22

Import specific lock types:

23

24

```python

25

from filelock import SoftFileLock, UnixFileLock, WindowsFileLock

26

from filelock import AsyncSoftFileLock, AsyncUnixFileLock, AsyncWindowsFileLock

27

```

28

29

Import exceptions:

30

31

```python

32

from filelock import Timeout

33

```

34

35

Import version:

36

37

```python

38

from filelock import __version__

39

```

40

41

Import utility functions:

42

43

```python

44

from filelock._util import raise_on_not_writable_file, ensure_directory_exists

45

from filelock._unix import has_fcntl

46

```

47

48

## Basic Usage

49

50

```python

51

from filelock import FileLock

52

import time

53

54

# Create a file lock

55

lock = FileLock("my_file.lock")

56

57

# Use with context manager (recommended)

58

with lock:

59

# Critical section - only one process can execute this at a time

60

print("Lock acquired, doing work...")

61

time.sleep(2)

62

print("Work completed")

63

# Lock is automatically released

64

65

# Async usage

66

import asyncio

67

from filelock import AsyncFileLock

68

69

async def async_example():

70

lock = AsyncFileLock("async_file.lock")

71

72

async with lock:

73

print("Async lock acquired")

74

await asyncio.sleep(2)

75

print("Async work completed")

76

77

# Manual acquire/release (not recommended)

78

lock = FileLock("manual.lock")

79

try:

80

lock.acquire(timeout=10)

81

print("Lock acquired manually")

82

finally:

83

lock.release()

84

```

85

86

## Architecture

87

88

Filelock uses a hierarchical class design with platform-specific implementations:

89

90

- **BaseFileLock**: Abstract base class defining the common interface

91

- **Platform Implementations**: UnixFileLock (fcntl), WindowsFileLock (msvcrt), SoftFileLock (fallback)

92

- **FileLock Alias**: Automatically selects the best implementation for the current platform

93

- **Async Support**: BaseAsyncFileLock and async variants of all lock types

94

- **Context Management**: All locks support both synchronous `with` and asynchronous `async with` statements

95

96

The library automatically chooses the most appropriate locking mechanism based on the platform and available system features.

97

98

## Capabilities

99

100

### Platform-Specific File Locks

101

102

Cross-platform file locking with automatic platform detection. FileLock automatically selects the best available implementation for the current system.

103

104

```python { .api }

105

class FileLock(BaseFileLock):

106

"""Platform-specific file lock (alias for UnixFileLock/WindowsFileLock/SoftFileLock)."""

107

108

def __init__(

109

self,

110

lock_file: str | os.PathLike[str],

111

timeout: float = -1,

112

mode: int = 0o644,

113

thread_local: bool = True,

114

*,

115

blocking: bool = True,

116

is_singleton: bool = False,

117

) -> None:

118

"""

119

Create a new lock object.

120

121

Args:

122

lock_file: Path to the lock file

123

timeout: Default timeout in seconds (-1 for no timeout)

124

mode: File permissions for the lock file

125

thread_local: Whether context should be thread local

126

blocking: Whether the lock should be blocking

127

is_singleton: If True, only one instance per lock file path

128

"""

129

130

class AsyncFileLock(BaseAsyncFileLock):

131

"""Platform-specific async file lock."""

132

133

def __init__(

134

self,

135

lock_file: str | os.PathLike[str],

136

timeout: float = -1,

137

mode: int = 0o644,

138

thread_local: bool = False,

139

*,

140

blocking: bool = True,

141

is_singleton: bool = False,

142

loop: asyncio.AbstractEventLoop | None = None,

143

run_in_executor: bool = True,

144

executor: concurrent.futures.Executor | None = None,

145

) -> None:

146

"""

147

Create a new async lock object.

148

149

Args:

150

lock_file: Path to the lock file

151

timeout: Default timeout in seconds (-1 for no timeout)

152

mode: File permissions for the lock file

153

thread_local: Whether context should be thread local

154

blocking: Whether the lock should be blocking

155

is_singleton: If True, only one instance per lock file path

156

loop: Event loop to use

157

run_in_executor: Whether to run in executor

158

executor: Executor to use for blocking operations

159

"""

160

```

161

162

### Unix File Locks (fcntl-based)

163

164

Hard file locking using fcntl.flock for Unix-like systems (Linux, macOS, BSD).

165

166

```python { .api }

167

class UnixFileLock(BaseFileLock):

168

"""Uses fcntl.flock to hard lock the file on Unix systems."""

169

170

class AsyncUnixFileLock(UnixFileLock, BaseAsyncFileLock):

171

"""Async version of UnixFileLock."""

172

```

173

174

### Platform Availability Constants

175

176

Constants indicating platform-specific feature availability.

177

178

```python { .api }

179

has_fcntl: bool

180

# Boolean constant indicating if fcntl is available on the current system

181

# True on Unix-like systems with fcntl support, False on Windows or systems without fcntl

182

```

183

184

### Windows File Locks (msvcrt-based)

185

186

Hard file locking using msvcrt.locking for Windows systems.

187

188

```python { .api }

189

class WindowsFileLock(BaseFileLock):

190

"""Uses msvcrt.locking to hard lock the file on Windows systems."""

191

192

class AsyncWindowsFileLock(WindowsFileLock, BaseAsyncFileLock):

193

"""Async version of WindowsFileLock."""

194

```

195

196

### Soft File Locks (cross-platform fallback)

197

198

File existence-based locking that works on all platforms but provides softer guarantees.

199

200

```python { .api }

201

class SoftFileLock(BaseFileLock):

202

"""Simply watches the existence of the lock file."""

203

204

class AsyncSoftFileLock(SoftFileLock, BaseAsyncFileLock):

205

"""Async version of SoftFileLock."""

206

```

207

208

### Lock Acquisition and Release

209

210

Core methods for acquiring and releasing file locks with timeout support.

211

212

```python { .api }

213

class BaseFileLock:

214

def acquire(

215

self,

216

timeout: float | None = None,

217

poll_interval: float = 0.05,

218

*,

219

poll_intervall: float | None = None,

220

blocking: bool | None = None,

221

) -> AcquireReturnProxy:

222

"""

223

Try to acquire the file lock.

224

225

Args:

226

timeout: Maximum wait time in seconds (None uses default)

227

poll_interval: Interval between acquisition attempts

228

poll_intervall: Deprecated, use poll_interval instead

229

blocking: Whether to block until acquired

230

231

Returns:

232

Context manager proxy for the lock

233

234

Raises:

235

Timeout: If lock cannot be acquired within timeout

236

"""

237

238

def release(self, force: bool = False) -> None:

239

"""

240

Release the file lock.

241

242

Args:

243

force: If True, ignore lock counter and force release

244

"""

245

246

class BaseAsyncFileLock:

247

@property

248

def run_in_executor(self) -> bool:

249

"""Whether operations run in an executor."""

250

251

@property

252

def executor(self) -> concurrent.futures.Executor | None:

253

"""The executor used for blocking operations."""

254

255

@executor.setter

256

def executor(self, value: concurrent.futures.Executor | None) -> None:

257

"""Set the executor for blocking operations."""

258

259

@property

260

def loop(self) -> asyncio.AbstractEventLoop | None:

261

"""The event loop associated with this lock."""

262

263

async def acquire(

264

self,

265

timeout: float | None = None,

266

poll_interval: float = 0.05,

267

*,

268

blocking: bool | None = None,

269

) -> AsyncAcquireReturnProxy:

270

"""

271

Async version of acquire.

272

273

Args:

274

timeout: Maximum wait time in seconds (None uses default)

275

poll_interval: Interval between acquisition attempts

276

blocking: Whether to block until acquired

277

278

Returns:

279

Async context manager proxy for the lock

280

281

Raises:

282

Timeout: If lock cannot be acquired within timeout

283

"""

284

285

async def release(self, force: bool = False) -> None:

286

"""

287

Async version of release.

288

289

Args:

290

force: If True, ignore lock counter and force release

291

"""

292

```

293

294

### Lock State and Properties

295

296

Properties and methods for inspecting lock state and configuration.

297

298

```python { .api }

299

class BaseFileLock:

300

@property

301

def is_locked(self) -> bool:

302

"""Whether the lock is currently held."""

303

304

@property

305

def lock_counter(self) -> int:

306

"""Number of times lock has been acquired (for reentrant locking)."""

307

308

@property

309

def lock_file(self) -> str:

310

"""Path to the lock file."""

311

312

@property

313

def timeout(self) -> float:

314

"""Default timeout value in seconds."""

315

316

@timeout.setter

317

def timeout(self, value: float | str) -> None:

318

"""Set the default timeout value."""

319

320

@property

321

def blocking(self) -> bool:

322

"""Whether locking is blocking by default."""

323

324

@blocking.setter

325

def blocking(self, value: bool) -> None:

326

"""Set the default blocking behavior."""

327

328

@property

329

def mode(self) -> int:

330

"""File permissions for the lock file."""

331

332

@property

333

def is_singleton(self) -> bool:

334

"""Whether this lock uses singleton pattern."""

335

336

def is_thread_local(self) -> bool:

337

"""Whether this lock uses thread-local context."""

338

```

339

340

### Context Manager Support

341

342

Built-in support for context managers enabling safe automatic lock release.

343

344

```python { .api }

345

class BaseFileLock:

346

def __enter__(self) -> BaseFileLock:

347

"""Enter the context manager (acquire lock)."""

348

349

def __exit__(

350

self,

351

exc_type: type[BaseException] | None,

352

exc_value: BaseException | None,

353

traceback: types.TracebackType | None,

354

) -> None:

355

"""Exit the context manager (release lock)."""

356

357

class BaseAsyncFileLock:

358

async def __aenter__(self) -> BaseAsyncFileLock:

359

"""Enter the async context manager (acquire lock)."""

360

361

async def __aexit__(

362

self,

363

exc_type: type[BaseException] | None,

364

exc_value: BaseException | None,

365

traceback: types.TracebackType | None,

366

) -> None:

367

"""Exit the async context manager (release lock)."""

368

369

def __enter__(self) -> NoReturn:

370

"""Raises NotImplementedError - use async with instead."""

371

```

372

373

### Context Manager Proxies

374

375

Helper classes that provide context manager functionality while preventing double-acquisition.

376

377

```python { .api }

378

class AcquireReturnProxy:

379

"""Context manager returned by acquire() for safe lock handling."""

380

381

def __init__(self, lock: BaseFileLock) -> None: ...

382

383

def __enter__(self) -> BaseFileLock: ...

384

385

def __exit__(

386

self,

387

exc_type: type[BaseException] | None,

388

exc_value: BaseException | None,

389

traceback: types.TracebackType | None,

390

) -> None: ...

391

392

class AsyncAcquireReturnProxy:

393

"""Async context manager returned by async acquire()."""

394

395

def __init__(self, lock: BaseAsyncFileLock) -> None: ...

396

397

async def __aenter__(self) -> BaseAsyncFileLock: ...

398

399

async def __aexit__(

400

self,

401

exc_type: type[BaseException] | None,

402

exc_value: BaseException | None,

403

traceback: types.TracebackType | None,

404

) -> None: ...

405

```

406

407

### Exception Handling

408

409

Exception class for lock acquisition timeouts and error handling.

410

411

```python { .api }

412

class Timeout(TimeoutError):

413

"""Raised when the lock could not be acquired within the timeout period."""

414

415

def __init__(self, lock_file: str) -> None:

416

"""

417

Create a timeout exception.

418

419

Args:

420

lock_file: Path to the lock file that timed out

421

"""

422

423

def __str__(self) -> str:

424

"""Return string representation of the exception."""

425

426

def __repr__(self) -> str:

427

"""Return detailed string representation of the exception."""

428

429

def __reduce__(self) -> str | tuple[Any, ...]:

430

"""Support for pickling the exception."""

431

432

@property

433

def lock_file(self) -> str:

434

"""Path of the file lock that timed out."""

435

436

# Other exceptions that may be raised:

437

# ValueError: When invalid parameters are passed to singleton locks

438

# NotImplementedError: When platform-specific features are unavailable

439

# PermissionError: When lock file cannot be written (via utility functions)

440

# IsADirectoryError: When lock path points to a directory (via utility functions)

441

```

442

443

### Utility Functions

444

445

Internal utility functions that are part of the public API for file and directory handling.

446

447

```python { .api }

448

def raise_on_not_writable_file(filename: str) -> None:

449

"""

450

Raise an exception if attempting to open the file for writing would fail.

451

452

This is done so files that will never be writable can be separated from files

453

that are writable but currently locked.

454

455

Args:

456

filename: Path to the file to check

457

458

Raises:

459

PermissionError: If file exists but is not writable

460

IsADirectoryError: If path points to a directory (Unix/macOS)

461

PermissionError: If path points to a directory (Windows)

462

"""

463

464

def ensure_directory_exists(filename: str | os.PathLike[str]) -> None:

465

"""

466

Ensure the directory containing the file exists (create it if necessary).

467

468

Args:

469

filename: Path to the file whose parent directory should exist

470

"""

471

```

472

473

### Version Information

474

475

Package version information.

476

477

```python { .api }

478

__version__: str

479

# Version of the filelock package as a string

480

```

481

482

## Types

483

484

```python { .api }

485

import os

486

import asyncio

487

import concurrent.futures

488

from types import TracebackType

489

from typing import Union, Optional, Any, NoReturn

490

491

# Type aliases used in the API

492

PathLike = Union[str, os.PathLike[str]]

493

OptionalFloat = Optional[float]

494

OptionalBool = Optional[bool]

495

OptionalLoop = Optional[asyncio.AbstractEventLoop]

496

OptionalExecutor = Optional[concurrent.futures.Executor]

497

OptionalExceptionType = Optional[type[BaseException]]

498

OptionalException = Optional[BaseException]

499

OptionalTraceback = Optional[TracebackType]

500

```

501

502

## Usage Examples

503

504

### Timeout Handling

505

506

```python

507

from filelock import FileLock, Timeout

508

509

lock = FileLock("resource.lock", timeout=5)

510

511

try:

512

with lock:

513

print("Got the lock!")

514

time.sleep(10) # Simulate work

515

except Timeout:

516

print("Could not acquire lock within 5 seconds")

517

```

518

519

### Non-blocking Lock Attempts

520

521

```python

522

from filelock import FileLock

523

524

lock = FileLock("resource.lock", blocking=False)

525

526

try:

527

with lock.acquire():

528

print("Lock acquired immediately")

529

except Timeout:

530

print("Lock is currently held by another process")

531

```

532

533

### Singleton Locks

534

535

```python

536

from filelock import FileLock

537

538

# All instances with same path share the same lock object

539

lock1 = FileLock("shared.lock", is_singleton=True)

540

lock2 = FileLock("shared.lock", is_singleton=True)

541

542

assert lock1 is lock2 # Same object

543

```

544

545

### Async Lock Usage

546

547

```python

548

import asyncio

549

from filelock import AsyncFileLock

550

551

async def worker(worker_id: int):

552

lock = AsyncFileLock("shared_resource.lock")

553

554

async with lock:

555

print(f"Worker {worker_id} acquired lock")

556

await asyncio.sleep(1)

557

print(f"Worker {worker_id} releasing lock")

558

559

async def main():

560

# Run multiple workers concurrently

561

await asyncio.gather(

562

worker(1),

563

worker(2),

564

worker(3)

565

)

566

567

asyncio.run(main())

568

```