or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

async-processing.mdconfiguration.mderror-processing.mdindex.mdmain-interface.mdplugin-development.mdpytest-integration.mdvcs-hooks.md

error-processing.mddocs/

0

# Error Processing

1

2

Error representation, deduplication, and formatting capabilities for managing linting results across multiple tools and output formats. Pylama provides comprehensive error handling with intelligent deduplication and flexible formatting options.

3

4

## Type Imports

5

6

```python

7

from typing import Any, Dict, Generator, List, Optional, Set, Tuple

8

from argparse import Namespace

9

```

10

11

## Capabilities

12

13

### Error Representation

14

15

Core error class that represents individual linting issues with comprehensive metadata.

16

17

```python { .api }

18

class Error:

19

"""

20

Represents a single linting error with source information.

21

22

Attributes:

23

filename: str - File path where error occurred

24

lnum: int - Line number (1-based)

25

col: int - Column number (1-based)

26

message: str - Error message text

27

etype: str - Error type (E=error, W=warning, etc.)

28

source: str - Linter that generated the error

29

number: str - Error code (extracted from text)

30

"""

31

32

def __init__(

33

self,

34

source: str = "pylama",

35

col: int = 1,

36

lnum: int = 1,

37

type: Optional[str] = None,

38

text: str = "unknown error",

39

filename: str = "",

40

number: str = "",

41

**_

42

):

43

"""

44

Initialize error with position and message information.

45

46

Args:

47

source: Name of linter that found the error

48

col: Column number (1-based)

49

lnum: Line number (1-based)

50

type: Error type/severity (stored as etype attribute)

51

text: Error message text (stored as message attribute)

52

filename: File path where error occurred

53

number: Error code number

54

**_: Additional unused parameters

55

"""

56

57

def to_dict(self) -> Dict[str, Any]:

58

"""

59

Convert error to dictionary representation.

60

61

Returns:

62

Dict[str, Any]: Error data as dictionary with keys:

63

- filename, lnum, col, message, etype, source, number

64

"""

65

66

def format(self, template: str) -> str:

67

"""

68

Format error using template string.

69

70

Args:

71

template: Format string with placeholders like {filename}, {lnum}, etc.

72

73

Returns:

74

str: Formatted error message

75

76

Available template variables:

77

- {filename}: File path

78

- {lnum}: Line number

79

- {col}: Column number

80

- {message}: Error message text

81

- {etype}: Error type

82

- {source}: Linter name

83

- {number}: Error code

84

"""

85

```

86

87

### Error Deduplication

88

89

Remove duplicate errors that are reported by multiple linters for the same issue.

90

91

```python { .api }

92

def remove_duplicates(errors: List[Error]) -> Generator[Error, None, None]:

93

"""

94

Remove duplicate errors from different linters.

95

96

Args:

97

errors: List of Error objects potentially containing duplicates

98

99

Yields:

100

Error: Unique errors with duplicates removed

101

102

Deduplication rules:

103

- Errors at same location with equivalent meanings are deduplicated

104

- Priority given to more specific linters (e.g., pycodestyle over pylint for style)

105

- Common duplicate patterns handled automatically (see DUPLICATES mapping)

106

"""

107

```

108

109

### Error Sorting

110

111

Sort errors according to configurable criteria.

112

113

```python { .api }

114

def default_sorter(err: Error) -> Any:

115

"""

116

Default error sorting function.

117

118

Args:

119

err: Error object to generate sort key for

120

121

Returns:

122

Any: Sort key (typically line number for default sorter)

123

124

Default sort order:

125

- Line number (ascending)

126

"""

127

```

128

129

### Error Display

130

131

Format and output errors using various output formats.

132

133

```python { .api }

134

def display_errors(errors: List[Error], options: Namespace):

135

"""

136

Format and display errors using specified format.

137

138

Args:

139

errors: List of Error objects to display

140

options: Configuration options containing format settings

141

142

Supported formats:

143

- 'json': JSON array of error dictionaries

144

- 'pylint': Pylint-compatible format

145

- 'pycodestyle': pycodestyle-compatible format

146

- 'parsable': Default parsable format (same as default)

147

- Custom format strings

148

149

Output is sent to the configured logger at WARNING level.

150

"""

151

```

152

153

## Duplicate Error Mappings

154

155

Pylama automatically deduplicates common errors reported by multiple linters:

156

157

```python { .api }

158

DUPLICATES: Dict[Tuple[str, str], Set] = {

159

# Multiple statements on one line

160

("pycodestyle", "E701"): {("pylint", "C0321")},

161

162

# Unused variable

163

("pylint", "W0612"): {("pyflakes", "W0612")},

164

165

# Undefined variable

166

("pylint", "E0602"): {("pyflakes", "E0602")},

167

168

# Unused import

169

("pylint", "W0611"): {("pyflakes", "W0611")},

170

171

# Whitespace issues

172

("pylint", "C0326"): {

173

("pycodestyle", "E202"), # whitespace before ')'

174

("pycodestyle", "E211"), # whitespace before '('

175

("pycodestyle", "E222"), # multiple spaces after operator

176

("pycodestyle", "E225"), # missing whitespace around operator

177

("pycodestyle", "E251"), # unexpected spaces

178

},

179

180

# Long lines

181

("pylint", "C0301"): {("pycodestyle", "E501")},

182

183

# Other common duplicates...

184

}

185

```

186

187

## Usage Examples

188

189

### Basic Error Processing

190

191

```python

192

from pylama.main import check_paths

193

from pylama.config import parse_options

194

from pylama.errors import remove_duplicates

195

196

# Get errors from checking

197

options = parse_options(['--linters=pycodestyle,pylint', 'myfile.py'])

198

errors = check_paths(['myfile.py'], options)

199

200

# Remove duplicates

201

unique_errors = list(remove_duplicates(errors))

202

print(f"Found {len(errors)} total, {len(unique_errors)} unique errors")

203

```

204

205

### Custom Error Formatting

206

207

```python

208

from pylama.errors import Error

209

210

# Create error object

211

error = Error(

212

source="pycodestyle",

213

col=10,

214

lnum=42,

215

type="E",

216

text="E501 line too long (82 > 79 characters)",

217

filename="example.py"

218

)

219

220

# Format with different templates

221

default_format = "{filename}:{lnum}:{col} [{etype}] {number} {message} [{source}]"

222

pylint_format = "{filename}:{lnum}: [{etype}] {number} {message} [{source}]"

223

224

print(error.format(default_format))

225

print(error.format(pylint_format))

226

227

# Convert to dictionary

228

error_dict = error.to_dict()

229

print(error_dict)

230

231

# Access error message

232

print(f"Error message: {error.message}")

233

```

234

235

### JSON Output Processing

236

237

```python

238

import json

239

from pylama.main import check_paths

240

from pylama.config import parse_options

241

242

# Configure for JSON output

243

options = parse_options(['--format=json', '--linters=pyflakes', 'myfile.py'])

244

errors = check_paths(['myfile.py'], options)

245

246

# Process as JSON data

247

error_data = [error.to_dict() for error in errors]

248

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

249

print(json_output)

250

251

# Filter by error type

252

warnings = [e for e in errors if e.etype == 'W']

253

errors_only = [e for e in errors if e.etype == 'E']

254

255

# Access error messages

256

for error in errors:

257

print(f"File: {error.filename}, Message: {error.message}")

258

```

259

260

### Custom Error Sorting

261

262

```python

263

from pylama.errors import Error

264

265

errors = [

266

Error(source="pycodestyle", col=5, lnum=10, type="E", text="E501 line too long", filename="file1.py"),

267

Error(source="pylint", col=1, lnum=5, type="W", text="W0612 unused variable", filename="file1.py"),

268

Error(source="pyflakes", col=1, lnum=1, type="F", text="F401 unused import", filename="file2.py"),

269

]

270

271

# Sort by severity (errors first, then warnings)

272

def severity_sorter(err):

273

severity_order = {'E': 0, 'F': 1, 'W': 2}

274

return (severity_order.get(err.etype, 999), err.filename, err.lnum)

275

276

sorted_errors = sorted(errors, key=severity_sorter)

277

278

# Sort by error source (linter)

279

def source_sorter(err):

280

return (err.source, err.filename, err.lnum)

281

282

sorted_by_source = sorted(errors, key=source_sorter)

283

```

284

285

### Error Analysis

286

287

```python

288

from collections import defaultdict

289

from pylama.main import check_paths

290

from pylama.config import parse_options

291

292

# Analyze error patterns

293

options = parse_options(['src/'])

294

errors = check_paths(['src/'], options)

295

296

# Group by error type

297

by_type = defaultdict(list)

298

for error in errors:

299

by_type[error.etype].append(error)

300

301

# Group by source linter

302

by_source = defaultdict(list)

303

for error in errors:

304

by_source[error.source].append(error)

305

306

# Group by file

307

by_file = defaultdict(list)

308

for error in errors:

309

by_file[error.filename].append(error)

310

311

# Print summary

312

print("Error Summary:")

313

print(f"Total errors: {len(errors)}")

314

print(f"Files with issues: {len(by_file)}")

315

print(f"Error types: {list(by_type.keys())}")

316

print(f"Linters used: {list(by_source.keys())}")

317

318

# Print messages for each error

319

for error in errors:

320

print(f"{error.filename}:{error.lnum} - {error.message}")

321

```

322

323

## Format Templates

324

325

```python { .api }

326

DEFAULT_FORMAT: str = "{filename}:{lnum}:{col} [{etype}] {number} {message} [{source}]"

327

328

MESSAGE_FORMATS: Dict[str, str] = {

329

"pylint": "{filename}:{lnum}: [{etype}] {number} {message} [{source}]",

330

"pycodestyle": "{filename}:{lnum}:{col} {number} {message} [{source}]",

331

"parsable": DEFAULT_FORMAT,

332

}

333

```