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

index.mddocs/

0

# Griffe

1

2

Griffe is a comprehensive Python library that extracts signatures and API information from entire Python programs. It provides both static analysis (AST parsing) and dynamic analysis (runtime inspection) capabilities to generate API documentation, detect breaking changes, and support development workflows requiring detailed code structure analysis.

3

4

## Package Information

5

6

- **Package Name**: griffe

7

- **Language**: Python

8

- **Installation**: `pip install griffe`

9

- **CLI Tool**: Available as `griffe` command-line tool

10

- **Git Support**: `pip install griffe[pypi]` for enhanced Git/PyPI integration

11

12

## Core Imports

13

14

```python

15

import griffe

16

```

17

18

Common imports for specific functionality:

19

20

```python

21

# Loading packages

22

from griffe import load, load_git, load_pypi

23

24

# CLI functions

25

from griffe import main, check, dump

26

27

# Core models

28

from griffe import Module, Class, Function, Attribute, Alias

29

30

# Analysis agents

31

from griffe import visit, inspect

32

33

# Breaking change detection

34

from griffe import find_breaking_changes, Breakage

35

36

# Docstring parsing

37

from griffe import parse, parse_auto, parse_google, parse_numpy, parse_sphinx

38

39

# Serialization

40

from griffe import JSONEncoder, json_decoder

41

```

42

43

## Basic Usage

44

45

### Loading Python Package Data

46

47

```python

48

import griffe

49

50

# Load a package from the current environment

51

package = griffe.load("requests")

52

print(f"Package: {package.name}")

53

print(f"Modules: {list(package.modules.keys())}")

54

55

# Load from specific Git reference

56

old_version = griffe.load_git("mypackage", ref="v1.0.0")

57

current_version = griffe.load("mypackage")

58

59

# Load from PyPI

60

pypi_package = griffe.load_pypi("django", "Django", "4.2.0")

61

```

62

63

### Detecting API Breaking Changes

64

65

```python

66

import griffe

67

68

# Compare two versions of a package

69

old_api = griffe.load_git("mypackage", ref="v1.0.0")

70

new_api = griffe.load("mypackage")

71

72

# Find breaking changes

73

breakages = griffe.find_breaking_changes(old_api, new_api)

74

for breakage in breakages:

75

print(f"Breaking change: {breakage}")

76

```

77

78

### CLI Usage

79

80

```bash

81

# Dump package API as JSON

82

griffe dump fastapi httpx

83

84

# Check for breaking changes

85

griffe check mypackage --verbose

86

87

# With src layout

88

griffe check --search src mypackage --verbose

89

```

90

91

## Architecture

92

93

Griffe is built around several key architectural concepts:

94

95

- **Agents**: Static analysis via `visit()` (AST parsing) and dynamic analysis via `inspect()` (runtime inspection)

96

- **Models**: Core object representations (`Module`, `Class`, `Function`, `Attribute`, `Alias`) that form the API structure

97

- **Loaders**: High-level functions (`load`, `load_git`, `load_pypi`) that orchestrate the analysis process

98

- **Extensions**: Pluggable system for custom analysis and processing during code examination

99

- **Expressions**: Abstract syntax tree representations of Python code snippets (decorators, annotations, etc.)

100

101

## Capabilities

102

103

### CLI Entry Points

104

105

Command-line interface functions that can be called from Python or as CLI commands.

106

107

```python { .api }

108

def main() -> int:

109

"""

110

Run the main griffe program.

111

112

Returns:

113

int: Exit code (0 for success)

114

"""

115

116

def check(*args, **kwargs) -> int:

117

"""

118

Check for API breaking changes between versions.

119

120

Returns:

121

int: Exit code (0 if no breaking changes)

122

"""

123

124

def dump(*args, **kwargs) -> int:

125

"""

126

Load packages and dump API data as JSON.

127

128

Returns:

129

int: Exit code (0 for success)

130

"""

131

```

132

133

[CLI Functions](./cli.md)

134

135

### Package Loading

136

137

High-level functions for loading Python packages and modules from different sources.

138

139

```python { .api }

140

def load(

141

objspec: str | Path | None = None,

142

/,

143

*,

144

submodules: bool = True,

145

try_relative_path: bool = True,

146

extensions: Extensions | None = None,

147

search_paths: Sequence[str | Path] | None = None,

148

docstring_parser: DocstringStyle | Parser | None = None,

149

docstring_options: dict[str, Any] | None = None,

150

lines_collection: LinesCollection | None = None,

151

modules_collection: ModulesCollection | None = None,

152

allow_inspection: bool = True,

153

force_inspection: bool = False,

154

store_source: bool = True,

155

find_stubs_package: bool = False,

156

resolve_aliases: bool = False,

157

resolve_external: bool | None = None,

158

resolve_implicit: bool = False,

159

) -> Object | Alias: ...

160

161

def load_git(

162

objspec: str,

163

ref: str = "HEAD",

164

*,

165

repo: str | Path = ".",

166

submodules: bool = True,

167

**load_kwargs: Any,

168

) -> Object | Alias: ...

169

170

def load_pypi(

171

package: str,

172

distribution: str,

173

version_spec: str,

174

*,

175

submodules: bool = True,

176

extensions: Extensions | None = None,

177

search_paths: Sequence[str | Path] | None = None,

178

docstring_parser: DocstringStyle | Parser | None = None,

179

docstring_options: dict[str, Any] | None = None,

180

lines_collection: LinesCollection | None = None,

181

modules_collection: ModulesCollection | None = None,

182

allow_inspection: bool = True,

183

force_inspection: bool = False,

184

find_stubs_package: bool = False,

185

) -> Object | Alias: ...

186

```

187

188

[Loaders](./loaders.md)

189

190

### Core Object Models

191

192

The primary classes representing Python API elements.

193

194

```python { .api }

195

class Object:

196

"""Base class for all Griffe objects."""

197

198

@property

199

def name(self) -> str: ...

200

201

@property

202

def path(self) -> str: ...

203

204

def serialize(self, **kwargs: Any) -> dict[str, Any]: ...

205

206

class Module(Object):

207

"""A Python module."""

208

209

@property

210

def filepath(self) -> Path | None: ...

211

212

@property

213

def modules(self) -> dict[str, Module]: ...

214

215

@property

216

def classes(self) -> dict[str, Class]: ...

217

218

@property

219

def functions(self) -> dict[str, Function]: ...

220

221

@property

222

def attributes(self) -> dict[str, Attribute]: ...

223

224

class Class(Object):

225

"""A Python class."""

226

227

@property

228

def bases(self) -> list[Expr]: ...

229

230

@property

231

def decorators(self) -> list[Decorator]: ...

232

233

@property

234

def methods(self) -> dict[str, Function]: ...

235

236

class Function(Object):

237

"""A Python function or method."""

238

239

@property

240

def parameters(self) -> Parameters: ...

241

242

@property

243

def returns(self) -> Expr | None: ...

244

245

@property

246

def decorators(self) -> list[Decorator]: ...

247

248

class Attribute(Object):

249

"""A Python attribute."""

250

251

@property

252

def annotation(self) -> Expr | None: ...

253

254

@property

255

def value(self) -> Expr | None: ...

256

257

class Alias(Object):

258

"""An alias or import reference to an object."""

259

260

@property

261

def target_path(self) -> str: ...

262

263

def resolve(self) -> Object | None: ...

264

```

265

266

[Models](./models.md)

267

268

### Analysis Agents

269

270

Static and dynamic analysis functions for extracting API information.

271

272

```python { .api }

273

def visit(

274

module: Module,

275

filepath: str | Path,

276

code: str | None = None,

277

extensions: Extensions | None = None,

278

parent: Module | None = None,

279

in_try_block: bool = False,

280

) -> Module: ...

281

282

def inspect(

283

module_name: str,

284

filepath: str | Path | None = None,

285

parent: Module | None = None,

286

) -> Module: ...

287

```

288

289

[Agents](./agents.md)

290

291

### API Breakage Detection

292

293

Functions and classes for detecting breaking changes between API versions.

294

295

```python { .api }

296

def find_breaking_changes(

297

old_object: Object,

298

new_object: Object,

299

**kwargs: Any,

300

) -> Iterator[Breakage]: ...

301

302

class Breakage:

303

"""Base class for API breakages."""

304

305

@property

306

def kind(self) -> BreakageKind: ...

307

308

@property

309

def object_path(self) -> str: ...

310

311

class ObjectRemovedBreakage(Breakage):

312

"""A public object was removed."""

313

314

class ParameterAddedRequiredBreakage(Breakage):

315

"""A required parameter was added to a function."""

316

317

class ReturnChangedTypeBreakage(Breakage):

318

"""A function's return type annotation changed."""

319

```

320

321

[Breaking Changes](./breaking-changes.md)

322

323

### Serialization

324

325

JSON encoding and decoding for Griffe objects.

326

327

```python { .api }

328

class JSONEncoder(json.JSONEncoder):

329

"""JSON encoder for Griffe objects."""

330

331

def default(self, obj: Any) -> Any: ...

332

333

def json_decoder(dct: dict[str, Any]) -> dict[str, Any] | Object:

334

"""

335

Decode Griffe objects from JSON.

336

337

Args:

338

dct: Dictionary from JSON decoder

339

340

Returns:

341

Decoded object or dictionary

342

"""

343

```

344

345

[Serialization](./serialization.md)

346

347

### Docstring Parsing

348

349

Comprehensive docstring parsing supporting multiple formats.

350

351

```python { .api }

352

def parse(

353

text: str,

354

parser: Parser | str | None = None,

355

**options: Any,

356

) -> list[DocstringSection]: ...

357

358

def parse_auto(text: str, **options: Any) -> list[DocstringSection]: ...

359

360

def parse_google(text: str, **options: Any) -> list[DocstringSection]: ...

361

362

def parse_numpy(text: str, **options: Any) -> list[DocstringSection]: ...

363

364

def parse_sphinx(text: str, **options: Any) -> list[DocstringSection]: ...

365

```

366

367

[Docstrings](./docstrings.md)

368

369

### Extensions

370

371

Extensible plugin system for custom analysis.

372

373

```python { .api }

374

class Extension:

375

"""Base class for Griffe extensions."""

376

377

def on_package_loaded(self, *, pkg: Module) -> None: ...

378

379

def on_module_loaded(self, *, mod: Module) -> None: ...

380

381

def on_class_loaded(self, *, cls: Class) -> None: ...

382

383

def on_function_loaded(self, *, func: Function) -> None: ...

384

385

def load_extensions(

386

extensions: list[LoadableExtensionType] | None = None

387

) -> Extensions: ...

388

```

389

390

[Extensions](./extensions.md)

391

392

## Types

393

394

### Core Type Aliases

395

396

```python { .api }

397

from pathlib import Path

398

from typing import Any, Sequence, IO

399

400

# Collection types

401

LinesCollection = dict[str, dict[int, str]]

402

ModulesCollection = dict[str, Module]

403

Extensions = dict[str, Extension]

404

405

# Docstring and parser types

406

DocstringStyle = str

407

ExplanationStyle = str

408

```

409

410

### Core Enumerations

411

412

```python { .api }

413

from enum import Enum

414

415

class Kind(Enum):

416

"""Object kinds."""

417

MODULE = "module"

418

CLASS = "class"

419

FUNCTION = "function"

420

ATTRIBUTE = "attribute"

421

422

class ParameterKind(Enum):

423

"""Parameter kinds."""

424

POSITIONAL_ONLY = 0

425

POSITIONAL_OR_KEYWORD = 1

426

VAR_POSITIONAL = 2

427

KEYWORD_ONLY = 3

428

VAR_KEYWORD = 4

429

430

class Parser(Enum):

431

"""Docstring parser types."""

432

AUTO = "auto"

433

GOOGLE = "google"

434

NUMPY = "numpy"

435

SPHINX = "sphinx"

436

437

class BreakageKind(Enum):

438

"""API breakage types."""

439

OBJECT_REMOVED = "object_removed"

440

PARAMETER_ADDED_REQUIRED = "parameter_added_required"

441

PARAMETER_REMOVED = "parameter_removed"

442

RETURN_CHANGED_TYPE = "return_changed_type"

443

```

444

445

### Parameter Types

446

447

```python { .api }

448

class Parameter:

449

"""A function parameter."""

450

451

def __init__(

452

self,

453

name: str,

454

annotation: Expr | None = None,

455

default: Expr | None = None,

456

kind: ParameterKind = ParameterKind.POSITIONAL_OR_KEYWORD,

457

) -> None: ...

458

459

@property

460

def name(self) -> str: ...

461

462

@property

463

def annotation(self) -> Expr | None: ...

464

465

@property

466

def default(self) -> Expr | None: ...

467

468

class Parameters:

469

"""Container for function parameters."""

470

471

def __iter__(self) -> Iterator[Parameter]: ...

472

473

def __getitem__(self, key: int | str) -> Parameter: ...

474

475

def __len__(self) -> int: ...

476

```

477

478

### Expression Types

479

480

```python { .api }

481

class Expr:

482

"""Base expression class."""

483

484

def __str__(self) -> str: ...

485

486

class ExprName(Expr):

487

"""A name expression."""

488

489

def __init__(self, name: str) -> None: ...

490

491

class ExprAttribute(Expr):

492

"""An attribute access expression like a.b."""

493

494

def __init__(self, value: Expr, attr: str) -> None: ...

495

496

class ExprCall(Expr):

497

"""A function call expression."""

498

499

def __init__(

500

self,

501

function: Expr,

502

arguments: list[Expr] | None = None,

503

) -> None: ...

504

```