Python
Samples
Install and check
See my Makefile in py-project-template, I have refined that over time to work well for me.
Check types
For MyPy, see Mypy - Add to project guide in this cookbook project.
Mypy and Read The Docs
From: github.com/willmcgugan
Makefile
- I am interested in the Mypy lines here.test: pytest --cov-report term-missing --cov=rich tests/ -vv format: black --check rich typecheck: mypy -p rich --ignore-missing-imports --warn-unreachable typecheck-report: mypy -p rich --ignore-missing-imports --warn-unreachable --html-report mypy_report .PHONY: docs docs: cd docs && make html
docs/Makefile
- build Read The Docs site with Sphinx.# Minimal makefile for Sphinx documentation # # You can set these variables from the command line, and also # from the environment for the first two. SPHINXOPTS ?= SPHINXBUILD ?= sphinx-build SOURCEDIR = source BUILDDIR = build # Put it first so that "make" without argument is like "make help". help: @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) .PHONY: help Makefile # Catch-all target: route all unknown targets to Sphinx using the new # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). %: Makefile @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
Clean
clean:
find . -name '*.pyc' -delete
Install, check and clean
That does not deal with cleaning a project or handling a Python package install / clean flow. So for interest see also this project copied from article
The clean command is probably out of date for PY3 work.
For find
:
The plus sign at the end of the command is for
-exec command {}
which means that the total number of invocations of the command will be much less than the number of matched files.
TEST_PATH=./
clean-pyc:
find . -name '*.pyc' -exec rm --force {} +
find . -name '*.pyo' -exec rm --force {} +
name '*~' -exec rm --force {}
clean-build:
rm --force --recursive build/
rm --force --recursive dist/
rm --force --recursive *.egg-info
isort:
sh -c "isort --skip-glob=.tox --recursive . "
lint:
flake8 --exclude=.tox
test: clean-pyc
py.test --verbose --color=yes $(TEST_PATH)
run:
python manage.py runserver
Removing .pyc
files might be different for pycache dir in newer PY3 or even the global dir.
Optionally add this at the top to prevent a file with that name from being executed of the make
target.
.PHONY: clean-pyc clean-build
Running with parameters
Makefile
run: python manage.py runserver --host $(HOST) --port $(PORT)
Run:
$ make run HOST=127.0.0.1 PORT=8000
Environment variables
Note here the virtual env directory is .venv
, though I prefer venv
. Which is also the name of the Python venv
module used.
VIRTUALENV = python3 -m venv
SPHINX_BUILDDIR = docs/_build
VENV := $(shell realpath $${VIRTUAL_ENV-.venv})
PYTHON = $(VENV)/bin/python3
DEV_STAMP = $(VENV)/.dev_env_installed.stamp
DOC_STAMP = $(VENV)/.doc_env_installed.stamp
INSTALL_STAMP = $(VENV)/.install.stamp
TEMPDIR := $(shell mktemp -d)
ZOPFLIPNG := zopflipng
This allows things like this:
virtualenv: $(PYTHON)
$(PYTHON):
$(VIRTUALENV) $(VENV)
black: install-dev ## Run the tests
$(VENV)/bin/black --target-version=py34 .
Though it is a lot easier if you only run make
inside a virtual env locally (and not in a virtualenv on CI). Anyway there it is.
Temp directory is used for:
foo:
mkdir $(TEMPDIR)/zopfli
Linting
Spellcheck
On comments and docstrings.
spell:
@pylint --disable all --enable spelling --spelling-dict en_US --spelling-private-dict-file spell.txt my_app
Full
Based on Redmine CLI.
venv:
python3 -m venv venv
install:
pip install -e .
install-dev:
pip install -r requirements-dev.txt
lint:
flake8 --max-line-length 88 abc/ tests/
isort -rc -c abc/ tests/
test:
pytest
coverage:
pytest --cov=abc
clean:
rm -rf build dist *.egg-info venv
bdist:
python3 setup.py sdist bdist_wheel
upload:
twine upload dist/*
From dingy.
.PHONY: help clean requirements
.DEFAULT_GOAL := help
help: ## display this help message
@echo "Please use \`make <target>' where <target> is one of"
@awk -F ':.*?## ' '/^[a-zA-Z]/ && NF==2 {printf "\033[36m %-25s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST) | sort
clean: ## remove stuff we don't need
find . -name '__pycache__' -exec rm -rf {} +
find . -name '*.pyc' -exec rm -f {} +
find . -name '*.pyo' -exec rm -f {} +
find . -name '*~' -exec rm -f {} +
rm -fr build/ dist/ src/*.egg-info
rm -fr .*_cache/
rm -f out_*.json
requirements: ## install development environment requirements
pip install -r dev-requirements.txt
.PHONY: test quality black lint
test: ## run tests in the current virtualenv
pytest tests
quality: black lint ## run code-checking tools
black:
black -q src tests
lint:
pylint src tests
.PHONY: dist pypi testpypi
dist: ## build the distributions
python -m check_manifest
python -m build --sdist --wheel
python -m twine check dist/*
pypi: ## upload the built distributions to PyPI.
python -m twine upload --verbose dist/*
testpypi: ## upload the distrubutions to PyPI's testing server.
python -m twine upload --verbose --repository testpypi dist/*
Quality checks and formatitng
Based on promptsource.
Without config files.
CHECK_DIRS = my_app
LINE_LENGTH = 119
fmt-check:
black $(CHECK_DIRS) --line-length $(LINE_LENGTH) --target-version py38 --check
isort $(CHECK_DIRS) --check-only
flake8 $(CHECK_DIRS) --max-line-length $(LINE_LENGTH)
fmt:
black $(CHECK_DIRS) --line-length $(LINE_LENGTH) --target-version py38
isort $(CHECK_DIRS)