Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 4 additions & 6 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,10 @@ jobs:
- uses: actions/checkout@v5
- name: Install Python tools
uses: BrandonLWhite/pipx-install-action@v1.0.3
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we even need pipx anymore? I dont think it is used in the ci pipeline.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We use poe

- name: Setup Python with poetry caching
# poetry cache requires poetry to already be installed, weirdly
uses: actions/setup-python@v6
- name: Install uv
uses: astral-sh/setup-uv@v8.1.0
with:
python-version: ${{ matrix.python-version }}
cache: poetry

- name: Install system dependencies on Windows
if: matrix.platform == 'windows-latest'
Expand Down Expand Up @@ -85,15 +83,15 @@ jobs:
- if: ${{ env.IS_MAIN_PYTHON != 'true' }}
name: Test without coverage
run: |
poetry install --without=lint --extras=autobpm --extras=discogs --extras=lyrics --extras=replaygain --extras=reflink --extras=fetchart --extras=chroma --extras=sonosupdate
poe install --group test --extra autobpm --extra discogs --extra lyrics --extra replaygain --extra reflink --extra fetchart --extra chroma --extra sonosupdate
poe test

Comment thread
snejus marked this conversation as resolved.
- if: ${{ env.IS_MAIN_PYTHON == 'true' }}
name: Test with coverage
env:
LYRICS_UPDATED: ${{ steps.lyrics-update.outputs.any_changed }}
run: |
poetry install --extras=autobpm --extras=discogs --extras=lyrics --extras=docs --extras=replaygain --extras=reflink --extras=fetchart --extras=chroma --extras=sonosupdate
poe install --group test --extra autobpm --extra discogs --extra lyrics --extra replaygain --extra reflink --extra fetchart --extra chroma --extra sonosupdate --group docs
poe docs
poe test-with-coverage

Comment thread
snejus marked this conversation as resolved.
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/integration_test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@ jobs:
- uses: actions/checkout@v5
- name: Install Python tools
uses: BrandonLWhite/pipx-install-action@v1.0.3
- uses: actions/setup-python@v6
- name: Install uv
uses: astral-sh/setup-uv@v8.1.0
with:
python-version: ${{ env.PYTHON_VERSION }}
cache: poetry

- name: Install dependencies
run: poetry install
run: poe install --only-group test

- name: Test
env:
Expand Down
30 changes: 15 additions & 15 deletions .github/workflows/lint.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,15 @@ jobs:
with:
files: |
**.py
poetry.lock
uv.lock

- name: Check changed python files
id: changed-python-files
env:
CHANGED_PYTHON_FILES: ${{ steps.raw-changed-python-files.outputs.all_changed_files }}
run: |
if [[ " $CHANGED_PYTHON_FILES " == *" poetry.lock "* ]]; then
# if poetry.lock is changed, we need to check everything
if [[ " $CHANGED_PYTHON_FILES " == *" uv.lock "* ]]; then
# if uv.lock is changed, we need to check everything
CHANGED_PYTHON_FILES="."
fi
echo "all_changed_files=$CHANGED_PYTHON_FILES" >> "$GITHUB_OUTPUT"
Expand All @@ -59,13 +59,13 @@ jobs:
- uses: actions/checkout@v5
- name: Install Python tools
uses: BrandonLWhite/pipx-install-action@v1.0.3
- uses: actions/setup-python@v6
- name: Install uv
uses: astral-sh/setup-uv@v8.1.0
with:
python-version: ${{ env.PYTHON_VERSION }}
cache: poetry

- name: Install dependencies
run: poetry install --only=lint
run: poe install --only-group lint

- name: Check code formatting
# the job output will contain colored diffs with what needs adjusting
Expand All @@ -80,13 +80,13 @@ jobs:
- uses: actions/checkout@v5
- name: Install Python tools
uses: BrandonLWhite/pipx-install-action@v1.0.3
- uses: actions/setup-python@v6
- name: Install uv
uses: astral-sh/setup-uv@v8.1.0
with:
python-version: ${{ env.PYTHON_VERSION }}
cache: poetry

- name: Install dependencies
run: poetry install --only=lint
run: poe install --only-group lint

- name: Lint code
run: poe lint --output-format=github ${{ needs.changed-files.outputs.changed_python_files }}
Expand All @@ -100,13 +100,13 @@ jobs:
- uses: actions/checkout@v5
- name: Install Python tools
uses: BrandonLWhite/pipx-install-action@v1.0.3
- uses: actions/setup-python@v6
- name: Install uv
uses: astral-sh/setup-uv@v8.1.0
with:
python-version: ${{ env.PYTHON_VERSION }}
cache: poetry

- name: Install dependencies
run: poetry install --only=typing
run: poe install --only-group docs --only-group typing

- name: Type check code
uses: liskin/gh-problem-matcher-wrap@v3
Expand All @@ -125,13 +125,13 @@ jobs:
fetch-depth: 0 # needed to get the full git history for the changelog check
- name: Install Python tools
uses: BrandonLWhite/pipx-install-action@v1.0.3
- uses: actions/setup-python@v6
- name: Install uv
uses: astral-sh/setup-uv@v8.1.0
with:
python-version: ${{ env.PYTHON_VERSION }}
cache: poetry

- name: Install dependencies
run: poetry install --extras=docs
run: poe install --only-group docs --only-group lint

- name: Add Sphinx problem matchers
run: |
Expand Down
12 changes: 6 additions & 6 deletions .github/workflows/make_release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@ jobs:
- uses: actions/checkout@v5
- name: Install Python tools
uses: BrandonLWhite/pipx-install-action@v1.0.3
- uses: actions/setup-python@v6
- name: Install uv
uses: astral-sh/setup-uv@v8.1.0
with:
python-version: ${{ env.PYTHON_VERSION }}
cache: poetry

- name: Install dependencies
run: poetry install --with=release --extras=docs
run: poe install --only-group docs

- name: Bump project version
run: poe bump "${{ env.NEW_VERSION }}"
Comment thread
snejus marked this conversation as resolved.
Expand All @@ -51,13 +51,13 @@ jobs:

- name: Install Python tools
uses: BrandonLWhite/pipx-install-action@v1.0.3
- uses: actions/setup-python@v6
- name: Install uv
uses: astral-sh/setup-uv@v8.1.0
with:
python-version: ${{ env.PYTHON_VERSION }}
cache: poetry

- name: Install dependencies
run: poetry install --with=release --extras=docs
run: poe install --only-group docs

- name: Install pandoc
run: sudo apt update && sudo apt install pandoc -y
Expand Down
61 changes: 24 additions & 37 deletions CONTRIBUTING.rst
Original file line number Diff line number Diff line change
Expand Up @@ -65,79 +65,66 @@ Development Tools

In order to develop beets, you will need a few tools installed:

- poetry_ for packaging, virtual environment and dependency management
- uv_ for packaging, virtual environment and dependency management
- poethepoet_ to run tasks, such as linting, formatting, testing

Python community recommends using pipx_ to install stand-alone command-line
applications such as above. pipx_ installs each application in an isolated
virtual environment, where its dependencies will not interfere with your system
and other CLI tools.
Follow the `uv installation instructions
<https://docs.astral.sh/uv/getting-started/installation/>`__ to install uv_.

If you do not have pipx_ installed in your system, follow `pipx installation
instructions <https://pipx.pypa.io/stable/how-to/install-pipx/>`__ or
poethepoet_ is a stand-alone CLI tool. The Python community recommends using
pipx_ to install such tools in isolated environments so their dependencies don't
interfere with your system. If you don't have pipx_ installed, follow the `pipx
installation instructions <https://pipx.pypa.io/stable/how-to/install-pipx/>`__
or run:

.. code-block:: sh

$ python3 -m pip install --user pipx
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the pipx recommendation still valid? I think poethepoet is now just a dev dependency. I dont think it is necessary anymore. Just running uv sync should do the job nicely.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Introduction of uv does not change this. Both uv and poethepoet should be installed using pipx globally, outside of beets virtual environment.

Copy link
Copy Markdown
Contributor

@semohr semohr Apr 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why tho? uv is just a binary you drop somewhere. uv has no dependency on python, thus installing uv inside a pipx environment does not really do anything.

uv creates an environment for you, including poe if registered as dev dep.

I generally think pipx is not needed at all for the dev setup if we switch to uv.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I use global uv and poethepoet binaries installed outside any specific project environment primarily because I maintain multiple projects.

Note we recommend using pipx to install these tools because they may not be available through the package manager of whatever distribution people use (for example, I doubt that poethepoet can be installed using apt).

Copy link
Copy Markdown
Contributor

@semohr semohr May 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I get how you currently manage your dev envs now 👍 . Still, sorry to press on here.

Essentially we should not care how people install their uv (via pipx or just as a binary)`, right? We can give a recommendation ofc.

I think my misunderstanding boils down to that I don't really understand why we wont want to move poethepoet into the dev dependencies and have it be part of our dev environment (managed by uv).
What are the realistic reasons of having it externally managed? I don't really see any that's why I'm pressing here.

Moving poethepoet into our dev env will completely remove our pipx dependency in the ci and for the dev setup. It also lets us create a truly reproducible dev environment as we control the poe version. It should also eases the initial setup burden as people dont have to install another tool (just run uv sync and you are ready).

I for myself am still using conda for beets and would like to drop it in favor of just a singular uv venv if possible. One can install poe using uv tool install poethepoet too but than we wont have the guarantee that e.g. the CI poe version is the same version as my local poe version.


Install poetry_ and poethepoet_ using pipx_:
Then install poethepoet_:

::

$ pipx install poetry poethepoet
$ pipx install poethepoet

.. admonition:: Check ``tool.pipx-install`` section in ``pyproject.toml`` to see supported versions

.. code-block:: toml

[tool.pipx-install]
poethepoet = ">=0.26"
poetry = "<2"

.. _getting-the-source:

Getting the Source
++++++++++++++++++

The easiest way to get started with the latest beets source is to clone the
repository and install ``beets`` in a local virtual environment using poetry_.
This can be done with:
repository and install ``beets`` in a local virtual environment using uv_. This
can be done with:

.. code-block:: bash

$ git clone https://github.com/beetbox/beets.git
$ cd beets
$ poetry install
$ uv sync

This will install ``beets`` and all development dependencies into its own
virtual environment in your ``$POETRY_CACHE_DIR``. See ``poetry install --help``
for installation options, including installing ``extra`` dependencies for
plugins.
This will install ``beets`` and all development dependencies into a ``.venv``
virtual environment. See ``uv sync --help`` for options, including installing
``extra`` dependencies for plugins (e.g. ``uv sync --extra fetchart``).

If you will build the documentation you will need to run the following command:

.. code-block:: bash

$ poetry install -E docs

This will install the optional dependencies for the documentation.

In order to run something within this virtual environment, start the command
with ``poetry run`` to them, for example ``poetry run pytest``.

On the other hand, it may get tedious to type ``poetry run`` before every
command. Instead, you can activate the virtual environment in your shell with:
To run commands within this virtual environment, either activate it:

::

$ poetry shell
$ source .venv/bin/activate
$ pytest

You should see ``(beets-py3.10)`` prefix in your shell prompt. Now you can run
commands directly, for example:
Or prefix commands with ``uv run``:

::

$ (beets-py3.10) pytest
$ uv run pytest

Additionally, poethepoet_ task runner assists us with the most common
operations. Formatting, linting, testing are defined as ``poe`` tasks in
Expand Down Expand Up @@ -352,7 +339,7 @@ Test Dependencies
The tests have a few more dependencies than beets itself. (The additional
dependencies consist of testing utilities and dependencies of non-default
plugins exercised by the test suite.) The dependencies are listed under the
``tool.poetry.group.test.dependencies`` section in pyproject.toml_.
``test`` group in the ``dependency-groups`` section of pyproject.toml_.

Writing Tests
~~~~~~~~~~~~~
Expand Down Expand Up @@ -424,8 +411,6 @@ contributor.

.. _poethepoet: https://poethepoet.natn.io/index.html

.. _poetry: https://python-poetry.org/docs/

.. _pyproject.toml: https://github.com/beetbox/beets/blob/master/pyproject.toml

.. _pytest: https://docs.pytest.org/en/stable/
Expand All @@ -440,4 +425,6 @@ contributor.

.. _unittest: https://docs.python.org/3/library/unittest.html

.. _uv: https://docs.astral.sh/uv/

.. _vim: https://www.vim.org/
19 changes: 8 additions & 11 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,14 @@ Unreleased
For plugin developers
~~~~~~~~~~~~~~~~~~~~~

..
Other changes
~~~~~~~~~~~~~
Other changes
~~~~~~~~~~~~~

- :doc:`contributing`: The project now uses ``uv`` for packaging, virtual
environment, and dependency management, replacing ``poetry``. The build
backend has changed from ``poetry-core`` to ``hatchling``. Please see updates
in :ref:`development-tools` and :ref:`getting-the-source` for more
information. :bug:`5783`

2.11.0 (May 06, 2026)
---------------------
Expand Down Expand Up @@ -94,10 +99,6 @@ Bug fixes
``import.quiet: yes`` config) during import so the corrupt-file prompt is
suppressed in non-interactive imports. :bug:`4736`

..
For plugin developers
~~~~~~~~~~~~~~~~~~~~~

Other changes
~~~~~~~~~~~~~

Expand Down Expand Up @@ -168,10 +169,6 @@ For plugin developers
``TypedDict`` models for releases, recordings, works, and relations. Update
direct access to raw MusicBrainz response keys if needed.

..
Other changes
~~~~~~~~~~~~~

2.9.0 (April 11, 2026)
----------------------

Expand Down
4 changes: 1 addition & 3 deletions docs/dev/plugins/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -79,14 +79,12 @@ and you're good to go!
information, see for example pep-3119_.

.. [3] There are a variety of packaging tools available for python, for example
you can use poetry_, setuptools_ or hatchling_.
you can use setuptools_ or hatchling_.

.. _hatchling: https://hatch.pypa.io/latest/config/build/#build-system

.. _pep-3119: https://peps.python.org/pep-3119/#rationale

.. _poetry: https://python-poetry.org/docs/pyproject/#packages

.. _setuptools: https://setuptools.pypa.io/en/latest/userguide/package_discovery.html#finding-simple-packages

.. _this article: https://realpython.com/python-namespace-package/#setting-up-some-namespace-packages
Expand Down
2 changes: 1 addition & 1 deletion docs/extensions/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
class Conf(ObjectDescription[str]):
"""Directive for documenting a single configuration value."""

option_spec: ClassVar[OptionSpec] = {
option_spec: ClassVar[OptionSpec] = { # type: ignore[misc]
"default": directives.unchanged,
}

Expand Down
3 changes: 2 additions & 1 deletion docs/faq.rst
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,8 @@ helpful to run on the "bleeding edge". To run the latest source:
.. code-block:: shell

git clone https://github.com/beetbox/beets.git
poetry install
cd beets
pip install -e .

This approach lets you decide where the source is stored, with any changes
immediately reflected in your environment.
Expand Down
2 changes: 1 addition & 1 deletion extra/release.py
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ def validate_new_version(
) -> Version:
"""Validate the version is newer than the current one."""
with PYPROJECT.open("rb") as f:
current = parse(tomli.load(f)["tool"]["poetry"]["version"])
current = parse(tomli.load(f)["project"]["version"])

if not value > current:
msg = f"version must be newer than {current}"
Expand Down
Loading
Loading