61 lines
3.8 KiB
Markdown
61 lines
3.8 KiB
Markdown
cookiecutter-pypackage-minimal
|
|
==============================
|
|
|
|
An opinionated, minimal [cookiecutter](https://github.com/audreyr/cookiecutter) template for Python packages, and some guidelines for Python packaging.
|
|
|
|
Usage
|
|
-----
|
|
|
|
pip install cookiecutter
|
|
git clone https://github.com/kragniz/cookiecutter-pypackage-minimal.git
|
|
cookiecutter cookiecutter-pypackage-minimal/
|
|
|
|
You should then change the classifiers in `{{ package_name }}/setup.py` - it is assumed that the project will run on the latest versions of Python 2 and 3, so you should remove any classifiers that do not apply. The full list of PyPI classifiers can be found [here](https://pypi.org/classifiers/).
|
|
|
|
Fill out the README, and - if necessary - [choose a license](https://choosealicense.com/) for the project.
|
|
|
|
Explanation
|
|
-----------
|
|
|
|
The decisions `cookiecutter-pypackage-minimal` makes should all be explained here.
|
|
|
|
### README
|
|
|
|
* **README should use reStructuredText format**
|
|
This is the format used by most Python tools, is expected by [setuptools](https://setuptools.readthedocs.io), and can be used by [Sphinx](http://sphinx-doc.org/).
|
|
* **As few README files as possible**
|
|
Additional README files (AUTHORS, CHANGELOG, etc) should be left to the user to create when necessary.
|
|
|
|
### LICENSE
|
|
|
|
* **LICENSE can use reStructuredText format**
|
|
The provided license file use reStructuredText format. Of course you can decide to use a text format or even [Markdown](https://en.wikipedia.org/wiki/Markdown). It's up to you to choose the format which best satisfies your needs.
|
|
* **MIT license by default**
|
|
This template provides you the classic [MIT](https://choosealicense.com/licenses/mit/) licence: it lets people do almost anything they want with your project, including to make and distribute closed source versions.
|
|
If you [choose another license](https://choosealicense.com/), you also need to update the `{{ package_name }}/setup.py` file:
|
|
adjust the `classifiers` and `license` fields accordingly.
|
|
* **A license is a requirement**
|
|
Nowadays, people who want to use your library/application want to make sure they can do it legally.
|
|
If your library is a private library, you can use a private license. In the `{{ package_name }}/setup.py` file, set `license="Proprietary"`, and choose `'License :: Other/Proprietary License'` in the trove classifiers.
|
|
|
|
### `setup.py`
|
|
|
|
* **Use setuptools**
|
|
It's the standard packaging library for Python. `distribute` has merged back into `setuptools`, and `distutils` is less capable.
|
|
* **setup.py should not import anything from the package**
|
|
When installing from source, the user may not have the packages dependencies installed, and importing the package is likely to raise an `ImportError`.
|
|
* **setup.py should be the canonical source of package dependencies**
|
|
There is no reason to duplicate dependency specifiers (i.e. also using a `requirements.txt` file). See the testing section below for testing dependencies.
|
|
|
|
### Testing
|
|
|
|
* **Use [Tox](https://tox.readthedocs.io) to manage test environments**
|
|
Tox provides isolation, runs tests across multiple Python versions, and ensures the package can be installed.
|
|
* **Uses [pytest](https://docs.pytest.org) as the default test runner**
|
|
This can be changed easily, though pytest is a easier, more powerful test library and runner than the standard library's unittest.
|
|
* **Define testing dependencies in `tox.ini`**
|
|
Avoid duplicating dependency definitions, and use `tox.ini` as the canonical description of how the unittests should be run.
|
|
* **`tests` directory should not be a package**
|
|
The `tests` directory should not be a Python package unless you want to define some fixtures.
|
|
But the best practices are to use [PyTest fixtures](https://docs.pytest.org/en/latest/fixture.html) which provides a better solution.
|
|
Therefore, the `tests` directory has no `__init__.py` file.
|