Python Setup#
We want a nice home for our Python project: metadata, dependencies, and sharing. We’ll choose the really-modern Python approach:
pyproject.toml
setuptools
as the build backend (no Poetry/Hatch, just regular pip)
Why?#
Python certainly has…lots of options. Why this as-yet-little-known approach?
Why an “editable install”?
The Python testing community encourages an src
layout of your project, as recommended by others.
When you make your workspace into a proper “package”, you can import from anywhere…once the package is an “editable install”.
Why not just a requirements.txt
?
This won’t get you into “proper package” mode.
Ditto for pipenv
which is more about applications than packages.
Why not setup.py
?
The Python world is (hopefully) moving away from that, to a world with pyproject.toml
as the central configuration spot.
Why not Poetry or Hatch?
This series is trying to stay on a mainstream path.
pip
is still the king of the hill.
Now that setuptools
is a valid pyproject.toml
backend, that’s a good happy path for beginners.
Also, setuptools
directly supports the src
layout described above.
Dear heavens, I hope one day to never need to explain that again.
Python editable install with pyproject.toml
#
We’re doing a “joyful Python” project.
That means coding through the lens of a test.
pytest
best practices say to make a package and then do an “editable install.”
We’ll follow the setuptools
page above, starting with an empty pyproject.toml
.
$ touch pyproject.toml
Build backend#
In the first section of the TOML file, we need to tell our packaging tool what build backend to use.
There are lots of packaging tools – we’re using pip
.
There are a number of backends – we’re using setuptools
:
[build-system]
requires = ["setuptools"]
build-backend = "setuptools.build_meta"
Project metadata#
Next, we’ll tell our tooling – and the world – a little about our project.
Add this section to the pyproject.toml
file:
[project]
name = "pyodide_components"
version = "0.0.1"
requires-python = ">=3.10"
license = {text = "BSD 3-Clause License"}
classifiers = [
"Programming Language :: Python :: 3",
]
dependencies = [
"sphinx",
]
We’re doing the minimum for dependencies for now: just Sphinx, as a way to ensure our installation works.
Project directory#
Let’s put some empty code into our project directory. We said we were adopting the src layout. Make an empty package file as a starter:
$ touch src/pyodide_components/__init__.py```
Virtual environment#
We want to follow best practices and work in a virtual environment.
Make one in the project folder, then upgrade the pip
and setuptools
it uses:
$ python -m venv .venv
$ .venv/bin/pip install --upgrade pip setuptools
Editable install#
We have a virtual environment.
We have a pyproject.toml
that defines our package.
But the virtual environment needs to know about our package.
Let’s do an editable install.
This put pyodide_components
in the virtual environment’s site-packages
.
But, as basically a symbolic link back to the src/pyodide_components
directory:
$ .venv/bin/pip install -e .
If this worked correctly, you now have a src/pyodide_components.egg-info
directory.
You also have sphinx-quickstart
in your virtual environment’s bin
:
$ ls src/pyodide_components.egg-info
PKG-INFO requires.txt
SOURCES.txt top_level.txt
dependency_links.txt
$ ls .venv/bin/sphinx*
.venv/bin/sphinx-apidoc
.venv/bin/sphinx-autogen
.venv/bin/sphinx-build
.venv/bin/sphinx-quickstart
To confirm that we can import pyodide_components
outside its source directory:
$ .venv/bin/python -c "import pyodide_components"
Cleanup#
There we go, a modern Python workspace. Let’s clean up a bit.
First, add some exclusions to your .gitignore
file:
*.egg-info/
.venv
__pycache__/
Now commit your work:
$ git add .gitignore pyproject.toml src
$ git commit -m"Python project workspace setup"