feat: replace poetry with uv in Makefiles
What changed, and why it matters
This commit is a routine build-tooling change: it swaps the Python package manager from Poetry to uv in Makefiles, updates how package versions are read, and wraps Python commands with `uv run`. There is no change to Core Lightning's runtime code, network protocol handling, wallet logic, or cryptography, so it does not introduce or fix a security vulnerability.
No security action required. Reviewers may optionally verify that `uv` is installed in CI/dev environments and that the new `uv run` invocations still use the intended Python interpreter and dependency lockfile.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The diff replaces poetry version, poetry install, poetry build, poetry publish, and bare pytest/flake8/mypy invocations with uv equivalents (uv run, uv build, uv publish, uv sync). Version extraction now uses grep/sed on pyproject.toml instead of poetry version -s. New aggregate Makefile targets for building Python packages are added. No source code, tests, or configuration semantics are altered in a security-relevant way.
Changed components
Makefilecontrib/pyln-client/Makefilecontrib/pyln-grpc-proto/Makefilecontrib/pyln-proto/Makefilecontrib/pyln-spec/Makefilecontrib/pyln-testing/MakefileInspect captured patch +63 / −84
diff --git a/Makefile b/Makefile
index ab36d7b6..3eb6761a 100644
--- a/Makefile
+++ b/Makefile
@@ -477,11 +477,11 @@ check: check-units installcheck pytest
pytest: $(ALL_PROGRAMS) $(DEFAULT_TARGETS) $(ALL_TEST_PROGRAMS) $(ALL_TEST_GEN)
ifeq ($(PYTEST),)
- @echo "py.test is required to run the integration tests, please install using 'pip3 install -r requirements.txt', and rerun 'configure'."
+ @echo "pytest is required to run the integration tests, please install using 'uv sync --all-extras --all-groups', and rerun 'configure'."
exit 1
else
# Explicitly hand VALGRIND so you can override on make cmd line.
- PYTHONPATH=$(MY_CHECK_PYTHONPATH) TEST_DEBUG=1 VALGRIND=$(VALGRIND) $(PYTEST) $(PYTEST_TESTS) $(PYTEST_OPTS)
+ PYTHONPATH=$(MY_CHECK_PYTHONPATH) TEST_DEBUG=1 VALGRIND=$(VALGRIND) uv run $(PYTEST) $(PYTEST_TESTS) $(PYTEST_OPTS)
endif
check-fuzz: $(ALL_FUZZ_TARGETS)
@@ -542,7 +542,7 @@ PYSRC=$(shell git ls-files "*.py" | grep -v /text.py)
# allows it to find that
PYLN_PATH=$(shell pwd)/lightningd:$(PATH)
check-pyln-%: $(BIN_PROGRAMS) $(PKGLIBEXEC_PROGRAMS) $(PLUGINS)
- @(cd contrib/$(shell echo $@ | cut -b 7-) && PATH=$(PYLN_PATH) PYTHONPATH=$(MY_CHECK_PYTHONPATH) $(MAKE) check)
+ @(cd contrib/$(shell echo $@ | cut -b 7-) && PATH=$(PYLN_PATH) PYTHONPATH=$(MY_CHECK_PYTHONPATH) uv run $(MAKE) check)
check-python: check-python-flake8 check-pytest-pyln-proto check-pyln-client check-pyln-testing
@@ -551,10 +551,10 @@ check-python-flake8:
@# E731 do not assign a lambda expression, use a def
@# W503: line break before binary operator
@# E741: ambiguous variable name
- @flake8 --ignore=E501,E731,E741,W503,F541,E275 --exclude $(shell echo ${PYTHON_GENERATED} | sed 's/ \+/,/g') ${PYSRC}
+ @uv run flake8 --ignore=E501,E731,E741,W503,F541,E275 --exclude $(shell echo ${PYTHON_GENERATED} | sed 's/ \+/,/g') ${PYSRC}
check-pytest-pyln-proto:
- PATH=$(PYLN_PATH) PYTHONPATH=$(MY_CHECK_PYTHONPATH) $(PYTEST) contrib/pyln-proto/tests/
+ PATH=$(PYLN_PATH) PYTHONPATH=$(MY_CHECK_PYTHONPATH) uv run $(PYTEST) contrib/pyln-proto/tests/
check-includes: check-src-includes check-hdr-includes
@tools/check-includes.sh
@@ -751,29 +751,48 @@ clean: obsclean
find . -name '*gcno' -delete
find . -name '*.nccout' -delete
if [ "${RUST}" -eq "1" ]; then cargo clean; fi
+ rm -rf .venv
-PYLNS=client proto testing
# See doc/contribute-to-core-lightning/contributor-workflow.md
-update-versions: update-pyln-versions update-poetry-lock update-dot-version update-doc-examples
-
+PYLNS=client proto testing
update-pyln-versions: $(PYLNS:%=update-pyln-version-%)
update-pyln-version-%:
@if [ -z "$(NEW_VERSION)" ]; then echo "Set NEW_VERSION!" >&2; exit 1; fi
- cd contrib/pyln-$* && $(MAKE) upgrade-version
+ @echo "Updating contrib/pyln-$* to $(NEW_VERSION)"
+ @sed -i '' 's/^version = .*/version = "$(NEW_VERSION)"/' contrib/pyln-$*/pyproject.toml
pyln-release: $(PYLNS:%=pyln-release-%)
pyln-release-%:
cd contrib/pyln-$* && $(MAKE) prod-release
-update-poetry-lock:
- poetry update pyln-client pyln-proto pyln-testing update-reckless-version
+pyln-build: $(PYLNS:%=pyln-build-%)
+
+pyln-build-%:
+ uv build contrib/pyln-$*/
+
+BOLT_SPECS := bolt1 bolt2 bolt4 bolt7
+pyln-build-bolts: $(BOLT_SPECS:%=pyln-build-%)
+ @echo "building bolt specs complete"
+
+$(BOLT_SPECS:%=pyln-build-%) pyln-build-grpc-proto pyln-build-wss-proxy:
+ @case $@ in \
+ pyln-build-grpc-proto) uv build contrib/pyln-grpc-proto/ ;; \
+ pyln-build-bolt*) uv build contrib/pyln-spec/$(patsubst pyln-build-%,%,$@)/ ;; \
+ pyln-build-wss-proxy) uv build plugins/wss-proxy/ ;; \
+ esac
+
+pyln-build-all: pyln-build pyln-build-bolts pyln-build-grpc-proto pyln-build-wss-proxy
+ @echo "building python packages complete"
+
+update-lock:
+ uv sync --all-extras --all-groups
update-reckless-version:
@if [ -z "$(NEW_VERSION)" ]; then echo "Set NEW_VERSION!" >&2; exit 1; fi
- @sed -i "s/__VERSION__ = '\([.-z]*\)'/__VERSION__ = '$(NEW_VERSION)'/" tools/reckless
+ @sed -i '' "s/__VERSION__ = '\([.-z]*\)'/__VERSION__ = '$(NEW_VERSION)'/" tools/reckless
update-dot-version:
@if [ -z "$(NEW_VERSION)" ]; then echo "Set NEW_VERSION!" >&2; exit 1; fi
diff --git a/contrib/pyln-client/Makefile b/contrib/pyln-client/Makefile
index 27d596f4..c0c6cf6d 100644
--- a/contrib/pyln-client/Makefile
+++ b/contrib/pyln-client/Makefile
@@ -1,7 +1,7 @@
#!/usr/bin/make
PKG=client
-VERSION := $(shell poetry version -s)
+VERSION := $(shell grep 'version' pyproject.toml | head -n1 | cut -d'"' -f2)
# You can set these variables from the command line.
SPHINXOPTS =
@@ -17,31 +17,20 @@ check: check-source check-pytest
check-source: check-flake8 check-mypy check-version
-# We want to create an env for this directory.
check-version:
- poetry env remove -q python3 || true
- poetry env use python3
- poetry install
- [ "`poetry run python3 -c 'from pyln import $(PKG); print($(PKG).__version__)'`" = "$(VERSION)" ] || exit 1
+ [ "`uv run python3 -c 'from pyln import $(PKG); print($(PKG).__version__)'`" = "$(VERSION)" ] || exit 1
check-flake8:
- flake8 --ignore=E501,E731,W503,E741 pyln tests
+ uv run flake8 --ignore=E501,E731,W503,E741 pyln tests
check-pytest:
- pytest tests
+ uv run pytest tests
check-mypy:
# MYPYPATH=$(PYTHONPATH) mypy --namespace-packages --follow-imports=skip tests pyln
-# Having versions in two places sucks, but so does every other option :(
-# See https://github.com/python-poetry/poetry/issues/144
-upgrade-version:
- if [ -z "$(NEW_VERSION)" ]; then echo "Set NEW_VERSION!" >&2; exit 1; fi
- poetry version $(NEW_VERSION)
- sed 's/^__version__ = .*/__version__ = "$(NEW_VERSION)"/' < pyln/$(PKG)/__init__.py > pyln/$(PKG)/__init__.py.new && mv pyln/$(PKG)/__init__.py.new pyln/$(PKG)/__init__.py
-
$(SDIST_FILE) $(BDIST_FILE):
- poetry build
+ uv build
prod-release: check-version $(ARTEFACTS)
- poetry publish
+ uv publish
diff --git a/contrib/pyln-grpc-proto/Makefile b/contrib/pyln-grpc-proto/Makefile
index b677445d..e082732a 100644
--- a/contrib/pyln-grpc-proto/Makefile
+++ b/contrib/pyln-grpc-proto/Makefile
@@ -2,7 +2,7 @@
.PHONY: clean protos
PKG=grpc
-VERSION := $(shell poetry version -s)
+VERSION := $(shell grep 'version' pyproject.toml | head -n1 | cut -d'"' -f2)
PROTOS = \
pyln/grpc/node_pb2.py \
@@ -16,7 +16,7 @@ PROTOSRC = \
../../cln-grpc/proto/primitives.proto
${PROTOS} &: ${PROTOSRC}
- python \
+ uv run \
-m grpc_tools.protoc \
-I ../../cln-grpc/proto \
../../cln-grpc/proto/node.proto \
@@ -40,13 +40,6 @@ ${PROTOS} &: ${PROTOSRC}
sed -i 's/import primitives_pb2/from pyln.grpc import primitives_pb2/g' pyln/grpc/node_pb2.pyi
sed -i 's/import node_pb2 as node__pb2/from pyln.grpc import node_pb2 as node__pb2/g' pyln/grpc/node_pb2_grpc.py
-# Having versions in two places sucks, but so does every other option :(
-# See https://github.com/python-poetry/poetry/issues/144
-upgrade-version:
- if [ -z "$(NEW_VERSION)" ]; then echo "Set NEW_VERSION!" >&2; exit 1; fi
- poetry version $(NEW_VERSION)
- sed 's/^__version__ = .*/__version__ = "$(NEW_VERSION)"/' < pyln/$(PKG)/__init__.py > pyln/$(PKG)/__init__.py.new && mv pyln/$(PKG)/__init__.py.new pyln/$(PKG)/__init__.py
-
protos: ${PROTOS}
clean:
diff --git a/contrib/pyln-proto/Makefile b/contrib/pyln-proto/Makefile
index 373c812d..9c278745 100644
--- a/contrib/pyln-proto/Makefile
+++ b/contrib/pyln-proto/Makefile
@@ -1,7 +1,7 @@
#!/usr/bin/make
PKG=proto
-VERSION := $(shell poetry version -s)
+VERSION := $(shell grep 'version' pyproject.toml | head -n1 | cut -d'"' -f2)
# You can set these variables from the command line.
SPHINXOPTS =
@@ -19,32 +19,19 @@ check-source: check-flake8 check-mypy check-version
# We want to create an env for this directory.
check-version:
- poetry env remove -q python3 || true
- poetry env use python3
- poetry install
- [ "`poetry run python3 -c 'from pyln import $(PKG); print($(PKG).__version__)'`" = "$(VERSION)" ] || exit 1
+ [ "`uv run python3 -c 'from pyln import $(PKG); print($(PKG).__version__)'`" = "$(VERSION)" ] || exit 1
check-flake8:
- flake8 --ignore=E501,E731,W503,E741 pyln tests
+ uv run flake8 --ignore=E501,E731,W503,E741 pyln tests
check-pytest:
- pytest tests
+ uv run pytest tests
check-mypy:
# MYPYPATH=$(PYTHONPATH) mypy --namespace-packages --follow-imports=skip tests pyln
-pyproject.toml: pyln/${PKG}/__init__.py
- poetry version ${VERSION}
-
-# Having versions in two places sucks, but so does every other option :(
-# See https://github.com/python-poetry/poetry/issues/144
-upgrade-version:
- if [ -z "$(NEW_VERSION)" ]; then echo "Set NEW_VERSION!" >&2; exit 1; fi
- poetry version $(NEW_VERSION)
- sed 's/^__version__ = .*/__version__ = "$(NEW_VERSION)"/' < pyln/$(PKG)/__init__.py > pyln/$(PKG)/__init__.py.new && mv pyln/$(PKG)/__init__.py.new pyln/$(PKG)/__init__.py
-
$(SDIST_FILE) $(BDIST_FILE):
- poetry build
+ uv build
prod-release: check-version $(ARTEFACTS)
- poetry publish
+ uv publish
diff --git a/contrib/pyln-spec/Makefile b/contrib/pyln-spec/Makefile
index e497bb58..8d70ea9c 100755
--- a/contrib/pyln-spec/Makefile
+++ b/contrib/pyln-spec/Makefile
@@ -17,18 +17,18 @@ CODE_DIRS := $(foreach b,$(BOLTS),bolt$b/pyln/spec/bolt$b)
check: $(DIRS:%=check-pytest-%)
check-pytest-%:
- cd $* && pytest
+ cd $* && uv run pytest
check-source: check-source-flake8 check-source-mypy
check-source-flake8: $(DIRS:%=check-source-flake8-%)
check-source-mypy: $(DIRS:%=check-source-mypy-%)
check-source-flake8-%:
- cd $* && flake8 --ignore=E501,E731,W503,E741 --exclude=text.py
+ cd $* && uv run flake8 --ignore=E501,E731,W503,E741 --exclude=text.py
# mypy . does not recurse. I have no idea why...
check-source-mypy-%:
- cd $* && mypy --ignore-missing-imports `find * -name '*.py'`
+ cd $* && uv run mypy --ignore-missing-imports `find * -name '*.py'`
# Given a bolt number and a variable, get the value from inside the package.
extract = $(shell cat bolt$1/pyln/spec/bolt$1/gen_*version.py | sed -n 's/^$2 = \"\(.*\)\"/\1/p')
@@ -45,32 +45,33 @@ sdistfiles = $(foreach b,$(BOLTS),bolt$b/dist/pyln-bolt$b-$(call version,$b).tar
bdistfiles = $(foreach b,$(BOLTS),bolt$b/dist/pyln_bolt$b-$(call version,$b)-py3-none-any.whl)
%.tar.gz:
- cd $(dir $@)/.. && python3 setup.py sdist
+ cd $(dir $@)/.. && uv build
%.whl:
- cd $(dir $@)/.. && python3 setup.py bdist_wheel
+ cd $(dir $@)/.. && uv build
ARTEFACTS := $(foreach b,$(BOLTS),$(call bdistfiles,$b) $(call sdistfiles,$b))
test-release-%:
- cd bolt$b && poetry publish --repository testpypi
+ cd bolt$* && uv publish --publish-url https://test.pypi.org/legacy/
test-release: $(BOLTS:%=prod-release-%)
prod-release-%:
- cd bolt$b && poetry publish
+ cd bolt$* && uv publish
prod-release: $(BOLTS:%=prod-release-%)
# Pattern rules don't work reliably with multiple % in prereqs!
refresh-1: bolt1/pyln/spec/bolt1/gen_csv_version.py bolt1/pyln/spec/bolt1/gen_version.py
- cd bolt1 && poetry version $(call version,1)
+ # Update version in pyproject.toml using sed (uv doesn't have version command)
+ cd bolt1 && sed -i 's/^version = .*/version = "$(call version,1)"/' pyproject.toml
refresh-2: bolt2/pyln/spec/bolt2/gen_csv_version.py bolt2/pyln/spec/bolt2/gen_version.py
- cd bolt2 && poetry version $(call version,2)
+ cd bolt2 && sed -i 's/^version = .*/version = "$(call version,2)"/' pyproject.toml
refresh-4: bolt4/pyln/spec/bolt4/gen_csv_version.py bolt4/pyln/spec/bolt4/gen_version.py
- cd bolt4 && poetry version $(call version,4)
+ cd bolt4 && sed -i 's/^version = .*/version = "$(call version,4)"/' pyproject.toml
refresh-7: bolt7/pyln/spec/bolt7/gen_csv_version.py bolt7/pyln/spec/bolt7/gen_version.py
- cd bolt7 && poetry version $(call version,7)
+ cd bolt7 && sed -i 's/^version = .*/version = "$(call version,7)"/' pyproject.toml
refresh: $(BOLTS:%=refresh-%)
diff --git a/contrib/pyln-testing/Makefile b/contrib/pyln-testing/Makefile
index 2b45e51c..c59c7dca 100644
--- a/contrib/pyln-testing/Makefile
+++ b/contrib/pyln-testing/Makefile
@@ -1,7 +1,7 @@
#!/usr/bin/make
PKG=testing
-VERSION := $(shell poetry version -s)
+VERSION := $(shell grep 'version' pyproject.toml | head -n1 | cut -d'"' -f2)
# You can set these variables from the command line.
SPHINXOPTS =
@@ -19,29 +19,19 @@ check-source: check-flake8 check-mypy check-version
# We want to create an env for this directory.
check-version:
- poetry env remove -q python3 || true
- poetry env use python3
- poetry install
- [ "`poetry run python3 -c 'from pyln import $(PKG); print($(PKG).__version__)'`" = "$(VERSION)" ] || exit 1
+ [ "`uv run python3 -c 'from pyln import $(PKG); print($(PKG).__version__)'`" = "$(VERSION)" ] || exit 1
check-flake8:
- flake8 --ignore=E501,E731,W503,E741 --exclude '*_pb2*.py,grpc2py.py' pyln tests
+ uv run flake8 --ignore=E501,E731,W503,E741 --exclude '*_pb2*.py,grpc2py.py' pyln tests
check-pytest:
- pytest tests
+ uv run pytest tests
check-mypy:
# MYPYPATH=$(PYTHONPATH) mypy --namespace-packages --follow-imports=skip tests pyln
-# Having versions in two places sucks, but so does every other option :(
-# See https://github.com/python-poetry/poetry/issues/144
-upgrade-version:
- if [ -z "$(NEW_VERSION)" ]; then echo "Set NEW_VERSION!" >&2; exit 1; fi
- poetry version $(NEW_VERSION)
- sed 's/^__version__ = .*/__version__ = "$(NEW_VERSION)"/' < pyln/$(PKG)/__init__.py > pyln/$(PKG)/__init__.py.new && mv pyln/$(PKG)/__init__.py.new pyln/$(PKG)/__init__.py
-
$(SDIST_FILE) $(BDIST_FILE):
- poetry build
+ uv build
prod-release: check-version $(ARTEFACTS)
- poetry publish
+ uv publish
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.