= 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.in``` or ```setup.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 (```setup.py:extras_require```) and test dependencies (```setup.py:tests_require```) * Put development dependencies in ```extras_require[dev]```, not `tests_require```. They are not compulsory. * Understand the distinctions between development and user testing (eg: the latter doesn't want/need coverage, pylint, pep8 etc). * Use `>=` version specs for '''distribution''' dependencies. * Understand the distinctions between packaging and deployment (pinned) dependencies. * Use these for development testing too. This makes sure issues are picked up in development '''early''', and '''before''' releases/users. * Use the '''lowest''' supported version of a dependency that your code '''requires'''. === Tests === * Have a '''HOW TO RUN TESTS''' section in your README in the repository root. Noone should need to go looking. * Have '''one''' entry point, and ideally one command to run tests. * Include tests, test data files, and test ''related'' files in the source distribution. Use ```MANIFEST.in``` and/or ```setup.py:packages``` * 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.