Coding Standards
Last updated on 2026-10-07 | Edit this page
Overview
Questions
- What tools can help achieve the objectives?
Objectives
- Enforce uniform style in the code
- Partially compensate for duck-typing in Python code
Use the following commands if you want to save your work from the previous episode
Now use the following to get files for this episode
which should yield
OUTPUT
Makefile
analyze.py
books/abyss.txt
books/isles.txt
src/TeX/local.bib
src/TeX/report.tex
src/analysis/countwords.py
src/analysis/testzipf.py
src/plotscripts/plotcounts.py
tests/test_countwords.py
tests/test_plotcounts.py
tests/test_testzipf.py
Put this block in the Makefile:
## pylintrc : Fetch standard from google
pylintrc:
wget https://google.github.io/styleguide/pylintrc
## lint : Run pylint
.PHONY : lint
lint : pylintrc
pylint --rcfile pylintrc src
And run pylint with
Well, let’s focus on one file
OUTPUT
************* Module analysis.countwords
src/analysis/countwords.py:32:0: W1405: Quote delimiter " is inconsistent with the rest of the file (inconsistent-quotes)
src/analysis/countwords.py:89:0: W1405: Quote delimiter " is inconsistent with the rest of the file (inconsistent-quotes)
src/analysis/countwords.py:59:12: C0103: Variable name "_tuple" doesn't conform to '^[a-z][a-z0-9_]*$' pattern (invalid-name)
After fixing those let’s try again
Let’s fix those and try again
OUTPUT
pylint --rcfile pylintrc src
Check consistency of code style
YAPF Yet Another Python Formatter
Google AI says
YAPF is an open-source Python code formatter developed by Google. Unlike “opinionated” formatters like Black that enforce a single rigid standard, YAPF uses an algorithm inspired by clang-format to search for the “best” layout matching your specific configuration rules. It works by calculating the “lowest-cost” formatting decision to generate code that looks like an experienced human wrote it.
Let’s use the following block in the Makefile to run yapf
## yapf : Force google format on all python code
.PHONY : yapf
yapf :
yapf -i --recursive --style "google" src
In order to see what yapf does let’s first stage the files it might change
Since that looks good, we run yapf
OUTPUT
yapf -i --recursive --style "google" src
and check on the changes.
Check Python type hints
By default Python code does not check the types of data. At run time, the interpreter executes procedures that are appropriate for the type of the data, eg,
This is called duck typing.
Before running Python code, one can use tools such as mypy to look for consistency in types. To support that, Python supports type hints. EG,
BASH
$ cat > foo.py
a : str = '1'
b : str = '2'
print(a*b)
$ python foo.py
Traceback (most recent call last):
File "/mnt/precious/home/andy_nix/projects/SIAMDS27/learner_setup/foo.py", line 3, in <module>
print(a*b)
~^~
TypeError: can't multiply sequence by non-int of type 'str'
ds27$ mypy --strict foo.py
foo.py:3: error: Unsupported operand types for * ("str" and "str") [operator]
Found 1 error in 1 file (checked 1 source file)
$ rm foo.py
Notice that mypy found the problem before running the code.
MYPY
Google AI says
Mypy is an optional static type checker for Python that analyzes your source code to detect bugs and type mismatches before your program ever runs. Because Python is traditionally a dynamically typed language, typos or invalid variable types normally crash your application at runtime. Mypy acts like a powerful linter, scanning your type annotations (type hints) to ensure type consistency across your codebase.
Here is the Makefile block that we will use to invoke mypy
## check-types : Checks type hints
.PHONY : check-types
check-types:
export MYPYPATH=$$PYTHONPATH; mypy --strict src/analysis
And here is what mypy has to say about our code
OUTPUT
export MYPYPATH=$PYTHONPATH; mypy --strict src/analysis
src/analysis/testzipf.py:9: error: Missing type parameters for generic type "list" [type-arg]
src/analysis/testzipf.py:30: error: Missing type parameters for generic type "list" [type-arg]
src/analysis/testzipf.py:45: error: Function is missing a type annotation [no-untyped-def]
src/analysis/testzipf.py:84: error: Call to untyped function "main" in typed context [no-untyped-call]
src/analysis/countwords.py:10: error: Function is missing a type annotation [no-untyped-def]
src/analysis/countwords.py:29: error: Need type annotation for "counts" (hint: "counts: dict[<type>, <type>] = ...") [var-annotated]
src/analysis/countwords.py:65: error: Function is missing a type annotation [no-untyped-def]
src/analysis/countwords.py:85: error: Call to untyped function "word_count" in typed context [no-untyped-call]
src/analysis/countwords.py:91: error: Call to untyped function "main" in typed context [no-untyped-call]
Found 9 errors in 2 files (checked 2 source files)
make: *** [Makefile:49: check-types] Error 1
Let’s address those issues now.
- We use yapf to coerce Python code into standard use of white space
- We use lint to detect deviations of our Python code from standards specified in pylintrc
- We use mypy to check our use of Python type hints