pyflakes

A fast, false-positive-averse Python linter that finds real errors without ever complaining about style.

Tool
PyPI
v3.4.0
1,455stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
41/100Fair
Development Activity0
Maintenance0
Community76
Maturity60
Momentum28

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
86/100Excellent
Architecture85
Code Quality88
Innovation82
Learning Curve90

Pyflakes is a lightweight static analysis tool for Python that checks source files for a focused set of real errors — unused imports, undefined names, redefinitions, unused variables, and similar mistakes. Unlike tools that import your code, Pyflakes works purely by parsing the abstract syntax tree of each file, so it is safe to run against modules with side effects and dramatically faster than heavier analyzers.

It makes a deliberate promise: it will never complain about style, and it tries very hard never to emit false positives. That narrow, high-signal scope makes it a popular foundation for larger tools — most notably Flake8, which combines Pyflakes with style checks — and a dependable first line of defense in editors, pre-commit hooks, and CI pipelines.

What You Get

  • A command-line linter (pyflakes or python -m pyflakes) that scans files and directories for errors
  • A small, importable Python API (check, checkPath, checkRecursive) for embedding checks in your own tools
  • A pluggable Reporter interface for customizing how warnings and syntax errors are formatted
  • A stable message catalog (unused imports, undefined names, redefinitions, unused variables, and more) with file:line:col output

Common Use Cases

  • Catching unused imports and undefined names before code review or commit
  • Running as the error-checking engine behind Flake8 and editor integrations
  • Wiring a fast, low-noise lint gate into pre-commit hooks and CI
  • Programmatically checking Python source from a custom build or tooling script

Under The Hood

Architecture Pyflakes is organized around three cooperating modules under pyflakes/. api.py (185 lines) is the command-line entry point and public interface, exposing check, checkPath, checkRecursive, and iterSourceCode; it parses source with ast.parse, catches syntax errors, and delegates to a Reporter. The heart of the tool is checker.py (2,223 lines), whose Checker class walks the AST, models Python scoping (module, function, class, generator, comprehension) with binding objects, and emits Message subclasses when it detects problems. messages.py defines the catalog of diagnostics (e.g. UnusedImport, RedefinedWhileUnused, UndefinedName) with printf-style templates rendered as file:line:col: message, and reporter.py formats warnings and syntax errors to stdout/stderr. Execution flows from a file path, to an AST, to a scope-aware tree walk, to a stream of formatted messages.

Tech Stack The project is pure Python (100%, ~287 KB) with zero runtime dependencies — it relies only on the standard library’s ast module, making it trivially portable across all active Python versions (3.9+). Packaging is handled the classic way via setup.py and setup.cfg, with tox.ini driving multi-version test runs. There is no compiled extension and no external toolchain, which is a large part of why it is so fast and easy to install.

Code Quality Code quality is high and battle-tested: the pyflakes/test/ suite contains 13 test modules covering the API, imports, doctests, match statements, dict literals, type annotations, and more, and the project self-lints with flake8 as a contribution requirement. Core files are cleanly separated by responsibility, use docstrings and epytext-style parameter docs, and follow consistent naming. The Checker is a large single class by necessity (AST traversal is inherently broad), but message definitions and reporting are small, focused, and easy to extend.

API Design The public surface is deliberately tiny and ergonomic. For CLI users it is a single command; for programmatic use, check(codeString, filename, reporter=None) and checkPath(filename, reporter=None) require almost no boilerplate, defaulting to a sensible reporter when none is supplied. The Reporter abstraction is the main extension point, letting integrators redirect or reformat output without touching the checker. The main friction is that its scope is intentionally narrow — there are few configuration knobs — which is by design, since flexibility is delegated to wrappers like Flake8.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search