Skip to content

Switch packaging from Poetry to setuptools + PEP 621 #72

Description

@trvrb

Via Claude

Summary

Propose migrating evofr's packaging from Poetry (poetry-core backend + [tool.poetry] metadata) to setuptools with PEP 621 [project] metadata.

Motivation

1. Caret constraints silently over-cap dependencies

Poetry's default constraint syntax (poetry add writes ^X.Y.Z) caps at the next major version, so pyproject.toml had:

numpy = "^1.22.4"   # => >=1.22.4,<2.0.0
pandas = "^1.4.2"   # => >=1.4.2,<2.0.0

For a library, upper-capping is an anti-pattern: it stops evofr from composing with downstream environments on modern numpy/pandas, and the cap propagates to everything that depends on evofr.

Concrete failure: on Python 3.12 with pandas 3.x already installed, pip install evofr ignores the installed pandas (it violates <2.0), tries to install pandas==1.5.3 to satisfy the cap, and fails — pandas 1.5.x has no cp312 wheel and won't build from source on 3.12. (0.2.1 relaxed numpy/pandas to >= as a stopgap, but the caret convention is the root cause.)

2. evofr is a library, not an application

Poetry's headline value is the lockfile (poetry.lock) + managed virtualenvs for reproducible application deployments. A published library neither ships nor uses a lockfile — consumers resolve against their own environments. So the main benefit doesn't apply, while the constraint-capping default actively hurts.

3. Tooling friction

poetry build / poetry publish require Poetry as an extra maintainer dependency. The standard python -m build + twine flow works with any PEP 517 backend and needs no Poetry.

Proposed change

  • Replace [tool.poetry] with a PEP 621 [project] table (name, version, description, authors, license, readme, requires-python, dependencies, optional-dependencies, and [project.scripts] evofr = "evofr.cli:main").
  • [build-system]: requires = ["setuptools>=61"], build-backend = "setuptools.build_meta".
  • Move dev deps into [project.optional-dependencies] (e.g. a dev extra).
  • Use >= lower bounds; add an upper bound only where a real, known incompatibility exists.
  • Build/publish via python -m build + twine upload.

Notes / non-goals

  • No change to the public API or to pip install evofr for consumers — the wheel is the same kind of artifact.
  • Could pair this with GitHub Actions Trusted Publishing so tagged releases publish automatically. The CI workflow already matches version tags ([0-9]+.[0-9]+.[0-9]+*) and a comment references a "release job," but no publish job currently exists.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions