/cookiecutter-pylibrary

Enhanced cookiecutter template for Python libraries.

Primary LanguagePython

cookiecutter-pylibrary

Cookiecutter template for a Python python library. Travis-CI Build Status AppVeyor Build Status

Notes:

Features

This is an "all inclusive" sort of template.

  • BSD 2-clause license.
  • Tox for managing test environments for Python 2.6, 2.7, 3.3, PyPy etc.
  • Pytest or Nose 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 or Codecov 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)

Requirements

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

Usage

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
"no"
Make C extensions optional (will allow your package to install even if extensions can't be compiled)
test_matrix_configurator
"no"
Enable the test matrix generator script. If you don't have a huge number of test environments then probably you don't need this.
test_runner
"pytest"
Test runner to use. Available options: pytest or nose.
command_line_interface
"plain"

Option to enable a CLI (a bin/executable file). Available options:

  • plain - a very simple command.
  • click - a command implemented with click - which you can use to build more complex commands.
  • no - no CLI at all.
cookiecutter.coveralls
"yes"
Enable pushing coverage data to Coveralls and add badge in README.rst.
cookiecutter.codecov
"no"

Enable pushing coverage data to Codecov and add badge in README.rst.

Note: Doesn't support pushing C extension coverage yet.

cookiecutter.landscape
"no"
Add a Landscape badge in README.rst.
cookiecutter.scrutinizer
"no"
Add a Scrutinizer badge in README.rst.
cookiecutter.codacy
"no"

Add a Codacy badge in README.rst.

Note: After importing the project in Codacy, find the hexadecimal project ID from settings and replace it in badge URL
cookiecutter.codeclimate
"no"
Add a CodeClimate badge in README.rst.
sphinx_theme
"readthedocs"

What Sphinx theme to use.

If theme is different than "readthedocs" then it's also going to be added in docs/requirements.txt.

Suggested alternative: sphinx-py3doc-enhanced-theme <https://pypi.python.org/pypi/sphinx_py3doc_enhanced_theme> for a responsive theme based on the Python 3 documentation.

travis
"yes"
If you want the Travis_ badge and configuration.
appveyor
"yes"
If you want the AppVeyor badge and configuration.
requiresio
"yes"
If you want the requires.io badge and configuration.

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 bootstrap

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 git@github.com:ionelmc/python-nameless.git
git push -u origin master

Then:

Developing the project

To run all the tests, just run:

tox

To see all the tox environments:

tox -l

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

Releasing the project

Before releasing your package on PyPI you should have all the tox environments passing.

Version management

This template provides a basic bumpversion configuration. It's as simple as running:

  • bumpversion patch to increase version from 1.0.0 to 1.0.1.
  • bumpversion minor to increase version from 1.0.0 to 1.1.0.
  • bumpversion major to increase version from 1.0.0 to 2.0.0.

You should read Semantic Versioning 2.0.0 before bumping versions.

Building and uploading

To make a release of the project on PyPI, the most simple usage is:

python setup.py release
twine upload dist/*

Explanations:

  • release is aliased to register clean sdist bdist_wheel, see setup.cfg.
  • twine is a tool that you can use to securely upload your releases to PyPI.

Changelog

See CHANGELOG.rst.

Questions & answers

There's no Makefile?

Sorry, no Makefile yet. The Tox environments stand for whatever you'd have in a Makefile.

Why does tox.ini have a passenv = *?

Tox 2.0 changes the way it runs subprocesses - it no longer passes all the environment variables by default. This causes all sorts of problems if you want to run/use any of these with Tox: SSH Agents, Browsers (for Selenium), Appengine SDK, VC Compiler and so on.

cookiecutter-pylibrary errs on the side of convenience here. You can always remove passenv = * if you like the strictness.

Why is the version stored in several files (pkg/__init__.py, setup.py, docs/conf.py)?

We cannot use a metadata/version file [1] because this template is to be used with both distributions of packages (dirs with __init__.py) and modules (simple .py files that go straigh in site-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.

[1]Example, an __about__.py file.

Not Exactly What You Want?

No way, this is the best. 😜

If you have criticism or suggestions please open up an Issue or Pull Request.