or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

ast-visitor.mdbadge-generation.mdcli-interface.mdconfiguration.mdcoverage-analysis.mdindex.mdutilities.md

coverage-analysis.mddocs/

0

# Coverage Analysis

1

2

Core functionality for analyzing docstring coverage in Python codebases. The coverage analysis engine traverses Python Abstract Syntax Trees (AST) to identify missing docstrings across modules, classes, functions, and methods.

3

4

## Capabilities

5

6

### Main Coverage Class

7

8

The primary class for running docstring coverage analysis on Python files and directories.

9

10

```python { .api }

11

class InterrogateCoverage:

12

"""Main class for analyzing docstring coverage."""

13

14

# Class constants

15

COMMON_EXCLUDE: List[str] = [".tox", ".venv", "venv", ".git", ".hg"]

16

VALID_EXT: List[str] = [".py", ".pyi"]

17

18

def __init__(self, paths, conf=None, excluded=None, extensions=None):

19

"""

20

Initialize coverage analyzer.

21

22

Args:

23

paths: List of file/directory paths to analyze

24

conf: Configuration object with analysis options (optional)

25

excluded: Tuple of files and directories to exclude (optional)

26

extensions: Set of file extensions to analyze (optional)

27

"""

28

29

def get_filenames_from_paths(self) -> List[str]:

30

"""

31

Get all Python filenames from configured paths.

32

33

Returns:

34

List[str]: Python file paths to analyze

35

"""

36

37

def get_coverage(self) -> InterrogateResults:

38

"""

39

Analyze docstring coverage for configured paths.

40

41

Returns:

42

InterrogateResults: Aggregated coverage results

43

"""

44

45

def print_results(self, results: InterrogateResults, output_file: Optional[str] = None) -> None:

46

"""

47

Print formatted coverage results.

48

49

Args:

50

results: Coverage analysis results

51

output_file: Optional file path for output (defaults to stdout)

52

"""

53

```

54

55

### Results Classes

56

57

Data structures for storing and managing coverage analysis results.

58

59

```python { .api }

60

class BaseInterrogateResult:

61

"""Base class for coverage results."""

62

63

total: int # Total number of items analyzed

64

covered: int # Number of items with docstrings

65

missing: int # Number of items missing docstrings

66

perc_covered: float # Percentage coverage (0-100)

67

68

class InterrogateFileResult(BaseInterrogateResult):

69

"""Coverage results for a single file."""

70

71

filename: str # Path to analyzed file

72

ignore_module: bool # Whether module-level docstring was ignored

73

nodes: List[CovNode] # List of analyzed AST nodes

74

75

def combine(self) -> None:

76

"""

77

Tally results from each AST node visited.

78

79

Updates the total, covered, and missing counts based on nodes.

80

"""

81

82

class InterrogateResults(BaseInterrogateResult):

83

"""Aggregated coverage results for all analyzed files."""

84

85

ret_code: int # Exit code based on coverage

86

file_results: Dict[str, InterrogateFileResult] # Per-file results

87

88

def combine(self) -> None:

89

"""

90

Tally results from each file.

91

92

Updates the total, covered, and missing counts from all file results.

93

"""

94

```

95

96

### AST Coverage Nodes

97

98

Data structures representing coverage information for individual code elements.

99

100

```python { .api }

101

class CovNode:

102

"""Coverage information for an AST node."""

103

104

name: str # Name of the code element

105

path: str # File path containing the element

106

level: int # Nesting level (0 = module, 1 = class/function, etc.)

107

lineno: int # Line number in source file

108

covered: bool # Whether element has docstring

109

node_type: str # Type of AST node ("module", "class", "function", "method")

110

is_nested_func: bool # Whether function is nested inside another function

111

is_nested_cls: bool # Whether class is nested inside another class

112

parent: Optional[CovNode] # Parent node (for nested elements)

113

```

114

115

### AST Visitor

116

117

The visitor class that traverses Python AST to collect docstring coverage information.

118

119

```python { .api }

120

class CoverageVisitor(ast.NodeVisitor):

121

"""AST visitor for collecting docstring coverage data."""

122

123

def __init__(self, filename: str, config: InterrogateConfig):

124

"""

125

Initialize AST visitor.

126

127

Args:

128

filename: Path to file being analyzed

129

config: Configuration with analysis options

130

"""

131

132

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

133

"""Visit module-level node."""

134

135

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

136

"""Visit class definition node."""

137

138

def visit_FunctionDef(self, node: ast.FunctionDef) -> None:

139

"""Visit function definition node."""

140

141

def visit_AsyncFunctionDef(self, node: ast.AsyncFunctionDef) -> None:

142

"""Visit async function definition node."""

143

```

144

145

## Usage Examples

146

147

### Basic Coverage Analysis

148

149

```python

150

from interrogate.coverage import InterrogateCoverage

151

from interrogate.config import InterrogateConfig

152

153

# Configure analysis

154

config = InterrogateConfig(

155

ignore_init_method=True,

156

ignore_private=True,

157

fail_under=80.0

158

)

159

160

# Run analysis

161

coverage = InterrogateCoverage(["src/myproject"], config)

162

results = coverage.get_coverage()

163

164

# Check results

165

print(f"Coverage: {results.perc_covered:.1f}%")

166

print(f"Files analyzed: {len(results.file_results)}")

167

print(f"Missing docstrings: {results.missing}")

168

169

# Print detailed results

170

coverage.print_results(results)

171

```

172

173

### Programmatic Result Processing

174

175

```python

176

from interrogate.coverage import InterrogateCoverage

177

from interrogate.config import InterrogateConfig

178

179

config = InterrogateConfig()

180

coverage = InterrogateCoverage(["src/"], config)

181

results = coverage.get_coverage()

182

183

# Process individual file results

184

for filename, file_result in results.file_results.items():

185

print(f"{filename}: {file_result.perc_covered:.1f}% coverage")

186

187

# Examine individual nodes

188

for node in file_result.nodes:

189

if not node.covered:

190

print(f" Missing docstring: {node.name} ({node.node_type}) at line {node.lineno}")

191

192

# Check if coverage meets threshold

193

if results.ret_code != 0:

194

print(f"Coverage {results.perc_covered:.1f}% below required threshold")

195

```

196

197

### Custom File Filtering

198

199

```python

200

from interrogate.coverage import InterrogateCoverage

201

from interrogate.config import InterrogateConfig

202

203

# Create coverage analyzer

204

config = InterrogateConfig()

205

coverage = InterrogateCoverage(["src/"], config)

206

207

# Get all Python files that would be analyzed

208

python_files = list(coverage.get_filenames_from_paths())

209

print(f"Files to analyze: {len(python_files)}")

210

211

for filepath in python_files:

212

print(f" {filepath}")

213

```