Timeout decorator for Python functions with signal-based and multiprocessing timeout strategies
npx @tessl/cli install tessl/pypi-timeout-decorator@0.5.00
# Timeout Decorator
1
2
A Python decorator that enables developers to set execution timeouts for functions, preventing them from running indefinitely. It offers two timeout strategies: signal-based timeouts for main thread execution and multiprocessing-based timeouts for worker threads or web application contexts where signals are not available.
3
4
## Package Information
5
6
- **Package Name**: timeout-decorator
7
- **Package Type**: pypi
8
- **Language**: Python
9
- **Installation**: `pip install timeout-decorator`
10
11
## Core Imports
12
13
```python
14
from timeout_decorator import timeout, TimeoutError
15
```
16
17
Alternative import pattern:
18
19
```python
20
import timeout_decorator
21
22
# Use as timeout_decorator.timeout(5)
23
```
24
25
## Basic Usage
26
27
```python
28
import time
29
from timeout_decorator import timeout, TimeoutError
30
31
# Basic timeout with default settings (signal-based)
32
@timeout(5)
33
def slow_function():
34
print("Start")
35
for i in range(1, 10):
36
time.sleep(1)
37
print(f"{i} seconds have passed")
38
39
# This will raise TimeoutError after 5 seconds
40
try:
41
slow_function()
42
except TimeoutError:
43
print("Function timed out!")
44
45
# Multiprocessing-based timeout for thread-safe contexts
46
@timeout(3, use_signals=False)
47
def worker_function():
48
time.sleep(5) # This will timeout
49
50
try:
51
worker_function()
52
except TimeoutError:
53
print("Worker function timed out!")
54
```
55
56
## Architecture
57
58
The timeout decorator provides two distinct timeout strategies to accommodate different execution contexts:
59
60
### Signal-based Strategy (Default)
61
- **Mechanism**: Uses `signal.SIGALRM` to interrupt function execution
62
- **Context**: Only works in the main thread of the process
63
- **Precision**: Provides precise timeout control down to microseconds
64
- **Performance**: Minimal overhead, direct signal handling
65
- **Use Cases**: Single-threaded applications, command-line tools, standalone scripts
66
67
### Multiprocessing Strategy
68
- **Mechanism**: Spawns a separate process to execute the function with timeout monitoring
69
- **Context**: Works in any thread or execution environment (main thread, worker threads, web applications)
70
- **Precision**: Limited to 0.01-second (10ms) granularity due to polling mechanism
71
- **Performance**: Higher overhead due to process creation and inter-process communication
72
- **Requirements**: Function arguments and return values must be pickle-serializable
73
- **Use Cases**: Web applications, multi-threaded applications, any context where signals are not available
74
75
The decorator automatically handles strategy selection based on the `use_signals` parameter, allowing developers to choose the appropriate timeout mechanism for their specific execution context.
76
77
## Capabilities
78
79
### Timeout Decorator
80
81
The main decorator function that adds timeout functionality to any function. Supports both signal-based and multiprocessing-based timeout strategies with configurable exception handling.
82
83
```python { .api }
84
def timeout(seconds=None, use_signals=True, timeout_exception=TimeoutError, exception_message=None):
85
"""
86
Add a timeout parameter to a function and return it.
87
88
Parameters:
89
- seconds (float, optional): Time limit in seconds or fractions of a second.
90
If None is passed, no timeout is applied. This adds flexibility to usage:
91
you can disable timing out depending on settings.
92
- use_signals (bool, default=True): Flag indicating whether signals should be
93
used for timing function out or multiprocessing. When using multiprocessing,
94
timeout granularity is limited to 10ths of a second.
95
- timeout_exception (Exception, default=TimeoutError): Custom exception type
96
to raise on timeout.
97
- exception_message (str, optional): Custom message for the timeout exception.
98
99
Returns:
100
Decorated function with timeout capability
101
102
Raises:
103
TimeoutError (or custom exception) if time limit is reached
104
"""
105
```
106
107
#### Usage Examples
108
109
**Basic timeout with seconds:**
110
```python
111
@timeout(5)
112
def my_function():
113
# Function implementation
114
pass
115
```
116
117
**Fractional seconds:**
118
```python
119
@timeout(0.5)
120
def quick_function():
121
# Must complete within half a second
122
pass
123
```
124
125
**Custom exception type:**
126
```python
127
@timeout(5, timeout_exception=RuntimeError)
128
def my_function():
129
# Will raise RuntimeError instead of TimeoutError
130
pass
131
```
132
133
**Custom exception message:**
134
```python
135
@timeout(5, exception_message="Operation took too long")
136
def my_function():
137
# Will raise TimeoutError with custom message
138
pass
139
```
140
141
**Multiprocessing strategy (thread-safe):**
142
```python
143
@timeout(5, use_signals=False)
144
def thread_worker():
145
# Safe to use in threads or web applications
146
pass
147
```
148
149
**Runtime timeout override:**
150
```python
151
@timeout(10)
152
def flexible_function():
153
pass
154
155
# Override timeout at runtime
156
flexible_function(timeout=5) # Will timeout after 5 seconds instead of 10
157
```
158
159
**Disabled timeout:**
160
```python
161
@timeout() # or @timeout(None)
162
def conditional_function():
163
# No timeout applied
164
pass
165
```
166
167
### Exception Class
168
169
Custom exception raised when timeout occurs, extending Python's AssertionError.
170
171
```python { .api }
172
class TimeoutError(AssertionError):
173
"""
174
Thrown when a timeout occurs in the timeout decorator.
175
176
Parameters:
177
- value (str, default="Timed Out"): Error message
178
"""
179
180
def __init__(self, value="Timed Out"):
181
"""Initialize TimeoutError with custom message."""
182
183
def __str__(self):
184
"""Return string representation of the exception."""
185
```
186
187
## Advanced Usage Patterns
188
189
### Class Methods
190
191
The decorator works with class methods and instance methods:
192
193
```python
194
class MyClass:
195
@timeout(5)
196
def instance_method(self):
197
# Will timeout after 5 seconds
198
pass
199
200
@classmethod
201
@timeout(3)
202
def class_method(cls):
203
# Will timeout after 3 seconds
204
pass
205
```
206
207
### Function Metadata Preservation
208
209
The decorator preserves original function metadata:
210
211
```python
212
@timeout(5)
213
def documented_function():
214
"""This function has documentation."""
215
pass
216
217
# Original function name and documentation are preserved
218
print(documented_function.__name__) # "documented_function"
219
print(documented_function.__doc__) # "This function has documentation."
220
```
221
222
### Error Handling Strategy
223
224
```python
225
from timeout_decorator import timeout, TimeoutError
226
227
@timeout(2)
228
def risky_operation():
229
# Some operation that might take too long
230
import requests
231
return requests.get("https://httpbin.org/delay/5")
232
233
try:
234
result = risky_operation()
235
print("Operation completed successfully")
236
except TimeoutError:
237
print("Operation timed out - implementing fallback")
238
# Implement fallback logic
239
except Exception as e:
240
print(f"Operation failed with error: {e}")
241
# Handle other exceptions
242
```
243
244
## Implementation Notes
245
246
### Signal-based Strategy (default)
247
248
- Uses `signal.SIGALRM` for timeout implementation
249
- Works only in the main thread
250
- Provides precise timeout control
251
- Recommended for single-threaded applications
252
253
### Multiprocessing Strategy
254
255
- Creates a separate process to execute the function
256
- Works in any thread or execution context
257
- Timeout granularity limited to 0.01 seconds (10ms)
258
- Required for web applications and multi-threaded contexts
259
- Functions must return serializable objects (pickle-compatible)
260
261
### Considerations
262
263
- **Signal limitations**: Signal-based timeouts only work in the main thread
264
- **Serialization**: When using `use_signals=False`, function arguments and return values must be pickle-serializable
265
- **Resource cleanup**: Timed-out processes are automatically terminated
266
- **Precision**: Multiprocessing strategy polls every 0.01 seconds for completion