From 8e3a6f4271963ed135678fca122e7541c4fbac3c Mon Sep 17 00:00:00 2001 From: grayson-helmholz <107720976+grayson-helmholz@users.noreply.github.com> Date: Fri, 11 Oct 2024 17:57:34 +0200 Subject: [PATCH] MAINT: drop Python 3.7 & 3.8 support due to EOL (#440) --- .constraints/py3.7.txt | 214 ------------------ .constraints/py3.8.txt | 214 ------------------ docs/_extend_docstrings.py | 12 +- docs/conf.py | 8 +- .../dynamics/analytic-continuation.ipynb | 2 +- docs/usage/dynamics/k-matrix.ipynb | 4 +- docs/usage/helicity/spin-alignment.ipynb | 4 +- docs/usage/kinematics.ipynb | 4 +- pyproject.toml | 7 +- src/ampform/_qrules.py | 7 +- src/ampform/dynamics/builder.py | 10 +- src/ampform/dynamics/form_factor.py | 8 +- src/ampform/dynamics/kmatrix.py | 12 +- src/ampform/dynamics/phasespace.py | 10 +- src/ampform/helicity/__init__.py | 37 ++- src/ampform/helicity/align/axisangle.py | 10 +- src/ampform/helicity/align/dpd.py | 12 +- src/ampform/helicity/decay.py | 20 +- src/ampform/helicity/naming.py | 8 +- src/ampform/io/__init__.py | 5 +- src/ampform/kinematics/__init__.py | 4 +- src/ampform/kinematics/angles.py | 4 +- src/ampform/kinematics/lorentz.py | 4 +- src/ampform/sympy/__init__.py | 9 +- src/ampform/sympy/_array_expressions.py | 4 +- src/ampform/sympy/_cache.py | 2 +- src/ampform/sympy/_decorator.py | 9 +- src/ampform/sympy/deprecated.py | 2 +- src/ampform/sympy/math.py | 2 +- src/symplot/__init__.py | 18 +- tests/helicity/test_angular_distributions.py | 5 +- tests/helicity/test_decay.py | 5 +- tests/symplot/test_symplot.py | 5 +- tests/sympy/test_cache.py | 13 +- 34 files changed, 114 insertions(+), 580 deletions(-) delete mode 100644 .constraints/py3.7.txt delete mode 100644 .constraints/py3.8.txt diff --git a/.constraints/py3.7.txt b/.constraints/py3.7.txt deleted file mode 100644 index ce9abc77d..000000000 --- a/.constraints/py3.7.txt +++ /dev/null @@ -1,214 +0,0 @@ -# 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 -alabaster==0.7.13 -anyio==3.7.1 -argon2-cffi==23.1.0 -argon2-cffi-bindings==21.2.0 -arrow==1.2.3 -attrs==24.2.0 -babel==2.14.0 -backcall==0.2.0 -beautifulsoup4==4.12.3 -black==23.3.0 -bleach==6.0.0 -cached-property==1.5.2 -cachetools==5.5.0 -cattrs==23.1.2 -certifi==2024.8.30 -cffi==1.15.1 -cfgv==3.3.1 -chardet==5.2.0 -charset-normalizer==3.3.2 -click==8.1.7 -colorama==0.4.6 -comm==0.1.4 -coverage==7.2.7 -cycler==0.11.0 -debugpy==1.7.0 -decorator==5.1.1 -defusedxml==0.7.1 -distlib==0.3.8 -docstring-to-markdown==0.15 -docutils==0.17.1 -entrypoints==0.4 -exceptiongroup==1.2.2 -execnet==2.0.2 -fastjsonschema==2.20.0 -filelock==3.12.2 -fonttools==4.38.0 -fqdn==1.5.1 -gitdb==4.0.11 -gitpython==3.1.43 -gprof2dot==2022.7.29 -graphviz==0.20.1 -greenlet==3.1.0 -hepunits==2.3.3 -identify==2.5.24 -idna==3.8 -imagesize==1.4.1 -importlib-metadata==6.7.0 -importlib-resources==5.12.0 -iniconfig==2.0.0 -ipykernel==6.16.2 -ipympl==0.9.3 -ipython==7.34.0 -ipython-genutils==0.2.0 -ipywidgets==8.1.5 -isoduration==20.11.0 -jedi==0.18.2 -jinja2==3.1.4 -json5==0.9.16 -jsonpointer==3.0.0 -jsonschema==4.17.3 -jupyter-cache==0.5.0 -jupyter-client==7.4.9 -jupyter-core==4.12.0 -jupyter-events==0.6.3 -jupyter-lsp==1.5.1 -jupyter-server==1.24.0 -jupyter-server-fileid==0.9.3 -jupyter-server-mathjax==0.2.6 -jupyter-server-ydoc==0.8.0 -jupyter-ydoc==0.2.5 -jupyterlab==3.6.8 -jupyterlab-code-formatter==3.0.2 -jupyterlab-git==0.44.0 -jupyterlab-lsp==3.10.2 -jupyterlab-myst==1.2.0 -jupyterlab-pygments==0.2.2 -jupyterlab-server==2.24.0 -jupyterlab-widgets==3.0.13 -kiwisolver==1.4.5 -latexcodec==3.0.0 -livereload==2.7.0 -lsprotocol==2023.0.1 -markdown-it-py==2.2.0 -markupsafe==2.1.5 -matplotlib==3.5.3 -matplotlib-inline==0.1.6 -mdit-py-plugins==0.3.5 -mdurl==0.1.2 -mistune==3.0.2 -mpl-interactions==0.24.1 -mpmath==1.3.0 -mypy==1.4.1 -mypy-extensions==1.0.0 -myst-nb==0.17.2 -myst-parser==0.18.1 -nbclassic==1.1.0 -nbclient==0.5.13 -nbconvert==7.6.0 -nbdime==3.2.1 -nbformat==5.8.0 -nbmake==1.3.0 -nest-asyncio==1.6.0 -nodeenv==1.9.1 -notebook==6.5.7 -notebook-shim==0.2.4 -numpy==1.21.6 -packaging==24.0 -pandocfilters==1.5.1 -parso==0.8.4 -particle==0.23.1 -pathspec==0.11.2 -pexpect==4.9.0 -pickleshare==0.7.5 -pillow==9.5.0 -pkgutil-resolve-name==1.3.10 -platformdirs==4.0.0 -pluggy==1.2.0 -pre-commit==2.21.0 -prometheus-client==0.17.1 -prompt-toolkit==3.0.47 -psutil==6.0.0 -ptyprocess==0.7.0 -py-cpuinfo==9.0.0 -pybtex==0.24.0 -pybtex-docutils==1.0.3 -pycparser==2.21 -pydantic==1.10.18 -pydata-sphinx-theme==0.13.3 -pygments==2.17.2 -pyparsing==3.1.4 -pyproject-api==1.5.3 -pyrsistent==0.19.3 -pytest==7.4.4 -pytest-benchmark==4.0.0 -pytest-cov==4.1.0 -pytest-profiling==1.7.0 -pytest-xdist==3.5.0 -python-constraint==1.4.0 -python-dateutil==2.9.0.post0 -python-json-logger==2.0.7 -python-lsp-jsonrpc==1.0.0 -python-lsp-ruff==1.6.0 -python-lsp-server==1.7.4 -pytoolconfig==1.3.0 -pytz==2024.1 -pyyaml==6.0.1 -pyzmq==26.2.0 -qrules==0.10.2 -requests==2.31.0 -rfc3339-validator==0.1.4 -rfc3986-validator==0.1.1 -rich==13.8.1 -rope==1.9.0 -ruff==0.1.15 -scipy==1.7.3 -send2trash==1.8.3 -singledispatchmethod==1.0 -six==1.16.0 -smmap==5.0.1 -sniffio==1.3.1 -snowballstemmer==2.2.0 -soupsieve==2.4.1 -sphinx==5.3.0 -sphinx-api-relink==0.0.9 -sphinx-autobuild==2021.3.14 -sphinx-book-theme==1.0.1 -sphinx-codeautolink==0.15.2 -sphinx-comments==0.0.3 -sphinx-copybutton==0.5.2 -sphinx-design==0.4.1 -sphinx-hep-pdgref==0.2.0 -sphinx-pybtex-etal-style==0.0.2 -sphinx-thebe==0.2.1 -sphinx-togglebutton==0.3.2 -sphinxcontrib-applehelp==1.0.2 -sphinxcontrib-bibtex==2.6.2 -sphinxcontrib-devhelp==1.0.2 -sphinxcontrib-htmlhelp==2.0.0 -sphinxcontrib-jsmath==1.0.1 -sphinxcontrib-qthelp==1.0.3 -sphinxcontrib-serializinghtml==1.1.5 -sqlalchemy==1.4.54 -sympy==1.10.1 -tabulate==0.9.0 -terminado==0.17.1 -tinycss2==1.2.1 -tomli==2.0.1 -tornado==6.2 -tox==4.8.0 -tqdm==4.66.5 -traitlets==5.9.0 -typed-ast==1.5.5 -typing-extensions==4.7.1 -ujson==5.7.0 -uri-template==1.3.0 -urllib3==2.0.7 -virtualenv==20.26.4 -wcwidth==0.2.13 -webcolors==1.13 -webencodings==0.5.1 -websocket-client==1.6.1 -wheel==0.42.0 -widgetsnbextension==4.0.13 -y-py==0.6.2 -ypy-websocket==0.8.4 -zipp==3.15.0 - -# The following packages were excluded from the output: -# setuptools diff --git a/.constraints/py3.8.txt b/.constraints/py3.8.txt deleted file mode 100644 index 800cface4..000000000 --- a/.constraints/py3.8.txt +++ /dev/null @@ -1,214 +0,0 @@ -# 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.4.0 -argon2-cffi==23.1.0 -argon2-cffi-bindings==21.2.0 -arrow==1.3.0 -asttokens==2.4.1 -async-lru==2.0.4 -attrs==24.2.0 -babel==2.16.0 -backcall==0.2.0 -beautifulsoup4==4.12.3 -black==24.8.0 -bleach==6.1.0 -cachetools==5.5.0 -cattrs==24.1.0 -certifi==2024.8.30 -cffi==1.17.1 -cfgv==3.4.0 -chardet==5.2.0 -charset-normalizer==3.3.2 -click==8.1.7 -colorama==0.4.6 -comm==0.2.2 -contourpy==1.1.1 -coverage==7.6.1 -cycler==0.12.1 -debugpy==1.8.5 -decorator==5.1.1 -defusedxml==0.7.1 -distlib==0.3.8 -docstring-to-markdown==0.15 -docutils==0.17.1 -exceptiongroup==1.2.2 -execnet==2.1.1 -executing==2.1.0 -fastjsonschema==2.20.0 -filelock==3.16.0 -fonttools==4.53.1 -fqdn==1.5.1 -gitdb==4.0.11 -gitpython==3.1.43 -gprof2dot==2024.6.6 -graphviz==0.20.3 -greenlet==3.1.0 -h11==0.14.0 -hepunits==2.3.4 -httpcore==1.0.5 -httpx==0.27.2 -identify==2.6.0 -idna==3.8 -imagesize==1.4.1 -importlib-metadata==8.4.0 -importlib-resources==6.4.5 -iniconfig==2.0.0 -ipykernel==6.29.5 -ipympl==0.9.3 -ipython==8.12.3 -ipython-genutils==0.2.0 -ipywidgets==8.1.5 -isoduration==20.11.0 -jedi==0.19.1 -jinja2==3.1.4 -json5==0.9.25 -jsonpointer==3.0.0 -jsonschema==4.23.0 -jsonschema-specifications==2023.12.1 -jupyter-cache==0.6.1 -jupyter-client==8.6.2 -jupyter-core==5.7.2 -jupyter-events==0.10.0 -jupyter-lsp==2.2.5 -jupyter-server==2.14.2 -jupyter-server-mathjax==0.2.6 -jupyter-server-terminals==0.5.3 -jupyterlab==4.2.5 -jupyterlab-code-formatter==3.0.2 -jupyterlab-git==0.50.1 -jupyterlab-lsp==5.1.0 -jupyterlab-myst==2.4.2 -jupyterlab-pygments==0.3.0 -jupyterlab-server==2.27.3 -jupyterlab-widgets==3.0.13 -kiwisolver==1.4.7 -latexcodec==3.0.0 -livereload==2.7.0 -lsprotocol==2023.0.1 -markdown-it-py==2.2.0 -markupsafe==2.1.5 -matplotlib==3.7.5 -matplotlib-inline==0.1.7 -mdit-py-plugins==0.3.5 -mdurl==0.1.2 -mistune==3.0.2 -mpl-interactions==0.24.2 -mpmath==1.3.0 -mypy==1.11.2 -mypy-extensions==1.0.0 -myst-nb==0.17.2 -myst-parser==0.18.1 -nbclient==0.6.8 -nbconvert==7.16.4 -nbdime==4.0.2 -nbformat==5.10.4 -nbmake==1.5.4 -nest-asyncio==1.6.0 -nodeenv==1.9.1 -notebook-shim==0.2.4 -numpy==1.24.4 -overrides==7.7.0 -packaging==24.1 -pandocfilters==1.5.1 -parso==0.8.4 -particle==0.25.0 -pathspec==0.12.1 -pexpect==4.9.0 -pickleshare==0.7.5 -pillow==10.4.0 -pkgutil-resolve-name==1.3.10 -platformdirs==4.3.2 -pluggy==1.5.0 -pre-commit==3.5.0 -prometheus-client==0.20.0 -prompt-toolkit==3.0.47 -psutil==6.0.0 -ptyprocess==0.7.0 -pure-eval==0.2.3 -py-cpuinfo==9.0.0 -pybtex==0.24.0 -pybtex-docutils==1.0.3 -pycparser==2.22 -pydata-sphinx-theme==0.14.4 -pygments==2.18.0 -pyparsing==3.1.4 -pyproject-api==1.7.1 -pytest==8.3.3 -pytest-benchmark==4.0.0 -pytest-cov==5.0.0 -pytest-profiling==1.7.0 -pytest-xdist==3.6.1 -python-constraint2==2.0.0b5 -python-dateutil==2.9.0.post0 -python-json-logger==2.0.7 -python-lsp-jsonrpc==1.1.2 -python-lsp-ruff==2.2.2 -python-lsp-server==1.12.0 -pytoolconfig==1.3.1 -pytz==2024.1 -pyyaml==6.0.2 -pyzmq==26.2.0 -qrules==0.10.2 -referencing==0.35.1 -requests==2.32.3 -rfc3339-validator==0.1.4 -rfc3986-validator==0.1.1 -rich==13.8.1 -rope==1.13.0 -rpds-py==0.20.0 -ruff==0.6.4 -scipy==1.10.1 -send2trash==1.8.3 -six==1.16.0 -smmap==5.0.1 -sniffio==1.3.1 -snowballstemmer==2.2.0 -soupsieve==2.6 -sphinx==5.3.0 -sphinx-api-relink==0.0.9 -sphinx-autobuild==2021.3.14 -sphinx-book-theme==1.0.1 -sphinx-codeautolink==0.15.2 -sphinx-comments==0.0.3 -sphinx-copybutton==0.5.2 -sphinx-design==0.5.0 -sphinx-hep-pdgref==0.2.0 -sphinx-pybtex-etal-style==0.0.2 -sphinx-thebe==0.3.1 -sphinx-togglebutton==0.3.2 -sphinxcontrib-applehelp==1.0.4 -sphinxcontrib-bibtex==2.6.2 -sphinxcontrib-devhelp==1.0.2 -sphinxcontrib-htmlhelp==2.0.1 -sphinxcontrib-jsmath==1.0.1 -sphinxcontrib-qthelp==1.0.3 -sphinxcontrib-serializinghtml==1.1.5 -sqlalchemy==2.0.34 -stack-data==0.6.3 -sympy==1.13.2 -tabulate==0.9.0 -terminado==0.18.1 -tinycss2==1.3.0 -tomli==2.0.1 -tornado==6.4.1 -tox==4.18.1 -tqdm==4.66.5 -traitlets==5.14.3 -types-python-dateutil==2.9.0.20240906 -typing-extensions==4.12.2 -ujson==5.10.0 -uri-template==1.3.0 -urllib3==2.2.2 -virtualenv==20.26.4 -wcwidth==0.2.13 -webcolors==24.8.0 -webencodings==0.5.1 -websocket-client==1.8.0 -wheel==0.44.0 -widgetsnbextension==4.0.13 -zipp==3.20.1 - -# The following packages were excluded from the output: -# setuptools diff --git a/docs/_extend_docstrings.py b/docs/_extend_docstrings.py index 7d44e164c..77cdef987 100644 --- a/docs/_extend_docstrings.py +++ b/docs/_extend_docstrings.py @@ -10,15 +10,13 @@ import inspect import logging import pickle -import sys import textwrap +from importlib.metadata import version as get_package_version from pathlib import Path from typing import TYPE_CHECKING, Callable import attrs - -# sphinx.ext.graphviz does not work well on RTD -import graphviz +import graphviz # sphinx.ext.graphviz does not work well on RTD import qrules import sympy as sp from sympy.printing.numpy import NumPyPrinter @@ -27,10 +25,6 @@ from ampform.kinematics.lorentz import ArraySize, FourMomentumSymbol from ampform.sympy._array_expressions import ArrayMultiplication -if sys.version_info < (3, 8): - from importlib_metadata import version as get_package_version -else: - from importlib.metadata import version as get_package_version if TYPE_CHECKING: from qrules.transition import ReactionInfo, SpinFormalism @@ -515,7 +509,7 @@ def extend_chew_mandelstam_s_wave() -> None: with :math:`q^2(s)` defined as :eq:`BreakupMomentumSquared`. - .. seealso:: :doc:`compwa:report/003` + .. seealso:: :doc:`compwa-report:003` """, ) diff --git a/docs/conf.py b/docs/conf.py index 974c4dc10..b84a475e7 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -266,6 +266,7 @@ def _get_dataclasses(module): "IPython": (f"https://ipython.readthedocs.io/en/{pin('IPython')}", None), "attrs": (f"https://www.attrs.org/en/{pin('attrs')}", None), "compwa": ("https://compwa.github.io", None), + "compwa-report": ("https://compwa.github.io/report", None), "graphviz": ("https://graphviz.readthedocs.io/en/stable", None), "ipywidgets": (f"https://ipywidgets.readthedocs.io/en/{pin('ipywidgets')}", None), "matplotlib": (f"https://matplotlib.org/{pin('matplotlib')}", None), @@ -282,11 +283,12 @@ def _get_dataclasses(module): linkcheck_anchors = False linkcheck_ignore = [ "http://www.curtismeyer.com", - "https://doi.org/10.1002/andp.19955070504", # 403 for onlinelibrary.wiley.com - "https://doi.org/10.1093/ptep/ptaa104", - "https://doi.org/10.1155/2020/6674595", # 403 for hindawi.com + "https://doi.org/10.1002", # 403 for onlinelibrary.wiley.com + "https://doi.org/10.1103", # 403 for Phys Rev D + "https://doi.org/10.1155", # 403 for hindawi.com "https://home.fnal.gov/~kutschke/Angdist/angdist.ps", "https://hss-opus.ub.ruhr-uni-bochum.de", + "https://journals.aps.org/prd", # 403 for Phys Rev D "https://physique.cuso.ch", "https://suchung.web.cern.ch", "https://www.bookfinder.com", diff --git a/docs/usage/dynamics/analytic-continuation.ipynb b/docs/usage/dynamics/analytic-continuation.ipynb index e67f67525..211444827 100644 --- a/docs/usage/dynamics/analytic-continuation.ipynb +++ b/docs/usage/dynamics/analytic-continuation.ipynb @@ -63,7 +63,7 @@ "source": [ ":::{note}\n", "\n", - "Improvements to analytic continuation in AmpForm are currently being developed in {doc}`compwa:report/003` and {doc}`compwa:report/004`.\n", + "Improvements to analytic continuation in AmpForm are currently being developed in {doc}`compwa-report:003` and {doc}`compwa-report:004`.\n", "\n", ":::" ] diff --git a/docs/usage/dynamics/k-matrix.ipynb b/docs/usage/dynamics/k-matrix.ipynb index e0368a908..7997d6499 100644 --- a/docs/usage/dynamics/k-matrix.ipynb +++ b/docs/usage/dynamics/k-matrix.ipynb @@ -74,7 +74,7 @@ "\n", ":::{note}\n", "\n", - "The $\\boldsymbol{K}$-matrix approach was originally worked worked out in {doc}`compwa:report/005`, {doc}`compwa:report/009`, and {doc}`compwa:report/010`. Those reports contained a few mistakes, which have been addressed here.\n", + "The $\\boldsymbol{K}$-matrix approach was originally worked worked out in {doc}`compwa-report:005`, {doc}`compwa-report:009`, and {doc}`compwa-report:010`. Those reports contained a few mistakes, which have been addressed here.\n", "\n", ":::\n", "\n", @@ -331,7 +331,7 @@ "\\end{eqnarray}\n", "$$ (K-hat-and-T-hat)\n", "\n", - "[^rho-dagger]: An unpublished primer on the $\\boldsymbol{K}$-matrix by Chung {cite}`chungPrimerKmatrixFormalism1995` uses a conjugate transpose of $\\boldsymbol{\\rho}$, e.g. $\\boldsymbol{T} = \\sqrt{\\boldsymbol{\\rho^\\dagger}} \\; \\boldsymbol{\\hat{T}} \\sqrt{\\boldsymbol{\\rho}}$. This should not matter above threshold, where the phase space factor is real, but could have effects below threshold. This is where things become tricky: on the one hand, we need to ensure that $\\boldsymbol{K}$ remains real (unitarity) and on the other, we need to take keep track of which imaginary square root we choose (**Riemann sheet**). The latter is often called the requirement of **analyticity**. This is currently being explored in {doc}`compwa:report/003` and {doc}`compwa:report/004`.\n", + "[^rho-dagger]: An unpublished primer on the $\\boldsymbol{K}$-matrix by Chung {cite}`chungPrimerKmatrixFormalism1995` uses a conjugate transpose of $\\boldsymbol{\\rho}$, e.g. $\\boldsymbol{T} = \\sqrt{\\boldsymbol{\\rho^\\dagger}} \\; \\boldsymbol{\\hat{T}} \\sqrt{\\boldsymbol{\\rho}}$. This should not matter above threshold, where the phase space factor is real, but could have effects below threshold. This is where things become tricky: on the one hand, we need to ensure that $\\boldsymbol{K}$ remains real (unitarity) and on the other, we need to take keep track of which imaginary square root we choose (**Riemann sheet**). The latter is often called the requirement of **analyticity**. This is currently being explored in {doc}`compwa-report:003` and {doc}`compwa-report:004`.\n", "\n", "With these definitions, we can deduce that:\n", "\n", diff --git a/docs/usage/helicity/spin-alignment.ipynb b/docs/usage/helicity/spin-alignment.ipynb index 8308998c3..efd137f4e 100644 --- a/docs/usage/helicity/spin-alignment.ipynb +++ b/docs/usage/helicity/spin-alignment.ipynb @@ -93,7 +93,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "As described in {doc}`compwa:report/015`, the {doc}`'standard' helicity formalism ` is not suited for state transitions that have different decay topologies. For this reason, the {class}`.HelicityAmplitudeBuilder` can insert a number of Wigner-$D$ functions into the amplitude model to 'align' the final state spins of underlying {class}`~qrules.topology.Topology` instances in the full decay.\n", + "As described in {doc}`compwa-report:015`, the {doc}`'standard' helicity formalism ` is not suited for state transitions that have different decay topologies. For this reason, the {class}`.HelicityAmplitudeBuilder` can insert a number of Wigner-$D$ functions into the amplitude model to 'align' the final state spins of underlying {class}`~qrules.topology.Topology` instances in the full decay.\n", "\n", "Imagine we have the following the decay:" ] @@ -388,7 +388,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "For more information about these angles, see {ref}`compwa:report/015:Compute Wigner rotation angles` in {doc}`TR-015 `." + "For more information about these angles, see {ref}`compwa-report:015:Compute Wigner rotation angles` in {doc}`TR-015 `." ] } ], diff --git a/docs/usage/kinematics.ipynb b/docs/usage/kinematics.ipynb index 37d4f08d0..96f7dacc7 100644 --- a/docs/usage/kinematics.ipynb +++ b/docs/usage/kinematics.ipynb @@ -260,7 +260,7 @@ "metadata": {}, "source": [ ":::{margin}\n", - "This notebook originates from {doc}`compwa:report/017`.\n", + "This notebook originates from {doc}`compwa-report:017`.\n", ":::\n", "\n", "Kinematics for a three-body decay $0 \\to 123$ can be fully described by two **Mandelstam variables** $\\sigma_1, \\sigma_2$, because the third variable $\\sigma_3$ can be expressed in terms $\\sigma_1, \\sigma_2$, the mass $m_0$ of the initial state, and the masses $m_1, m_2, m_3$ of the final state. As can be seen, the roles of $\\sigma_1, \\sigma_2, \\sigma_3$ are interchangeable.\n", @@ -384,7 +384,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "See {doc}`compwa:report/017` for an interactive visualization of the phase space region and an analytic expression for the phase space boundary." + "See {doc}`compwa-report:017` for an interactive visualization of the phase space region and an analytic expression for the phase space boundary." ] } ], diff --git a/pyproject.toml b/pyproject.toml index ea651f9fd..b592217ad 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -18,8 +18,6 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python", "Topic :: Scientific/Engineering :: Physics", @@ -30,9 +28,6 @@ dependencies = [ "attrs >=20.1.0", # on_setattr and https://www.attrs.org/en/stable/api.html#next-gen "qrules >=0.9.6", "sympy >=1.10", - 'importlib-metadata; python_version <"3.8.0"', - 'singledispatchmethod; python_version <"3.8.0"', - 'typing-extensions; python_version <"3.8.0"', ] description = "Automatically generate symbolic amplitude models for Partial Wave Analysis" dynamic = ["version"] @@ -48,7 +43,7 @@ keywords = [ license = {file = "LICENSE"} maintainers = [{email = "compwa-admin@ep1.rub.de"}] name = "ampform" -requires-python = ">=3.7" +requires-python = ">=3.9" [project.optional-dependencies] all = [ diff --git a/src/ampform/_qrules.py b/src/ampform/_qrules.py index a325d474b..ef97cec0f 100644 --- a/src/ampform/_qrules.py +++ b/src/ampform/_qrules.py @@ -1,12 +1,7 @@ from __future__ import annotations -import sys from functools import lru_cache - -if sys.version_info < (3, 8): - from importlib_metadata import version -else: - from importlib.metadata import version +from importlib.metadata import version @lru_cache(maxsize=1) diff --git a/src/ampform/dynamics/builder.py b/src/ampform/dynamics/builder.py index a4415b4eb..59ba8fcfc 100644 --- a/src/ampform/dynamics/builder.py +++ b/src/ampform/dynamics/builder.py @@ -2,8 +2,7 @@ from __future__ import annotations -import sys -from typing import TYPE_CHECKING, Dict, Tuple +from typing import TYPE_CHECKING, Protocol import sympy as sp from attrs import field, frozen @@ -16,11 +15,6 @@ PhaseSpaceFactorProtocol, ) -if sys.version_info >= (3, 8): - from typing import Protocol -else: # pragma: no cover - from typing_extensions import Protocol - if TYPE_CHECKING: from qrules.particle import Particle @@ -42,7 +36,7 @@ class TwoBodyKinematicVariableSet: angular_momentum: int | None = field(default=None) -BuilderReturnType = Tuple[sp.Expr, Dict[sp.Symbol, float]] +BuilderReturnType = tuple[sp.Expr, dict[sp.Symbol, float]] """Type that a `.ResonanceDynamicsBuilder` should return. The first element in this `tuple` is the `sympy.Expr ` that diff --git a/src/ampform/dynamics/form_factor.py b/src/ampform/dynamics/form_factor.py index e1c6b7336..422d4f9f8 100644 --- a/src/ampform/dynamics/form_factor.py +++ b/src/ampform/dynamics/form_factor.py @@ -2,7 +2,7 @@ from __future__ import annotations -from functools import lru_cache +from functools import cache, lru_cache from typing import Any, Callable import sympy as sp @@ -52,7 +52,7 @@ class BlattWeisskopfSquared(sp.Expr): :pdg-review:`2021; Resonances; p.9`. We normalize the form factor such that :math:`B_L^2(1)=1` and that :math:`B_L^2` is unitless no matter what :math:`z` is. - .. seealso:: :ref:`usage/dynamics:Form factor`, :doc:`TR-029`, + .. seealso:: :ref:`usage/dynamics:Form factor`, :doc:`TR-029`, and :cite:`chungFormulasAngularMomentumBarrier2015`. With this, the implementation becomes @@ -94,7 +94,7 @@ def _formulate_blatt_weisskopf(ell, z) -> sp.Expr: class SphericalHankel1(sp.Expr): r"""Spherical Hankel function of the first kind for real-valued :math:`z`. - See :cite:`VonHippel:1972fg`, Equation (A12), and :doc:`TR-029` + See :cite:`VonHippel:1972fg`, Equation (A12), and :doc:`TR-029` for more info. `This page `_ explains the difference with the *general* Hankel function of the first kind, @@ -134,7 +134,7 @@ def doit(self, deep: bool = True, **kwargs) -> sp.Expr: return super().doit(deep=deep, **kwargs) -@lru_cache(maxsize=None) +@cache def _get_indices(expr: sp.Sum) -> set[sp.Basic]: free_symbols = set() for index in expr.args[1:]: diff --git a/src/ampform/dynamics/kmatrix.py b/src/ampform/dynamics/kmatrix.py index 47bf7dd29..0b326b3ef 100644 --- a/src/ampform/dynamics/kmatrix.py +++ b/src/ampform/dynamics/kmatrix.py @@ -2,8 +2,8 @@ .. seealso:: :doc:`/usage/dynamics/k-matrix`. -This module is an implementation of :doc:`compwa:report/005`, -:doc:`compwa:report/009`, and :doc:`compwa:report/010`. It works with classes to +This module is an implementation of :doc:`compwa-report:005`, +:doc:`compwa-report:009`, and :doc:`compwa-report:010`. It works with classes to keep the code organized and to enable caching of the matrix multiplications, but this might change once these dynamics are implemented into the amplitude builder. """ @@ -35,7 +35,7 @@ def formulate( class RelativisticKMatrix(TMatrix): @staticmethod - @functools.lru_cache(maxsize=None) + @functools.cache def _create_matrices( n_channels, return_t_hat: bool = False ) -> tuple[sp.MutableDenseMatrix, sp.MutableDenseMatrix]: @@ -141,7 +141,7 @@ def residue_function(pole_id, i) -> sp.Expr: class NonRelativisticKMatrix(TMatrix): @staticmethod - @functools.lru_cache(maxsize=None) + @functools.cache def _create_matrices( n_channels, ) -> tuple[sp.MutableDenseMatrix, sp.MutableDenseMatrix]: @@ -199,7 +199,7 @@ def residue_function(pole_id, i) -> sp.Expr: class NonRelativisticPVector(TMatrix): @staticmethod - @functools.lru_cache(maxsize=None) + @functools.cache def _create_matrices( n_channels, ) -> tuple[sp.MutableDenseMatrix, sp.MutableDenseMatrix, sp.MutableDenseMatrix]: @@ -272,7 +272,7 @@ def parametrization( # noqa: PLR0917 class RelativisticPVector(TMatrix): @staticmethod - @functools.lru_cache(maxsize=None) + @functools.cache def _create_matrices( n_channels, return_f_hat: bool = False ) -> tuple[sp.MutableDenseMatrix, sp.MutableDenseMatrix, sp.MutableDenseMatrix]: diff --git a/src/ampform/dynamics/phasespace.py b/src/ampform/dynamics/phasespace.py index 75a424a5d..6ee409d50 100644 --- a/src/ampform/dynamics/phasespace.py +++ b/src/ampform/dynamics/phasespace.py @@ -12,8 +12,7 @@ from __future__ import annotations -import sys -from typing import TYPE_CHECKING, Any, Sequence +from typing import TYPE_CHECKING, Any import sympy as sp @@ -21,12 +20,11 @@ from ampform.sympy.math import ComplexSqrt if TYPE_CHECKING: + from collections.abc import Sequence + from sympy.printing.latex import LatexPrinter -if sys.version_info >= (3, 8): - from typing import Protocol -else: - from typing_extensions import Protocol # pragma: no cover +from typing import Protocol # pragma: no cover class PhaseSpaceFactorProtocol(Protocol): diff --git a/src/ampform/helicity/__init__.py b/src/ampform/helicity/__init__.py index e1df7257e..03f96f392 100644 --- a/src/ampform/helicity/__init__.py +++ b/src/ampform/helicity/__init__.py @@ -13,18 +13,8 @@ import sys import warnings from collections import OrderedDict, abc -from functools import reduce -from typing import ( - TYPE_CHECKING, - ItemsView, - Iterable, - Iterator, - KeysView, - Mapping, - Sequence, - Union, - ValuesView, -) +from functools import reduce, singledispatchmethod +from typing import TYPE_CHECKING, Union import attrs import sympy as sp @@ -71,16 +61,21 @@ from ampform.sympy import PoolSum, determine_indices from ampform.sympy._array_expressions import ArraySum -if sys.version_info >= (3, 8): - from functools import singledispatchmethod -else: - from singledispatchmethod import singledispatchmethod - if sys.version_info < (3, 12): from typing_extensions import override else: from typing import override if TYPE_CHECKING: + from collections.abc import ( + ItemsView, + Iterable, + Iterator, + KeysView, + Mapping, + Sequence, + ValuesView, + ) + from IPython.lib.pretty import PrettyPrinter from qrules.topology import MutableTransition @@ -128,7 +123,7 @@ class HelicityModel: helicity combination. These amplitudes are indicated with as `sp.Indexed ` instances and this attribute provides the definitions for each of these. See also - :ref:`TR-014 `. + :ref:`TR-014 `. """ parameter_defaults: ParameterValues = field(converter=_to_parameter_values) """A mapping of suggested parameter values. @@ -733,10 +728,10 @@ def _(self, particle: Particle, builder: ResonanceDynamicsBuilder) -> None: return self.assign(particle.name, builder) def __getitem__( - self, __k: TwoBodyDecay | tuple[StateTransition, int] + self, k: TwoBodyDecay | tuple[StateTransition, int], / ) -> ResonanceDynamicsBuilder: - __k = TwoBodyDecay.create(__k) - return self.__choices[__k] + k = TwoBodyDecay.create(k) + return self.__choices[k] def __len__(self) -> int: return len(self.__choices) diff --git a/src/ampform/helicity/align/axisangle.py b/src/ampform/helicity/align/axisangle.py index 8c45c96b3..ac26d9a57 100644 --- a/src/ampform/helicity/align/axisangle.py +++ b/src/ampform/helicity/align/axisangle.py @@ -6,7 +6,7 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Generator, Sequence, TypeVar, overload +from typing import TYPE_CHECKING, TypeVar, overload import sympy as sp @@ -31,16 +31,12 @@ from ampform.sympy import PoolSum if TYPE_CHECKING: - import sys + from collections.abc import Generator, Sequence + from typing import Literal from qrules.topology import Topology from qrules.transition import ReactionInfo, StateTransition - if sys.version_info >= (3, 8): - from typing import Literal - else: - from typing_extensions import Literal - class AxisAngleAlignment(SpinAlignment): """Alignment amplitudes with the "axis-angle" method. diff --git a/src/ampform/helicity/align/dpd.py b/src/ampform/helicity/align/dpd.py index 061e959cc..0d7b65c98 100644 --- a/src/ampform/helicity/align/dpd.py +++ b/src/ampform/helicity/align/dpd.py @@ -5,9 +5,8 @@ from __future__ import annotations -import sys -from functools import lru_cache, singledispatch -from typing import TYPE_CHECKING, TypeVar +from functools import cache, singledispatch +from typing import TYPE_CHECKING, Literal, TypeVar import attrs import sympy as sp @@ -28,11 +27,6 @@ from ampform.kinematics.angles import formulate_zeta_angle from ampform.sympy import PoolSum -if sys.version_info < (3, 8): - from typing_extensions import Literal -else: - from typing import Literal - if TYPE_CHECKING: from sympy.physics.quantum.spin import WignerD @@ -59,7 +53,7 @@ def define_symbols(self, reaction: ReactionInfo) -> dict[sp.Symbol, sp.Expr]: return _formulate_aligned_amplitude(reaction, self.reference_subsystem)[1] -@lru_cache(maxsize=None) +@cache def _formulate_aligned_amplitude( # noqa: PLR0914 reaction: ReactionInfo, reference_subsystem: Literal[1, 2, 3] ) -> tuple[sp.Expr, dict[sp.Symbol, sp.Expr]]: diff --git a/src/ampform/helicity/decay.py b/src/ampform/helicity/decay.py index 606df2889..790e753ea 100644 --- a/src/ampform/helicity/decay.py +++ b/src/ampform/helicity/decay.py @@ -4,8 +4,8 @@ import collections import sys -from functools import lru_cache, singledispatch -from typing import TYPE_CHECKING, Iterable +from functools import cache, singledispatch +from typing import TYPE_CHECKING from attrs import frozen from qrules.quantum_numbers import InteractionProperties @@ -14,12 +14,12 @@ from ampform._qrules import get_qrules_version if TYPE_CHECKING: + from collections.abc import Iterable + from qrules.topology import Topology -if sys.version_info < (3, 8): - from typing_extensions import Literal -else: - from typing import Literal +from typing import Literal + if sys.version_info < (3, 10): from typing_extensions import TypeGuard else: @@ -129,7 +129,7 @@ def _is_qrules_state_transition(obj) -> TypeGuard[StateTransition]: return get_qrules_version() < (0, 10) and isinstance(obj, StateTransition) # type: ignore[misc] -@lru_cache(maxsize=None) +@cache def is_opposite_helicity_state(topology: Topology, state_id: int) -> bool: """Determine if an edge is an "opposite helicity" state. @@ -194,7 +194,7 @@ def get_sibling_state_id(topology: Topology, state_id: int) -> int: return next(iter(out_state_ids)) -@lru_cache(maxsize=None) +@cache def get_spectator_id(topology: Topology) -> Literal[1, 2, 3]: assert_three_body_decay(topology) decay_products = topology.get_edge_ids_outgoing_from_node(1) @@ -202,7 +202,7 @@ def get_spectator_id(topology: Topology) -> Literal[1, 2, 3]: return next(iter(spectator_id_candidates)) # type: ignore[arg-type] -@lru_cache(maxsize=None) +@cache def get_decay_product_ids( topology: Topology, ) -> tuple[Literal[1, 2, 3], Literal[1, 2, 3]]: @@ -298,7 +298,7 @@ def assert_isobar_topology(topology: Topology) -> None: assert_two_body_decay(topology, node_id) -@lru_cache(maxsize=None) +@cache def assert_three_body_decay(topology: Topology) -> None: n_initial = len(topology.incoming_edge_ids) n_final = len(topology.outgoing_edge_ids) diff --git a/src/ampform/helicity/naming.py b/src/ampform/helicity/naming.py index f1f78de4e..999e5fdbd 100644 --- a/src/ampform/helicity/naming.py +++ b/src/ampform/helicity/naming.py @@ -6,8 +6,8 @@ import sys from abc import ABC, abstractmethod from collections import defaultdict -from functools import lru_cache -from typing import TYPE_CHECKING, Iterable +from functools import cache +from typing import TYPE_CHECKING import sympy as sp from qrules.transition import ReactionInfo, State, StateTransition @@ -26,6 +26,8 @@ else: from typing import override if TYPE_CHECKING: + from collections.abc import Iterable + from qrules.topology import Topology @@ -343,7 +345,7 @@ def get_helicity_angle_symbols( ) -@lru_cache(maxsize=None) +@cache def get_boost_chain_suffix(topology: Topology, state_id: int) -> str: """Generate a subscript-superscript to identify a chain of Lorentz boosts. diff --git a/src/ampform/io/__init__.py b/src/ampform/io/__init__.py index cfdd783a9..044490379 100644 --- a/src/ampform/io/__init__.py +++ b/src/ampform/io/__init__.py @@ -17,10 +17,13 @@ from collections import abc from functools import singledispatch -from typing import Iterable, Mapping, Sequence +from typing import TYPE_CHECKING import sympy as sp +if TYPE_CHECKING: + from collections.abc import Iterable, Mapping, Sequence + @singledispatch def aslatex(obj, **kwargs) -> str: # noqa: D417 diff --git a/src/ampform/kinematics/__init__.py b/src/ampform/kinematics/__init__.py index c36efbada..79847a982 100644 --- a/src/ampform/kinematics/__init__.py +++ b/src/ampform/kinematics/__init__.py @@ -11,7 +11,7 @@ import itertools from collections import abc from functools import singledispatch -from typing import TYPE_CHECKING, Iterable +from typing import TYPE_CHECKING import attrs from qrules.topology import Topology @@ -26,6 +26,8 @@ ) if TYPE_CHECKING: + from collections.abc import Iterable + import sympy as sp diff --git a/src/ampform/kinematics/angles.py b/src/ampform/kinematics/angles.py index f2b65bf45..d905989a6 100644 --- a/src/ampform/kinematics/angles.py +++ b/src/ampform/kinematics/angles.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Mapping +from typing import TYPE_CHECKING import sympy as sp @@ -37,6 +37,8 @@ ) if TYPE_CHECKING: + from collections.abc import Mapping + from qrules.topology import Topology diff --git a/src/ampform/kinematics/lorentz.py b/src/ampform/kinematics/lorentz.py index 0aeab4496..9ba678fc9 100644 --- a/src/ampform/kinematics/lorentz.py +++ b/src/ampform/kinematics/lorentz.py @@ -3,7 +3,7 @@ from __future__ import annotations import sys -from typing import TYPE_CHECKING, Any, Callable, Dict +from typing import TYPE_CHECKING, Any, Callable import sympy as sp @@ -44,7 +44,7 @@ def create_four_momentum_symbol(index: int) -> FourMomentumSymbol: return FourMomentumSymbol(f"p{index}", shape=[]) -FourMomenta = Dict[int, "FourMomentumSymbol"] +FourMomenta = dict[int, "FourMomentumSymbol"] """A mapping of state IDs to their corresponding `.FourMomentumSymbol`. It's best to create a `dict` of `.FourMomenta` with diff --git a/src/ampform/sympy/__init__.py b/src/ampform/sympy/__init__.py index 75ff53049..ae3a164c0 100644 --- a/src/ampform/sympy/__init__.py +++ b/src/ampform/sympy/__init__.py @@ -19,8 +19,9 @@ import sys import warnings from abc import abstractmethod +from importlib.metadata import version from pathlib import Path -from typing import TYPE_CHECKING, Iterable, Sequence, SupportsFloat +from typing import TYPE_CHECKING, SupportsFloat import sympy as sp from sympy.printing.conventions import split_super_sub @@ -42,10 +43,6 @@ make_commutative, # pyright: ignore[reportUnusedImport] # noqa: F401 ) -if sys.version_info < (3, 8): - from importlib_metadata import version -else: - from importlib.metadata import version if sys.version_info < (3, 11): from typing_extensions import Self else: @@ -55,6 +52,8 @@ else: from typing import override if TYPE_CHECKING: + from collections.abc import Iterable, Sequence + from sympy.printing.latex import LatexPrinter from sympy.printing.numpy import NumPyPrinter diff --git a/src/ampform/sympy/_array_expressions.py b/src/ampform/sympy/_array_expressions.py index 84e5b3b99..4beedb004 100644 --- a/src/ampform/sympy/_array_expressions.py +++ b/src/ampform/sympy/_array_expressions.py @@ -10,7 +10,7 @@ import sys from collections import abc from itertools import zip_longest -from typing import TYPE_CHECKING, Iterable, overload +from typing import TYPE_CHECKING, overload import sympy as sp from sympy.codegen.ast import none @@ -36,6 +36,8 @@ else: from typing import override if TYPE_CHECKING: + from collections.abc import Iterable + from sympy.printing.numpy import NumPyPrinter diff --git a/src/ampform/sympy/_cache.py b/src/ampform/sympy/_cache.py index 41d0f3e1d..29ad05ebc 100644 --- a/src/ampform/sympy/_cache.py +++ b/src/ampform/sympy/_cache.py @@ -76,7 +76,7 @@ def _get_python_hash_seed() -> int | None: return None -@functools.lru_cache(maxsize=None) # warn once +@functools.cache # warn once def _warn_about_unsafe_hash() -> None: message = """ PYTHONHASHSEED has not been set. For faster and safer hashing of SymPy expressions, diff --git a/src/ampform/sympy/_decorator.py b/src/ampform/sympy/_decorator.py index 9d41a7ed4..51a55be9d 100644 --- a/src/ampform/sympy/_decorator.py +++ b/src/ampform/sympy/_decorator.py @@ -13,23 +13,20 @@ from dataclasses import fields as _get_fields from inspect import isclass from types import MappingProxyType -from typing import TYPE_CHECKING, Any, Callable, Hashable, Iterable, TypeVar, overload +from typing import TYPE_CHECKING, Any, Callable, Protocol, TypedDict, TypeVar, overload import sympy as sp from sympy.core.basic import _aresame # noqa: PLC2701 from sympy.utilities.exceptions import SymPyDeprecationWarning -if sys.version_info < (3, 8): - from typing_extensions import Protocol, TypedDict -else: - from typing import Protocol, TypedDict - if sys.version_info < (3, 11): from typing_extensions import dataclass_transform else: from typing import dataclass_transform if TYPE_CHECKING: + from collections.abc import Hashable, Iterable + from sympy.printing.latex import LatexPrinter if sys.version_info < (3, 11): diff --git a/src/ampform/sympy/deprecated.py b/src/ampform/sympy/deprecated.py index f7093155f..eb83d173b 100644 --- a/src/ampform/sympy/deprecated.py +++ b/src/ampform/sympy/deprecated.py @@ -31,7 +31,7 @@ class UnevaluatedExpression(sp.Expr): 1. condense the LaTeX representation of an expression tree by providing a custom :meth:`_latex` method. 2. overwrite its printer methods (see `.NumPyPrintable` and e.g. - :doc:`compwa:report/001`). + :doc:`compwa-report:001`). The `UnevaluatedExpression` base class makes implementations of its derived classes more secure by enforcing the developer to provide implementations for these methods, diff --git a/src/ampform/sympy/math.py b/src/ampform/sympy/math.py index b7370c088..8f6f1d66c 100644 --- a/src/ampform/sympy/math.py +++ b/src/ampform/sympy/math.py @@ -26,7 +26,7 @@ class ComplexSqrt(NumPyPrintable): A special version :func:`~sympy.functions.elementary.miscellaneous.sqrt` that renders nicely as LaTeX and and can be used as a handle for lambdify printers. See - :doc:`compwa:report/000`, :doc:`compwa:report/001`, and + :doc:`compwa-report:000`, :doc:`compwa-report:001`, and :doc:`sympy:modules/printing` for how to implement a custom :func:`~sympy.utilities.lambdify.lambdify` printer. """ diff --git a/src/symplot/__init__.py b/src/symplot/__init__.py index 6b504a2dc..8541cb039 100644 --- a/src/symplot/__init__.py +++ b/src/symplot/__init__.py @@ -16,16 +16,7 @@ import inspect import logging from collections import abc -from typing import ( - TYPE_CHECKING, - Callable, - Iterator, - Mapping, - Sequence, - Tuple, - TypeVar, - Union, -) +from typing import TYPE_CHECKING, Callable, TypeVar, Union import sympy as sp from ipywidgets.widgets import FloatSlider, IntSlider @@ -33,6 +24,7 @@ if TYPE_CHECKING: # pragma: no cover import sys + from collections.abc import Iterator, Mapping, Sequence from IPython.lib.pretty import PrettyPrinter @@ -46,8 +38,8 @@ Slider = Union[FloatSlider, IntSlider] """Allowed :doc:`ipywidgets ` slider types.""" RangeDefinition = Union[ - Tuple[float, float], - Tuple[float, float, Union[float, int]], + tuple[float, float], + tuple[float, float, Union[float, int]], ] """Types of range definitions used in :meth:`.set_ranges`.""" @@ -390,7 +382,7 @@ def rename_symbols( def substitute_indexed_symbols(expression: sp.Expr) -> sp.Expr: """Substitute `~sympy.tensor.indexed.IndexedBase` with symbols. - See :doc:`compwa:report/008` for more info. + See :doc:`compwa-report:008` for more info. """ return expression.xreplace({ s: _indexed_to_symbol(s) diff --git a/tests/helicity/test_angular_distributions.py b/tests/helicity/test_angular_distributions.py index 027f791bc..5bcbbce9c 100644 --- a/tests/helicity/test_angular_distributions.py +++ b/tests/helicity/test_angular_distributions.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import Iterable, Sequence +from typing import TYPE_CHECKING import pytest import qrules @@ -10,6 +10,9 @@ from ampform import get_builder +if TYPE_CHECKING: + from collections.abc import Iterable, Sequence + def calculate_sympy_integral( intensity, diff --git a/tests/helicity/test_decay.py b/tests/helicity/test_decay.py index 4a06b3b4d..1835af370 100644 --- a/tests/helicity/test_decay.py +++ b/tests/helicity/test_decay.py @@ -1,7 +1,7 @@ from __future__ import annotations import itertools -from typing import Iterable +from typing import TYPE_CHECKING import pytest from qrules.topology import Topology, create_isobar_topologies @@ -13,6 +13,9 @@ is_opposite_helicity_state, ) +if TYPE_CHECKING: + from collections.abc import Iterable + def test_determine_attached_final_state(): topologies = create_isobar_topologies(4) diff --git a/tests/symplot/test_symplot.py b/tests/symplot/test_symplot.py index 78b7dbfe9..2b45f9891 100644 --- a/tests/symplot/test_symplot.py +++ b/tests/symplot/test_symplot.py @@ -2,7 +2,7 @@ import logging from copy import deepcopy -from typing import Any, Callable, Pattern, no_type_check +from typing import TYPE_CHECKING, Any, Callable, no_type_check import pytest import sympy as sp @@ -12,6 +12,9 @@ from symplot import RangeDefinition, Slider, SliderKwargs +if TYPE_CHECKING: + from re import Pattern + class TestSliderKwargs: @pytest.fixture() diff --git a/tests/sympy/test_cache.py b/tests/sympy/test_cache.py index a99ba42c0..9bd2793fb 100644 --- a/tests/sympy/test_cache.py +++ b/tests/sympy/test_cache.py @@ -94,9 +94,7 @@ def test_get_readable_hash_energy_dependent_width(): pytest.skip("PYTHONHASHSEED has not been set") if python_hash_seed != "0": pytest.skip(f"PYTHONHASHSEED is not set to 0, but to {python_hash_seed}") - if sys.version_info < (3, 8): - assert h == "pythonhashseed-0-6795262906917625791" - elif sys.version_info >= (3, 11): + if sys.version_info >= (3, 11): assert h == "pythonhashseed-0+4377931190501974271" else: assert h == "pythonhashseed-0+8267198661922532208" @@ -107,14 +105,7 @@ def test_get_readable_hash_large(amplitude_model: tuple[str, HelicityModel]): if python_hash_seed != "0": pytest.skip("PYTHONHASHSEED is not 0") formalism, model = amplitude_model - if sys.version_info < (3, 8): - # https://github.com/ComPWA/ampform/actions/runs/3277058875/jobs/5393849802 - # https://github.com/ComPWA/ampform/actions/runs/3277143883/jobs/5394043014 - expected_hash = { - "canonical-helicity": "pythonhashseed-0-4409019767276782833", - "helicity": "pythonhashseed-0+8495836064961054249", - }[formalism] - elif sys.version_info >= (3, 11): + if sys.version_info >= (3, 11): expected_hash = { "canonical-helicity": "pythonhashseed-0-8140852268928771574", "helicity": "pythonhashseed-0-991855900379383849",