3 # "Build" a given Python file `foo`: format it, type-check it, lint it, and
4 # generate the final file from the `foo.in` file.
6 # The following Python tools are used by this script.
9 # - `black`, for general formatting. This avoids the need for style checkers
10 # like `flake8`. Note that `black` allows a max line length of 88, which is
11 # a mild but common PEP-8 violation.
12 # - `isort`, for import sorting.
15 # - `mypy`. This is the most commonly used Python type checker.
16 # - `pyright`. This is another good type checker.
17 # - Sometimes they give different result. Both should be kept happy.
20 # - `ruff`. Sometimes useful, and very fast to run.
21 # - `pylint`. Sometimes annoying, sometimes useful. The `pylintrc`
22 # modifies/disables the more annoying lints.
23 # - Sometimes they give different result. Both should be kept happy.
25 # The following tools are relevant, but not run by this script.
28 # - `cProfile` + `snakeviz`: Typically run with
29 # `python3 -m cProfile -o cg.prof cg_annotate $INPUT && snakeviz cg.prof`.
30 # - `scalene`. Typically run with `scalene ./cg_annotate $INPUT`.
33 # - `cp` is used for distribution. This is possible because this program is a
34 # single file and only uses the Python Standard Library. This avoids the
35 # needs for any of the million different Python package management tools.
37 # All of the above tools can be installed with `pip3 install $NAME`, except
38 # `cProfile` which is built into Python.
42 # Currently targetting Python 3.9 (released in October 2020) and up. The tools
43 # use two different syntaxes for specifying the version number.
50 if [ -z "$outfile" ] ; then
63 mypy
--strict $infile --python-version $ver
66 # Strict mode for pyright is enabled by a `pyright: strict` comment inside each
69 # Note: `pyright` refuses to check any file without a `.py` extension, hence
70 # the copying to a temp file with a `.py` extension.
72 tmpfile
=`mktemp --tmpdir $infile.XXX.py`
73 echo "program output" >> $tmpfile
75 pyright
--pythonversion $ver $tmpfile
80 ruff check
--target-version $pyver $infile
84 pylint
--rcfile=$auxprogs/pylintrc
--py-version $ver $infile
86 echo "== config.status =="