--- jupytext: text_representation: extension: .md format_name: myst format_version: 0.13 jupytext_version: 1.17.1 kernelspec: display_name: Python 3 (ipykernel) language: python name: python3 --- (release)= # Make a Release {sub-ref}`wordcount-minutes` min read +++ Releases are a key step in the development of a project. A release tells to the world that a new version of your work is available. You cannot take a release back: if you made a mistake, you will have to make another release to patch your errors. It is therefore important to take your time when you craft a release. +++ ## 1. Ruff your code Pycharm gives you a lot of hints about the quality of your code, but you don't always look at all the signs on the right of the screen. You can use [Ruff] to check all your files at once. ```console $ uv run ruff format . ``` → Make your code look prettier. ```console $ uv run ruff check . ``` → Investigate possible issues (you can use `--fix` to try auto-fixing them if possible). :::{hint} Inside the PyCharm terminal the virtual environment should be activated by default so the `uv run` part is not needed: ```console $ ruff format $ ruff check --fix ``` ::: [Ruff]: https://docs.astral.sh/ruff/ ## 2. Check dependencies in your `pyproject.toml` +++ :::{hint} If you have time, check [the UV documentation about dependencies](https://docs.astral.sh/uv/concepts/projects/dependencies/). ::: Your dependencies (i.e. the packages you rely upon) are handled in two places: - Inside `pyproject.toml`, you declare (manually or using `uv add`) them, optionally with some version requirements: - Use `>=x.y.z` to declare a minimum required version, e.g. `"numpy>=1.23.4"`. - Use `=1.23.4,<2"`. - The `uv.lock` file describes a combination of specific versions that respects the constraints of `pyproject.toml`: - The lock handles all required packages (including dependecies of dependencies of dependencies of depen...) with many metadata, so it can be quite large. - See it as a recipe to install *something that works*. - **NEVER EDIT IT MANUALLY**. The lock is managed by uv through the `uv sync` command. Once in a while, especially when you draft a new release, it can be good to check your versions: - Upgrade the requirements from your `pyproject.toml` if you need to. - Use `uv sync --upgrade` to push your version to the limit and test that your code still works. - If you detect some strong incompatibility, declare a *stopping point* (e.g. `"<2"`). :::{hint} To upgrade a package to the latest version in `pyproject.toml` you can do things like ```console $ uv remove pkg && uv add --upgrade pkg ``` ::: :::{admonition} Prefer future to past Being incompatible with latest versions will not stop anyone from installing your package in a dedicated environment (docker, `.venv`, etc.) where the version of each dependency is controlled by `uv.lock`. However, it will be harder and harder for users to use it in their main Python environment. For example, imagine that your code uses both `numpy` and `pandas`, but your code requires `numpy<2`, while the latest Pandas requires `numpy>=2`. This means that everytime you install your package you will have to downgrade pandas, whereas other packages of your distribution may need the latest versions... To avoid this as much as possible, whenever you need to choose between `pkg1>=x.y.z` and `pkg2