Cookiecutter template for a Python python library.
Notes:
- This is largely designed to address this blog post about packaging python
libraries.
- ... and it will save you from packaging pitfalls.
- There's a bare library using this template (if you're curious about the final result): https://github.com/ionelmc/python-nameless.
- There's also a minimal version of this, see [1]
This is an "all inclusive" sort of template.
- BSD 2-clause license.
- Tox and Pytest for testing Python 2.6, 2.7, 3.3, PyPy etc.
- Optional support for creating a tests matrix out of dependencies and python versions.
- Travis-CI and AppVeyor for continuous testing.
- Coveralls for coverage tracking (using Tox).
- Documentation with Sphinx, ready for ReadTheDocs.
- Configurations for:
- Support for C extensions (including coverage measurement for the C code).
- Packaging and code quality checks. This template comes with a tox environment (
check
) that will:- Check if your
README.rst
is valid. - Check if the
MANIFEST.in
has any issues. - Run
flake8
(a combo of PEP8, pyflakes and McCabe checks)
- Check if your
Projects using this template have these minimal dependencies:
- Cookiecutter - just for creating the project
- Tox - for running the tests
- Setuptools - for building the package, wheels etc. Now-days Setuptools is widely available, it shouldn't pose a problem :)
To get quickly started on a new system, just install setuptools and then install pip. That's the bare minimum to required install Tox and Cookiecutter. To install them, just run this in your shell or command prompt:
pip install tox cookiecutter
This template is more involved than the regular cookiecutter-pypackage.
First generate your project:
cookiecutter gh:ionelmc/cookiecutter-pylibrary
You will be asked for these fields:
Template variable | Default | Description |
---|---|---|
project_name |
"Nameless" |
Verbose project name, used in headings (docs, readme, etc). |
repo_name |
"python-nameless" |
Repository name on github. |
package_name |
"nameless" |
Python package name (whatever you would import). |
distribution_name |
"nameless" |
PyPI distribution name (what you would pip install ). |
c_extension_support |
"no" |
Support C extensions (will slighly change the outputted setup.py ) |
c_extension_optional |
"yes" |
Make C extensions optional (will allow your package to install even if extensions can't be compiled) |
test_matrix_configurator |
"yes" |
Enable the test matrix generator script. If you don't have a huge number of test environments then probably you don't need this. |
The testing (tox.ini
and .travis.yml
) configuration is generated from templates. For your convenience there's an
initial bootstrap tox.ini
, to get the initial generation going just run:
tox
You can later regenerate tox.ini
and .travis.yml
by running (if you enabled the test_matrix_configurator
option):
tox -e configure
After this you can create the initial repository (make sure you create an empty Github project):
git init . git add . git commit -m "Initial skel." git remote add origin [email protected]:ionelmc/python-nameless.git git push -u origin master
Then:
- Enable the repository in your Travis CI account.
- Enable the repository in your Coveralls account.
- Add the repo to your ReadTheDocs account + turn on the ReadTheDocs
service hook. Don't forget to enable virtualenv and specify
docs/requirements.txt
as the requirements file in Advanced Settings.
To run all the tests, just run:
tox
To see all the tox environments:
tox --listenvs
To only build the docs:
tox -e docs
To build and verify that the built package is proper and other code QA checks:
tox -e check
Before releasing your package on PyPI you should have all the tox environments passing.
To make a release of the project on PyPI, the most simple usage is:
python setup.py release
(release
is aliased to register clean sdist bdist_wheel upload
, see setup.cfg
).
If you care about security you can do secure uploads to PyPI using twine.
There's no Makefile?
Sorry, noMakefile
yet. The Tox environments stand for whatever you'd have in aMakefile
.
Why is the version stored in several files (pkg/__init__.py
, setup.py
, docs/conf.py
)?
We cannot use a metadata/version file [2] because this template is to be used with both distributions of packages (dirs with
__init__.py
) and modules (simple.py
files that go straigh insite-packages
). There's no good place for that extra file if you're distributing modules.But this isn't so bad - bumpversion manages the version string quite neatly.
No way, this is the best. 😜
[1] | In case you don't fancy pytest there's a simpler variant of this template that doesn't use Pytest. Just bare crappy unittest . |
[2] | Example, an __about__.py file. |
If you have criticism or suggestions please open up an Issue or Pull Request.