Repository navigation
make sdk-python fails on a Python 3.14 host, with an error that names nothing relevant #692
Description
On a machine whose python3 is 3.14, make sdk-python fails in dependency resolution:
$ make sdk-python
python3 -m venv sdk/python/.venv
./sdk/python/.venv/bin/pip install -q -e './sdk/python[test,examples]'
...
File ".../coincurve_.../hatch_build.py", line 34, in initialize
raise RuntimeError(message)
RuntimeError: Expected exactly one LICENSE file in cffi distribution, got 0
error: metadata-generation-failed
× Encountered error while generating package metadata.
╰─> coincurve
make: *** [Makefile:176: sdk-python] Error 1
Nothing in that output says "this Python is too new", which is what actually happened.
Cause
Two things combine:
-
Makefile:175ispython3 -m venv sdk/python/.venv— the target pins no interpreter, so it
takes whateverpython3is onPATH. -
sdk/python/pyproject.tomldeclaresrequires-python = ">=3.11", with no upper bound. But
libp2p(py-libp2p) 0.8.0 pinscoincurve==21.0.0:$ curl -s https://pypi.org/pypi/libp2p/0.8.0/json | jq -r '.info.requires_dist[]' | grep coincurve coincurve==21.0.0coincurve 21.0.0 (2025-03-08, still the latest on PyPI) publishes cp39–cp313 wheels only, and
building its sdist raises the error above fromcoincurve/hatch_build.py:34.
So requires-python is wider than what can actually be installed: 3.14 satisfies the
declared floor and then fails deep inside a transitive dependency's build.
CI does not see this because every workflow pins python-version: "3.12"
(.github/workflows/sdk.yml:75, release.yml:118, member-journey.yaml:74). Only a developer
whose system python3 is 3.14 hits it, and the error does not tell them why.
The upstream half is tracked at
libp2p/py-libp2p#1140; it is blocked on
coincurve itself, so the ceiling is real for now rather than something agentmesh can resolve.
Suggested fix
Two small changes, both verified locally:
1. Declare the real ceiling in sdk/python/pyproject.toml:
requires-python = ">=3.11,<3.14"The failure then names the actual constraint, on the path make sdk-python takes:
ERROR: Package 'agentmesh-p2p' requires a different Python: 3.14.7 not in '<3.14,>=3.11'
This also helps anyone installing the published agentmesh-p2p from PyPI, not just this
Makefile target. Worth a comment saying the bound is py-libp2p's and when to lift it.
Caveat I should flag: uv pip install -e does not enforce requires-python for an
editable local path — it resolves and still fails on the coincurve build. So this improves pip
(what the Makefile and pip install agentmesh-p2p use) but does not change the uv-editable
path.
2. Let the target's interpreter be overridden, matching the ?= convention already used
elsewhere in the Makefile (AGENTMESH_ONE_BIN, AGENTMESH_ONE_DATA_DIR):
PYTHON ?= python3
sdk-python:
$(PYTHON) -m venv sdk/python/.venvso a developer on 3.14 has a way forward:
$ make sdk-python PYTHON=python3.13
...
168 passed in 43.89s
I have both changes on a branch with the above output reproduced. I have not opened a PR yet
because I have not signed the Google CLA — happy to do that and send it if you would like the
patch, or to leave it with you if you would rather fix it differently.
Verified at cf1d27fa9bc6cc93dbe79cc99fa420d954f30ee9, CPython 3.14.7 / 3.13.15, Linux.
Activity
asivanadi0 commentedon Oct 13, 2026
You mentioned you already have a fix and are waiting on the CLA. Are you still planning to send it? If it would help, I have a version on asivanadi0:fix/sdk-python-version that sets
requires-python = ">=3.11,<3.14"and hasmake sdk-pythonpick the newest supported interpreter with a clear error on 3.14. Happy to defer to yours.yashksaini-coder commentedon Oct 14, 2026
Please send yours — it is better than what I have, and you are not blocked where I am.
I fetched
asivanadi0:fix/sdk-python-versionand compared just the two files at issue.On
pyproject.tomlwe wrote the same thing:requires-python = ">=3.11,<3.14"citinglibp2p/py-libp2p#1140. Yours says it in two lines, mine took five.
On the
Makefileyours is the better design. Mine was onlyPYTHON ?= python3, which stillrequires the developer to know to override it — on a 3.14 host with no override it walks into
the same coincurve error the issue is about. Yours probes for a supported interpreter and
pre-flight-checks with a message that names what it found and how to override.
I tested your logic on the host that prompted the issue (3.14.7, and no
python3.11/12/13onPATHat all), lifted into a scratch Makefile so the rest of your branch was not in the way:PATHpython3, guard fires:sdk-python needs Python 3.11 to 3.13 ... python3 is Python 3.14.7. Install python3.13 or run: make sdk-python PYTHON=python3.13, exit 1python3.13also onPATHpython3.13(3.13.15)PYTHON=/path/to/python3.13All three are what you would want. Mine only gets the third one right.
One small thing, if you want it.
PYTHON ?= $(or $(firstword $(foreach p,...,$(shell ...))))is a recursively expanded variable, so the probes re-run on every
$(PYTHON)expansion ratherthan once. I measured it by putting a counting shim on
PATHaspython3.12: your form probeseach candidate 5 times per
makerun, against 1 for a simply expanded helper:With four candidates that is roughly 20 subprocess spawns instead of 4, and
PYTHON=on thecommand line still wins. Same behaviour otherwise — all three rows above still hold with it.
Entirely your call; it is a papercut, not a problem.
I have not signed the Google CLA, so there is no reason to wait on me here. Happy to review
your PR when it is up, and to retest it on the 3.14 host.
sdk/python: refuse Python 3.14 with a clear error, prefer 3.13 to 3.11
yashksaini-coder commentedon Oct 19, 2026
Correcting my own recommendation in this issue, since #709 is now stuck on it and the
suggestion was mine.
I wrote above that the fix was to "declare the real ceiling" with
requires-python = ">=3.11,<3.14". For a package that is already published that is wrong,and @aojea's pushback on #709 is right.
requires-pythonis per-release metadata, but peopleinstall a package: capping only the newest release does not tell a 3.14 user "this does not
support you", it tells the resolver "try an older one".
agentmesh-p2phas0.1.0,0.1.0rc10and0.1.1on PyPI, all>=3.11, all depending onlibp2p>=0.8,<0.9. I checked what pip actually does with a cap, using a local index with twohand-built wheels:
Then the same thing end to end on the real package, on 3.14.8:
pip install agentmesh-p2presolves0.1.1and fails loudly in coincurve'sbuild (
RuntimeError: Expected exactly one LICENSE file in cffi distribution, got 0);0.1.1and falls back to0.1.0— andpip install agentmesh-p2p==0.1.0on 3.14 fails with the identical coincurve error.
So the cap costs a silent downgrade and buys nothing: the user ends up at the same cryptic
message either way. It would only read correctly if every existing release were capped too, and
nobody is proposing that.
It is also worth being clear about whose constraint this is.
libp2p0.8.0 declaresrequires-python >=3.10,<4.0while pinningcoincurve==21.0.0, and coincurve 21.0.0 declares>=3.9while publishing cp39-cp313 wheels only and shipping an sdist that does not build. Themetadata that is actually wrong is two levels upstream; libp2p/py-libp2p#1140 tracks it. Agent
Mesh restating it downstream does not make it true, and goes stale the moment coincurve ships
3.14 wheels.
What does hold up is the
make sdk-pythonguard in #709: it involves no resolver, it is adeveloper-workflow check rather than published metadata, and it is the part that fixes the thing
this issue actually reported — a confusing failure when building from the repo. @asivanadi0
already offered on #709 to drop the pyproject cap and keep only that; that is the right shape,
and the reason to do it is stronger than "upper bounds are discouraged".
Sorry for sending #709 down this path to begin with.