or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

baseline.mdcli.mdconfiguration.mdcore-analysis.mdflake8-plugin.mdindex.mdutility-apis.mdviolations.md

violations.mddocs/

0

# Violation System

1

2

Comprehensive violation reporting system with specific error codes (DOC0xx-DOC6xx) covering all categories of docstring issues, from formatting to argument mismatches.

3

4

## Capabilities

5

6

### Violation Class

7

8

Core class representing individual docstring violations with detailed error information.

9

10

```python { .api }

11

class Violation:

12

"""

13

Represents a docstring violation with detailed error information.

14

15

Provides comprehensive violation reporting including error codes,

16

line numbers, and formatted messages for both CLI and flake8 output.

17

"""

18

19

code: int # Violation code number (1-6xx range)

20

line: int # Line number where violation occurs

21

msg: str # Complete violation message

22

msgPostfix: str # Additional message content

23

24

def __init__(

25

self,

26

line: int,

27

code: int,

28

msgPrefix: str = '',

29

msgPostfix: str = '',

30

) -> None:

31

"""

32

Initialize violation with error details.

33

34

Parameters:

35

- line: Line number of violation (0 for file-level issues)

36

- code: Violation code number

37

- msgPrefix: Prefix for violation message (deprecated)

38

- msgPostfix: Additional information to append to standard message

39

"""

40

41

@property

42

def fullErrorCode(self) -> str:

43

"""

44

Get full error code with DOC prefix.

45

46

Returns:

47

str: Full error code (e.g., "DOC101", "DOC201")

48

"""

49

50

def getInfoForFlake8(self) -> tuple[int, int, str]:

51

"""

52

Format violation information for flake8 output.

53

54

Returns:

55

tuple containing:

56

- int: Line number

57

- int: Column offset (always 0)

58

- str: Formatted error message with DOC code

59

"""

60

61

def __str__(self) -> str:

62

"""

63

String representation of violation.

64

65

Returns:

66

str: Formatted violation message

67

"""

68

```

69

70

### Violation Codes Reference

71

72

Complete mapping of violation codes to their standard error messages.

73

74

```python { .api }

75

VIOLATION_CODES: dict[int, str] = {

76

# General and formatting issues (DOC0xx)

77

1: "Potential formatting errors in docstring. Error message:",

78

2: "Syntax errors; cannot parse this Python file. Error message:",

79

3: "Docstring style mismatch. (Please read more at https://jsh9.github.io/pydoclint/style_mismatch.html ).",

80

81

# Argument-related violations (DOC1xx)

82

101: "Docstring contains fewer arguments than in function signature.",

83

102: "Docstring contains more arguments than in function signature.",

84

103: "Docstring arguments are different from function arguments. (Or could be other formatting issues: https://jsh9.github.io/pydoclint/violation_codes.html#notes-on-doc103 ).",

85

104: "Arguments are the same in the docstring and the function signature, but are in a different order.",

86

105: "Argument names match, but type hints in these args do not match:",

87

106: "The option `--arg-type-hints-in-signature` is `True` but there are no argument type hints in the signature",

88

107: "The option `--arg-type-hints-in-signature` is `True` but not all args in the signature have type hints",

89

108: "The option `--arg-type-hints-in-signature` is `False` but there are argument type hints in the signature",

90

109: "The option `--arg-type-hints-in-docstring` is `True` but there are no type hints in the docstring arg list",

91

110: "The option `--arg-type-hints-in-docstring` is `True` but not all args in the docstring arg list have type hints",

92

111: "The option `--arg-type-hints-in-docstring` is `False` but there are type hints in the docstring arg list",

93

94

# Return-related violations (DOC2xx)

95

201: "does not have a return section in docstring",

96

202: "has a return section in docstring, but there are no return statements or annotations",

97

203: "return type(s) in docstring not consistent with the return annotation.",

98

99

# Class and __init__ violations (DOC3xx)

100

301: "__init__() should not have a docstring; please combine it with the docstring of the class",

101

302: "The class docstring does not need a \"Returns\" section, because __init__() cannot return anything",

102

303: "The __init__() docstring does not need a \"Returns\" section, because it cannot return anything",

103

304: "Class docstring has an argument/parameter section; please put it in the __init__() docstring",

104

305: "Class docstring has a \"Raises\" section; please put it in the __init__() docstring",

105

306: "The class docstring does not need a \"Yields\" section, because __init__() cannot yield anything",

106

307: "The __init__() docstring does not need a \"Yields\" section, because __init__() cannot yield anything",

107

108

# Yield-related violations (DOC4xx)

109

402: "has \"yield\" statements, but the docstring does not have a \"Yields\" section",

110

403: "has a \"Yields\" section in the docstring, but there are no \"yield\" statements, or the return annotation is not a Generator/Iterator/Iterable. (Or it could be because the function lacks a return annotation.)",

111

404: "yield type(s) in docstring not consistent with the return annotation.",

112

405: "has both \"return\" and \"yield\" statements. Please use Generator[YieldType, SendType, ReturnType] as the return type annotation, and put your yield type in YieldType and return type in ReturnType. More details in https://jsh9.github.io/pydoclint/notes_generator_vs_iterator.html",

113

114

# Raises-related violations (DOC5xx)

115

501: "has raise statements, but the docstring does not have a \"Raises\" section",

116

502: "has a \"Raises\" section in the docstring, but there are not \"raise\" statements in the body",

117

503: "exceptions in the \"Raises\" section in the docstring do not match those in the function body.",

118

504: "has assert statements, but the docstring does not have a \"Raises\" section. (Assert statements could raise \"AssertError\".)",

119

120

# Class attribute violations (DOC6xx)

121

601: "Class docstring contains fewer class attributes than actual class attributes.",

122

602: "Class docstring contains more class attributes than in actual class attributes.",

123

603: "Class docstring attributes are different from actual class attributes. (Or could be other formatting issues: https://jsh9.github.io/pydoclint/violation_codes.html#notes-on-doc103 ).",

124

604: "Attributes are the same in docstring and class def, but are in a different order",

125

605: "Attribute names match, but type hints in these attributes do not match",

126

}

127

```

128

129

## Usage Examples

130

131

### Creating and Using Violations

132

133

```python

134

from pydoclint.utils.violation import Violation, VIOLATION_CODES

135

136

# Create a violation for missing arguments

137

violation = Violation(

138

code=101,

139

line=15,

140

msgPostfix="Missing arguments: x, y"

141

)

142

143

print(violation.fullErrorCode) # "DOC101"

144

print(str(violation)) # Full formatted message

145

print(violation.getInfoForFlake8()) # (15, 0, "DOC101: Docstring contains fewer arguments...")

146

147

# Check violation code meaning

148

print(VIOLATION_CODES[101]) # "Docstring contains fewer arguments than in function signature."

149

```

150

151

### Processing Violations from Analysis

152

153

```python

154

from pydoclint.main import _checkFile

155

from pathlib import Path

156

157

# Analyze file and process violations

158

violations = _checkFile(Path("example.py"), style="numpy")

159

160

for violation in violations:

161

print(f"Line {violation.line}: {violation.fullErrorCode}")

162

print(f" {violation.msg}")

163

164

# Handle specific violation types

165

if violation.code in [101, 102, 103]:

166

print(" -> Argument mismatch issue")

167

elif violation.code in [201, 202, 203]:

168

print(" -> Return section issue")

169

elif violation.code in [402, 403, 404]:

170

print(" -> Yield section issue")

171

```

172

173

### Filtering and Categorizing Violations

174

175

```python

176

def categorize_violations(violations: list[Violation]) -> dict[str, list[Violation]]:

177

"""Categorize violations by type."""

178

categories = {

179

"general": [], # DOC001-DOC003

180

"arguments": [], # DOC101-DOC111

181

"returns": [], # DOC201-DOC203

182

"class_init": [], # DOC301-DOC307

183

"yields": [], # DOC402-DOC405

184

"raises": [], # DOC501-DOC502

185

"class_attrs": [], # DOC601-DOC603

186

}

187

188

for violation in violations:

189

if 1 <= violation.code <= 3:

190

categories["general"].append(violation)

191

elif 101 <= violation.code <= 111:

192

categories["arguments"].append(violation)

193

elif 201 <= violation.code <= 203:

194

categories["returns"].append(violation)

195

elif 301 <= violation.code <= 307:

196

categories["class_init"].append(violation)

197

elif 402 <= violation.code <= 405:

198

categories["yields"].append(violation)

199

elif 501 <= violation.code <= 502:

200

categories["raises"].append(violation)

201

elif 601 <= violation.code <= 603:

202

categories["class_attrs"].append(violation)

203

204

return categories

205

206

# Usage

207

violations = _checkFile(Path("example.py"))

208

categorized = categorize_violations(violations)

209

210

print(f"Argument issues: {len(categorized['arguments'])}")

211

print(f"Return issues: {len(categorized['returns'])}")

212

```

213

214

### Custom Violation Processing

215

216

```python

217

class ViolationProcessor:

218

"""Process and format violations for different outputs."""

219

220

def __init__(self, show_filenames: bool = False):

221

self.show_filenames = show_filenames

222

223

def format_for_console(self, filename: str, violations: list[Violation]) -> str:

224

"""Format violations for console output."""

225

if not violations:

226

return ""

227

228

output = []

229

if not self.show_filenames:

230

output.append(f"{filename}:")

231

232

for violation in violations:

233

prefix = f"{filename}:" if self.show_filenames else " "

234

output.append(f"{prefix}{violation.line}: {violation.fullErrorCode}: {violation.msg}")

235

236

return "\n".join(output)

237

238

def format_for_json(self, filename: str, violations: list[Violation]) -> dict:

239

"""Format violations for JSON output."""

240

return {

241

"file": filename,

242

"violations": [

243

{

244

"line": v.line,

245

"code": v.fullErrorCode,

246

"message": v.msg,

247

"severity": self._get_severity(v.code)

248

}

249

for v in violations

250

]

251

}

252

253

def _get_severity(self, code: int) -> str:

254

"""Determine violation severity."""

255

if code in [1, 2]:

256

return "error"

257

elif code in [101, 102, 201, 402, 501]:

258

return "warning"

259

else:

260

return "info"

261

262

# Usage

263

processor = ViolationProcessor(show_filenames=True)

264

violations = _checkFile(Path("example.py"))

265

266

# Console output

267

console_output = processor.format_for_console("example.py", violations)

268

print(console_output)

269

270

# JSON output

271

json_output = processor.format_for_json("example.py", violations)

272

import json

273

print(json.dumps(json_output, indent=2))

274

```

275

276

## Violation Code Categories

277

278

### General Issues (DOC001-DOC003)

279

- **DOC001**: Docstring parsing/formatting errors

280

- **DOC002**: Python syntax errors preventing analysis

281

- **DOC003**: Docstring style mismatch (e.g., Google style in numpy-configured project)

282

283

### Argument Issues (DOC101-DOC111)

284

- **DOC101-DOC104**: Argument count and order mismatches

285

- **DOC105**: Type hint inconsistencies

286

- **DOC106-DOC111**: Type hint presence/absence violations

287

288

### Return Issues (DOC201-DOC203)

289

- **DOC201**: Missing return section

290

- **DOC202**: Unnecessary return section

291

- **DOC203**: Return type inconsistencies

292

293

### Class and Init Issues (DOC301-DOC307)

294

- **DOC301**: Improper __init__ docstring placement

295

- **DOC302-DOC303**: Inappropriate return sections in class/__init__

296

- **DOC304-DOC305**: Misplaced argument/raises sections

297

- **DOC306-DOC307**: Inappropriate yields sections

298

299

### Yield Issues (DOC402-DOC405)

300

- **DOC402**: Missing yields section for generators

301

- **DOC403**: Unnecessary yields section

302

- **DOC404**: Yield type inconsistencies

303

- **DOC405**: Mixed return/yield usage

304

305

### Raises Issues (DOC501-DOC502)

306

- **DOC501**: Missing raises section

307

- **DOC502**: Unnecessary raises section

308

309

### Class Attribute Issues (DOC601-DOC603)

310

- **DOC601-DOC603**: Class attribute documentation mismatches