or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

asynctools.mdbuiltins.mdcontextlib.mdfunctools.mdheapq.mdindex.mditertools.md

contextlib.mddocs/

0

# Context Management

1

2

Async context managers and decorators for resource management, providing async versions of contextlib utilities with additional safety features. These tools ensure proper cleanup of async resources and enable context-aware programming patterns.

3

4

## Capabilities

5

6

### Context Manager Creation

7

8

Create context managers from generator functions and existing objects.

9

10

```python { .api }

11

def contextmanager(func):

12

"""

13

Decorator to create async context manager from generator function.

14

15

Parameters:

16

- func: Callable[..., AsyncGenerator[T, None]] - Generator function yielding once

17

18

Returns:

19

Callable[..., ContextDecorator[T]] - Function returning context manager

20

21

Usage:

22

@contextmanager

23

async def my_context():

24

# setup code

25

yield value

26

# cleanup code

27

"""

28

```

29

30

### Context Manager Base Classes

31

32

Base classes for creating reusable context managers.

33

34

```python { .api }

35

class ContextDecorator:

36

"""

37

Base class for context managers usable as decorators.

38

39

Inheriting from this class allows context managers to be used

40

as decorators on async functions.

41

"""

42

43

def _recreate_cm(self):

44

"""

45

Create a copy of the context manager for decorator usage.

46

47

Returns:

48

Self - Copy of the context manager

49

"""

50

51

def __call__(self, func):

52

"""

53

Use context manager as decorator.

54

55

Parameters:

56

- func: Async callable to decorate

57

58

Returns:

59

Decorated async callable

60

"""

61

```

62

63

### Resource Management

64

65

Context managers for automatic resource cleanup.

66

67

```python { .api }

68

class closing:

69

"""

70

Context manager that calls aclose() on the wrapped object when exiting.

71

"""

72

73

def __init__(self, thing):

74

"""

75

Parameters:

76

- thing: Object with aclose() method - Resource to manage

77

"""

78

79

async def __aenter__(self):

80

"""

81

Enter context and return the managed resource.

82

83

Returns:

84

The managed resource object

85

"""

86

87

async def __aexit__(self, exc_type, exc_val, exc_tb):

88

"""

89

Exit context and close the resource.

90

91

Parameters:

92

- exc_type: Exception type or None

93

- exc_val: Exception value or None

94

- exc_tb: Exception traceback or None

95

"""

96

97

class nullcontext:

98

"""

99

No-op async context manager.

100

"""

101

102

def __init__(self, enter_result=None):

103

"""

104

Parameters:

105

- enter_result: T, optional - Value to return from __aenter__

106

"""

107

108

async def __aenter__(self):

109

"""

110

Enter context and return enter_result.

111

112

Returns:

113

T - The enter_result value

114

"""

115

116

async def __aexit__(self, exc_type, exc_val, exc_tb):

117

"""

118

Exit context (no-op).

119

120

Parameters:

121

- exc_type: Exception type or None

122

- exc_val: Exception value or None

123

- exc_tb: Exception traceback or None

124

"""

125

```

126

127

### Context Stack Management

128

129

Manage multiple context managers as a single unit.

130

131

```python { .api }

132

class ExitStack:

133

"""

134

Context manager for managing multiple async context managers.

135

"""

136

137

def __init__(self):

138

"""Initialize empty exit stack."""

139

140

def pop_all(self):

141

"""

142

Remove all contexts from stack and return new stack with them.

143

144

Returns:

145

ExitStack - New stack containing all contexts

146

"""

147

148

def push(self, exit):

149

"""

150

Add context manager or exit callback to stack.

151

152

Parameters:

153

- exit: AsyncContextManager or exit callback - Context to manage

154

155

Returns:

156

The same context manager or callback

157

"""

158

159

def callback(self, callback, *args, **kwargs):

160

"""

161

Add callback function to be called on exit.

162

163

Parameters:

164

- callback: Callable - Function to call on exit

165

- *args: Arguments for callback

166

- **kwargs: Keyword arguments for callback

167

168

Returns:

169

Callable - The callback function

170

"""

171

172

async def enter_context(self, cm):

173

"""

174

Enter context manager and add to stack.

175

176

Parameters:

177

- cm: AsyncContextManager[T] - Context manager to enter

178

179

Returns:

180

T - Result from context manager's __aenter__

181

"""

182

183

async def aclose(self):

184

"""Close all contexts in reverse order."""

185

186

async def __aenter__(self):

187

"""

188

Enter the exit stack context.

189

190

Returns:

191

ExitStack - This exit stack instance

192

"""

193

194

async def __aexit__(self, exc_type, exc_val, exc_tb):

195

"""

196

Exit all managed contexts in reverse order.

197

198

Parameters:

199

- exc_type: Exception type or None

200

- exc_val: Exception value or None

201

- exc_tb: Exception traceback or None

202

203

Returns:

204

bool - True if exception was handled

205

"""

206

```

207

208

## Usage Examples

209

210

### Custom Context Managers

211

```python

212

from asyncstdlib import contextmanager

213

import asyncio

214

215

@contextmanager

216

async def database_transaction():

217

"""Context manager for database transactions."""

218

print("BEGIN TRANSACTION")

219

try:

220

yield "transaction_handle"

221

except Exception:

222

print("ROLLBACK")

223

raise

224

else:

225

print("COMMIT")

226

227

async def transaction_example():

228

async with database_transaction() as tx:

229

print(f"Using {tx}")

230

# Automatic commit on success

231

232

try:

233

async with database_transaction() as tx:

234

print(f"Using {tx}")

235

raise ValueError("Something went wrong")

236

except ValueError:

237

pass # Automatic rollback on exception

238

```

239

240

### Context Manager as Decorator

241

```python

242

from asyncstdlib import contextmanager

243

244

@contextmanager

245

async def timing_context():

246

"""Context manager that measures execution time."""

247

import time

248

start = time.time()

249

try:

250

yield

251

finally:

252

end = time.time()

253

print(f"Execution took {end - start:.2f} seconds")

254

255

# Use as context manager

256

async def context_usage():

257

async with timing_context():

258

await asyncio.sleep(1) # "Execution took 1.00 seconds"

259

260

# Use as decorator (if inheriting from ContextDecorator)

261

@timing_context()

262

async def timed_function():

263

await asyncio.sleep(0.5) # "Execution took 0.50 seconds"

264

```

265

266

### Resource Management

267

```python

268

from asyncstdlib import closing, nullcontext

269

import aiofiles

270

271

async def resource_example():

272

# Automatic cleanup with closing

273

async with closing(await aiofiles.open("file.txt")) as file:

274

content = await file.read()

275

# File automatically closed on exit

276

277

# Conditional context manager

278

use_file = True

279

async with (aiofiles.open("data.txt") if use_file else nullcontext("default")) as resource:

280

if use_file:

281

data = await resource.read()

282

else:

283

data = resource # "default"

284

```

285

286

### Managing Multiple Contexts

287

```python

288

from asyncstdlib import ExitStack

289

import aiofiles

290

import aiohttp

291

292

async def multi_context_example():

293

async with ExitStack() as stack:

294

# Add multiple context managers

295

file1 = await stack.enter_context(aiofiles.open("input.txt"))

296

file2 = await stack.enter_context(aiofiles.open("output.txt", "w"))

297

session = await stack.enter_context(aiohttp.ClientSession())

298

299

# Add cleanup callback

300

stack.callback(lambda: print("All resources cleaned up"))

301

302

# Use all resources

303

data = await file1.read()

304

async with session.get("https://api.example.com/data") as resp:

305

api_data = await resp.text()

306

307

await file2.write(f"Combined: {data} + {api_data}")

308

309

# All contexts automatically exited in reverse order

310

# Callback executed last

311

```

312

313

### Transferring Contexts

314

```python

315

async def context_transfer():

316

stack1 = ExitStack()

317

318

async with stack1:

319

file1 = await stack1.enter_context(aiofiles.open("temp.txt", "w"))

320

await file1.write("test data")

321

322

# Transfer contexts to another stack

323

stack2 = stack1.pop_all()

324

325

# file1 is still open, managed by stack2

326

async with stack2:

327

# file1 closed here

328

pass

329

```

330

331

### Error Handling in Context Managers

332

```python

333

@contextmanager

334

async def error_handling_context():

335

"""Context manager with custom error handling."""

336

print("Setting up resource")

337

try:

338

yield "resource"

339

except ValueError as e:

340

print(f"Handling ValueError: {e}")

341

# Return True to suppress the exception

342

return True

343

except Exception as e:

344

print(f"Unexpected error: {e}")

345

# Re-raise unexpected exceptions

346

raise

347

finally:

348

print("Cleaning up resource")

349

350

async def error_example():

351

# ValueError is suppressed

352

async with error_handling_context() as resource:

353

raise ValueError("This will be handled")

354

355

print("Execution continues") # This runs because exception was suppressed

356

```