Learning Goals
3 min- Run pylint and read its message categories + score.
- Understand the design smells it flags (too many args, complexity).
- Configure / disable rules sensibly.
- Decide where pylint adds value over ruff.
Warm-Up · Deeper Than Style
5 minruff: "unused import", "bad spacing", "likely bug" (fast, surface)
pylint: ALSO "this function has 9 arguments",
"this class has 2 public methods — is it really a class?",
"you're catching Exception too broadly",
"this method could be a function" (slow, design-level)pylint analyses your code's design, not just its surface. It flags complexity, too-many-arguments, broad excepts, and other smells that hint at deeper problems. It's opinionated (sometimes annoyingly) — but a great teacher of clean design.
New Concept · pylint's Output & Score
14 minInstall & run
pip install pylint pylint mymodule.py pylint mypackage/
Message categories (the letter prefix)
C Convention naming, docstrings, formatting R Refactor design smells (too complex, too many args) W Warning likely problems (unused var, broad except) E Error real bugs (undefined name, wrong arg count) F Fatal pylint couldn't even analyse the file Each message has a code (C0114) AND a slug (missing-module-docstring).
The score
************* Module cart cart.py:1:0: C0114: Missing module docstring (missing-module-docstring) cart.py:12:4: R0913: Too many arguments (7/5) (too-many-arguments) cart.py:20:8: W0703: Catching too general exception Exception (broad-except) ------------------------------------------------------------------ Your code has been rated at 7.50/10 (previous run: 6.20/10)
pylint scores your code out of 10. The score is a rough guide, not gospel — but watching it rise as you clean up is motivating, and teams sometimes gate on a minimum.
Configure / disable
# pyproject.toml [tool.pylint.main] max-line-length = 100 [tool.pylint."messages control"] disable = ["missing-module-docstring", "too-few-public-methods"]
x = something() # pylint: disable=unused-variable (inline, with the slug)
ruff vs pylint — use both
ruff every save / CI gate — fast, catches the common stuff pylint periodically / in review — slow, catches design smells They overlap but complement. ruff for speed; pylint for depth.
Worked Example · A Design Smell pylint Catches
12 min# order.py — works, but smells
def create_order(name, email, phone, address, item, qty, price, discount, gift):
try:
# ... lots of logic ...
return {"name": name, "total": qty * price * (1 - discount)}
except Exception: # too broad — hides real bugs
return None$ pylint order.py order.py:1:0: R0913: Too many arguments (9/5) (too-many-arguments) order.py:5:4: W0703: Catching too general exception Exception (broad-except) Your code has been rated at 5.00/10
pylint is telling you about design: 9 arguments is a sign these belong in a dataclass; a bare except Exception hides bugs. The fix improves the design, not just the lint score:
from dataclasses import dataclass @dataclass class OrderRequest: name: str; email: str; phone: str; address: str item: str; qty: int; price: float; discount: float = 0; gift: bool = False def create_order(req: OrderRequest): try: return {"name": req.name, "total": req.qty * req.price * (1 - req.discount)} except (KeyError, ValueError) as e: # specific exceptions log.warning("order failed: %s", e) return None
Read the diff
pylint pushed you toward a real improvement: group the nine parameters into an OrderRequest dataclass, and catch specific exceptions instead of swallowing everything. The score went up because the design got better. That's pylint's value — it's a design coach, where ruff is a spell-checker.
Try It Yourself
13 minRun pylint on a module. Note the score and the categories (C/R/W/E) of the findings.
Find an R finding (too-many-arguments, too-many-branches). Refactor to address it and watch the score rise.
Disable a few rules you genuinely disagree with (e.g. missing-docstring on tiny scripts) in pyproject.toml, with a comment justifying each.
Mini-Challenge · Raise the Score Honestly
8 minTake a module scoring under 7/10. Raise it above 9 by genuinely improving the code (docstrings, splitting big functions, specific excepts, dataclasses) — NOT by mass-disabling rules. Note which fixes were real improvements vs which rules you legitimately disabled.
Recap
3 minpylint is deeper and slower than ruff: it grades design (C/R/W/E categories, a /10 score), flagging smells like too-many-arguments and broad excepts. Configure it in pyproject.toml; disable rules deliberately, not reflexively. Use ruff for the fast loop and pylint periodically as a design coach. Next: formatting with black + isort.
Vocabulary Card
- pylint
- A deep, opinionated linter that also analyses design and scores code.
- code smell
- A surface symptom of a deeper design problem (e.g. too many arguments).
- message category
- C/R/W/E/F — convention, refactor, warning, error, fatal.
- broad except
- Catching
Exceptiontoo generally, hiding real bugs.
Homework
4 minRun pylint on a real module, record the starting score, then improve the code to raise it above 9/10 through genuine fixes (docstrings, smaller functions, specific excepts, dataclasses). Submit before/after scores and a short note distinguishing real improvements from rules you justifiably disabled.
Follow the order.py refactor. The graded insight: distinguish "I improved the code" from "I disabled the rule" — both are valid, but be honest about which.