or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

agents.mdbreaking-changes.mdcli.mddocstrings.mdextensions.mdindex.mdloaders.mdmodels.mdserialization.md

agents.mddocs/

0

# Agents

1

2

Analysis agents for extracting API information from Python code. Griffe provides two complementary approaches: static analysis through AST parsing (`visit`) and dynamic analysis through runtime inspection (`inspect`). These agents form the foundation of Griffe's code analysis capabilities.

3

4

## Capabilities

5

6

### Static Analysis (Visitor)

7

8

Parse and analyze Python source code using Abstract Syntax Tree (AST) parsing.

9

10

```python { .api }

11

def visit(

12

module: Module,

13

filepath: str | Path,

14

code: str | None = None,

15

extensions: Extensions | None = None,

16

parent: Module | None = None,

17

in_try_block: bool = False,

18

) -> Module:

19

"""

20

Parse and visit a module file using static analysis.

21

22

Creates Griffe objects from AST nodes by parsing Python source code.

23

This approach analyzes code structure without executing it, making it

24

safe for analyzing any Python code.

25

26

Args:

27

module: Module object to populate with visited data

28

filepath: Path to the Python file to analyze

29

code: Source code string (if None, reads from filepath)

30

extensions: Extensions to apply during visiting

31

parent: Parent module for submodule analysis

32

in_try_block: Whether this module is in a try block

33

34

Returns:

35

Module: The populated module with analyzed contents

36

37

Raises:

38

LoadingError: If file cannot be read or parsed

39

40

Examples:

41

Visit a module file:

42

>>> module = griffe.Module("mymodule")

43

>>> visited = griffe.visit(module, "path/to/mymodule.py")

44

45

Visit with custom code:

46

>>> code = "def hello(): return 'world'"

47

>>> visited = griffe.visit(module, "virtual.py", code=code)

48

"""

49

50

class Visitor:

51

"""

52

AST visitor class that traverses Python source code.

53

54

Creates Griffe objects from AST nodes by walking through

55

the abstract syntax tree and extracting relevant information.

56

"""

57

58

def __init__(

59

self,

60

module: Module,

61

filepath: str | Path,

62

code: str,

63

extensions: Extensions | None = None,

64

parent: Module | None = None,

65

in_try_block: bool = False,

66

) -> None:

67

"""

68

Initialize the visitor.

69

70

Args:

71

module: Module to populate

72

filepath: Path to source file

73

code: Source code to parse

74

extensions: Extensions to apply

75

parent: Parent module

76

in_try_block: Whether in try block context

77

"""

78

79

def visit(self) -> None:

80

"""

81

Visit the module and populate it with objects.

82

83

Parses the source code and creates appropriate Griffe objects

84

for all discovered Python constructs.

85

"""

86

87

def visit_module(self, node: ast.Module) -> None:

88

"""Visit a module AST node."""

89

90

def visit_classdef(self, node: ast.ClassDef) -> None:

91

"""Visit a class definition AST node."""

92

93

def visit_functiondef(self, node: ast.FunctionDef | ast.AsyncFunctionDef) -> None:

94

"""Visit a function definition AST node."""

95

96

def visit_assign(self, node: ast.Assign) -> None:

97

"""Visit an assignment AST node."""

98

99

def visit_annassign(self, node: ast.AnnAssign) -> None:

100

"""Visit an annotated assignment AST node."""

101

```

102

103

### Dynamic Analysis (Inspector)

104

105

Inspect live Python objects at runtime to extract API information.

106

107

```python { .api }

108

def inspect(

109

module_name: str,

110

filepath: str | Path | None = None,

111

parent: Module | None = None,

112

) -> Module:

113

"""

114

Inspect a module dynamically at runtime.

115

116

Creates Griffe objects from live Python objects by importing

117

and examining modules at runtime. This approach can access

118

runtime-generated attributes and dynamic behavior.

119

120

Args:

121

module_name: Name of module to inspect

122

filepath: Path to module file (optional)

123

parent: Parent module for submodules

124

125

Returns:

126

Module: Module populated with inspected data

127

128

Raises:

129

UnimportableModuleError: If module cannot be imported

130

131

Examples:

132

Inspect an installed package:

133

>>> module = griffe.inspect("requests")

134

135

Inspect with specific filepath:

136

>>> module = griffe.inspect("mymodule", filepath="path/to/mymodule.py")

137

"""

138

139

class Inspector:

140

"""

141

Runtime inspector class that examines live Python objects.

142

143

Creates Griffe representations by importing modules and

144

using Python's introspection capabilities to extract information.

145

"""

146

147

def __init__(

148

self,

149

module_name: str,

150

filepath: str | Path | None = None,

151

parent: Module | None = None,

152

) -> None:

153

"""

154

Initialize the inspector.

155

156

Args:

157

module_name: Name of module to inspect

158

filepath: Path to module file

159

parent: Parent module

160

"""

161

162

def inspect(self) -> Module:

163

"""

164

Inspect the module and return populated Module object.

165

166

Returns:

167

Module: Module with inspected contents

168

"""

169

170

def inspect_module(self, module: types.ModuleType) -> Module:

171

"""Inspect a module object."""

172

173

def inspect_class(self, class_obj: type, parent: Module | Class) -> Class:

174

"""Inspect a class object."""

175

176

def inspect_function(

177

self,

178

func_obj: types.FunctionType | types.MethodType,

179

parent: Module | Class

180

) -> Function:

181

"""Inspect a function or method object."""

182

183

def inspect_attribute(

184

self,

185

name: str,

186

value: Any,

187

parent: Module | Class

188

) -> Attribute:

189

"""Inspect an attribute."""

190

```

191

192

## Decorator Recognition

193

194

Built-in decorator sets that Griffe recognizes and handles specially.

195

196

```python { .api }

197

builtin_decorators: set[str]

198

"""Set of built-in Python decorators recognized by Griffe."""

199

200

stdlib_decorators: set[str]

201

"""Set of standard library decorators recognized by Griffe."""

202

203

typing_overload: str

204

"""Reference to typing.overload decorator for function overloads."""

205

```

206

207

## AST Utilities

208

209

Helper functions for working with Abstract Syntax Tree nodes during static analysis.

210

211

```python { .api }

212

def ast_children(node: ast.AST) -> Iterator[ast.AST]:

213

"""

214

Get child nodes of an AST node.

215

216

Args:

217

node: AST node to examine

218

219

Yields:

220

ast.AST: Child nodes

221

"""

222

223

def ast_first_child(node: ast.AST) -> ast.AST | None:

224

"""

225

Get the first child node of an AST node.

226

227

Args:

228

node: AST node to examine

229

230

Returns:

231

ast.AST | None: First child or None if no children

232

"""

233

234

def ast_last_child(node: ast.AST) -> ast.AST | None:

235

"""

236

Get the last child node of an AST node.

237

238

Args:

239

node: AST node to examine

240

241

Returns:

242

ast.AST | None: Last child or None if no children

243

"""

244

245

def ast_next(node: ast.AST) -> ast.AST | None:

246

"""

247

Get the next sibling of an AST node.

248

249

Args:

250

node: AST node to examine

251

252

Returns:

253

ast.AST | None: Next sibling or None

254

"""

255

256

def ast_previous(node: ast.AST) -> ast.AST | None:

257

"""

258

Get the previous sibling of an AST node.

259

260

Args:

261

node: AST node to examine

262

263

Returns:

264

ast.AST | None: Previous sibling or None

265

"""

266

267

def ast_siblings(node: ast.AST) -> Iterator[ast.AST]:

268

"""

269

Get all siblings of an AST node.

270

271

Args:

272

node: AST node to examine

273

274

Yields:

275

ast.AST: Sibling nodes

276

"""

277

```

278

279

## Node Processing Functions

280

281

Functions for extracting specific information from AST nodes.

282

283

```python { .api }

284

def get_docstring(node: ast.AST) -> str | None:

285

"""

286

Extract docstring from an AST node.

287

288

Args:

289

node: AST node (function, class, or module)

290

291

Returns:

292

str | None: Docstring text or None if not found

293

"""

294

295

def get_parameters(node: ast.FunctionDef | ast.AsyncFunctionDef) -> Parameters:

296

"""

297

Extract function parameters from an AST node.

298

299

Args:

300

node: Function definition AST node

301

302

Returns:

303

Parameters: Extracted parameters

304

"""

305

306

def get_name(node: ast.AST) -> str | None:

307

"""

308

Get name from an assignment AST node.

309

310

Args:

311

node: Assignment AST node

312

313

Returns:

314

str | None: Variable name or None

315

"""

316

317

def get_names(node: ast.AST) -> list[str]:

318

"""

319

Get multiple names from an assignment AST node.

320

321

Args:

322

node: Assignment AST node

323

324

Returns:

325

list[str]: List of variable names

326

"""

327

328

def get_value(node: ast.AST) -> Expr | None:

329

"""

330

Extract value from an AST node as a Griffe expression.

331

332

Args:

333

node: AST node with value

334

335

Returns:

336

Expr | None: Griffe expression or None

337

"""

338

339

def safe_get_value(node: ast.AST) -> Expr | None:

340

"""

341

Safely extract value from AST node, returns None on error.

342

343

Args:

344

node: AST node with value

345

346

Returns:

347

Expr | None: Griffe expression or None if extraction fails

348

"""

349

```

350

351

## Usage Examples

352

353

### Static Analysis with Visit

354

355

```python

356

import griffe

357

358

# Create a module and visit source code

359

module = griffe.Module("mymodule")

360

361

# Visit from file

362

visited_module = griffe.visit(

363

module=module,

364

filepath="path/to/mymodule.py"

365

)

366

367

# Visit from code string

368

code = '''

369

def hello(name: str) -> str:

370

"""Say hello to someone."""

371

return f"Hello, {name}!"

372

373

class Greeter:

374

"""A class for greeting."""

375

376

def __init__(self, greeting: str = "Hello"):

377

self.greeting = greeting

378

379

def greet(self, name: str) -> str:

380

return f"{self.greeting}, {name}!"

381

'''

382

383

visited_from_code = griffe.visit(

384

module=griffe.Module("example"),

385

filepath="example.py",

386

code=code

387

)

388

389

print("Functions:", list(visited_from_code.functions.keys()))

390

print("Classes:", list(visited_from_code.classes.keys()))

391

```

392

393

### Dynamic Analysis with Inspect

394

395

```python

396

import griffe

397

398

# Inspect installed packages

399

requests_module = griffe.inspect("requests")

400

print("Requests classes:", list(requests_module.classes.keys()))

401

402

# Inspect with error handling

403

try:

404

custom_module = griffe.inspect("my_custom_module")

405

except griffe.UnimportableModuleError as e:

406

print(f"Cannot import module: {e}")

407

408

# Compare static vs dynamic analysis

409

static_module = griffe.visit(

410

griffe.Module("example"),

411

"example.py"

412

)

413

414

dynamic_module = griffe.inspect("example")

415

416

print("Static analysis found:", len(static_module.functions))

417

print("Dynamic analysis found:", len(dynamic_module.functions))

418

```

419

420

### Using Both Agents Together

421

422

```python

423

import griffe

424

425

# Load using both agents (this is what load() does internally)

426

loader = griffe.GriffeLoader(allow_inspection=True)

427

428

# This will try static analysis first, fall back to inspection

429

module = loader.load("some_package")

430

431

# Manual combination

432

try:

433

# Try static analysis first

434

static_result = griffe.visit(

435

griffe.Module("mypackage"),

436

"path/to/mypackage/__init__.py"

437

)

438

except Exception:

439

# Fall back to dynamic analysis

440

static_result = griffe.inspect("mypackage")

441

```

442

443

### Working with Extensions

444

445

```python

446

import griffe

447

448

# Load extensions for enhanced analysis

449

extensions = griffe.load_extensions(["dataclasses"])

450

451

# Use with visitor

452

module = griffe.Module("mymodule")

453

visited = griffe.visit(

454

module=module,

455

filepath="mymodule.py",

456

extensions=extensions

457

)

458

459

# Custom visitor with extensions

460

visitor = griffe.Visitor(

461

module=module,

462

filepath="mymodule.py",

463

code=source_code,

464

extensions=extensions

465

)

466

visitor.visit()

467

```

468

469

### AST Analysis Utilities

470

471

```python

472

import ast

473

import griffe

474

475

# Parse Python code

476

source = "def hello(): return 'world'"

477

tree = ast.parse(source)

478

479

# Use AST utilities

480

for node in griffe.ast_children(tree):

481

if isinstance(node, ast.FunctionDef):

482

print(f"Function: {node.name}")

483

484

# Get function details

485

docstring = griffe.get_docstring(node)

486

parameters = griffe.get_parameters(node)

487

488

print(f" Docstring: {docstring}")

489

print(f" Parameters: {[p.name for p in parameters]}")

490

```

491

492

## Types

493

494

```python { .api }

495

import ast

496

import types

497

from pathlib import Path

498

from typing import Iterator, Any

499

500

# AST node types from Python's ast module

501

AST = ast.AST

502

Module = ast.Module

503

ClassDef = ast.ClassDef

504

FunctionDef = ast.FunctionDef

505

AsyncFunctionDef = ast.AsyncFunctionDef

506

507

# Runtime types from Python's types module

508

ModuleType = types.ModuleType

509

FunctionType = types.FunctionType

510

MethodType = types.MethodType

511

512

# Griffe types

513

from griffe import Module, Class, Function, Attribute, Extensions, Parameters, Expr

514

515

# Parameter extraction type

516

ParametersType = Parameters

517

```