Developing pylibftdi

How do I checkout and use the latest development version?

Note

pylibftdi is currently developed on GitHub, though started out as a Mercurial repository on bitbucket.org. There may still be references to old bitbucket issues in the docs.

pylibftdi is developed using uv, and a Dockerfile plus Makefile make development tasks straightforward. In any case, start with a local clone of the repository:

$ git clone https://github.com/codedstructure/pylibftdi
$ cd pylibftdi

Note that pylibftdi itself only requires the Python standard library for normal use. The development dependencies (pytest, ruff, mypy) are declared in the [dependency-groups] section of pyproject.toml and are only needed for development and testing.

There are then two main approaches, though pick and mix the different elements to suit:

uv and docker If make and docker are available in your environment, the easiest way to do development may be to simply run make shell. This creates an Ubuntu-based docker environment with libftdi, uv, and other requirements pre-installed, and drops into a shell where the current pylibftdi code is available.

make on its own will run through all the unittests and linting available for pylibftdi, and is a useful check to make sure things haven’t been broken.

The downside of running in a docker container is that USB support to actual FTDI devices may be lacking…

local install with uv With uv installed, run uv sync from the project root. This creates a .venv virtual environment, installs the development dependencies from uv.lock, and installs pylibftdi itself in editable mode — no separate activation step is needed to run tools:

.../pylibftdi$ uv sync
.../pylibftdi$ uv run pytest
.../pylibftdi$ uv run ruff check src tests

If you prefer to work inside an activated virtual environment:

.../pylibftdi$ uv sync
.../pylibftdi$ source .venv/bin/activate
(pylibftdi) .../pylibftdi$ pytest

Note

The uv.lock file pins all dependency versions for reproducible installs. To upgrade all dependencies to their latest allowed versions, run uv lock --upgrade, or target a single package with uv lock --upgrade-package pytest. Follow either with uv sync to apply the changes to the virtual environment.

How do I run the tests?

From the root directory of a cloned pylibftdi repository, run:

.../pylibftdi$ uv run pytest

Or, with a virtualenv already activated:

(pylibftdi) .../pylibftdi$ pytest

The standard unittest runner also works if preferred:

(pylibftdi) .../pylibftdi$ python3 -m unittest discover

How do I make a PyPI release?

Ensure the working tree is clean, all tests pass, and CHANGES.txt is up to date. Update the version number in pyproject.toml, sync uv, then tag the commit:

.../pylibftdi$ vim pyproject.toml CHANGES.txt  # update with new version
.../pylibftdi$ uv sync --upgrade
.../pylibftdi$ make  # ensure everything works
.../pylibftdi$ git add pyproject.toml uv.lock CHANGES.txt
.../pylibftdi$ git commit -m "Release 0.x.0"
.../pylibftdi$ git tag 0.x.0

Build the distribution artifacts using uv build (or make build, which runs the same command inside the docker container):

.../pylibftdi$ uv build

This produces a source distribution and a wheel under dist/.

Publish to PyPI using uv publish. A PyPI API token is required; either export it as an environment variable or pass it directly:

.../pylibftdi$ uv publish --token pypi-...

# or via environment variable
.../pylibftdi$ UV_PUBLISH_TOKEN=pypi-... uv publish

Note

To do a dry run first, publish to TestPyPI:

.../pylibftdi$ uv publish --publish-url https://test.pypi.org/legacy/ --token pypi-...

You can verify the result at https://test.pypi.org/project/pylibftdi/

Finally, push the tag:

.../pylibftdi$ git push origin main --tags