--- /dev/null
+There is a significant amount of Python project tooling. This document collects my personal recommendations on how to set up a Python project.
+
+It is not meant to reflect the best or most common practices, just my personal taste.
+
+# Use pipx
+
+Pipx is a tool that installs Python packages to your user environment. It creates an isolated environment for every tool, so if you install multiple packages they won't have version conflicts. It also takes care of adding a module's entrypoints to your user path.
+
+Pipx is useful for two purposes:
+
+* To install tools such as poetry
+* To let other users install your software easily
+
+# Use Poetry
+
+When using third-party dependencies in your Python code, it is highly interesting to avoid installing any project-specific dependency outside the project.
+
+To achieve that, traditionally virtualenvs are used; those are miniature Python installations where you can install any library you want. Virtualenvs need to be explicitly activated to be used, so it is easy to have a virtualenv for each Python project you are working on.
+
+Poetry is a tool that leverages virtualenvs to manage a project's dependencies, managing virtualenvs automatically.
+
+There are many similar tools such as pipenv and there are many multiple ways to specify a project's dependencies (`setup.py`, `requirements.txt`, etc.); Poetry provides a convenient way to do everything.
+
+You can install poetry using pipx.
+
+Commit `poetry.lock` to version control. For runtime dependencies, specify bounded dependency ranges. For development dependencies, use unbounded dependencies.
+
+# Test your code
+
+Write the necessary amount of tests so you can make changes to your code with confidence.
+
+If you find yourself iterating over a piece of code slowly, try to isolate the code you are writing so it can be tested in isolation for faster iteration.
+
+## Use pytest for testing
+
+Python provides *two* testing frameworks in its standard library, but they have some limitations:
+
+* `unittest` is an xUnit-style testing framework which follows non-PEP-8 naming conventions (probably because it copied the Java's jUnit), so extra work needs to be done to make your test cases PEP-8 compliant
+* `doctest` is a tool which allows you to run tests embedded in comments. For some code, it is great and helps you provide good, up-to-date documentation. However, a significant amount of code is awkward to test using `doctest`.
+
+Use `doctest` whenever you can, but outside that, use `pytest` to write PEP-8-compliant tests.
+
+Ensure that your test suite runs correctly by running `pytest` without any arguments.
+
+Use plain Python's `assert` statements to check assertions in your tests; `pytest` does some magic to provide nice error messages on failed assertions.
+
+## Gate your changes with testing
+
+Set up your version control so changes cannot be made to your main codeline without passing continuous integration tests (and possibly, code review).
+
+# Perform automated code formatting and static checking
+
+## Use Black
+
+Use Black to format your code.
+
+## Use flake8
+
+Use `flake8` to gate changes. Use `flake8-black` to prevent committed code which does not follow Black style.
+
+## Evaluate the use of mypy
+
+If you think it will benefit your codebase, consider integrating mypy as soon as possible.
+
+# Version control
+
+## Use a minimal gitignore file
+
+Keep editor-specific ignores in a personal `excludesfile`. Do not include patterns in gitignore which do not match anything generated by documented and supported development procedures.
+
+## Keep your code together
+
+All the code you modify as part of the project should be kept in a single repository so you can make atomic changes. If you find yourself making changes across multiple repositories and having to coordinate them, consider merging those repositories.
+
+Use git submodules or similar mechanisms to refer to code you modify that must be kept external.
+
+Use git subrepo to publish parts of the repository outside the main repository if needed.
+
+# Support multiple modern versions of Python
+
+Unless you have a specific requirement to support Python 2, don't.
+
+It is reasonable to support multiple versions of Python 3 from 3.4 onwards. Supporting the oldest versions might limit the features you can use (although features from more modern versions have been backported), so evaluate which operating systems and versions you need to support and try to support Python versions readily available for them (in Linux, by using mainline distro repos, for instance).
+
+Even if you are not running your code using the latest versions of Python, try to support all the newest available versions.
+
+Use continuous integration to run your tests in all supported versions of Python.
+
+This implies that development should be possible to do without using a specific version of Python, so pyenv or similar is not strictly needed.
+
+# Use ipython and ipdb
+
+Add ipython and ipdb as development dependencies.
+
+# Versioning
+
+Unless you have a specific requirement to support multiple versions of your code or to distribute to a platform that *requires* versioning (such as pypi), do not explicitly version your code but allow implicit versioning (e.g. it should be possible to identify which Git commit deployed code comes from).
+
+# Documentation
+
+Provide a `README` containing:
+
+* The purpose of the code
+* How to use the code
+* How to develop the code
+
+If the `README` becomes unwieldly, separate usage instructions to `USAGE` and/or development instructions to `HACKING`.
+
+Provide docstrings detailing the external interface of Python modules. Provide internal comments in modules detailing implementation.
+
+Consider the use of Sphinx to render documentation and publish it to the web if developing a library/framework.
+
+# Distribution
+
+If your code can be executed from a command line, consider documenting installation via `pipx`.
+
+If your code has significant binary dependencies, consider publishing a Docker image. Design your Docker images so rebuilding the image on most changes is fast.