or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

built-in-checkers.mdchecker-development.mdconfiguration.mdcore-linting.mdextensions.mdindex.mdmessages.mdpyreverse.mdreporters.mdtest-utilities.md

messages.mddocs/

0

# Message System

1

2

Structured message definitions with categories, confidence levels, and detailed location information for precise error reporting and filtering. Pylint's message system provides comprehensive information about code issues with standardized formatting and metadata.

3

4

## Capabilities

5

6

### Message Representation

7

8

Core classes for representing individual messages and their metadata.

9

10

```python { .api }

11

class Message:

12

"""

13

Individual message/warning representation.

14

15

Attributes:

16

msg_id (str): Message identifier (e.g., 'C0111')

17

symbol (str): Message symbol (e.g., 'missing-docstring')

18

msg (str): Formatted message text

19

C (str): Message category letter (C/R/W/E/F/I)

20

category (str): Full category name

21

confidence (str): Confidence level

22

abspath (str): Absolute file path

23

path (str): Relative file path

24

module (str): Module name

25

obj (str): Object name (function, class, etc.)

26

line (int): Line number

27

column (int): Column number

28

end_line (int): End line number (optional)

29

end_column (int): End column number (optional)

30

"""

31

32

def __init__(self, msg_id, line=None, node=None, args=None,

33

confidence=None, col_offset=None, end_lineno=None,

34

end_col_offset=None):

35

"""

36

Initialize message instance.

37

38

Args:

39

msg_id (str): Message identifier

40

line (int): Line number

41

node: AST node

42

args (tuple): Message arguments

43

confidence (str): Confidence level

44

col_offset (int): Column offset

45

end_lineno (int): End line number

46

end_col_offset (int): End column offset

47

"""

48

49

def format(self, template=None):

50

"""

51

Format message according to template.

52

53

Args:

54

template (str): Format template

55

56

Returns:

57

str: Formatted message

58

"""

59

```

60

61

### Message Definitions

62

63

Classes for defining and managing message types and their properties.

64

65

```python { .api }

66

class MessageDefinition:

67

"""

68

Message type definition.

69

70

Defines the structure and properties of a specific message type

71

including its identifier, description, and formatting template.

72

"""

73

74

def __init__(self, checker, msgid, msg, description, symbol=None,

75

scope=None, minversion=None, maxversion=None,

76

old_names=None):

77

"""

78

Initialize message definition.

79

80

Args:

81

checker: Checker that defines this message

82

msgid (str): Unique message identifier (e.g., 'C0111')

83

msg (str): Message template with placeholders

84

description (str): Detailed description

85

symbol (str): Symbolic name (e.g., 'missing-docstring')

86

scope (str): Scope where message applies

87

minversion (tuple): Minimum Python version

88

maxversion (tuple): Maximum Python version

89

old_names (list): Previous names for this message

90

"""

91

92

@property

93

def msgid(self):

94

"""Message identifier."""

95

return self._msgid

96

97

@property

98

def symbol(self):

99

"""Message symbol."""

100

return self._symbol

101

102

def format_help(self, checkerref=False):

103

"""

104

Format help text for this message.

105

106

Args:

107

checkerref (bool): Include checker reference

108

109

Returns:

110

str: Formatted help text

111

"""

112

113

class MessageDefinitionStore:

114

"""

115

Storage for message definitions.

116

117

Manages the collection of all message definitions from

118

all checkers, providing lookup and validation capabilities.

119

"""

120

121

def __init__(self):

122

"""Initialize empty message definition store."""

123

self._messages_definitions = {}

124

self._msgs_by_category = {}

125

126

def register_message(self, message_definition):

127

"""

128

Register a message definition.

129

130

Args:

131

message_definition: MessageDefinition instance

132

"""

133

134

def get_message_definitions(self, msgid_or_symbol):

135

"""

136

Get message definition by ID or symbol.

137

138

Args:

139

msgid_or_symbol (str): Message ID or symbol

140

141

Returns:

142

MessageDefinition: Message definition if found

143

"""

144

145

def get_msg_display_string(self, msgid):

146

"""

147

Get display string for message.

148

149

Args:

150

msgid (str): Message identifier

151

152

Returns:

153

str: Display string combining ID and symbol

154

"""

155

```

156

157

### Message ID Management

158

159

Classes for managing message identifiers and symbolic names.

160

161

```python { .api }

162

class MessageIdStore:

163

"""

164

Message ID management and lookup.

165

166

Provides mapping between message IDs, symbols, and their

167

definitions, including support for deprecated message names.

168

"""

169

170

def __init__(self):

171

"""Initialize message ID store."""

172

self._msgid_to_symbol = {}

173

self._symbol_to_msgid = {}

174

self._old_names = {}

175

176

def register_message_definition(self, msgid, symbol, old_names=None):

177

"""

178

Register message ID and symbol mapping.

179

180

Args:

181

msgid (str): Message identifier

182

symbol (str): Message symbol

183

old_names (list): List of deprecated names

184

"""

185

186

def get_active_msgids(self, msgid_or_symbol):

187

"""

188

Get active message IDs for given ID or symbol.

189

190

Args:

191

msgid_or_symbol (str): Message ID or symbol

192

193

Returns:

194

list: Active message IDs

195

"""

196

197

def get_msgid(self, symbol):

198

"""

199

Get message ID from symbol.

200

201

Args:

202

symbol (str): Message symbol

203

204

Returns:

205

str: Message ID

206

"""

207

208

def get_symbol(self, msgid):

209

"""

210

Get symbol from message ID.

211

212

Args:

213

msgid (str): Message ID

214

215

Returns:

216

str: Message symbol

217

"""

218

```

219

220

## Message Categories

221

222

### Category Definitions

223

224

```python { .api }

225

# Message category mappings

226

MSG_TYPES = {

227

'I': 'info', # Informational messages

228

'C': 'convention', # Coding standard violations

229

'R': 'refactor', # Refactoring suggestions

230

'W': 'warning', # Potential issues

231

'E': 'error', # Probable bugs

232

'F': 'fatal' # Errors preventing further processing

233

}

234

235

# Category status codes for exit codes

236

MSG_TYPES_STATUS = {

237

'I': 0, # Info - no impact on exit code

238

'C': 2, # Convention violation

239

'R': 4, # Refactor suggestion

240

'W': 8, # Warning

241

'E': 16, # Error

242

'F': 32 # Fatal error

243

}

244

```

245

246

### Confidence Levels

247

248

```python { .api }

249

# Confidence level constants

250

HIGH = "HIGH" # High confidence in the issue

251

CONTROL_FLOW = "CONTROL_FLOW" # Based on control flow analysis

252

INFERENCE = "INFERENCE" # Based on type inference

253

INFERENCE_FAILURE = "INFERENCE_FAILURE" # Failed type inference

254

UNDEFINED = "UNDEFINED" # No confidence level specified

255

```

256

257

## Usage Examples

258

259

### Creating Custom Messages

260

261

```python

262

from pylint.checkers import BaseChecker

263

from pylint.interfaces import HIGH, INFERENCE

264

265

class CustomChecker(BaseChecker):

266

"""Example checker with custom messages."""

267

268

name = 'custom'

269

msgs = {

270

'W9001': (

271

'Function "%s" has too many parameters (%d > %d)',

272

'too-many-params-custom',

273

'Function should have fewer parameters for better maintainability',

274

),

275

'C9001': (

276

'Variable name "%s" should use snake_case',

277

'invalid-variable-name-custom',

278

'Variable names should follow snake_case convention',

279

),

280

'E9001': (

281

'Undefined variable "%s" used in function "%s"',

282

'undefined-variable-custom',

283

'Variable must be defined before use',

284

)

285

}

286

287

def visit_functiondef(self, node):

288

"""Check function parameters."""

289

max_params = 5

290

param_count = len(node.args.args)

291

292

if param_count > max_params:

293

self.add_message(

294

'too-many-params-custom',

295

node=node,

296

args=(node.name, param_count, max_params),

297

confidence=HIGH

298

)

299

300

def visit_name(self, node):

301

"""Check variable naming."""

302

import re

303

if not re.match(r'^[a-z_][a-z0-9_]*$', node.name):

304

self.add_message(

305

'invalid-variable-name-custom',

306

node=node,

307

args=(node.name,),

308

confidence=INFERENCE

309

)

310

```

311

312

### Message Processing and Filtering

313

314

```python

315

from pylint.lint import PyLinter

316

from pylint.reporters import CollectingReporter

317

318

# Collect messages for processing

319

collector = CollectingReporter()

320

linter = PyLinter()

321

linter.set_reporter(collector)

322

linter.check(['mymodule.py'])

323

324

messages = collector.finalize()

325

326

# Filter messages by category

327

errors = [msg for msg in messages if msg.category == 'error']

328

warnings = [msg for msg in messages if msg.category == 'warning']

329

330

# Filter by confidence level

331

high_confidence = [msg for msg in messages if msg.confidence == 'HIGH']

332

333

# Filter by message type

334

missing_docstrings = [msg for msg in messages

335

if msg.symbol == 'missing-docstring']

336

337

# Group messages by file

338

from collections import defaultdict

339

by_file = defaultdict(list)

340

for msg in messages:

341

by_file[msg.path].append(msg)

342

343

# Process each message

344

for msg in messages:

345

print(f"{msg.path}:{msg.line}:{msg.column} - {msg.msg_id}: {msg.msg}")

346

print(f" Category: {msg.category}")

347

print(f" Confidence: {msg.confidence}")

348

print(f" Symbol: {msg.symbol}")

349

```

350

351

### Custom Message Formatting

352

353

```python

354

def format_message_custom(msg):

355

"""Custom message formatting function."""

356

severity_map = {

357

'error': '❌',

358

'warning': '⚠️ ',

359

'convention': '📋',

360

'refactor': '♻️ ',

361

'info': 'ℹ️ '

362

}

363

364

icon = severity_map.get(msg.category, '?')

365

return f"{icon} {msg.path}:{msg.line} - {msg.msg} ({msg.symbol})"

366

367

# Apply custom formatting

368

for msg in messages:

369

formatted = format_message_custom(msg)

370

print(formatted)

371

```

372

373

### Message Template Configuration

374

375

```python

376

# Configure message template

377

linter = PyLinter()

378

379

# Standard templates

380

linter.config.msg_template = '{path}:{line}: [{msg_id}({symbol}), {obj}] {msg}'

381

linter.config.msg_template = '{path}:{line}:{column}: {category}: {msg} ({symbol})'

382

383

# Custom template with all fields

384

template = (

385

'{path}:{line}:{column}: {msg_id}: {msg}\n'

386

' Category: {category} | Confidence: {confidence}\n'

387

' Object: {obj} | Symbol: {symbol}'

388

)

389

linter.config.msg_template = template

390

```

391

392

## Built-in Message Examples

393

394

### Convention Messages (C)

395

396

```python { .api }

397

# C0103: invalid-name

398

# "Name doesn't conform to naming convention"

399

400

# C0111: missing-docstring

401

# "Missing module/class/function docstring"

402

403

# C0301: line-too-long

404

# "Line too long (%d/%d characters)"

405

406

# C0326: bad-whitespace

407

# "Wrong hanging indentation"

408

```

409

410

### Refactor Messages (R)

411

412

```python { .api }

413

# R0201: no-self-use

414

# "Method could be a function"

415

416

# R0903: too-few-public-methods

417

# "Too few public methods (%d/%d)"

418

419

# R0913: too-many-arguments

420

# "Too many arguments (%d/%d)"

421

422

# R1705: no-else-return

423

# "Unnecessary else after return statement"

424

```

425

426

### Warning Messages (W)

427

428

```python { .api }

429

# W0613: unused-argument

430

# "Unused argument '%s'"

431

432

# W0622: redefined-builtin

433

# "Redefining built-in '%s'"

434

435

# W0703: broad-except

436

# "Catching too general exception %s"

437

438

# W1203: logging-fstring-interpolation

439

# "Use lazy % formatting in logging functions"

440

```

441

442

### Error Messages (E)

443

444

```python { .api }

445

# E0601: used-before-assignment

446

# "Using variable '%s' before assignment"

447

448

# E1101: no-member

449

# "%s %r has no %r member"

450

451

# E1120: no-value-for-parameter

452

# "No value provided for parameter %s in function call"

453

454

# E1136: unsubscriptable-object

455

# "Value '%s' is unsubscriptable"

456

```

457

458

### Fatal Messages (F)

459

460

```python { .api }

461

# F0001: fatal

462

# "Error occurred preventing further processing: %s"

463

464

# F0010: error

465

# "Error while code parsing: %s"

466

467

# F0202: method-check-failed

468

# "Unable to check methods signature (%s / %s)"

469

```

470

471

## Message State Management

472

473

### Disabling Messages

474

475

```python

476

# Disable globally in configuration

477

linter.config.disable = ['missing-docstring', 'invalid-name']

478

479

# Disable via command line

480

# pylint --disable=missing-docstring,invalid-name mymodule.py

481

482

# Disable in code with comments

483

def my_function(): # pylint: disable=missing-docstring

484

pass

485

486

class MyClass: # pylint: disable=too-few-public-methods

487

pass

488

489

# Disable for entire file

490

# pylint: disable=missing-docstring

491

492

# Disable for code block

493

# pylint: disable-next=unused-variable

494

x = get_value()

495

```

496

497

### Enabling Messages

498

499

```python

500

# Enable specific messages

501

linter.config.enable = ['unused-variable']

502

503

# Enable message categories

504

linter.config.enable = ['warning', 'error']

505

506

# Enable all messages then disable specific ones

507

linter.config.disable = 'all'

508

linter.config.enable = ['error', 'fatal']

509

```