or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

commands-groups.mdcontext-management.mdexception-handling.mdformatting.mdindex.mdparameter-types.mdparameters.mdterminal-ui.mdtesting-support.md

context-management.mddocs/

0

# Context Management

1

2

Context objects that maintain state and configuration throughout command execution, enabling communication between commands and providing access to execution metadata.

3

4

## Capabilities

5

6

### Context Class

7

8

Core context object that maintains execution state and provides command coordination.

9

10

```python { .api }

11

class Context:

12

parent: Context | None

13

command: Command

14

info_name: str | None

15

params: dict[Any, Any]

16

args: list[str]

17

protected_args: list[str]

18

obj: Any

19

default_map: Mapping[str, Any] | None

20

invoked_subcommand: str | None

21

terminal_width: int | None

22

max_content_width: int | None

23

allow_extra_args: bool

24

allow_interspersed_args: bool

25

ignore_unknown_options: bool

26

help_option_names: list[str]

27

token_normalize_func: Callable[[str], str] | None

28

resilient_parsing: bool

29

auto_envvar_prefix: str | None

30

color: bool | None

31

32

def __init__(

33

self,

34

command: Command,

35

parent: Context | None = None,

36

info_name: str | None = None,

37

obj: Any | None = None,

38

auto_envvar_prefix: str | None = None,

39

default_map: Mapping[str, Any] | None = None,

40

terminal_width: int | None = None,

41

max_content_width: int | None = None,

42

resilient_parsing: bool = False,

43

allow_extra_args: bool | None = None,

44

allow_interspersed_args: bool | None = None,

45

ignore_unknown_options: bool | None = None,

46

help_option_names: list[str] | None = None,

47

token_normalize_func: Callable[[str], str] | None = None,

48

color: bool | None = None,

49

) -> None:

50

"""

51

Context for command execution state.

52

53

Parameters:

54

- command: Command being executed

55

- parent: Parent context for nested commands

56

- info_name: Command name for help/error messages

57

- obj: User object for passing data between commands

58

- auto_envvar_prefix: Prefix for automatic environment variables

59

- default_map: Default values mapping

60

- terminal_width: Terminal width for formatting

61

- max_content_width: Maximum content width

62

- resilient_parsing: Continue parsing despite errors

63

- allow_extra_args: Allow extra command arguments

64

- allow_interspersed_args: Allow interspersed arguments

65

- ignore_unknown_options: Ignore unknown options

66

- help_option_names: Names for help options

67

- token_normalize_func: Function to normalize option names

68

- color: Enable/disable colored output

69

"""

70

71

@property

72

def meta(self) -> dict[str, Any]:

73

"""

74

Dictionary for storing arbitrary metadata.

75

76

Returns:

77

Metadata dictionary

78

"""

79

80

@property

81

def command_path(self) -> str:

82

"""

83

Full command path from root to current command.

84

85

Returns:

86

Command path string

87

"""

88

89

def fail(self, message: str) -> NoReturn:

90

"""

91

Fail with an error message and exit.

92

93

Parameters:

94

- message: Error message

95

96

Usage:

97

if not os.path.exists(filename):

98

ctx.fail(f'File {filename} does not exist')

99

"""

100

101

def scope(self, cleanup: bool = True) -> ContextManager[Context]:

102

"""

103

Create a context manager that provides a new scope.

104

105

Parameters:

106

- cleanup: Whether to cleanup on exit

107

108

Returns:

109

Context manager for scoped execution

110

111

Usage:

112

with ctx.scope() as scope_ctx:

113

# Work in scoped context

114

scope_ctx.obj = some_data

115

"""

116

117

def make_formatter(self) -> HelpFormatter:

118

"""

119

Create a help formatter for this context.

120

121

Returns:

122

HelpFormatter instance

123

"""

124

125

def call_on_close(self, f: Callable[[], Any]) -> Callable[[], Any]:

126

"""

127

Register function to call when context closes.

128

129

Parameters:

130

- f: Function to call on close

131

132

Returns:

133

The registered function

134

135

Usage:

136

def cleanup():

137

# Cleanup resources

138

pass

139

140

ctx.call_on_close(cleanup)

141

"""

142

143

def close(self) -> None:

144

"""

145

Close the context and run cleanup callbacks.

146

147

Usage:

148

ctx.close() # Usually called automatically

149

"""

150

151

def abort(self) -> NoReturn:

152

"""

153

Abort command execution immediately.

154

155

Usage:

156

if not confirm_dangerous_operation():

157

ctx.abort()

158

"""

159

160

def exit(self, code: int | str = 0) -> NoReturn:

161

"""

162

Exit with specified code.

163

164

Parameters:

165

- code: Exit code (integer or string)

166

167

Usage:

168

if success:

169

ctx.exit(0)

170

else:

171

ctx.exit(1)

172

"""

173

174

def invoke(self, callback: Command | Callable[..., Any], *args: Any, **kwargs: Any) -> Any:

175

"""

176

Invoke another command or callback with current context.

177

178

Parameters:

179

- callback: Command or function to invoke

180

- *args: Positional arguments

181

- **kwargs: Keyword arguments

182

183

Returns:

184

Callback return value

185

186

Usage:

187

# Invoke another command

188

result = ctx.invoke(other_command, arg1='value')

189

190

# Invoke function with context

191

result = ctx.invoke(my_function, ctx, param1='value')

192

"""

193

194

def forward(self, callback: Command | Callable[..., Any], *args: Any, **kwargs: Any) -> Any:

195

"""

196

Forward to another command, replacing current context.

197

198

Parameters:

199

- callback: Command or function to forward to

200

- *args: Positional arguments

201

- **kwargs: Keyword arguments

202

203

Returns:

204

Callback return value

205

"""

206

207

def find_root(self) -> Context:

208

"""

209

Find the root context in the hierarchy.

210

211

Returns:

212

Root context

213

"""

214

215

def find_object(self, object_type: type) -> Any:

216

"""

217

Find object of specific type in context hierarchy.

218

219

Parameters:

220

- object_type: Type to search for

221

222

Returns:

223

Found object or None

224

"""

225

226

def ensure_object(self, object_type: type) -> Any:

227

"""

228

Ensure object of specific type exists in context.

229

230

Parameters:

231

- object_type: Type to ensure

232

233

Returns:

234

Found or created object

235

"""

236

237

def lookup_default(self, name: str) -> Any:

238

"""

239

Look up default value for parameter.

240

241

Parameters:

242

- name: Parameter name

243

244

Returns:

245

Default value or None

246

"""

247

248

def get_usage(self) -> str:

249

"""

250

Get usage information for current command.

251

252

Returns:

253

Usage string

254

"""

255

256

def get_help(self) -> str:

257

"""

258

Get help information for current command.

259

260

Returns:

261

Help string

262

"""

263

```

264

265

### Context Access Decorators

266

267

Decorators for accessing context and context objects in command functions.

268

269

```python { .api }

270

def pass_context(f: Callable) -> Callable:

271

"""

272

Decorator that passes the current context as first argument.

273

274

Parameters:

275

- f: Function to decorate

276

277

Returns:

278

Decorated function

279

280

Usage:

281

@click.command()

282

@click.pass_context

283

def my_command(ctx, other_args):

284

click.echo(f'Command path: {ctx.command_path}')

285

if ctx.parent:

286

click.echo('Has parent context')

287

"""

288

289

def pass_obj(f: Callable) -> Callable:

290

"""

291

Decorator that passes the context object as first argument.

292

293

Parameters:

294

- f: Function to decorate

295

296

Returns:

297

Decorated function

298

299

Usage:

300

@click.command()

301

@click.pass_obj

302

def my_command(obj, other_args):

303

click.echo(f'Object: {obj}')

304

"""

305

306

def make_pass_decorator(object_type: type, ensure: bool = False) -> Callable:

307

"""

308

Create a custom pass decorator for specific object types.

309

310

Parameters:

311

- object_type: Type of object to pass

312

- ensure: Create object if it doesn't exist

313

314

Returns:

315

Pass decorator function

316

317

Usage:

318

class Config:

319

def __init__(self):

320

self.debug = False

321

322

pass_config = click.make_pass_decorator(Config, ensure=True)

323

324

@click.command()

325

@pass_config

326

def debug_command(config):

327

config.debug = True

328

"""

329

```

330

331

### Global Context Functions

332

333

Functions for managing the global context stack.

334

335

```python { .api }

336

def get_current_context(silent: bool = False) -> Context:

337

"""

338

Get the current execution context.

339

340

Parameters:

341

- silent: Return None instead of raising if no context

342

343

Returns:

344

Current context

345

346

Raises:

347

RuntimeError: If no context and not silent

348

349

Usage:

350

def helper_function():

351

ctx = click.get_current_context()

352

ctx.fail('Something went wrong')

353

"""

354

355

def push_context(ctx: Context) -> None:

356

"""

357

Push a context onto the stack.

358

359

Parameters:

360

- ctx: Context to push

361

362

Usage:

363

# Rarely used directly - handled by click framework

364

click.push_context(new_context)

365

"""

366

367

def pop_context() -> None:

368

"""

369

Pop the current context from the stack.

370

371

Usage:

372

# Rarely used directly - handled by click framework

373

click.pop_context()

374

"""

375

```

376

377

### Context Utilities

378

379

Utility functions for context management.

380

381

```python { .api }

382

def resolve_color_default(color: bool | None = None) -> bool | None:

383

"""

384

Resolve color default based on context and environment.

385

386

Parameters:

387

- color: Explicit color setting

388

389

Returns:

390

Resolved color setting

391

392

Usage:

393

# Used internally by click for color handling

394

color_enabled = click.resolve_color_default(color)

395

"""

396

```

397

398

### Context Usage Patterns

399

400

**Sharing Data Between Commands:**

401

402

```python

403

@click.group()

404

@click.option('--config', type=click.Path(exists=True))

405

@click.pass_context

406

def cli(ctx, config):

407

"""Main CLI with shared configuration."""

408

ctx.ensure_object(dict)

409

if config:

410

with open(config) as f:

411

ctx.obj = json.load(f)

412

else:

413

ctx.obj = {}

414

415

@cli.command()

416

@click.pass_obj

417

def status(config):

418

"""Show status using shared config."""

419

debug = config.get('debug', False)

420

if debug:

421

click.echo('Debug mode enabled')

422

click.echo('Status: OK')

423

```

424

425

**Custom Context Objects:**

426

427

```python

428

class AppContext:

429

def __init__(self):

430

self.debug = False

431

self.database_url = None

432

433

def get_db_connection(self):

434

# Database connection logic

435

pass

436

437

pass_app_context = click.make_pass_decorator(AppContext, ensure=True)

438

439

@click.group()

440

@click.option('--debug', is_flag=True)

441

@pass_app_context

442

def cli(app_ctx, debug):

443

app_ctx.debug = debug

444

445

@cli.command()

446

@pass_app_context

447

def migrate(app_ctx):

448

db = app_ctx.get_db_connection()

449

if app_ctx.debug:

450

click.echo('Running migrations in debug mode')

451

```

452

453

**Error Handling with Context:**

454

455

```python

456

@click.command()

457

@click.argument('filename')

458

@click.pass_context

459

def process_file(ctx, filename):

460

if not os.path.exists(filename):

461

ctx.fail(f'File {filename} does not exist')

462

463

try:

464

# Process file

465

with open(filename) as f:

466

data = f.read()

467

except PermissionError:

468

ctx.fail(f'Permission denied: {filename}')

469

except Exception as e:

470

ctx.fail(f'Error processing file: {e}')

471

```

472

473

## Utility Functions

474

475

Internal utility functions for context and parameter processing.

476

477

```python { .api }

478

def invoke_param_callback(

479

callback: Callable[[Context, Parameter, str | None], Any],

480

ctx: Context,

481

param: Parameter,

482

value: str | None,

483

) -> Any:

484

"""

485

Invoke a parameter callback function safely.

486

487

Parameters:

488

- callback: Parameter callback function

489

- ctx: Current context

490

- param: Parameter being processed

491

- value: Parameter value

492

493

Returns:

494

Result of callback invocation

495

496

Usage:

497

# Internal use - rarely needed in user code

498

result = click.invoke_param_callback(my_callback, ctx, param, value)

499

"""

500

501

def augment_usage_errors(

502

ctx: Context,

503

param: Parameter | None = None

504

) -> ContextManager[None]:

505

"""

506

Context manager to enhance usage error messages.

507

508

Parameters:

509

- ctx: Current context

510

- param: Parameter that caused the error (optional)

511

512

Usage:

513

# Internal use - enhances error reporting

514

with click.augment_usage_errors(ctx, param):

515

# Parameter processing that might fail

516

process_parameter_value()

517

"""

518

519

def iter_params_for_processing(

520

invocation_order: Sequence[Parameter],

521

declaration_order: Iterable[Parameter],

522

) -> Iterable[Parameter]:

523

"""

524

Iterate parameters in proper processing order.

525

526

Parameters:

527

- invocation_order: Order parameters were invoked

528

- declaration_order: Order parameters were declared

529

530

Yields:

531

Parameters in processing order

532

533

Usage:

534

# Internal use - parameter processing order

535

for param in click.iter_params_for_processing(invoked, declared):

536

process_parameter(param)

537

"""

538

```