
1. Testing
1.1. Unit tests
1.1.1. Use pytest
1.1.2. Ideal unit tests should be
1.1.2.1. Fast
1.1.2.2. Isolated
1.1.2.3. Repeatable
1.1.3. Write tests before you write code, and make them fail. Then write code, then make the tests pass.
1.1.4. Allow you to refactor code
1.2. Code coverage
1.2.1. Use coverage.py
1.2.1.1. Integrate with pytest: pytest-cov
1.2.2. Use Codecov or coveralls for coverage reporting
1.3. Running tests automatically with relevant Python environments
1.3.1. Use nox
1.4. Mocking objects
1.4.1. Use pytest-mock
1.4.2. Or fixtures
1.4.3. Or fakes (fake implementations)
1.4.3.1. e.g. in-memory DB instead of real DB
1.4.4. Can check if obj is called
1.4.5. Can check called arguments
1.4.6. Can raise exceptions via side_effects
1.5. End-to-end tests
1.5.1. Use pytest, but with a marker
1.5.2. Can skip while invoking pytest
2. Documentation
2.1. Use docstrings
2.1.1. Use Google docstring style
2.2. flake8-docstrings can validate docstrings
2.3. Use darglint to ensure docstring matches prototype
2.4. Use xdoctest to run examples within docstrings
2.5. Use Sphinx to create project documentation
2.5.1. Markup is with reStructuredText
2.5.2. Comes with "autodoc" for API documentation
3. Version Control
3.1. Use git
4. CI/CD
4.1. Use GitHub actions for CI
4.2. Use Release Drafter to automatically add PRs for release notes as they merge
4.3. Use TestPyPI to test distribution
4.4. Use ReadTheDocs to host your documentation
5. Quick Reference for a Python project
6. User interface
6.1. CLI
6.1.1. Use click
6.2. REST API
6.2.1. Use requests or httpx
7. Language and environment
7.1. Python version
7.1.1. Use pyenv
7.2. Library dependencies
7.2.1. Use poetry
7.2.2. Poetry can also separate dependencies for dev, test and prod
7.2.3. Poetry can also upload package to PyPI
8. Linting
8.1. Use flake8
8.2. flake8-import-order checks imports
8.3. flake8-bugbear finds bugs and design problems
9. Security
9.1. flake8-bandit finds security issues
9.2. "Safety" package checks dependencies for known security issues
10. Code formatting
10.1. Use black
11. Data validation
11.1. Use dataclasses from standard library
11.2. Use Marshmallow to define and validate schemas
11.2.1. A package "Desert" can generate schemas based on dataclasses
12. Static and runtime type checking
12.1. Static: Use mypy
12.1.1. De-facto; core Python committers are involved in it