Tools III: Linters
OverviewTeaching: 10 min
Exercises: 5 minQuestions
How to make the editor pro-actively find errors and code-smellsObjectives
Remember how to install and use a linter in vscode without sweat
What is linting?
Linters enforce style rules on your code such as:
- disallow one letter variables outside of loops
- disallow nesting more than n deep
- detect code-smells (patterns that are often bugs, e.g. two functions with the same name)
- static type detection (mypy) where we tell the editor
what kind of objects (
int, etc) a function expects
Consistent styles make a code more consistent an easier to read, whether or not you agree with the style. Using an automated linter avoids bike-shedding since the linter is the final arbiter.
Why does linting matter?
- Code is read more often than written
- Setting up a linter in your editor takes 5 minutes
- Those 5 minutes are redeemed across the lifetime of the project
- Linters shortcut the
edit-run-debug and repeatworkflow
Rules for choosing linters
- Choose a few
- Stick with them
- flake8 because it is simple
- pylint because it is (too?) extensive
- mypy because it helps keep track of object types
Setup VS Code:
- Open Settings (see previous exercise if you’re not sure how):
- Search for “linting enable” and check the box for “Python > Linting: Enabled”.
- Search for “pylint enabled” and check the box for “Python > Linting: Pylint Enabled” (you may need to scroll down for this one).
- Search for “pylint use” and uncheck the box for “Python > Linting: Pylint Use Minimal Checkers”.
- Search for “flake8 enabled” and check the box for “Python > Linting: Flake8 Enabled”.
- Search for “mypy enable” and check the box for “Python > Linting: Mypy Enabled”.
Create a file
unlinted.pywith the following code and save it:
from typing import List class printer: pass def ActionatePrinters(printers: List[printer]): # pylint: disable=missing-docstring printing_actions =  for p in printers: if p == None: continue def action(): print(p) printing_actions.append(action) p = "something" print(p) for action in printing_actions: action() ActionatePrinters([1, 2, 2])
- Check the current errors (click on errors in status bar at the bottom)
- Try and correct them
- Alternatively, try and disable them (but remember: with great power…). We’ve already disabled-one at the function scope level. Check what happens if you move it to the top of the file at the module level.
Linting is about discovering errors and code-smells before running the code
It shortcuts the “edit-run-debug and repeat” workflow
Almost all editors and IDEs have some means to setup automatic linting
5 minutes to setup a linter is redeemed across the time of the project i.e. the cost is close to nothing