From e00da44874371367bb75f945c9244058dfeb03cb Mon Sep 17 00:00:00 2001 From: Remco de Boer <29308176+redeboer@users.noreply.github.com> Date: Thu, 7 Mar 2024 20:13:45 +0100 Subject: [PATCH 1/2] MAINT: update pip constraints and pre-commit (#405) * DX: outsource PR linting to ComPWA/actions * FIX: remove `nbclient` from `doc` dependencies * MAINT: generate constraint files with `uv pip compile` --------- Co-authored-by: GitHub Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .constraints/py3.10.txt | 33 +++++++++++++----------------- .constraints/py3.11.txt | 33 +++++++++++++----------------- .constraints/py3.12.txt | 33 +++++++++++++----------------- .constraints/py3.7.txt | 23 ++++++++------------- .constraints/py3.8.txt | 35 ++++++++++++++------------------ .constraints/py3.9.txt | 35 ++++++++++++++------------------ .github/workflows/pr-linting.yml | 23 ++------------------- .pre-commit-config.yaml | 6 +++--- pyproject.toml | 1 - 9 files changed, 86 insertions(+), 136 deletions(-) diff --git a/.constraints/py3.10.txt b/.constraints/py3.10.txt index e63fb0ca0..bc4ad4c2b 100644 --- a/.constraints/py3.10.txt +++ b/.constraints/py3.10.txt @@ -1,9 +1,5 @@ -# -# This file is autogenerated by pip-compile with Python 3.10 -# by the following command: -# -# pip-compile --extra=dev --no-annotate --output-file=.constraints/py3.10.txt --strip-extras --unsafe-package=ampform --unsafe-package=pip --unsafe-package=setuptools --unsafe-package=symplot -# +# This file was autogenerated by uv via the following command: +# uv pip compile pyproject.toml -o .constraints/py3.10.txt --all-extras --no-annotate --python-version=3.10 --no-emit-package setuptools accessible-pygments==0.0.4 alabaster==0.7.16 anyio==4.3.0 @@ -55,7 +51,7 @@ httpx==0.27.0 identify==2.5.35 idna==3.6 imagesize==1.4.1 -importlib-metadata==7.0.1 +importlib-metadata==7.0.2 iniconfig==2.0.0 ipykernel==6.29.3 ipympl==0.9.3 @@ -66,7 +62,7 @@ isoduration==20.11.0 isort==5.13.2 jedi==0.19.1 jinja2==3.1.3 -json5==0.9.20 +json5==0.9.22 jsonpointer==2.4 jsonschema==4.21.1 jsonschema-specifications==2023.12.1 @@ -74,11 +70,11 @@ jupyter-cache==1.0.0 jupyter-client==8.6.0 jupyter-core==5.7.1 jupyter-events==0.9.0 -jupyter-lsp==2.2.3 +jupyter-lsp==2.2.4 jupyter-server==2.13.0 jupyter-server-mathjax==0.2.6 jupyter-server-terminals==0.5.2 -jupyterlab==4.1.2 +jupyterlab==4.1.4 jupyterlab-code-formatter==2.2.1 jupyterlab-git==0.50.0 jupyterlab-lsp==5.1.0 @@ -87,7 +83,7 @@ jupyterlab-pygments==0.3.0 jupyterlab-server==2.25.3 jupyterlab-widgets==3.0.10 kiwisolver==1.4.5 -latexcodec==2.0.1 +latexcodec==3.0.0 livereload==2.6.3 lsprotocol==2023.0.1 markdown-it-py==3.0.0 @@ -104,10 +100,10 @@ mypy-extensions==1.0.0 myst-nb==1.0.0 myst-parser==2.0.0 nbclient==0.6.8 -nbconvert==7.16.1 +nbconvert==7.16.2 nbdime==4.0.1 nbformat==5.9.2 -nbmake==1.5.1 +nbmake==1.5.3 nest-asyncio==1.6.0 nodeenv==1.8.0 notebook-shim==0.2.4 @@ -133,13 +129,13 @@ pybtex-docutils==1.0.3 pycparser==2.21 pydata-sphinx-theme==0.15.2 pygments==2.17.2 -pyparsing==3.1.1 +pyparsing==3.1.2 pyproject-api==1.6.1 pytest==8.0.2 pytest-cov==4.1.0 pytest-profiling==1.7.0 pytest-xdist==3.5.0 -python-constraint==1.4.0 +python-constraint==1.3.1 python-dateutil==2.9.0.post0 python-json-logger==2.0.7 python-lsp-jsonrpc==1.1.2 @@ -156,7 +152,7 @@ rfc3986-validator==0.1.1 rich==13.7.1 rope==1.12.0 rpds-py==0.18.0 -ruff==0.3.0 +ruff==0.3.1 scipy==1.12.0 send2trash==1.8.2 six==1.16.0 @@ -191,7 +187,7 @@ terminado==0.18.0 tinycss2==1.2.1 tomli==2.0.1 tornado==6.4 -tox==4.13.0 +tox==4.14.1 tqdm==4.66.2 traitlets==5.14.1 types-python-dateutil==2.8.19.20240106 @@ -208,6 +204,5 @@ wheel==0.42.0 widgetsnbextension==4.0.10 zipp==3.17.0 -# The following packages are considered to be unsafe in a requirements file: -# ampform +# The following packages were excluded from the output: # setuptools diff --git a/.constraints/py3.11.txt b/.constraints/py3.11.txt index b6e92d8bd..1d24262b6 100644 --- a/.constraints/py3.11.txt +++ b/.constraints/py3.11.txt @@ -1,9 +1,5 @@ -# -# This file is autogenerated by pip-compile with Python 3.11 -# by the following command: -# -# pip-compile --extra=dev --no-annotate --output-file=.constraints/py3.11.txt --strip-extras --unsafe-package=ampform --unsafe-package=pip --unsafe-package=setuptools --unsafe-package=symplot -# +# This file was autogenerated by uv via the following command: +# uv pip compile pyproject.toml -o .constraints/py3.11.txt --all-extras --no-annotate --python-version=3.11 --no-emit-package setuptools accessible-pygments==0.0.4 alabaster==0.7.16 anyio==4.3.0 @@ -54,7 +50,7 @@ httpx==0.27.0 identify==2.5.35 idna==3.6 imagesize==1.4.1 -importlib-metadata==7.0.1 +importlib-metadata==7.0.2 iniconfig==2.0.0 ipykernel==6.29.3 ipympl==0.9.3 @@ -65,7 +61,7 @@ isoduration==20.11.0 isort==5.13.2 jedi==0.19.1 jinja2==3.1.3 -json5==0.9.20 +json5==0.9.22 jsonpointer==2.4 jsonschema==4.21.1 jsonschema-specifications==2023.12.1 @@ -73,11 +69,11 @@ jupyter-cache==1.0.0 jupyter-client==8.6.0 jupyter-core==5.7.1 jupyter-events==0.9.0 -jupyter-lsp==2.2.3 +jupyter-lsp==2.2.4 jupyter-server==2.13.0 jupyter-server-mathjax==0.2.6 jupyter-server-terminals==0.5.2 -jupyterlab==4.1.2 +jupyterlab==4.1.4 jupyterlab-code-formatter==2.2.1 jupyterlab-git==0.50.0 jupyterlab-lsp==5.1.0 @@ -86,7 +82,7 @@ jupyterlab-pygments==0.3.0 jupyterlab-server==2.25.3 jupyterlab-widgets==3.0.10 kiwisolver==1.4.5 -latexcodec==2.0.1 +latexcodec==3.0.0 livereload==2.6.3 lsprotocol==2023.0.1 markdown-it-py==3.0.0 @@ -103,10 +99,10 @@ mypy-extensions==1.0.0 myst-nb==1.0.0 myst-parser==2.0.0 nbclient==0.6.8 -nbconvert==7.16.1 +nbconvert==7.16.2 nbdime==4.0.1 nbformat==5.9.2 -nbmake==1.5.1 +nbmake==1.5.3 nest-asyncio==1.6.0 nodeenv==1.8.0 notebook-shim==0.2.4 @@ -132,13 +128,13 @@ pybtex-docutils==1.0.3 pycparser==2.21 pydata-sphinx-theme==0.15.2 pygments==2.17.2 -pyparsing==3.1.1 +pyparsing==3.1.2 pyproject-api==1.6.1 pytest==8.0.2 pytest-cov==4.1.0 pytest-profiling==1.7.0 pytest-xdist==3.5.0 -python-constraint==1.4.0 +python-constraint==1.3.1 python-dateutil==2.9.0.post0 python-json-logger==2.0.7 python-lsp-jsonrpc==1.1.2 @@ -155,7 +151,7 @@ rfc3986-validator==0.1.1 rich==13.7.1 rope==1.12.0 rpds-py==0.18.0 -ruff==0.3.0 +ruff==0.3.1 scipy==1.12.0 send2trash==1.8.2 six==1.16.0 @@ -189,7 +185,7 @@ tabulate==0.9.0 terminado==0.18.0 tinycss2==1.2.1 tornado==6.4 -tox==4.13.0 +tox==4.14.1 tqdm==4.66.2 traitlets==5.14.1 types-python-dateutil==2.8.19.20240106 @@ -206,6 +202,5 @@ wheel==0.42.0 widgetsnbextension==4.0.10 zipp==3.17.0 -# The following packages are considered to be unsafe in a requirements file: -# ampform +# The following packages were excluded from the output: # setuptools diff --git a/.constraints/py3.12.txt b/.constraints/py3.12.txt index 88dcebda3..0466f1d05 100644 --- a/.constraints/py3.12.txt +++ b/.constraints/py3.12.txt @@ -1,9 +1,5 @@ -# -# This file is autogenerated by pip-compile with Python 3.12 -# by the following command: -# -# pip-compile --extra=dev --no-annotate --output-file=.constraints/py3.12.txt --strip-extras --unsafe-package=ampform --unsafe-package=pip --unsafe-package=setuptools --unsafe-package=symplot -# +# This file was autogenerated by uv via the following command: +# uv pip compile pyproject.toml -o .constraints/py3.12.txt --all-extras --no-annotate --python-version=3.12 --no-emit-package setuptools accessible-pygments==0.0.4 alabaster==0.7.16 anyio==4.3.0 @@ -54,7 +50,7 @@ httpx==0.27.0 identify==2.5.35 idna==3.6 imagesize==1.4.1 -importlib-metadata==7.0.1 +importlib-metadata==7.0.2 iniconfig==2.0.0 ipykernel==6.29.3 ipympl==0.9.3 @@ -65,7 +61,7 @@ isoduration==20.11.0 isort==5.13.2 jedi==0.19.1 jinja2==3.1.3 -json5==0.9.20 +json5==0.9.22 jsonpointer==2.4 jsonschema==4.21.1 jsonschema-specifications==2023.12.1 @@ -73,11 +69,11 @@ jupyter-cache==1.0.0 jupyter-client==8.6.0 jupyter-core==5.7.1 jupyter-events==0.9.0 -jupyter-lsp==2.2.3 +jupyter-lsp==2.2.4 jupyter-server==2.13.0 jupyter-server-mathjax==0.2.6 jupyter-server-terminals==0.5.2 -jupyterlab==4.1.2 +jupyterlab==4.1.4 jupyterlab-code-formatter==2.2.1 jupyterlab-git==0.50.0 jupyterlab-lsp==5.1.0 @@ -86,7 +82,7 @@ jupyterlab-pygments==0.3.0 jupyterlab-server==2.25.3 jupyterlab-widgets==3.0.10 kiwisolver==1.4.5 -latexcodec==2.0.1 +latexcodec==3.0.0 livereload==2.6.3 lsprotocol==2023.0.1 markdown-it-py==3.0.0 @@ -103,10 +99,10 @@ mypy-extensions==1.0.0 myst-nb==1.0.0 myst-parser==2.0.0 nbclient==0.6.8 -nbconvert==7.16.1 +nbconvert==7.16.2 nbdime==4.0.1 nbformat==5.9.2 -nbmake==1.5.1 +nbmake==1.5.3 nest-asyncio==1.6.0 nodeenv==1.8.0 notebook-shim==0.2.4 @@ -132,13 +128,13 @@ pybtex-docutils==1.0.3 pycparser==2.21 pydata-sphinx-theme==0.15.2 pygments==2.17.2 -pyparsing==3.1.1 +pyparsing==3.1.2 pyproject-api==1.6.1 pytest==8.0.2 pytest-cov==4.1.0 pytest-profiling==1.7.0 pytest-xdist==3.5.0 -python-constraint==1.4.0 +python-constraint==1.3.1 python-dateutil==2.9.0.post0 python-json-logger==2.0.7 python-lsp-jsonrpc==1.1.2 @@ -155,7 +151,7 @@ rfc3986-validator==0.1.1 rich==13.7.1 rope==1.12.0 rpds-py==0.18.0 -ruff==0.3.0 +ruff==0.3.1 scipy==1.12.0 send2trash==1.8.2 six==1.16.0 @@ -189,7 +185,7 @@ tabulate==0.9.0 terminado==0.18.0 tinycss2==1.2.1 tornado==6.4 -tox==4.13.0 +tox==4.14.1 tqdm==4.66.2 traitlets==5.14.1 types-python-dateutil==2.8.19.20240106 @@ -206,6 +202,5 @@ wheel==0.42.0 widgetsnbextension==4.0.10 zipp==3.17.0 -# The following packages are considered to be unsafe in a requirements file: -# ampform +# The following packages were excluded from the output: # setuptools diff --git a/.constraints/py3.7.txt b/.constraints/py3.7.txt index 2ac9cce7b..6e9f40a5e 100644 --- a/.constraints/py3.7.txt +++ b/.constraints/py3.7.txt @@ -1,9 +1,5 @@ -# -# This file is autogenerated by pip-compile with Python 3.7 -# by the following command: -# -# pip-compile --extra=dev --no-annotate --output-file=.constraints/py3.7.txt --resolver=backtracking --strip-extras --unsafe-package=ampform --unsafe-package=pip --unsafe-package=setuptools --unsafe-package=symplot -# +# This file was autogenerated by uv via the following command: +# uv pip compile pyproject.toml -o .constraints/py3.7.txt --all-extras --no-annotate --python-version=3.7 --no-emit-package setuptools accessible-pygments==0.0.4 aiofiles==22.1.0 aiosqlite==0.19.0 @@ -53,7 +49,7 @@ hepunits==2.3.3 identify==2.5.24 idna==3.6 imagesize==1.4.1 -importlib-metadata==6.7.0 ; python_version < "3.8.0" +importlib-metadata==6.7.0 importlib-resources==5.12.0 iniconfig==2.0.0 ipykernel==6.16.2 @@ -87,7 +83,7 @@ jupyterlab-pygments==0.2.2 jupyterlab-server==2.24.0 jupyterlab-widgets==3.0.10 kiwisolver==1.4.5 -latexcodec==2.0.1 +latexcodec==3.0.0 livereload==2.6.3 lsprotocol==2023.0.1 markdown-it-py==2.2.0 @@ -136,14 +132,14 @@ pycparser==2.21 pydantic==1.10.14 pydata-sphinx-theme==0.13.3 pygments==2.17.2 -pyparsing==3.1.1 +pyparsing==3.1.2 pyproject-api==1.5.3 pyrsistent==0.19.3 pytest==7.4.4 pytest-cov==4.1.0 pytest-profiling==1.7.0 pytest-xdist==3.5.0 -python-constraint==1.4.0 +python-constraint==1.3.1 python-dateutil==2.9.0.post0 python-json-logger==2.0.7 python-lsp-jsonrpc==1.0.0 @@ -162,7 +158,7 @@ rope==1.9.0 ruff==0.1.15 scipy==1.7.3 send2trash==1.8.2 -singledispatchmethod==1.0 ; python_version < "3.8.0" +singledispatchmethod==1.0 six==1.16.0 smmap==5.0.1 sniffio==1.3.1 @@ -198,7 +194,7 @@ tox==4.8.0 tqdm==4.66.2 traitlets==5.9.0 typed-ast==1.5.5 -typing-extensions==4.7.1 ; python_version < "3.8.0" +typing-extensions==4.7.1 ujson==5.7.0 uri-template==1.3.0 urllib3==2.0.7 @@ -213,6 +209,5 @@ y-py==0.6.2 ypy-websocket==0.8.4 zipp==3.15.0 -# The following packages are considered to be unsafe in a requirements file: -# ampform +# The following packages were excluded from the output: # setuptools diff --git a/.constraints/py3.8.txt b/.constraints/py3.8.txt index 29311f703..ab0c6206f 100644 --- a/.constraints/py3.8.txt +++ b/.constraints/py3.8.txt @@ -1,9 +1,5 @@ -# -# This file is autogenerated by pip-compile with Python 3.8 -# by the following command: -# -# pip-compile --extra=dev --no-annotate --output-file=.constraints/py3.8.txt --strip-extras --unsafe-package=ampform --unsafe-package=pip --unsafe-package=setuptools --unsafe-package=symplot -# +# This file was autogenerated by uv via the following command: +# uv pip compile pyproject.toml -o .constraints/py3.8.txt --all-extras --no-annotate --python-version=3.8 --no-emit-package setuptools accessible-pygments==0.0.4 alabaster==0.7.13 anyio==4.3.0 @@ -56,8 +52,8 @@ httpx==0.27.0 identify==2.5.35 idna==3.6 imagesize==1.4.1 -importlib-metadata==7.0.1 -importlib-resources==6.1.2 +importlib-metadata==7.0.2 +importlib-resources==6.1.3 iniconfig==2.0.0 ipykernel==6.29.3 ipympl==0.9.3 @@ -68,7 +64,7 @@ isoduration==20.11.0 isort==5.13.2 jedi==0.19.1 jinja2==3.1.3 -json5==0.9.20 +json5==0.9.22 jsonpointer==2.4 jsonschema==4.21.1 jsonschema-specifications==2023.12.1 @@ -76,11 +72,11 @@ jupyter-cache==0.6.1 jupyter-client==8.6.0 jupyter-core==5.7.1 jupyter-events==0.9.0 -jupyter-lsp==2.2.3 +jupyter-lsp==2.2.4 jupyter-server==2.13.0 jupyter-server-mathjax==0.2.6 jupyter-server-terminals==0.5.2 -jupyterlab==4.1.2 +jupyterlab==4.1.4 jupyterlab-code-formatter==2.2.1 jupyterlab-git==0.50.0 jupyterlab-lsp==5.1.0 @@ -89,7 +85,7 @@ jupyterlab-pygments==0.3.0 jupyterlab-server==2.25.3 jupyterlab-widgets==3.0.10 kiwisolver==1.4.5 -latexcodec==2.0.1 +latexcodec==3.0.0 livereload==2.6.3 lsprotocol==2023.0.1 markdown-it-py==2.2.0 @@ -106,10 +102,10 @@ mypy-extensions==1.0.0 myst-nb==0.17.2 myst-parser==0.18.1 nbclient==0.6.8 -nbconvert==7.16.1 +nbconvert==7.16.2 nbdime==4.0.1 nbformat==5.9.2 -nbmake==1.5.1 +nbmake==1.5.3 nest-asyncio==1.6.0 nodeenv==1.8.0 notebook-shim==0.2.4 @@ -137,13 +133,13 @@ pybtex-docutils==1.0.3 pycparser==2.21 pydata-sphinx-theme==0.14.4 pygments==2.17.2 -pyparsing==3.1.1 +pyparsing==3.1.2 pyproject-api==1.6.1 pytest==8.0.2 pytest-cov==4.1.0 pytest-profiling==1.7.0 pytest-xdist==3.5.0 -python-constraint==1.4.0 +python-constraint==1.3.1 python-dateutil==2.9.0.post0 python-json-logger==2.0.7 python-lsp-jsonrpc==1.1.2 @@ -161,7 +157,7 @@ rfc3986-validator==0.1.1 rich==13.7.1 rope==1.12.0 rpds-py==0.18.0 -ruff==0.3.0 +ruff==0.3.1 scipy==1.10.1 send2trash==1.8.2 six==1.16.0 @@ -196,7 +192,7 @@ terminado==0.18.0 tinycss2==1.2.1 tomli==2.0.1 tornado==6.4 -tox==4.13.0 +tox==4.14.1 tqdm==4.66.2 traitlets==5.14.1 types-python-dateutil==2.8.19.20240106 @@ -213,6 +209,5 @@ wheel==0.42.0 widgetsnbextension==4.0.10 zipp==3.17.0 -# The following packages are considered to be unsafe in a requirements file: -# ampform +# The following packages were excluded from the output: # setuptools diff --git a/.constraints/py3.9.txt b/.constraints/py3.9.txt index 9e35a5047..8b5cb151f 100644 --- a/.constraints/py3.9.txt +++ b/.constraints/py3.9.txt @@ -1,9 +1,5 @@ -# -# This file is autogenerated by pip-compile with Python 3.9 -# by the following command: -# -# pip-compile --extra=dev --no-annotate --output-file=.constraints/py3.9.txt --strip-extras --unsafe-package=ampform --unsafe-package=pip --unsafe-package=setuptools --unsafe-package=symplot -# +# This file was autogenerated by uv via the following command: +# uv pip compile pyproject.toml -o .constraints/py3.9.txt --all-extras --no-annotate --python-version=3.9 --no-emit-package setuptools accessible-pygments==0.0.4 alabaster==0.7.16 anyio==4.3.0 @@ -55,8 +51,8 @@ httpx==0.27.0 identify==2.5.35 idna==3.6 imagesize==1.4.1 -importlib-metadata==7.0.1 -importlib-resources==6.1.2 +importlib-metadata==7.0.2 +importlib-resources==6.1.3 iniconfig==2.0.0 ipykernel==6.29.3 ipympl==0.9.3 @@ -67,7 +63,7 @@ isoduration==20.11.0 isort==5.13.2 jedi==0.19.1 jinja2==3.1.3 -json5==0.9.20 +json5==0.9.22 jsonpointer==2.4 jsonschema==4.21.1 jsonschema-specifications==2023.12.1 @@ -75,11 +71,11 @@ jupyter-cache==1.0.0 jupyter-client==8.6.0 jupyter-core==5.7.1 jupyter-events==0.9.0 -jupyter-lsp==2.2.3 +jupyter-lsp==2.2.4 jupyter-server==2.13.0 jupyter-server-mathjax==0.2.6 jupyter-server-terminals==0.5.2 -jupyterlab==4.1.2 +jupyterlab==4.1.4 jupyterlab-code-formatter==2.2.1 jupyterlab-git==0.50.0 jupyterlab-lsp==5.1.0 @@ -88,7 +84,7 @@ jupyterlab-pygments==0.3.0 jupyterlab-server==2.25.3 jupyterlab-widgets==3.0.10 kiwisolver==1.4.5 -latexcodec==2.0.1 +latexcodec==3.0.0 livereload==2.6.3 lsprotocol==2023.0.1 markdown-it-py==3.0.0 @@ -105,10 +101,10 @@ mypy-extensions==1.0.0 myst-nb==1.0.0 myst-parser==2.0.0 nbclient==0.6.8 -nbconvert==7.16.1 +nbconvert==7.16.2 nbdime==4.0.1 nbformat==5.9.2 -nbmake==1.5.1 +nbmake==1.5.3 nest-asyncio==1.6.0 nodeenv==1.8.0 notebook-shim==0.2.4 @@ -134,13 +130,13 @@ pybtex-docutils==1.0.3 pycparser==2.21 pydata-sphinx-theme==0.15.2 pygments==2.17.2 -pyparsing==3.1.1 +pyparsing==3.1.2 pyproject-api==1.6.1 pytest==8.0.2 pytest-cov==4.1.0 pytest-profiling==1.7.0 pytest-xdist==3.5.0 -python-constraint==1.4.0 +python-constraint==1.3.1 python-dateutil==2.9.0.post0 python-json-logger==2.0.7 python-lsp-jsonrpc==1.1.2 @@ -157,7 +153,7 @@ rfc3986-validator==0.1.1 rich==13.7.1 rope==1.12.0 rpds-py==0.18.0 -ruff==0.3.0 +ruff==0.3.1 scipy==1.12.0 send2trash==1.8.2 six==1.16.0 @@ -192,7 +188,7 @@ terminado==0.18.0 tinycss2==1.2.1 tomli==2.0.1 tornado==6.4 -tox==4.13.0 +tox==4.14.1 tqdm==4.66.2 traitlets==5.14.1 types-python-dateutil==2.8.19.20240106 @@ -209,6 +205,5 @@ wheel==0.42.0 widgetsnbextension==4.0.10 zipp==3.17.0 -# The following packages are considered to be unsafe in a requirements file: -# ampform +# The following packages were excluded from the output: # setuptools diff --git a/.github/workflows/pr-linting.yml b/.github/workflows/pr-linting.yml index cd3bb74f1..0fab84100 100644 --- a/.github/workflows/pr-linting.yml +++ b/.github/workflows/pr-linting.yml @@ -10,24 +10,5 @@ on: - unlabeled jobs: - check-labels: - name: Check labels - runs-on: ubuntu-22.04 - steps: - - uses: docker://agilepathway/pull-request-label-checker:latest # cspell:ignore agilepathway - with: - any_of: >- - 🐛 Bug,✨ Feature,⚙️ Enhancement,⚠️ Interface,❗ Behavior,📝 Docs,🔨 Maintenance,🖱️ DX - none_of: Epic,💫 Good first issue - repo_token: ${{ secrets.GITHUB_TOKEN }} - - check-title: - name: Check title - runs-on: ubuntu-22.04 - steps: - - uses: actions/checkout@v4 - - run: npm install @compwa/commitlint-config - - name: Create commitlint config - run: | - echo "module.exports = {extends: ['@compwa/commitlint-config']}" > commitlint.config.js - - uses: JulienKode/pull-request-name-linter-action@v0.5.0 # cspell:ignore kode + lint-pr: + uses: ComPWA/actions/.github/workflows/pr-linting.yml@v1 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 737526ee6..2540e25eb 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -40,7 +40,7 @@ repos: metadata.vscode - repo: https://github.com/ComPWA/policy - rev: 0.2.6 + rev: 0.3.0 hooks: - id: check-dev-files args: @@ -59,7 +59,7 @@ repos: - --extras-require=doc,viz - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.3.0 + rev: v0.3.1 hooks: - id: ruff args: [--fix] @@ -122,7 +122,7 @@ repos: pass_filenames: false - repo: https://github.com/streetsidesoftware/cspell-cli - rev: v8.5.0 + rev: v8.6.0 hooks: - id: cspell diff --git a/pyproject.toml b/pyproject.toml index 7216393cd..0a275ce3e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -72,7 +72,6 @@ doc = [ "matplotlib", "mpl-interactions", "myst-nb >=0.14", # nb_ configuration prefixes - "nbclient >=0.5.5", # https://github.com/executablebooks/jupyter-book/issues/833 "numpy", "rich", "sphinx-api-relink >=0.0.4", From 9dafbc82830a1f50aa5515d5b156f1556d585cfe Mon Sep 17 00:00:00 2001 From: Remco de Boer <29308176+redeboer@users.noreply.github.com> Date: Fri, 8 Mar 2024 14:20:13 +0100 Subject: [PATCH 2/2] ENH: write cache to user cache directory (#407) * ENH: add `ignore_hash_seed` flag * MAINT: move cache helper functions to `sympy._cache` --- src/ampform/sympy/__init__.py | 116 +++++++----------- src/ampform/sympy/_cache.py | 87 +++++++++++++ .../sympy/{test_caching.py => test_cache.py} | 2 +- 3 files changed, 129 insertions(+), 76 deletions(-) create mode 100644 src/ampform/sympy/_cache.py rename tests/sympy/{test_caching.py => test_cache.py} (98%) diff --git a/src/ampform/sympy/__init__.py b/src/ampform/sympy/__init__.py index a2f983dec..babfe0c8a 100644 --- a/src/ampform/sympy/__init__.py +++ b/src/ampform/sympy/__init__.py @@ -12,8 +12,6 @@ from __future__ import annotations -import functools -import hashlib import itertools import logging import os @@ -22,8 +20,7 @@ import sys import warnings from abc import abstractmethod -from os.path import abspath, dirname, expanduser -from textwrap import dedent +from os.path import abspath, dirname from typing import TYPE_CHECKING, Iterable, Sequence, SupportsFloat import sympy as sp @@ -31,6 +28,7 @@ from sympy.printing.precedence import PRECEDENCE from sympy.printing.pycode import _unpack_integral_limits # noqa: PLC2701 +from ._cache import get_readable_hash, get_system_cache_directory from ._decorator import ( ExprClass, # noqa: F401 # pyright: ignore[reportUnusedImport] SymPyAssumptions, # noqa: F401 # pyright: ignore[reportUnusedImport] @@ -290,77 +288,6 @@ def determine_indices(symbol: sp.Basic) -> list[int]: return list(indices) -def perform_cached_doit( - unevaluated_expr: sp.Expr, directory: str | None = None -) -> sp.Expr: - """Perform :meth:`~sympy.core.basic.Basic.doit` cache the result to disk. - - The cached result is fetched from disk if the hash of the original expression is the - same as the hash embedded in the filename. - - Args: - unevaluated_expr: A `sympy.Expr ` on which to call - :meth:`~sympy.core.basic.Basic.doit`. - directory: The directory in which to cache the result. If `None`, the cache - directory will be put under the home directory. - - .. tip:: For a faster cache, set `PYTHONHASHSEED - `_ to a - fixed value. - """ - if directory is None: - home_directory = expanduser("~") - directory = abspath(f"{home_directory}/.sympy-cache") - h = get_readable_hash(unevaluated_expr) - filename = f"{directory}/{h}.pkl" - os.makedirs(dirname(filename), exist_ok=True) - if os.path.exists(filename): - with open(filename, "rb") as f: - return pickle.load(f) # noqa: S301 - _LOGGER.warning( - f"Cached expression file {filename} not found, performing doit()..." - ) - unfolded_expr = unevaluated_expr.doit() - with open(filename, "wb") as f: - pickle.dump(unfolded_expr, f) - return unfolded_expr - - -def get_readable_hash(obj) -> str: - python_hash_seed = _get_python_hash_seed() - if python_hash_seed is not None: - return f"pythonhashseed-{python_hash_seed}{hash(obj):+}" - b = _to_bytes(obj) - return hashlib.sha256(b).hexdigest() - - -def _to_bytes(obj) -> bytes: - if isinstance(obj, sp.Expr): - # Using the str printer is slower and not necessarily unique, - # but pickle.dumps() does not always result in the same bytes stream. - _warn_about_unsafe_hash() - return str(obj).encode() - return pickle.dumps(obj) - - -def _get_python_hash_seed() -> int | None: - python_hash_seed = os.environ.get("PYTHONHASHSEED", "") - if python_hash_seed is not None and python_hash_seed.isdigit(): - return int(python_hash_seed) - return None - - -@functools.lru_cache(maxsize=None) # warn once -def _warn_about_unsafe_hash(): - message = """ - PYTHONHASHSEED has not been set. For faster and safer hashing of SymPy expressions, - set the PYTHONHASHSEED environment variable to a fixed value and rerun the program. - See https://docs.python.org/3/using/cmdline.html#envvar-PYTHONHASHSEED - """ - message = dedent(message).replace("\n", " ").strip() - _LOGGER.warning(message) - - class UnevaluatableIntegral(sp.Integral): abs_tolerance = 1e-5 rel_tolerance = 1e-5 @@ -405,3 +332,42 @@ def _warn_if_scipy_not_installed() -> None: " install ampform[scipy]'", stacklevel=1, ) + + +def perform_cached_doit( + unevaluated_expr: sp.Expr, cache_directory: str | None = None +) -> sp.Expr: + """Perform :meth:`~sympy.core.basic.Basic.doit` and cache the result to disk. + + The cached result is fetched from disk if the hash of the original expression is the + same as the hash embedded in the filename (see :func:`.get_readable_hash`). + + Args: + unevaluated_expr: A `sympy.Expr ` on which to call + :meth:`~sympy.core.basic.Basic.doit`. + cache_directory: The directory in which to cache the result. Defaults to + :file:`ampform` under the system cache directory (see + :func:`.get_system_cache_directory`). + + .. tip:: For a faster cache, set `PYTHONHASHSEED + `_ to a + fixed value. + + .. automodule:: ampform.sympy._cache + """ + if cache_directory is None: + system_cache_dir = get_system_cache_directory() + cache_directory = abspath(f"{system_cache_dir}/ampform") + h = get_readable_hash(unevaluated_expr) + filename = f"{cache_directory}/{h}.pkl" + os.makedirs(dirname(filename), exist_ok=True) + if os.path.exists(filename): + with open(filename, "rb") as f: + return pickle.load(f) # noqa: S301 + _LOGGER.warning( + f"Cached expression file {filename} not found, performing doit()..." + ) + unfolded_expr = unevaluated_expr.doit() + with open(filename, "wb") as f: + pickle.dump(unfolded_expr, f) + return unfolded_expr diff --git a/src/ampform/sympy/_cache.py b/src/ampform/sympy/_cache.py new file mode 100644 index 000000000..421f4d89c --- /dev/null +++ b/src/ampform/sympy/_cache.py @@ -0,0 +1,87 @@ +"""Helper functions for :func:`.perform_cached_doit`.""" + +from __future__ import annotations + +import functools +import hashlib +import logging +import os +import pickle # noqa: S403 +import sys +from textwrap import dedent + +import sympy as sp + +_LOGGER = logging.getLogger(__name__) + + +def get_system_cache_directory() -> str: + r"""Return the system cache directory for the current platform. + + >>> import sys, pytest + >>> if sys.platform.startswith("darwin"): + ... assert get_system_cache_directory().endswith("/Library/Caches") + >>> if sys.platform.startswith("linux"): + ... assert get_system_cache_directory().endswith("/.cache") + >>> if sys.platform.startswith("win"): + ... assert get_system_cache_directory().endswith(R"\AppData\Local") + """ + if sys.platform.startswith("linux"): + cache_directory = os.getenv("XDG_CACHE_HOME") + if cache_directory is not None: + return cache_directory + if sys.platform.startswith("darwin"): # macos + return os.path.expanduser("~/Library/Caches") + if sys.platform.startswith("win"): + cache_directory = os.getenv("LocalAppData") # noqa: SIM112 + if cache_directory is not None: + return cache_directory + return os.path.expanduser("~/AppData/Local") + return os.path.expanduser("~/.cache") + + +def get_readable_hash(obj, ignore_hash_seed: bool = False) -> str: + """Get a human-readable hash of any hashable Python object. + + The algorithm is fastest if `PYTHONHASHSEED + `_ is set. + Otherwise, it falls back to computing the hash with :func:`hashlib.sha256()`. + + Args: + obj: Any hashable object, mutable or immutable, to be hashed. + ignore_hash_seed: Ignore the :code:`PYTHONHASHSEED` environment variable. If + :code:`True`, the hash seed is ignored and the hash is computed with + :func:`hashlib.sha256`. + """ + python_hash_seed = _get_python_hash_seed() + if ignore_hash_seed or python_hash_seed is None: + b = _to_bytes(obj) + return hashlib.sha256(b).hexdigest() + return f"pythonhashseed-{python_hash_seed}{hash(obj):+}" + + +def _to_bytes(obj) -> bytes: + if isinstance(obj, sp.Expr): + # Using the str printer is slower and not necessarily unique, + # but pickle.dumps() does not always result in the same bytes stream. + _warn_about_unsafe_hash() + return str(obj).encode() + return pickle.dumps(obj) + + +def _get_python_hash_seed() -> int | None: + python_hash_seed = os.environ.get("PYTHONHASHSEED", "") + if python_hash_seed is not None and python_hash_seed.isdigit(): + return int(python_hash_seed) + return None + + +@functools.lru_cache(maxsize=None) # warn once +def _warn_about_unsafe_hash(): + message = """ + PYTHONHASHSEED has not been set. For faster and safer hashing of SymPy expressions, + set the PYTHONHASHSEED environment variable to a fixed value and rerun the program. + See https://docs.python.org/3/using/cmdline.html#envvar-PYTHONHASHSEED + """ + message = dedent(message).replace("\n", " ").strip() + _LOGGER.warning(message) diff --git a/tests/sympy/test_caching.py b/tests/sympy/test_cache.py similarity index 98% rename from tests/sympy/test_caching.py rename to tests/sympy/test_cache.py index 292996bfd..41fd50906 100644 --- a/tests/sympy/test_caching.py +++ b/tests/sympy/test_cache.py @@ -9,7 +9,7 @@ import sympy as sp from ampform.dynamics import EnergyDependentWidth -from ampform.sympy import _warn_about_unsafe_hash, get_readable_hash +from ampform.sympy._cache import _warn_about_unsafe_hash, get_readable_hash if TYPE_CHECKING: from _pytest.logging import LogCaptureFixture