0
# Future Objects
1
2
Future objects represent the result of an asynchronous computation. They provide methods to check the status of the computation, retrieve results, handle exceptions, and attach callbacks that execute when the computation completes.
3
4
## Capabilities
5
6
### Future Class
7
8
The Future class encapsulates the lifecycle and result of an asynchronous operation.
9
10
```python { .api }
11
class Future:
12
def __init__(self):
13
"""
14
Initialize a Future object.
15
16
Note: Should not be called directly by client code.
17
Futures are created by Executor.submit() calls.
18
"""
19
20
def cancel(self):
21
"""
22
Attempt to cancel the future.
23
24
Returns:
25
bool: True if successfully cancelled, False if already running or completed
26
27
Note: Cannot cancel futures that are already running or finished
28
"""
29
30
def cancelled(self):
31
"""
32
Check if the future was cancelled.
33
34
Returns:
35
bool: True if the future was cancelled before completion
36
"""
37
38
def running(self):
39
"""
40
Check if the future is currently executing.
41
42
Returns:
43
bool: True if the future is currently being executed
44
"""
45
46
def done(self):
47
"""
48
Check if the future has completed.
49
50
Returns:
51
bool: True if future completed (finished, cancelled, or failed)
52
"""
53
54
def result(self, timeout=None):
55
"""
56
Get the result of the future.
57
58
Parameters:
59
- timeout (float, optional): Maximum time to wait in seconds
60
61
Returns:
62
Any: The result returned by the callable
63
64
Raises:
65
CancelledError: If the future was cancelled
66
TimeoutError: If timeout exceeded before completion
67
Exception: Any exception raised by the callable
68
"""
69
70
def exception(self, timeout=None):
71
"""
72
Get the exception raised by the future's callable.
73
74
Parameters:
75
- timeout (float, optional): Maximum time to wait in seconds
76
77
Returns:
78
Exception or None: Exception raised by callable, or None if successful
79
80
Raises:
81
CancelledError: If the future was cancelled
82
TimeoutError: If timeout exceeded before completion
83
"""
84
85
def exception_info(self, timeout=None):
86
"""
87
Get exception and traceback information.
88
89
Parameters:
90
- timeout (float, optional): Maximum time to wait in seconds
91
92
Returns:
93
tuple: (exception, traceback) or (None, None) if successful
94
95
Raises:
96
CancelledError: If the future was cancelled
97
TimeoutError: If timeout exceeded before completion
98
"""
99
100
def add_done_callback(self, fn):
101
"""
102
Attach a callback to be called when the future completes.
103
104
Parameters:
105
- fn (callable): Function to call with the future as argument
106
107
Note: Callback is called immediately if future is already complete.
108
Multiple callbacks are called in the order they were added.
109
"""
110
```
111
112
### Usage Examples
113
114
**Basic Future Usage:**
115
116
```python
117
from concurrent.futures import ThreadPoolExecutor
118
119
def slow_function(n):
120
import time
121
time.sleep(1)
122
if n < 0:
123
raise ValueError("Negative number")
124
return n * n
125
126
with ThreadPoolExecutor() as executor:
127
# Submit task and get future
128
future = executor.submit(slow_function, 5)
129
130
# Check status
131
print(f"Cancelled: {future.cancelled()}") # False
132
print(f"Running: {future.running()}") # True or False
133
print(f"Done: {future.done()}") # False initially
134
135
# Get result (blocks until complete)
136
result = future.result()
137
print(f"Result: {result}") # 25
138
139
# Check final status
140
print(f"Done: {future.done()}") # True
141
```
142
143
**Handling Exceptions:**
144
145
```python
146
with ThreadPoolExecutor() as executor:
147
# Submit task that will raise exception
148
future = executor.submit(slow_function, -1)
149
150
try:
151
result = future.result()
152
except ValueError as e:
153
print(f"Task failed: {e}")
154
155
# Alternative: check exception directly
156
exception = future.exception()
157
if exception:
158
print(f"Exception occurred: {exception}")
159
```
160
161
**Using Timeouts:**
162
163
```python
164
with ThreadPoolExecutor() as executor:
165
future = executor.submit(slow_function, 5)
166
167
try:
168
# Wait maximum 0.5 seconds
169
result = future.result(timeout=0.5)
170
print(f"Quick result: {result}")
171
except TimeoutError:
172
print("Task didn't complete in time")
173
# Future continues running in background
174
175
# Wait for actual completion
176
result = future.result() # No timeout
177
print(f"Final result: {result}")
178
```
179
180
**Cancelling Futures:**
181
182
```python
183
import time
184
185
with ThreadPoolExecutor() as executor:
186
future = executor.submit(slow_function, 10)
187
188
# Try to cancel immediately
189
if future.cancel():
190
print("Successfully cancelled")
191
else:
192
print("Could not cancel (already running)")
193
194
# Check if cancelled
195
if future.cancelled():
196
try:
197
result = future.result()
198
except CancelledError:
199
print("Future was cancelled")
200
```
201
202
**Done Callbacks:**
203
204
```python
205
def task_completed(future):
206
try:
207
result = future.result()
208
print(f"Task completed with result: {result}")
209
except Exception as e:
210
print(f"Task failed with exception: {e}")
211
212
with ThreadPoolExecutor() as executor:
213
future = executor.submit(slow_function, 7)
214
215
# Add callback (can add multiple)
216
future.add_done_callback(task_completed)
217
218
# Callback will be called when future completes
219
# Main thread can continue other work
220
result = future.result() # Also wait for completion
221
```
222
223
**Advanced Callback Usage:**
224
225
```python
226
def log_completion(name):
227
def callback(future):
228
status = "succeeded" if not future.exception() else "failed"
229
print(f"Task '{name}' {status}")
230
return callback
231
232
def process_result(future):
233
if not future.exception():
234
result = future.result()
235
# Do something with result
236
print(f"Processing result: {result}")
237
238
with ThreadPoolExecutor() as executor:
239
future = executor.submit(slow_function, 3)
240
241
# Add multiple callbacks
242
future.add_done_callback(log_completion("calculation"))
243
future.add_done_callback(process_result)
244
245
# Both callbacks will be called when future completes
246
future.result()
247
```
248
249
### Future States and Lifecycle
250
251
A future progresses through these states:
252
253
1. **PENDING**: Future created but not yet running
254
2. **RUNNING**: Callable is currently executing
255
3. **CANCELLED**: Future was cancelled before completion
256
4. **FINISHED**: Callable completed (successfully or with exception)
257
258
```python
259
# Example showing state transitions
260
with ThreadPoolExecutor(max_workers=1) as executor:
261
def check_states(future, name):
262
print(f"{name} - Cancelled: {future.cancelled()}, "
263
f"Running: {future.running()}, Done: {future.done()}")
264
265
future = executor.submit(slow_function, 2)
266
check_states(future, "After submit") # May show running=True
267
268
result = future.result()
269
check_states(future, "After completion") # done=True
270
```
271
272
### Error Handling Patterns
273
274
**Comprehensive Error Handling:**
275
276
```python
277
from concurrent.futures import CancelledError, TimeoutError
278
279
def handle_future_result(future, timeout=None):
280
try:
281
result = future.result(timeout=timeout)
282
return {"success": True, "result": result}
283
except CancelledError:
284
return {"success": False, "error": "cancelled"}
285
except TimeoutError:
286
return {"success": False, "error": "timeout"}
287
except Exception as e:
288
return {"success": False, "error": str(e)}
289
290
# Usage
291
with ThreadPoolExecutor() as executor:
292
future = executor.submit(slow_function, 5)
293
outcome = handle_future_result(future, timeout=2.0)
294
295
if outcome["success"]:
296
print(f"Result: {outcome['result']}")
297
else:
298
print(f"Failed: {outcome['error']}")
299
```
300
301
## Internal Methods
302
303
These methods are primarily for use by Executor implementations:
304
305
```python { .api }
306
def set_running_or_notify_cancel(self):
307
"""
308
Mark future as running or notify cancellation.
309
310
Returns:
311
bool: False if cancelled, True if set to running
312
313
Note: For internal use by executors
314
"""
315
316
def set_result(self, result):
317
"""
318
Set the future's result.
319
320
Parameters:
321
- result: The result value
322
323
Note: For internal use by executors
324
"""
325
326
def set_exception(self, exception):
327
"""
328
Set the future's exception.
329
330
Parameters:
331
- exception: The exception that occurred
332
333
Note: For internal use by executors
334
"""
335
336
def set_exception_info(self, exception, traceback):
337
"""
338
Set the future's exception with traceback.
339
340
Parameters:
341
- exception: The exception that occurred
342
- traceback: The traceback information
343
344
Note: For internal use by executors
345
"""
346
```