or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

checker-system.mdcore-api.mdindex.mdmessage-types.mdreporter-system.md

message-types.mddocs/

0

# Message Types

1

2

Comprehensive set of structured warning and error classes representing different types of issues that can be detected in Python code. Each message type provides specific information about the problem and its location, enabling precise error reporting and programmatic handling of analysis results.

3

4

Pyflakes defines 48 message classes that inherit from the base `Message` class, each representing a specific type of code issue.

5

6

## Capabilities

7

8

### Base Message Class

9

10

Foundation class for all Pyflakes messages, providing common functionality for error reporting and formatting.

11

12

```python { .api }

13

class Message:

14

"""Base class for all pyflakes messages."""

15

16

message: str = '' # Format string for the message

17

message_args: tuple = () # Arguments for format string

18

19

def __init__(self, filename: str, loc):

20

"""

21

Initialize message with location information.

22

23

Parameters:

24

- filename (str): Name of file where issue was found

25

- loc: AST node with location information (lineno, col_offset)

26

"""

27

28

filename: str # File where issue occurs

29

lineno: int # Line number (1-based)

30

col: int # Column offset (0-based)

31

32

def __str__(self) -> str:

33

"""Format message as 'filename:line:col: description'."""

34

```

35

36

**Usage:**

37

38

```python

39

import pyflakes.api

40

from pyflakes.messages import UnusedImport, UndefinedName

41

42

# Get messages from analysis

43

code = "import os\nprint(x)"

44

checker_result = pyflakes.api.check(code, 'test.py')

45

46

# Messages are typically accessed through checker.messages

47

# Each message provides structured information:

48

# - message.filename: 'test.py'

49

# - message.lineno: line number

50

# - message.col: column position

51

# - str(message): formatted error string

52

```

53

54

### Import-Related Messages

55

56

Messages for issues related to import statements and module usage.

57

58

```python { .api }

59

class UnusedImport(Message):

60

"""Import statement that is never used."""

61

message = '%r imported but unused'

62

63

def __init__(self, filename: str, loc, name: str): ...

64

65

class RedefinedWhileUnused(Message):

66

"""Name redefined before being used."""

67

message = 'redefinition of unused %r from line %r'

68

69

def __init__(self, filename: str, loc, name: str, orig_loc): ...

70

71

class ImportShadowedByLoopVar(Message):

72

"""Import name shadowed by loop variable."""

73

message = 'import %r from line %r shadowed by loop variable'

74

75

def __init__(self, filename: str, loc, name: str, orig_loc): ...

76

77

class ImportStarNotPermitted(Message):

78

"""Star import used outside module level."""

79

message = "'from %s import *' only allowed at module level"

80

81

def __init__(self, filename: str, loc, modname: str): ...

82

83

class ImportStarUsed(Message):

84

"""Star import used, limiting name detection."""

85

message = "'from %s import *' used; unable to detect undefined names"

86

87

def __init__(self, filename: str, loc, modname: str): ...

88

89

class ImportStarUsage(Message):

90

"""Name may be from star import."""

91

message = "%r may be undefined, or defined from star imports: %s"

92

93

def __init__(self, filename: str, loc, name: str, from_list: str): ...

94

```

95

96

### Name Resolution Messages

97

98

Messages for undefined names and variable usage issues.

99

100

```python { .api }

101

class UndefinedName(Message):

102

"""Reference to undefined name."""

103

message = 'undefined name %r'

104

105

def __init__(self, filename: str, loc, name: str): ...

106

107

class UndefinedLocal(Message):

108

"""Local variable referenced before assignment."""

109

message = 'local variable %r {0} referenced before assignment'

110

default = 'defined in enclosing scope on line %r'

111

builtin = 'defined as a builtin'

112

113

def __init__(self, filename: str, loc, name: str, orig_loc): ...

114

115

class UndefinedExport(Message):

116

"""Name in __all__ is not defined."""

117

message = 'undefined name %r in __all__'

118

119

def __init__(self, filename: str, loc, name: str): ...

120

```

121

122

### Variable Usage Messages

123

124

Messages for unused variables and assignments.

125

126

```python { .api }

127

class UnusedVariable(Message):

128

"""Variable assigned but never used."""

129

message = 'local variable %r is assigned to but never used'

130

131

def __init__(self, filename: str, loc, names: str): ...

132

133

class UnusedAnnotation(Message):

134

"""Type annotation without assignment or usage."""

135

message = 'local variable %r is annotated but never used'

136

137

def __init__(self, filename: str, loc, names: str): ...

138

139

class UnusedIndirectAssignment(Message):

140

"""Global or nonlocal statement where name is never reassigned."""

141

message = '`%s %s` is unused: name is never assigned in scope'

142

143

def __init__(self, filename: str, loc, name: str): ...

144

```

145

146

### Syntax and Structure Messages

147

148

Messages for syntax errors and structural issues.

149

150

```python { .api }

151

class DoctestSyntaxError(Message):

152

"""Syntax error in doctest code."""

153

message = 'syntax error in doctest'

154

155

def __init__(self, filename: str, loc, position=None): ...

156

157

class DuplicateArgument(Message):

158

"""Duplicate argument in function definition."""

159

message = 'duplicate argument %r in function definition'

160

161

def __init__(self, filename: str, loc, name: str): ...

162

163

class MultiValueRepeatedKeyLiteral(Message):

164

"""Dictionary key repeated with different values."""

165

message = 'dictionary key %r repeated with different values'

166

167

def __init__(self, filename: str, loc, key): ...

168

169

class MultiValueRepeatedKeyVariable(Message):

170

"""Dictionary key variable repeated with different values."""

171

message = 'dictionary key variable %s repeated with different values'

172

173

def __init__(self, filename: str, loc, key): ...

174

```

175

176

### Future Import Messages

177

178

Messages for __future__ import issues.

179

180

```python { .api }

181

class LateFutureImport(Message):

182

"""__future__ import not at beginning of file."""

183

message = 'from __future__ imports must occur at the beginning of the file'

184

185

class FutureFeatureNotDefined(Message):

186

"""Unknown __future__ feature."""

187

message = 'future feature %s is not defined'

188

189

def __init__(self, filename: str, loc, name: str): ...

190

```

191

192

### Control Flow Messages

193

194

Messages for control flow statement issues.

195

196

```python { .api }

197

class ReturnOutsideFunction(Message):

198

"""Return statement outside function."""

199

message = "'return' outside function"

200

201

class YieldOutsideFunction(Message):

202

"""Yield statement outside function."""

203

message = "'yield' outside function"

204

205

class ContinueOutsideLoop(Message):

206

"""Continue statement outside loop."""

207

message = "'continue' not properly in loop"

208

209

class BreakOutsideLoop(Message):

210

"""Break statement outside loop."""

211

message = "'break' outside loop"

212

```

213

214

### Exception Handling Messages

215

216

Messages for exception handling issues.

217

218

```python { .api }

219

class DefaultExceptNotLast(Message):

220

"""Default except clause not last."""

221

message = 'default \'except:\' must be last'

222

```

223

224

### Assignment Expression Messages

225

226

Messages for assignment expression and unpacking issues.

227

228

```python { .api }

229

class TwoStarredExpressions(Message):

230

"""Multiple starred expressions in assignment."""

231

message = 'two starred expressions in assignment'

232

233

class TooManyExpressionsInStarredAssignment(Message):

234

"""Too many expressions in starred assignment."""

235

message = 'too many expressions in star-unpacking assignment'

236

```

237

238

### Comparison and Literal Messages

239

240

Messages for comparison and literal usage issues.

241

242

```python { .api }

243

class IfTuple(Message):

244

"""If statement with tuple condition (always true)."""

245

message = '\'if tuple literal\' is always true, perhaps remove accidental comma?'

246

247

class AssertTuple(Message):

248

"""Assert statement with tuple (always true)."""

249

message = 'assertion is always true, perhaps remove parentheses?'

250

251

class IsLiteral(Message):

252

"""Identity comparison with literal."""

253

message = 'use ==/!= to compare constant literals (str, bytes, int, float, tuple)'

254

```

255

256

### Forward Annotation Messages

257

258

Messages for type annotation issues.

259

260

```python { .api }

261

class ForwardAnnotationSyntaxError(Message):

262

"""Syntax error in forward annotation."""

263

message = 'syntax error in forward annotation %r'

264

265

def __init__(self, filename: str, loc, annotation: str): ...

266

```

267

268

### Python Version Compatibility Messages

269

270

Messages for Python version compatibility issues.

271

272

```python { .api }

273

class RaiseNotImplemented(Message):

274

"""Raise NotImplemented instead of NotImplementedError."""

275

message = "'raise NotImplemented' should be 'raise NotImplementedError'"

276

277

class InvalidPrintSyntax(Message):

278

"""Invalid print syntax (Python 2 style)."""

279

message = 'use of >> is invalid with print function'

280

```

281

282

### String Formatting Messages

283

284

Messages for string formatting issues (f-strings, .format(), % formatting).

285

286

```python { .api }

287

class FStringMissingPlaceholders(Message):

288

"""F-string without placeholders."""

289

message = 'f-string is missing placeholders'

290

291

class TStringMissingPlaceholders(Message):

292

"""T-string without placeholders."""

293

message = 't-string is missing placeholders'

294

295

class StringDotFormatExtraPositionalArguments(Message):

296

"""Extra positional arguments in .format() call."""

297

message = "'...'.format(...) has unused arguments at position(s): %s"

298

299

def __init__(self, filename: str, loc, extra_positions): ...

300

301

class StringDotFormatExtraNamedArguments(Message):

302

"""Extra named arguments in .format() call."""

303

message = "'...'.format(...) has unused named argument(s): %s"

304

305

def __init__(self, filename: str, loc, extra_keywords): ...

306

307

class StringDotFormatMissingArgument(Message):

308

"""Missing argument in .format() call."""

309

message = "'...'.format(...) is missing argument(s) for placeholder(s): %s"

310

311

def __init__(self, filename: str, loc, missing_arguments): ...

312

313

class StringDotFormatMixingAutomatic(Message):

314

"""Mixing automatic and manual field numbering."""

315

message = "'...'.format(...) mixes automatic and manual numbering"

316

317

class StringDotFormatInvalidFormat(Message):

318

"""Invalid format specifier."""

319

message = "'...'.format(...) has invalid format string: %s"

320

321

def __init__(self, filename: str, loc, error): ...

322

```

323

324

### Percent Formatting Messages

325

326

Messages for percent-style string formatting issues.

327

328

```python { .api }

329

class PercentFormatInvalidFormat(Message):

330

"""Invalid percent format string."""

331

message = "'...' %% ... has invalid format string: %s"

332

333

def __init__(self, filename: str, loc, error): ...

334

335

class PercentFormatMixedPositionalAndNamed(Message):

336

"""Mixed positional and named formatting."""

337

message = "'...' %% ... has mixed positional and named placeholders"

338

339

class PercentFormatUnsupportedFormatCharacter(Message):

340

"""Unsupported format character."""

341

message = "'...' %% ... has unsupported format character %r"

342

343

def __init__(self, filename: str, loc, c): ...

344

345

class PercentFormatPositionalCountMismatch(Message):

346

"""Wrong number of positional arguments."""

347

message = "'...' %% ... has %d placeholder(s) but %d substitution(s)"

348

349

def __init__(self, filename: str, loc, n_placeholders: int, n_substitutions: int): ...

350

351

class PercentFormatExtraNamedArguments(Message):

352

"""Extra named arguments in percent formatting."""

353

message = "'...' %% ... has unused named argument(s): %s"

354

355

def __init__(self, filename: str, loc, extra_keywords): ...

356

357

class PercentFormatMissingArgument(Message):

358

"""Missing argument in percent formatting."""

359

message = "'...' %% ... is missing argument(s) for placeholder(s): %s"

360

361

def __init__(self, filename: str, loc, missing_arguments): ...

362

363

class PercentFormatExpectedMapping(Message):

364

"""Expected mapping for named formatting."""

365

message = "'...' %% ... expected mapping but got sequence"

366

367

class PercentFormatExpectedSequence(Message):

368

"""Expected sequence for positional formatting."""

369

message = "'...' %% ... expected sequence but got mapping"

370

371

class PercentFormatStarRequiresSequence(Message):

372

"""Star format requires sequence."""

373

message = "'...' %% ... `*` specifier requires sequence"

374

```

375

376

## Complete Message Class List

377

378

All 48 message classes available in pyflakes.messages:

379

380

1. `Message` - Base class

381

2. `UnusedImport` - Unused import statement

382

3. `RedefinedWhileUnused` - Name redefined before use

383

4. `ImportShadowedByLoopVar` - Import shadowed by loop variable

384

5. `ImportStarNotPermitted` - Star import outside module level

385

6. `ImportStarUsed` - Star import used

386

7. `ImportStarUsage` - Name may be from star import

387

8. `UndefinedName` - Undefined name reference

388

9. `DoctestSyntaxError` - Doctest syntax error

389

10. `UndefinedExport` - Undefined name in __all__

390

11. `UndefinedLocal` - Local variable referenced before assignment

391

12. `DuplicateArgument` - Duplicate function argument

392

13. `MultiValueRepeatedKeyLiteral` - Repeated dictionary key literal

393

14. `MultiValueRepeatedKeyVariable` - Repeated dictionary key variable

394

15. `LateFutureImport` - Late __future__ import

395

16. `FutureFeatureNotDefined` - Undefined __future__ feature

396

17. `UnusedVariable` - Unused variable assignment

397

18. `UnusedAnnotation` - Unused type annotation

398

19. `UnusedIndirectAssignment` - Unused global/nonlocal statement

399

20. `ReturnOutsideFunction` - Return outside function

400

21. `YieldOutsideFunction` - Yield outside function

401

22. `ContinueOutsideLoop` - Continue outside loop

402

23. `BreakOutsideLoop` - Break outside loop

403

24. `DefaultExceptNotLast` - Default except not last

404

25. `TwoStarredExpressions` - Multiple starred expressions

405

26. `TooManyExpressionsInStarredAssignment` - Too many expressions in starred assignment

406

27. `IfTuple` - If with tuple literal

407

28. `AssertTuple` - Assert with tuple

408

29. `ForwardAnnotationSyntaxError` - Forward annotation syntax error

409

30. `RaiseNotImplemented` - Raise NotImplemented

410

31. `InvalidPrintSyntax` - Invalid print syntax

411

32. `IsLiteral` - Identity comparison with literal

412

33. `FStringMissingPlaceholders` - F-string without placeholders

413

34. `TStringMissingPlaceholders` - T-string without placeholders

414

35. `StringDotFormatExtraPositionalArguments` - Extra positional args in .format()

415

36. `StringDotFormatExtraNamedArguments` - Extra named args in .format()

416

37. `StringDotFormatMissingArgument` - Missing argument in .format()

417

38. `StringDotFormatMixingAutomatic` - Mixed numbering in .format()

418

39. `StringDotFormatInvalidFormat` - Invalid format in .format()

419

40. `PercentFormatInvalidFormat` - Invalid percent format

420

41. `PercentFormatMixedPositionalAndNamed` - Mixed percent format types

421

42. `PercentFormatUnsupportedFormatCharacter` - Unsupported percent format char

422

43. `PercentFormatPositionalCountMismatch` - Percent format count mismatch

423

44. `PercentFormatExtraNamedArguments` - Extra named args in percent format

424

45. `PercentFormatMissingArgument` - Missing argument in percent format

425

46. `PercentFormatExpectedMapping` - Expected mapping in percent format

426

47. `PercentFormatExpectedSequence` - Expected sequence in percent format

427

48. `PercentFormatStarRequiresSequence` - Star requires sequence in percent format

428

429

## Usage Examples

430

431

### Message Type Filtering

432

433

```python

434

import pyflakes.api

435

from pyflakes.messages import UnusedImport, UnusedVariable, UndefinedName

436

437

def categorize_issues(code: str, filename: str):

438

"""Categorize issues by type."""

439

import ast

440

import pyflakes.checker

441

442

tree = ast.parse(code, filename=filename)

443

checker = pyflakes.checker.Checker(tree, filename=filename)

444

445

categories = {

446

'unused_imports': [],

447

'unused_variables': [],

448

'undefined_names': [],

449

'other': []

450

}

451

452

for message in checker.messages:

453

if isinstance(message, UnusedImport):

454

categories['unused_imports'].append(message)

455

elif isinstance(message, UnusedVariable):

456

categories['unused_variables'].append(message)

457

elif isinstance(message, UndefinedName):

458

categories['undefined_names'].append(message)

459

else:

460

categories['other'].append(message)

461

462

return categories

463

464

# Usage

465

code = """

466

import os

467

import sys

468

unused_var = 42

469

print(undefined_name)

470

"""

471

472

issues = categorize_issues(code, 'test.py')

473

print(f"Unused imports: {len(issues['unused_imports'])}")

474

print(f"Undefined names: {len(issues['undefined_names'])}")

475

```

476

477

### Custom Message Handling

478

479

```python

480

import pyflakes.api

481

from pyflakes.messages import Message

482

483

class CustomMessageHandler:

484

"""Custom handler for pyflakes messages."""

485

486

def __init__(self):

487

self.errors = []

488

self.warnings = []

489

self.info = []

490

491

def process_message(self, message: Message):

492

"""Process a single message."""

493

error_types = {

494

'UndefinedName', 'UndefinedLocal', 'UndefinedExport',

495

'DoctestSyntaxError', 'ForwardAnnotationSyntaxError'

496

}

497

498

warning_types = {

499

'UnusedImport', 'UnusedVariable', 'RedefinedWhileUnused',

500

'ImportStarUsed', 'IsLiteral'

501

}

502

503

message_type = type(message).__name__

504

505

if message_type in error_types:

506

self.errors.append(message)

507

elif message_type in warning_types:

508

self.warnings.append(message)

509

else:

510

self.info.append(message)

511

512

def get_summary(self):

513

"""Get summary of processed messages."""

514

return {

515

'errors': len(self.errors),

516

'warnings': len(self.warnings),

517

'info': len(self.info),

518

'total': len(self.errors) + len(self.warnings) + len(self.info)

519

}

520

521

# Usage with checker

522

import ast

523

import pyflakes.checker

524

525

code = """

526

import os

527

x = 1

528

print(y)

529

"""

530

531

tree = ast.parse(code, 'test.py')

532

checker = pyflakes.checker.Checker(tree, 'test.py')

533

534

handler = CustomMessageHandler()

535

for message in checker.messages:

536

handler.process_message(message)

537

538

summary = handler.get_summary()

539

print(f"Summary: {summary}")

540

```