or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

file-locking.mdindex.mdlock-classes.mdredis-locking.mdsemaphores.mdutilities.md

index.mddocs/

0

# Portalocker

1

2

A cross-platform file locking library that provides reliable file locking mechanisms across Windows, Linux, Unix, and macOS systems. Portalocker offers both traditional file-based locks using native system calls and advanced Redis-based distributed locks for multi-process and multi-machine coordination.

3

4

## Package Information

5

6

- **Package Name**: portalocker

7

- **Language**: Python

8

- **Installation**: `pip install portalocker`

9

- **Optional Dependencies**: `pip install portalocker[redis]` for Redis-based locking

10

11

## Core Imports

12

13

```python

14

import portalocker

15

```

16

17

Common usage patterns:

18

19

```python

20

from portalocker import Lock, lock, unlock, LOCK_EX, LOCK_SH, LOCK_NB

21

```

22

23

For Redis-based locking:

24

25

```python

26

from portalocker import RedisLock

27

```

28

29

## Basic Usage

30

31

```python

32

import portalocker

33

34

# Basic file locking with context manager

35

with portalocker.Lock('my_file.txt', 'r+') as fh:

36

data = fh.read()

37

# File is automatically locked here

38

fh.write('new data')

39

# File is automatically unlocked when exiting context

40

41

# Manual locking and unlocking

42

with open('my_file.txt', 'r+') as fh:

43

portalocker.lock(fh, portalocker.LOCK_EX)

44

try:

45

# Do work with locked file

46

data = fh.read()

47

fh.write('modified data')

48

finally:

49

portalocker.unlock(fh)

50

51

# Non-blocking lock with timeout

52

try:

53

with portalocker.Lock('my_file.txt', timeout=5.0, fail_when_locked=True) as fh:

54

# Work with file

55

pass

56

except portalocker.AlreadyLocked:

57

print("File is locked by another process")

58

```

59

60

## Architecture

61

62

Portalocker provides a layered architecture for cross-platform file locking:

63

64

- **High-level Lock Classes**: Context managers (Lock, RLock, TemporaryFileLock) with timeout and error handling

65

- **Low-level Functions**: Direct lock/unlock functions (lock, unlock) for manual control

66

- **Platform Abstraction**: Automatic selection between Windows (Win32/msvcrt) and POSIX (fcntl) implementations

67

- **Advanced Features**: Redis-based distributed locks, bounded semaphores, atomic file operations

68

- **Type System**: Complete type definitions for all file handles, flags, and configuration options

69

70

This design ensures reliable cross-platform operation while providing flexibility from simple context managers to complex distributed locking scenarios.

71

72

## Capabilities

73

74

### File Locking

75

76

Core file locking functionality using advisory locks with support for exclusive/shared locks, non-blocking mode, and timeout handling. Works across Windows, Linux, Unix, and macOS.

77

78

```python { .api }

79

def lock(file: FileArgument, flags: LockFlags) -> None: ...

80

def unlock(file: FileArgument) -> None: ...

81

82

LOCK_EX: LockFlags # Exclusive lock

83

LOCK_SH: LockFlags # Shared lock

84

LOCK_NB: LockFlags # Non-blocking

85

LOCK_UN: LockFlags # Unlock

86

```

87

88

[File Locking](./file-locking.md)

89

90

### Lock Classes

91

92

High-level lock managers with built-in timeout, context manager support, and advanced features like reentrant locks and temporary file locks.

93

94

```python { .api }

95

class Lock:

96

def __init__(self, filename: Filename, mode: str = 'a', timeout: float | None = None,

97

check_interval: float = 0.25, fail_when_locked: bool = False,

98

flags: LockFlags = LOCK_EX | LOCK_NB, **file_open_kwargs) -> None: ...

99

def acquire(self, timeout: float | None = None, check_interval: float | None = None,

100

fail_when_locked: bool | None = None) -> typing.IO: ...

101

def release(self) -> None: ...

102

103

class RLock(Lock): ... # Reentrant lock

104

class TemporaryFileLock(Lock): ... # Auto-deleting temporary lock

105

```

106

107

[Lock Classes](./lock-classes.md)

108

109

### Redis Distributed Locking

110

111

Redis pubsub-based distributed locks that provide immediate unlocking when connections are lost, suitable for multi-process and multi-machine coordination.

112

113

```python { .api }

114

class RedisLock:

115

def __init__(self, channel: str, connection: redis.Redis | None = None,

116

timeout: float | None = None, check_interval: float | None = None,

117

fail_when_locked: bool | None = False, thread_sleep_time: float = 0.1,

118

unavailable_timeout: float = 1, redis_kwargs: dict | None = None) -> None: ...

119

def acquire(self, timeout: float | None = None, check_interval: float | None = None,

120

fail_when_locked: bool | None = None) -> 'RedisLock': ...

121

def release(self) -> None: ...

122

```

123

124

[Redis Locking](./redis-locking.md)

125

126

### Semaphores and Resource Management

127

128

Bounded semaphores for limiting concurrent processes accessing shared resources, with support for named semaphores across process boundaries.

129

130

```python { .api }

131

class BoundedSemaphore: # Deprecated

132

def __init__(self, maximum: int, name: str = 'bounded_semaphore',

133

filename_pattern: str = '{name}.{number:02d}.lock',

134

directory: str = tempfile.gettempdir(), **kwargs) -> None: ...

135

136

class NamedBoundedSemaphore(BoundedSemaphore):

137

def __init__(self, maximum: int, name: str | None = None, **kwargs) -> None: ...

138

```

139

140

[Semaphores](./semaphores.md)

141

142

### Utility Functions

143

144

Additional utilities for atomic file operations and helper functions.

145

146

```python { .api }

147

def open_atomic(filename: Filename, binary: bool = True) -> typing.Iterator[typing.IO]: ...

148

```

149

150

[Utilities](./utilities.md)

151

152

## Exception Handling

153

154

```python { .api }

155

class LockException(Exception):

156

"""Base exception for locking errors"""

157

158

class AlreadyLocked(LockException):

159

"""Raised when file is already locked by another process"""

160

```

161

162

## Type Definitions

163

164

```python { .api }

165

from typing import Union, Literal

166

import pathlib

167

168

# File path types

169

Filename = Union[str, pathlib.Path]

170

171

# File handle types

172

FileArgument = Union[typing.IO, int, HasFileno]

173

174

# File open modes

175

Mode = Literal['r', 'w', 'a', 'x', 'rb', 'wb', 'ab', 'xb', 'r+', 'w+', 'a+', 'x+', ...]

176

177

# Lock flags enum

178

class LockFlags(enum.IntFlag):

179

EXCLUSIVE: int

180

SHARED: int

181

NON_BLOCKING: int

182

UNBLOCK: int

183

184

# Protocol for objects with fileno() method

185

class HasFileno(typing.Protocol):

186

def fileno(self) -> int: ...

187

```