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.
Via Claude
Summary
Propose migrating evofr's packaging from Poetry (
poetry-corebackend +[tool.poetry]metadata) to setuptools with PEP 621[project]metadata.Motivation
1. Caret constraints silently over-cap dependencies
Poetry's default constraint syntax (
poetry addwrites^X.Y.Z) caps at the next major version, sopyproject.tomlhad: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 evofrignores the installed pandas (it violates<2.0), tries to installpandas==1.5.3to 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 publishrequire Poetry as an extra maintainer dependency. The standardpython -m build+twineflow works with any PEP 517 backend and needs no Poetry.Proposed change
[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".[project.optional-dependencies](e.g. adevextra).>=lower bounds; add an upper bound only where a real, known incompatibility exists.python -m build+twine upload.Notes / non-goals
pip install evofrfor consumers — the wheel is the same kind of artifact.[0-9]+.[0-9]+.[0-9]+*) and a comment references a "release job," but no publish job currently exists.