This is an old revision of the document!
Python Packaging Best Practices
Slightly opinionated, but nevertheless informed (imho) list of Python Packaging Best Practices, based on copious amounts of experience with many diverse Python projects, as a user and a packager.
This list seeks to be “tool” (solution) agnostic where possible, and describe things in terms of needs and outcomes, with the driving motivations being:
- PEP20 relevant (obvious, explicit, etc)
- Reducing friction, saving (everyone) time.
- Making your software easy to consume
- Encouraging contributions to your software
- Transcending the “downstream vs upstream divide”
We'll flesh out the motivations and caveats later.
Note: setup.py means setup.py or setup.cfg or other equivalent one place that has your package metadata.
Cheatsheet
General
- Have a clear LICENSE
- Pick a well-defined existing LICENSE.
- Have a LICENSE file in your repository
- Include LICENSE file to the source distribution (sdist). Use
MANIFEST.inorsetup.py:data_files - Define LICENSE in
setup.py:license
- Clearly declare exact Python version support.
setup.py:python_requires. This should at least match your CI coverage.
Dependencies
- Declare all dependencies in one place, in one way. This includes optional dependencies (
setup.py:extras_require) - Put development dependencies in
extras_require, nottests_require(- Understand the distinctions between development and user testing (eg: the latter doesnt want/need coverage tests)
Tests
- Have a HOW TO RUN TESTS section in your README in the repository root.
- Have one entry point, and ideally one command to run tests.
- Include tests, test data files, and test related files in the source distribution.
- Tests that need some external thing (package, file, environment) SKIP not FAIL if that test requirement is not fulfilled.
- Run tests using the the source distribution. This gets you coverage of the user test scenario and tests the complete packaging pipeline.