From 666b2717dc1740800c7c44e912df6e18d19a2bba Mon Sep 17 00:00:00 2001 From: Simon Heybrock Date: Mon, 30 Mar 2026 04:23:10 +0000 Subject: [PATCH] Add 7-day supply-chain cooldown to dependency resolution Switch pip-compile-multi to use uv as backend resolver and set UV_EXCLUDE_NEWER to 7 days in the past. This excludes recently uploaded package versions from dependency resolution, reducing risk of supply-chain attacks via newly published malicious packages. The cooldown can be overridden by setting UV_EXCLUDE_NEWER in the environment before running tox -e deps. Also removes the pip==24.2 pin (workaround for pip-tools#2131) which is no longer needed with the uv backend. --- requirements/base.txt | 26 +++++++------ requirements/basetest.txt | 45 ++++++++++++----------- requirements/ci.txt | 20 ++++++---- requirements/compile_with_cooldown.py | 36 ++++++++++++++++++ requirements/dev.txt | 25 ++++++------- requirements/docs.txt | 12 +++--- requirements/mypy.txt | 2 + requirements/nightly.txt | 53 +++++++++++++-------------- requirements/static.txt | 12 +++--- requirements/test.txt | 2 + requirements/wheels.txt | 2 + tox.ini | 5 +-- 12 files changed, 145 insertions(+), 95 deletions(-) create mode 100644 requirements/compile_with_cooldown.py diff --git a/requirements/base.txt b/requirements/base.txt index 9472b5cdc..6777d882f 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -5,13 +5,15 @@ # # requirements upgrade # +--index-url https://pypi.org/simple + annotated-types==0.7.0 # via pydantic certifi==2026.2.25 # via requests -charset-normalizer==3.4.4 +charset-normalizer==3.4.6 # via requests -confluent-kafka==2.13.0 +confluent-kafka==2.13.2 # via -r base.in contourpy==1.3.3 # via matplotlib @@ -25,13 +27,13 @@ email-validator==2.3.0 # via scippneutron ess-streaming-data-types==0.27.0 # via -r base.in -essreduce==26.2.2 +essreduce==26.3.1 # via -r base.in flatbuffers==25.12.19 # via ess-streaming-data-types -fonttools==4.61.1 +fonttools==4.62.1 # via matplotlib -h5py==3.15.1 +h5py==3.16.0 # via # scippneutron # scippnexus @@ -41,9 +43,9 @@ idna==3.11 # requests jinja2==3.1.6 # via -r base.in -kiwisolver==1.4.9 +kiwisolver==1.5.0 # via matplotlib -lazy-loader==0.4 +lazy-loader==0.5 # via # plopp # scippneutron @@ -57,7 +59,7 @@ mpltoolbox==26.2.0 # via scippneutron networkx==3.6.1 # via cyclebane -numpy==2.4.2 +numpy==2.4.3 # via # contourpy # ess-streaming-data-types @@ -73,9 +75,9 @@ packaging==26.0 # pooch pillow==12.1.1 # via matplotlib -platformdirs==4.9.2 +platformdirs==4.9.4 # via pooch -plopp==26.2.1 +plopp==26.3.1 # via scippneutron pooch==1.9.0 # via -r base.in @@ -97,13 +99,13 @@ requests==2.32.5 # via pooch sciline==25.11.1 # via essreduce -scipp==26.2.0 +scipp==26.3.1 # via # -r base.in # essreduce # scippneutron # scippnexus -scippneutron==26.2.0 +scippneutron==26.3.0 # via # -r base.in # essreduce diff --git a/requirements/basetest.txt b/requirements/basetest.txt index 083639f54..50360f45e 100644 --- a/requirements/basetest.txt +++ b/requirements/basetest.txt @@ -5,21 +5,23 @@ # # requirements upgrade # +--index-url https://pypi.org/simple + annotated-types==0.7.0 # via pydantic -ase==3.27.0 +ase==3.28.0 # via ncrystal asttokens==3.0.1 # via stack-data bleach==6.3.0 # via panel -bokeh==3.8.2 +bokeh==3.9.0 # via # holoviews # panel certifi==2026.2.25 # via requests -charset-normalizer==3.4.4 +charset-normalizer==3.4.6 # via requests click==8.3.1 # via dask @@ -37,7 +39,7 @@ cyclebane==24.10.0 # via sciline cycler==0.12.1 # via matplotlib -dask==2026.1.2 +dask==2026.3.0 # via # essdiffraction # esspolarization @@ -53,7 +55,7 @@ essdiffraction==26.3.0 # via -r basetest.in esspolarization==25.10.0 # via essreflectometry -essreduce==26.2.2 +essreduce==26.3.1 # via # essdiffraction # esspolarization @@ -62,13 +64,13 @@ essreduce==26.2.2 # essspectroscopy essreflectometry==26.2.0 # via -r basetest.in -esssans==26.2.1 +esssans==26.3.0 # via -r basetest.in essspectroscopy==26.2.0 # via -r basetest.in executing==2.2.1 # via stack-data -fonttools==4.61.1 +fonttools==4.62.1 # via matplotlib fsspec==2026.2.0 # via dask @@ -81,7 +83,7 @@ graphviz==0.21 # essreflectometry # esssans # essspectroscopy -h5py==3.15.1 +h5py==3.16.0 # via # scippneutron # scippnexus @@ -91,7 +93,7 @@ idna==3.11 # via # email-validator # requests -importlib-metadata==8.7.1 +importlib-metadata==9.0.0 # via dask iniconfig==2.3.0 # via pytest @@ -111,9 +113,9 @@ jinja2==3.1.6 # via bokeh jupyterlab-widgets==3.0.16 # via ipywidgets -kiwisolver==1.4.9 +kiwisolver==1.5.0 # via matplotlib -lazy-loader==0.4 +lazy-loader==0.5 # via # plopp # scippneutron @@ -143,12 +145,12 @@ mdurl==0.1.2 # via markdown-it-py mpltoolbox==26.2.0 # via scippneutron -narwhals==2.17.0 +narwhals==2.18.0 # via # bokeh # holoviews # panel -ncrystal[cif]==4.2.12 +ncrystal==4.2.12 # via essdiffraction ncrystal-core==4.2.12 # via ncrystal @@ -156,7 +158,7 @@ ncrystal-python==4.2.12 # via ncrystal networkx==3.6.1 # via cyclebane -numpy==2.4.2 +numpy==2.4.3 # via # ase # bokeh @@ -188,13 +190,12 @@ packaging==26.0 # pytest pandas==3.0.1 # via - # bokeh # essreflectometry # esssans # essspectroscopy # holoviews # panel -panel==1.8.7 +panel==1.8.10 # via # -r basetest.in # holoviews @@ -214,9 +215,9 @@ pillow==12.1.1 # via # bokeh # matplotlib -platformdirs==4.9.2 +platformdirs==4.9.4 # via pooch -plopp==26.2.1 +plopp==26.3.1 # via # essdiffraction # essreflectometry @@ -284,7 +285,7 @@ sciline==25.11.1 # essreflectometry # esssans # essspectroscopy -scipp==26.2.0 +scipp==26.3.1 # via # essdiffraction # esspolarization @@ -295,7 +296,7 @@ scipp==26.2.0 # scippneutron # scippnexus # tof -scippneutron==26.2.0 +scippneutron==26.3.0 # via # -r basetest.in # essdiffraction @@ -325,7 +326,7 @@ spglib==2.6.0 # ncrystal stack-data==0.6.3 # via ipython -tof==26.1.0 +tof==26.3.0 # via # essdiffraction # essspectroscopy @@ -333,7 +334,7 @@ toolz==1.1.0 # via # dask # partd -tornado==6.5.4 +tornado==6.5.5 # via bokeh tqdm==4.67.3 # via panel diff --git a/requirements/ci.txt b/requirements/ci.txt index 157d0bff2..385e5c6ac 100644 --- a/requirements/ci.txt +++ b/requirements/ci.txt @@ -5,17 +5,19 @@ # # requirements upgrade # -cachetools==7.0.1 +--index-url https://pypi.org/simple + +cachetools==7.0.5 # via tox certifi==2026.2.25 # via requests -charset-normalizer==3.4.4 +charset-normalizer==3.4.6 # via requests colorama==0.4.6 # via tox distlib==0.4.0 # via virtualenv -filelock==3.25.0 +filelock==3.25.2 # via # python-discovery # tox @@ -31,7 +33,7 @@ packaging==26.0 # -r ci.in # pyproject-api # tox -platformdirs==4.9.2 +platformdirs==4.9.4 # via # python-discovery # tox @@ -40,15 +42,17 @@ pluggy==1.6.0 # via tox pyproject-api==1.10.0 # via tox -python-discovery==1.1.0 +python-discovery==1.2.0 # via virtualenv requests==2.32.5 # via -r ci.in -smmap==5.0.2 +smmap==5.0.3 # via gitdb -tox==4.47.0 +tomli-w==1.2.0 + # via tox +tox==4.50.3 # via -r ci.in urllib3==2.6.3 # via requests -virtualenv==21.1.0 +virtualenv==21.2.0 # via tox diff --git a/requirements/compile_with_cooldown.py b/requirements/compile_with_cooldown.py new file mode 100644 index 000000000..1450a6279 --- /dev/null +++ b/requirements/compile_with_cooldown.py @@ -0,0 +1,36 @@ +"""Run pip-compile-multi with a supply-chain cooldown. + +Sets UV_EXCLUDE_NEWER to a date in the past before invoking +pip-compile-multi, so that recently uploaded package versions +are excluded from dependency resolution. This reduces the risk +of supply-chain attacks via newly published malicious packages. + +The cooldown can be overridden by setting UV_EXCLUDE_NEWER in +the environment before running this script. +""" + +import datetime +import os +import subprocess +import sys + +COOLDOWN_DAYS = 7 + + +def main() -> None: + if "UV_EXCLUDE_NEWER" not in os.environ: + cutoff = datetime.datetime.now(datetime.timezone.utc) - datetime.timedelta( + days=COOLDOWN_DAYS + ) + os.environ["UV_EXCLUDE_NEWER"] = cutoff.strftime("%Y-%m-%dT%H:%M:%SZ") + sys.stderr.write(f"UV_EXCLUDE_NEWER={os.environ['UV_EXCLUDE_NEWER']}\n") + sys.exit( + subprocess.run( # noqa: S603 + [sys.executable, "-m", "pip_compile_multi.cli", "--uv", *sys.argv[1:]], + check=False, + ).returncode + ) + + +if __name__ == "__main__": + main() diff --git a/requirements/dev.txt b/requirements/dev.txt index b808f53f4..03e1901d1 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -12,6 +12,8 @@ -r static.txt -r test.txt -r wheels.txt +--index-url https://pypi.org/simple + anyio==4.12.1 # via # httpx @@ -22,11 +24,11 @@ argon2-cffi-bindings==25.1.0 # via argon2-cffi arrow==1.4.0 # via isoduration -async-lru==2.2.0 +async-lru==2.3.0 # via jupyterlab cffi==2.0.0 # via argon2-cffi-bindings -copier==9.12.0 +copier==9.14.0 # via -r dev.in dunamai==1.26.0 # via copier @@ -46,13 +48,8 @@ jinja2-ansible-filters==1.3.2 # via copier json5==0.13.0 # via jupyterlab-server -jsonpointer==3.0.0 +jsonpointer==3.1.0 # via jsonschema -jsonschema[format-nongpl]==4.26.0 - # via - # jupyter-events - # jupyterlab-server - # nbformat jupyter-events==0.12.0 # via jupyter-server jupyter-lsp==2.3.0 @@ -65,7 +62,7 @@ jupyter-server==2.17.0 # notebook-shim jupyter-server-terminals==0.5.4 # via jupyter-server -jupyterlab==4.5.5 +jupyterlab==4.5.6 # via -r dev.in jupyterlab-server==2.28.0 # via jupyterlab @@ -75,6 +72,8 @@ notebook-shim==0.2.4 # via jupyterlab overrides==7.7.0 # via jupyter-server +pip==26.0.1 + # via pip-tools pip-compile-multi==3.2.2 # via -r dev.in pip-tools==7.5.3 @@ -101,6 +100,10 @@ rfc3987-syntax==1.1.0 # via jsonschema send2trash==2.1.0 # via jupyter-server +setuptools==82.0.1 + # via + # jupyterlab + # pip-tools terminado==0.18.1 # via # jupyter-server @@ -117,7 +120,3 @@ websocket-client==1.9.0 # via jupyter-server wheel==0.46.3 # via pip-tools - -# The following packages are considered to be unsafe in a requirements file: -# pip -# setuptools diff --git a/requirements/docs.txt b/requirements/docs.txt index 5206c51c4..726bdb6ae 100644 --- a/requirements/docs.txt +++ b/requirements/docs.txt @@ -6,13 +6,15 @@ # requirements upgrade # -r base.txt +--index-url https://pypi.org/simple + accessible-pygments==0.0.5 # via pydata-sphinx-theme alabaster==1.0.0 # via sphinx asttokens==3.0.1 # via stack-data -attrs==25.4.0 +attrs==26.1.0 # via # jsonschema # referencing @@ -26,7 +28,7 @@ beautifulsoup4==4.14.3 # via # nbconvert # pydata-sphinx-theme -bleach[css]==6.3.0 +bleach==6.3.0 # via nbconvert comm==0.2.3 # via @@ -48,7 +50,7 @@ executing==2.2.1 # via stack-data fastjsonschema==2.21.2 # via nbformat -imagesize==1.4.1 +imagesize==2.0.0 # via sphinx ipydatawidgets==4.3.5 # via pythreejs @@ -198,7 +200,7 @@ sphinxcontrib-htmlhelp==2.1.0 # via sphinx sphinxcontrib-jsmath==1.0.1 # via sphinx -sphinxcontrib-mermaid==2.0.0 +sphinxcontrib-mermaid==2.0.1 # via -r docs.in sphinxcontrib-qthelp==2.0.0 # via sphinx @@ -208,7 +210,7 @@ stack-data==0.6.3 # via ipython tinycss2==1.4.0 # via bleach -tornado==6.5.4 +tornado==6.5.5 # via # ipykernel # jupyter-client diff --git a/requirements/mypy.txt b/requirements/mypy.txt index f90f757a5..4d9439d71 100644 --- a/requirements/mypy.txt +++ b/requirements/mypy.txt @@ -6,6 +6,8 @@ # requirements upgrade # -r test.txt +--index-url https://pypi.org/simple + librt==0.8.1 # via mypy mypy==1.19.1 diff --git a/requirements/nightly.txt b/requirements/nightly.txt index b70cb754e..a6d87aca4 100644 --- a/requirements/nightly.txt +++ b/requirements/nightly.txt @@ -10,29 +10,29 @@ annotated-types==0.7.0 # via pydantic -ase==3.27.0 +ase==3.28.0 # via ncrystal asttokens==3.0.1 # via stack-data bleach==6.3.0 # via panel -bokeh==3.8.2 +bokeh==3.9.0 # via # holoviews # panel certifi==2026.2.25 # via requests -charset-normalizer==3.4.4 +charset-normalizer==3.4.6 # via requests click==8.3.1 # via dask cloudpickle==3.1.2 # via dask -colorcet==3.1.1a1 +colorcet==3.1.0 # via holoviews comm==0.2.3 # via ipywidgets -confluent-kafka==2.13.2rc1 +confluent-kafka==2.13.2 # via -r nightly.in contourpy==1.3.3 # via @@ -42,7 +42,7 @@ cyclebane==24.10.0 # via sciline cycler==0.12.1 # via matplotlib -dask==2026.1.2 +dask==2026.3.0 # via # essdiffraction # esspolarization @@ -60,7 +60,7 @@ essdiffraction==26.3.0 # via -r nightly.in esspolarization==25.10.0 # via essreflectometry -essreduce @ git+https://github.com/scipp/essreduce@main +essreduce @ git+https://github.com/scipp/essreduce@2eb2f8ba1ebfaffd4d5f18e1d0a95658f1004127 # via # -r nightly.in # essdiffraction @@ -78,7 +78,7 @@ executing==2.2.1 # via stack-data flatbuffers==25.12.19 # via ess-streaming-data-types -fonttools==4.61.1 +fonttools==4.62.1 # via matplotlib fsspec==2026.2.0 # via dask @@ -91,17 +91,17 @@ graphviz==0.21 # essreflectometry # esssans # essspectroscopy -h5py==3.15.1 +h5py==3.16.0 # via # scippneutron # scippnexus -holoviews==1.23.0b0 +holoviews==1.22.1 # via -r nightly.in idna==3.11 # via # email-validator # requests -importlib-metadata==8.7.1 +importlib-metadata==9.0.0 # via dask iniconfig==2.3.0 # via pytest @@ -123,9 +123,9 @@ jinja2==3.1.6 # bokeh jupyterlab-widgets==3.0.16 # via ipywidgets -kiwisolver==1.4.10rc0 +kiwisolver==1.5.0 # via matplotlib -lazy-loader==0.4 +lazy-loader==0.5 # via # plopp # scippneutron @@ -155,12 +155,12 @@ mdurl==0.1.2 # via markdown-it-py mpltoolbox==26.2.0 # via scippneutron -narwhals==2.17.0 +narwhals==2.18.0 # via # bokeh # holoviews # panel -ncrystal[cif]==4.2.12 +ncrystal==4.2.12 # via essdiffraction ncrystal-core==4.2.12 # via ncrystal @@ -168,7 +168,7 @@ ncrystal-python==4.2.12 # via ncrystal networkx==3.6.1 # via cyclebane -numpy==2.4.2 +numpy==2.4.3 # via # ase # bokeh @@ -201,13 +201,12 @@ packaging==26.0 # pytest pandas==3.0.1 # via - # bokeh # essreflectometry # esssans # essspectroscopy # holoviews # panel -panel==1.8.8b0 +panel==1.8.10 # via # -r nightly.in # holoviews @@ -227,9 +226,9 @@ pillow==12.1.1 # via # bokeh # matplotlib -platformdirs==4.9.2 +platformdirs==4.9.4 # via pooch -plopp==26.2.1 +plopp==26.3.1 # via # essdiffraction # essreflectometry @@ -250,11 +249,11 @@ pure-eval==0.2.3 # via stack-data py-cpuinfo==9.0.0 # via pytest-benchmark -pydantic==2.13.0b2 +pydantic==2.12.5 # via # -r nightly.in # scippneutron -pydantic-core==2.42.0 +pydantic-core==2.41.5 # via pydantic pygments==2.19.2 # via @@ -294,7 +293,7 @@ requests==2.32.5 # via # panel # pooch -sciline @ git+https://github.com/scipp/sciline@main +sciline @ git+https://github.com/scipp/sciline@af8bb02e9a0be692a6e89c7e3c6cda5cf0a3de69 # via # -r nightly.in # essdiffraction @@ -303,7 +302,7 @@ sciline @ git+https://github.com/scipp/sciline@main # essreflectometry # esssans # essspectroscopy -scipp==100.0.0.dev0 +scipp==26.3.1 # via # -r nightly.in # essdiffraction @@ -315,7 +314,7 @@ scipp==100.0.0.dev0 # scippneutron # scippnexus # tof -scippneutron==26.2.0 +scippneutron==26.3.0 # via # essdiffraction # essreduce @@ -346,7 +345,7 @@ stack-data==0.6.3 # via ipython structlog==25.5.0 # via -r nightly.in -tof==26.1.0 +tof==26.3.0 # via # essdiffraction # essspectroscopy @@ -354,7 +353,7 @@ toolz==1.1.0 # via # dask # partd -tornado==6.5.4 +tornado==6.5.5 # via bokeh tqdm==4.67.3 # via panel diff --git a/requirements/static.txt b/requirements/static.txt index e80710d74..0cc335a33 100644 --- a/requirements/static.txt +++ b/requirements/static.txt @@ -5,27 +5,29 @@ # # requirements upgrade # +--index-url https://pypi.org/simple + cfgv==3.5.0 # via pre-commit distlib==0.4.0 # via virtualenv -filelock==3.25.0 +filelock==3.25.2 # via # python-discovery # virtualenv -identify==2.6.17 +identify==2.6.18 # via pre-commit nodeenv==1.10.0 # via pre-commit -platformdirs==4.9.2 +platformdirs==4.9.4 # via # python-discovery # virtualenv pre-commit==4.5.1 # via -r static.in -python-discovery==1.1.0 +python-discovery==1.2.0 # via virtualenv pyyaml==6.0.3 # via pre-commit -virtualenv==21.1.0 +virtualenv==21.2.0 # via pre-commit diff --git a/requirements/test.txt b/requirements/test.txt index 6817392ee..2d060a491 100644 --- a/requirements/test.txt +++ b/requirements/test.txt @@ -7,3 +7,5 @@ # -r base.txt -r basetest.txt +--index-url https://pypi.org/simple + diff --git a/requirements/wheels.txt b/requirements/wheels.txt index 0d70d60c7..2d728117d 100644 --- a/requirements/wheels.txt +++ b/requirements/wheels.txt @@ -5,6 +5,8 @@ # # requirements upgrade # +--index-url https://pypi.org/simple + build==1.4.0 # via -r wheels.in packaging==26.0 diff --git a/tox.ini b/tox.ini index 5cac836e5..5c1444661 100644 --- a/tox.ini +++ b/tox.ini @@ -74,9 +74,8 @@ description = Update dependencies by running pip-compile-multi deps = pip-compile-multi tomli - # Avoid https://github.com/jazzband/pip-tools/issues/2131 - pip==24.2 + uv skip_install = true changedir = requirements commands = python ./make_base.py --nightly scipp,sciline,essreduce - pip-compile-multi -d . --backtracking --annotate-index + python ./compile_with_cooldown.py -d . --backtracking --annotate-index