Template for a Python project.
MIT License
This repository aims to provide a starting template for Python projects containing the most important configuration files (which have to be tailored for your project!) and an initial directory structure separating source code and tests.
I tried to incorporate most "best practices" but in the end, most of the design choices and tools are just personal preferences.
The following tools are used: black, covdefaults, coverage, pre-commit, pylint, pytest, tox
All of the source code goes into the src/<project-name> directory. Here, some dunder files can be found:
__init__.py
allowing calls via python -m <prog>
Testing is done with pytest
and tox
. All tests go into the test directory. Pytest automatically finds all directories
and modules as well as functions and classes within these matching test_*.py
/*_test.py
files, Test*
classes, and test_*
functions and methods (automatic test discovery).
The conftest.py file is sort of a setup file that can be used to create additional configurations/hooks (small example) and setup code (fixtures) for all tests.
The test environment for pytest is setup with the setup.cfg
and/or pyproject.toml
file. tox
needs extra configuration
which can be found in the deps section of tox.ini. Some projects also use a requirements-tests.txt
file that lists
all test dependencies and is also given in the deps section with deps = -rrequirements-tests.txt
.
Furthermore, to run pytest from tox, the commands
section must be given. Here, additional options for the code coverage report
from the coverage
tool are given.
When to use pytest, coverage and tox?
Personally, I mostly use just pytest without coverage to test in my working environment with pytest -svv test
or a specific
test module. Before committing, however, it is a good idea to check if your code also runs in different environments, which is where
tox
comes in. Running just tox
, will test in all environments specified in tox.ini's envlist and may take some
time. Certain environments can be selected with tox -e py37
. Note that tox
must be able to find a Python interpreter for
each version given in the envlist.
Unfortunately, this does not directly work with something like a conda environment but you can setup the environments and provide a symlink to a directory which is in your path.
mamba create --name "py311" python=3.11 -y
ln -s /opt/miniforge3/envs/py311/bin/python3.11 ~/bin/python3.11
Finally, some handy features of pytest you should be aware of:
with pytest.raises(Exception): ...
or @pytest.mark.xfail
)Packaging is done with setuptools
, which is configured through the pyproject.toml
and/or setup.cfg
/setup.py
files.
The setup.py
file is a Python script and configuration is passed through keyword arguments of setuptools.setup()
. This is not recommended due to possible security and parsing issues. The same setup can be accomplished in a declarative style within setup.cfg
and setup.py
remains mostly empty only calling setuptools.setup()
.
The pyproject.toml
file aims to unify configuration files including various tools like black or pytest. For packaging, it is very similar to setup.cfg
. However, pyproject.toml
has not been adopted as the default yet and many projects still use setup.cfg
to declare the packaging setup. Note that setup.py
is not necessary if a pyproject.toml
is present.
pyproject.toml
setup.cfg
src/
layoutMANIFEST.in
The package can be installed with pip install .
or something like pip install .[dev]
to also install additional dependencies specified in setup.cfg
's options.extras_require. Pass the -e
flag for editable mode, which loads the package from the source directory, i.e., changing the source code does not require a new installation.
Important! CI in private repositories is generally limited (to x minutes of execution time).
...
Tools
Websites