From d6cee73bbd4c70b7be4d7520079825319ec5d0dc Mon Sep 17 00:00:00 2001 From: Steven Murray Date: Sun, 22 Feb 2026 14:07:41 +0200 Subject: [PATCH 01/18] maint: use pyproject only and style up --- .isort.cfg | 11 - .pre-commit-config.yaml | 30 +- .readthedocs.yml | 2 +- VERSION | 1 - changethelog.py | 2 +- development/growth_factor_integration.ipynb | 35 +- development/halofit_testing.ipynb | 119 +- docs/conf.py | 71 +- docs/examples/broad_overview.ipynb | 42 +- docs/examples/change_mass_definition.ipynb | 148 +- docs/examples/fitting.ipynb | 147 +- docs/examples/plugins_and_extending.ipynb | 36 +- hmf_cfg.toml | 92 - hmf_dndm.txt | 500 ----- hmf_m.txt | 500 ----- hmf_sigma.txt | 500 ----- pyproject.toml | 173 +- requirements_dev.txt | 19 - setup.cfg | 119 -- src/hmf/_cli.py | 7 +- src/hmf/_internals/_cache.py | 5 +- src/hmf/_internals/_framework.py | 28 +- src/hmf/alternatives/wdm.py | 2 - src/hmf/cosmology/cosmo.py | 9 +- src/hmf/cosmology/growth_factor.py | 37 +- src/hmf/density_field/filters.py | 8 +- src/hmf/density_field/halofit.py | 6 +- src/hmf/density_field/transfer.py | 9 +- src/hmf/density_field/transfer_models.py | 11 +- src/hmf/halos/mass_definitions.py | 19 +- src/hmf/helpers/cfg_utils.py | 4 +- src/hmf/helpers/functional.py | 6 +- src/hmf/mass_function/fitting_functions.py | 86 +- src/hmf/mass_function/hmf.py | 31 +- src/hmf/mass_function/integrate_hmf.py | 1 - tests/conftest.py | 4 +- tests/test_cli.py | 4 +- tests/test_cosmo.py | 3 +- tests/test_fcoll.py | 3 +- tests/test_filters.py | 4 +- tests/test_fits.py | 16 +- tests/test_framework.py | 3 +- tests/test_genmf.py | 4 +- tests/test_growth.py | 4 +- tests/test_hmf.py | 3 +- tests/test_mdef.py | 3 +- tests/test_transfer.py | 3 +- tests/test_wcdm.py | 3 +- tests/test_wdm.py | 3 +- uv.lock | 1893 +++++++++++++++++++ 50 files changed, 2519 insertions(+), 2250 deletions(-) delete mode 100644 .isort.cfg delete mode 100644 VERSION delete mode 100644 hmf_cfg.toml delete mode 100644 hmf_dndm.txt delete mode 100644 hmf_m.txt delete mode 100644 hmf_sigma.txt delete mode 100644 requirements_dev.txt delete mode 100644 setup.cfg create mode 100644 uv.lock diff --git a/.isort.cfg b/.isort.cfg deleted file mode 100644 index cbc65b8b..00000000 --- a/.isort.cfg +++ /dev/null @@ -1,11 +0,0 @@ -[settings] -line_length=88 -indent=' ' -skip=.tox,.venv,build,dist -known_standard_library=setuptools,pkg_resources -known_test=pytest -known_first_party=hmf -sections=FUTURE,STDLIB,COMPAT,TEST,THIRDPARTY,FIRSTPARTY,LOCALFOLDER -default_section=THIRDPARTY -multi_line_output=3 -profile=black diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index dafcbf6e..674a88f6 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -17,36 +17,8 @@ repos: - id: requirements-txt-fixer - id: mixed-line-ending args: ['--fix=no'] -- repo: https://github.com/PyCQA/flake8 - rev: '7.3.0' # pick a git hash / tag to point to - hooks: - - id: flake8 - additional_dependencies: - - flake8-rst-docstrings - - flake8-docstrings - - flake8-builtins - - flake8-rst-docstrings - - flake8-rst - - flake8-markdown - - flake8-bugbear - - flake8-comprehensions - - flake8-print -# Using this mirror lets us use mypyc-compiled black, which is about 2x faster -- repo: https://github.com/psf/black-pre-commit-mirror - rev: 26.1.0 - hooks: - - id: black + - repo: https://github.com/pre-commit/pygrep-hooks rev: v1.10.0 hooks: - id: rst-backticks -- repo: https://github.com/PyCQA/isort - rev: 7.0.0 - hooks: - - id: isort - -- repo: https://github.com/asottile/pyupgrade - rev: v3.21.2 - hooks: - - id: pyupgrade - args: [--py38-plus] diff --git a/.readthedocs.yml b/.readthedocs.yml index cd75f7a7..461ccc7f 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -13,7 +13,7 @@ conda: environment: docs/environment.yaml python: - version: 3.7 + version: 3.13 install: - method: pip path: . diff --git a/VERSION b/VERSION deleted file mode 100644 index f9892605..00000000 --- a/VERSION +++ /dev/null @@ -1 +0,0 @@ -3.4.4 diff --git a/changethelog.py b/changethelog.py index 6c176cb5..c3335c8a 100644 --- a/changethelog.py +++ b/changethelog.py @@ -17,7 +17,7 @@ raise OSError("Couldn't Find 'dev-version' tag") lines.insert(_i + 2, "----------------------\n") - lines.insert(_i + 2, f'v{newversion} [{datetime.now().strftime("%d %b %Y")}]\n') + lines.insert(_i + 2, f"v{newversion} [{datetime.now().strftime('%d %b %Y')}]\n") lines.insert(_i + 2, "\n") with open("CHANGELOG.rst", "w") as fl: diff --git a/development/growth_factor_integration.ipynb b/development/growth_factor_integration.ipynb index b686b127..7fc2478f 100644 --- a/development/growth_factor_integration.ipynb +++ b/development/growth_factor_integration.ipynb @@ -26,10 +26,11 @@ }, "outputs": [], "source": [ + "import matplotlib.pyplot as plt\n", "import numpy as np\n", "from astropy.cosmology import Planck15\n", "from scipy import integrate as intg\n", - "import matplotlib.pyplot as plt\n", + "\n", "%matplotlib inline" ] }, @@ -85,7 +86,7 @@ " \"\"\"\n", "\n", " a_upper = 1.0 / (1.0 + z)\n", - " nlna = 1 + int((np.log(a_upper) - np.log(amin))/dlna)\n", + " nlna = 1 + int((np.log(a_upper) - np.log(amin)) / dlna)\n", "\n", " lna = np.linspace(np.log(amin), np.log(a_upper), nlna)\n", " _zvec = 1.0 / np.exp(lna) - 1.0\n", @@ -96,7 +97,9 @@ " integral = intg.simpson(np.exp(lna) * integrand, x=lna)\n", " dplus = 5.0 * cosmo.Om0 * cosmo.efunc(z) * integral / 2.0\n", " else:\n", - " integral = intg.cumulative_trapezoid(np.exp(lna) * integrand, dx=dlna, initial=0.0)\n", + " integral = intg.cumulative_trapezoid(\n", + " np.exp(lna) * integrand, dx=dlna, initial=0.0\n", + " )\n", " dplus = 5.0 * cosmo.Om0 * cosmo.efunc(_zvec) * integral / 2.0\n", "\n", " return dplus" @@ -123,10 +126,10 @@ ], "source": [ "%%timeit\n", - "Z = np.linspace(0,1,5000)\n", + "Z = np.linspace(0, 1, 5000)\n", "g = np.zeros(5000)\n", "\n", - "for i,z in enumerate(Z):\n", + "for i, z in enumerate(Z):\n", " g[i] = dplus(z)" ] }, @@ -163,7 +166,7 @@ } ], "source": [ - "plt.plot(Z,g)" + "plt.plot(Z, g)" ] }, { @@ -199,7 +202,7 @@ } ], "source": [ - "plt.plot(Z[:-1],np.diff(g))" + "plt.plot(Z[:-1], np.diff(g))" ] }, { @@ -236,10 +239,10 @@ " \"\"\"\n", "\n", " a_upper = 1.0 / (1.0 + z)\n", - " \n", + "\n", " lna = np.arange(np.log(amin), np.log(a_upper), dlna)\n", - " lna = np.hstack((lna,np.log(a_upper)))\n", - " \n", + " lna = np.hstack((lna, np.log(a_upper)))\n", + "\n", " _zvec = 1.0 / np.exp(lna) - 1.0\n", "\n", " integrand = 1.0 / (np.exp(lna) * cosmo.efunc(_zvec)) ** 3\n", @@ -248,7 +251,9 @@ " integral = intg.simpson(integrand, x=np.exp(lna))\n", " dplus = 5.0 * cosmo.Om0 * cosmo.efunc(z) * integral / 2.0\n", " else:\n", - " integral = intg.cumulative_trapezoid(np.exp(lna) * integrand, dx=dlna, initial=0.0)\n", + " integral = intg.cumulative_trapezoid(\n", + " np.exp(lna) * integrand, dx=dlna, initial=0.0\n", + " )\n", " dplus = 5.0 * cosmo.Om0 * cosmo.efunc(_zvec) * integral / 2.0\n", "\n", " return dplus" @@ -275,10 +280,10 @@ ], "source": [ "%%timeit\n", - "Z = np.linspace(0,1,5000)\n", + "Z = np.linspace(0, 1, 5000)\n", "g_dlna = np.zeros(5000)\n", "\n", - "for i,z in enumerate(Z):\n", + "for i, z in enumerate(Z):\n", " g_dlna[i] = dplus_dlna(z)" ] }, @@ -315,7 +320,7 @@ } ], "source": [ - "plt.plot(Z,g_dlna)" + "plt.plot(Z, g_dlna)" ] }, { @@ -351,7 +356,7 @@ } ], "source": [ - "plt.plot(Z[:-1],np.diff(g_dlna))" + "plt.plot(Z[:-1], np.diff(g_dlna))" ] }, { diff --git a/development/halofit_testing.ipynb b/development/halofit_testing.ipynb index 709000f2..daf6adf2 100644 --- a/development/halofit_testing.ipynb +++ b/development/halofit_testing.ipynb @@ -25,8 +25,8 @@ }, "outputs": [], "source": [ - "teh_nl_tk = Transfer(transfer_model=\"EH\", takahashi=True, z= 8.0)\n", - "teh_nl_ntk = Transfer(transfer_model=\"EH\", takahashi=False, z=8.0)\n" + "teh_nl_tk = Transfer(transfer_model=\"EH\", takahashi=True, z=8.0)\n", + "teh_nl_ntk = Transfer(transfer_model=\"EH\", takahashi=False, z=8.0)" ] }, { @@ -82,12 +82,14 @@ } ], "source": [ - "plt.plot(teh_nl_tk.k, np.abs(teh_nl_ntk.nonlinear_power/teh_nl_tk.nonlinear_power -1))\n", - "#plt.plot(teh_nl_ntk.k, teh_nl_ntk.nonlinear_power)\n", - "#plt.plot(teh_nl_ntk.k, teh_nl_ntk.power)\n", + "plt.plot(\n", + " teh_nl_tk.k, np.abs(teh_nl_ntk.nonlinear_power / teh_nl_tk.nonlinear_power - 1)\n", + ")\n", + "# plt.plot(teh_nl_ntk.k, teh_nl_ntk.nonlinear_power)\n", + "# plt.plot(teh_nl_ntk.k, teh_nl_ntk.power)\n", "\n", - "plt.xscale('log')\n", - "#plt.yscale('log')\n", + "plt.xscale(\"log\")\n", + "# plt.yscale('log')\n", "plt.grid(True)" ] }, @@ -162,48 +164,49 @@ "metadata": {}, "outputs": [], "source": [ - "#Nbodykit\n", - "#from nbodykit.lab import *\n", - "#from nbodykit import setup_logging\n", - "#from nbodykit.lab import cosmology\n", - "#setup_logging() # log output to stdout\n", + "# Nbodykit\n", + "# from nbodykit.lab import *\n", + "# from nbodykit import setup_logging\n", + "# from nbodykit.lab import cosmology\n", + "# setup_logging() # log output to stdout\n", "\n", - "#HMF\n", - "from hmf import cosmology as cm\n", - "from hmf import density_field\n", - "#from density_field import transfer\n", + "# HMF\n", "\n", - "import numpy as np\n", - "import matplotlib\n", - "#matplotlib.use('Agg') only when working from terminal\n", "\n", + "# matplotlib.use('Agg') only when working from terminal\n", "import matplotlib.pyplot as plt\n", "\n", + "# from density_field import transfer\n", + "import numpy as np\n", + "\n", "# Import the science packages/libraries\n", - "import scipy, scipy.interpolate, scipy.misc, scipy.integrate\n", "from scipy.interpolate import interp1d\n", - "import math\n", - "import random\n", - "#from IPython.display import display, Math\n", + "\n", + "from hmf import cosmology as cm\n", + "from hmf import density_field\n", + "\n", + "# from IPython.display import display, Math\n", "\n", "\n", "# In[4]:\n", "\n", "\n", "# PLANCK15 cosmology:\n", - "#cosmonbody= cosmology.Planck15 #nbodykit cosmology\n", - "my_cosmo = cm.Cosmology() #hmf cosmology, again Planck15\n", - "zbin=1.35\n", - "lx=1500 # in Mpc, box cube side\n", - "ngrid=400 #grid of the cube\n", + "# cosmonbody= cosmology.Planck15 #nbodykit cosmology\n", + "my_cosmo = cm.Cosmology() # hmf cosmology, again Planck15\n", + "zbin = 1.35\n", + "lx = 1500 # in Mpc, box cube side\n", + "ngrid = 400 # grid of the cube\n", "\n", - "#Modes\n", - "a=2*np.pi/lx #smallest k\n", - "b=ngrid*np.pi/lx #biggest k\n", - "npt=140 #number of k\n", - "kparal=np.linspace(a,b,npt) #k parallel data vector\n", - "ktotal=0.5*(kparal[1:]+kparal[:-1]) #k's (cfr. https://github.com/franciscovillaescusa/Pylians/blob/a5d9862dff855e07626ce62992f8273741e22e77/Pk/1D/Pk_1D.py)\n", - "kperpend=np.sqrt(ktotal**2-kparal[:-1]**2) #perpendicular modes\n", + "# Modes\n", + "a = 2 * np.pi / lx # smallest k\n", + "b = ngrid * np.pi / lx # biggest k\n", + "npt = 140 # number of k\n", + "kparal = np.linspace(a, b, npt) # k parallel data vector\n", + "ktotal = (\n", + " 0.5 * (kparal[1:] + kparal[:-1])\n", + ") # k's (cfr. https://github.com/franciscovillaescusa/Pylians/blob/a5d9862dff855e07626ce62992f8273741e22e77/Pk/1D/Pk_1D.py)\n", + "kperpend = np.sqrt(ktotal**2 - kparal[:-1] ** 2) # perpendicular modes\n", "\n", "\n", "# In[5]:\n", @@ -218,42 +221,44 @@ "# In[6]:\n", "\n", "\n", - "#halofit di hmf ha bisogno di vettori, quindi riempio vettori\n", - "#plinnbody=np.zeros(len(ktotal))\n", - "#plinnbody_nw=np.zeros(len(ktotal))\n", - "#pnlinnbody=np.zeros(len(ktotal))\n", + "# halofit di hmf ha bisogno di vettori, quindi riempio vettori\n", + "# plinnbody=np.zeros(len(ktotal))\n", + "# plinnbody_nw=np.zeros(len(ktotal))\n", + "# pnlinnbody=np.zeros(len(ktotal))\n", "\n", - "#plinnbody=P_w(ktotal) \n", - "#pnlinnbody=P_wh(ktotal) #nbodykit halofit\n", - "#plinnbody_nw=P_nw(ktotal)\n", + "# plinnbody=P_w(ktotal)\n", + "# pnlinnbody=P_wh(ktotal) #nbodykit halofit\n", + "# plinnbody_nw=P_nw(ktotal)\n", "\n", - "#pnorm=plinnbody*ktotal**3/(2*np.pi**2) #dimensionless power spectrum \n", - "#pnorm_nw=plinnbody_nw*ktotal**3/(2*np.pi**2) #dimensionless nowiggles power spectrum\n", + "# pnorm=plinnbody*ktotal**3/(2*np.pi**2) #dimensionless power spectrum\n", + "# pnorm_nw=plinnbody_nw*ktotal**3/(2*np.pi**2) #dimensionless nowiggles power spectrum\n", "\n", "\n", "# In[7]:\n", "\n", "\n", - "#Plot check\n", - "#plt.plot(ktotal,pnorm)\n", - "#plt.plot(ktotal,pnorm_nw)\n", + "# Plot check\n", + "# plt.plot(ktotal,pnorm)\n", + "# plt.plot(ktotal,pnorm_nw)\n", "\n", "\n", "# In[8]:\n", "\n", - "sigma_8=0.8\n", - "#sigma_8=cosmonbody.sigma8 #sigma8 \n", - "#print(sigma_8)\n", + "sigma_8 = 0.8\n", + "# sigma_8=cosmonbody.sigma8 #sigma8\n", + "# print(sigma_8)\n", "\n", "\n", "# In[9]:\n", - "t = Transfer(transfer_model='EH')\n", + "t = Transfer(transfer_model=\"EH\")\n", "k = t.k\n", "\n", - "pnorm = t.power * k**3 / (2*np.pi**2)\n", + "pnorm = t.power * k**3 / (2 * np.pi**2)\n", "pnorm_ = interp1d(k, pnorm)(ktotal)\n", - "pnlw=density_field.halofit(k, pnorm, sigma_8, zbin, cosmo=my_cosmo.cosmo, takahashi=True) #Generate (?) non-linear wiggles with halofit\n", - "#pnlnw=density_field.halofit.halofit(ktotal,pnorm_nw, sigma_8, zbin, cosmo=my_cosmo, takahashi=True) #Generate (?) non-linear no-wiggles with halofit" + "pnlw = density_field.halofit(\n", + " k, pnorm, sigma_8, zbin, cosmo=my_cosmo.cosmo, takahashi=True\n", + ") # Generate (?) non-linear wiggles with halofit\n", + "# pnlnw=density_field.halofit.halofit(ktotal,pnorm_nw, sigma_8, zbin, cosmo=my_cosmo, takahashi=True) #Generate (?) non-linear no-wiggles with halofit" ] }, { @@ -285,9 +290,9 @@ ], "source": [ "plt.plot(k, pnorm)\n", - "plt.plot(k,pnlw)\n", - "plt.xscale('log')\n", - "plt.yscale('log')" + "plt.plot(k, pnlw)\n", + "plt.xscale(\"log\")\n", + "plt.yscale(\"log\")" ] }, { diff --git a/docs/conf.py b/docs/conf.py index 3df9a287..2ff6b552 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # # hmf documentation build configuration file, created by # sphinx-quickstart on Mon Dec 2 10:40:08 2013. @@ -11,14 +10,16 @@ # All configuration values have a default; values that are commented out # serve to show the default. -import sys, os +import os +import sys import time + from importlib_metadata import version as _version # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. -sys.path.insert(0, os.path.abspath('../')) +sys.path.insert(0, os.path.abspath("../")) # -- General configuration ----------------------------------------------------- @@ -27,7 +28,7 @@ # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. -extensions =extensions = [ +extensions = extensions = [ "sphinx.ext.autodoc", "sphinx.ext.autosummary", "sphinx.ext.coverage", @@ -49,20 +50,20 @@ autosummary_generate = True # Add any paths that contain templates here, relative to this directory. -templates_path = ['templates'] +templates_path = ["templates"] # The suffix of source filenames. -source_suffix = '.rst' +source_suffix = ".rst" # The encoding of source files. # source_encoding = 'utf-8-sig' # The master toctree document. -master_doc = 'index' +master_doc = "index" # General information about the project. -project = u'hmf' -copyright = u'%s, Steven Murray' % (time.localtime()[0]) +project = "hmf" +copyright = "%s, Steven Murray" % (time.localtime()[0]) # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the @@ -77,11 +78,10 @@ ] - # The short X.Y version. -version = _version('hmf') +version = _version("hmf") # The full version, including alpha/beta/rc tags. -release = _version('hmf') +release = _version("hmf") # The language for content autogenerated by Sphinx. Refer to documentation @@ -109,7 +109,7 @@ # show_authors = False # The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' +pygments_style = "sphinx" # A list of ignored prefixes for module index sorting. # modindex_common_prefix = [] @@ -119,7 +119,7 @@ # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. -html_theme = 'sphinx_rtd_theme' +html_theme = "sphinx_rtd_theme" # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the @@ -148,7 +148,7 @@ # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] +html_static_path = ["_static"] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. @@ -192,27 +192,24 @@ # html_file_suffix = None # Output file base name for HTML help builder. -htmlhelp_basename = 'hmfdoc' +htmlhelp_basename = "hmfdoc" # -- Options for LaTeX output -------------------------------------------------- latex_elements = { -# The paper size ('letterpaper' or 'a4paper'). -# 'papersize': 'letterpaper', - -# The font size ('10pt', '11pt' or '12pt'). -# 'pointsize': '10pt', - -# Additional stuff for the LaTeX preamble. -# 'preamble': '', + # The paper size ('letterpaper' or 'a4paper'). + # 'papersize': 'letterpaper', + # The font size ('10pt', '11pt' or '12pt'). + # 'pointsize': '10pt', + # Additional stuff for the LaTeX preamble. + # 'preamble': '', } # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, documentclass [howto/manual]). latex_documents = [ - ('index', 'hmf.tex', u'hmf Documentation', - u'Steven Murray', 'manual'), + ("index", "hmf.tex", "hmf Documentation", "Steven Murray", "manual"), ] # The name of an image file (relative to this directory) to place at the top of @@ -240,10 +237,7 @@ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). -man_pages = [ - ('index', 'hmf', u'hmf Documentation', - [u'Steven Murray'], 1) -] +man_pages = [("index", "hmf", "hmf Documentation", ["Steven Murray"], 1)] # If true, show URL addresses after external links. # man_show_urls = False @@ -255,9 +249,15 @@ # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ - ('index', 'hmf', u'hmf Documentation', - u'Steven Murray', 'hmf', 'One line description of project.', - 'Miscellaneous'), + ( + "index", + "hmf", + "hmf Documentation", + "Steven Murray", + "hmf", + "One line description of project.", + "Miscellaneous", + ), ] # Documents to append as an appendix to all manuals. @@ -278,5 +278,6 @@ } -mathjax_path = "http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML" - +mathjax_path = ( + "http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML" +) diff --git a/docs/examples/broad_overview.ipynb b/docs/examples/broad_overview.ipynb index f0ff35ac..7c104b5a 100644 --- a/docs/examples/broad_overview.ipynb +++ b/docs/examples/broad_overview.ipynb @@ -41,11 +41,8 @@ "outputs": [], "source": [ "from hmf import (\n", - " cosmology, # Defines cosmographic parameters and growth functions\n", " density_field, # Defines power spectra and transfer functions, as well as window functions/filters on those\n", - " halos, # Defines halo-specific forms such as mass definitions\n", - " mass_function # Defines routines that combine the above to obtain halo mass functions\n", - ")" + " )" ] }, { @@ -65,9 +62,7 @@ } }, "outputs": [], - "source": [ - "from hmf import MassFunction" - ] + "source": [] }, { "cell_type": "markdown", @@ -653,6 +648,7 @@ "outputs": [], "source": [ "import numpy as np\n", + "\n", "%matplotlib inline\n", "import matplotlib.pyplot as plt" ] @@ -707,8 +703,8 @@ " tr_ = Transfer(z=z)\n", " plt.plot(tr_.k, tr_.power)\n", "\n", - "plt.xscale('log')\n", - "plt.yscale('log');" + "plt.xscale(\"log\")\n", + "plt.yscale(\"log\");" ] }, { @@ -751,11 +747,11 @@ "%%time\n", "\n", "for z in redshifts:\n", - " tr.z=z\n", + " tr.z = z\n", " plt.plot(tr.k, tr.power)\n", "\n", - "plt.xscale('log')\n", - "plt.yscale('log');" + "plt.xscale(\"log\")\n", + "plt.yscale(\"log\");" ] }, { @@ -811,7 +807,7 @@ }, "outputs": [], "source": [ - "tr.transfer_model = 'EH'" + "tr.transfer_model = \"EH\"" ] }, { @@ -899,7 +895,7 @@ } ], "source": [ - "tr.transfer.lnt(np.linspace(0,1,10))" + "tr.transfer.lnt(np.linspace(0, 1, 10))" ] }, { @@ -959,7 +955,7 @@ }, "outputs": [], "source": [ - "tr.growth_params = {'dlna': 1} # By default it is 0.01" + "tr.growth_params = {\"dlna\": 1} # By default it is 0.01" ] }, { @@ -1127,7 +1123,7 @@ } ], "source": [ - "get_best_param_order(Transfer, q='power')" + "get_best_param_order(Transfer, q=\"power\")" ] }, { @@ -1204,16 +1200,18 @@ } ], "source": [ - "for power, tr, label in get_hmf(req_qauntities=['power'],\n", - " framework=Transfer,\n", - " fast_kwargs={\"transfer_model\": \"EH\"},\n", - " z=[0,1,2,3,4,5],\n", - " cosmo_params = [{'Om0': 0.3}, {'Om0': 0.2}, {'Om0': 0.4}]):\n", + "for power, tr, label in get_hmf(\n", + " req_qauntities=[\"power\"],\n", + " framework=Transfer,\n", + " fast_kwargs={\"transfer_model\": \"EH\"},\n", + " z=[0, 1, 2, 3, 4, 5],\n", + " cosmo_params=[{\"Om0\": 0.3}, {\"Om0\": 0.2}, {\"Om0\": 0.4}],\n", + "):\n", " print(tr.cosmo_params, tr.z)\n", " plt.plot(tr.k, tr.power)\n", "\n", "plt.xscale(\"log\")\n", - "plt.yscale('log')" + "plt.yscale(\"log\")" ] }, { diff --git a/docs/examples/change_mass_definition.ipynb b/docs/examples/change_mass_definition.ipynb index 1f5270dc..fe6fe1cf 100644 --- a/docs/examples/change_mass_definition.ipynb +++ b/docs/examples/change_mass_definition.ipynb @@ -67,7 +67,7 @@ "import hmf\n", "from hmf.halos import mass_definitions as md\n", "\n", - "print(\"Using hmf version v%s\"%hmf.__version__)" + "print(\"Using hmf version v%s\" % hmf.__version__)" ] }, { @@ -86,8 +86,9 @@ "outputs": [], "source": [ "import matplotlib.pyplot as plt\n", + "\n", "%matplotlib inline\n", - "import inspect\n" + "import inspect" ] }, { @@ -122,7 +123,11 @@ } ], "source": [ - "[x[1] for x in inspect.getmembers(md, inspect.isclass) if issubclass(x[1], md.MassDefinition)]" + "[\n", + " x[1]\n", + " for x in inspect.getmembers(md, inspect.isclass)\n", + " if issubclass(x[1], md.MassDefinition)\n", + "]" ] }, { @@ -201,7 +206,7 @@ } ], "source": [ - "mdef_1.halo_density(), mdef_1.halo_density()/mdef_1.mean_density()" + "mdef_1.halo_density(), mdef_1.halo_density() / mdef_1.mean_density()" ] }, { @@ -243,9 +248,9 @@ ], "source": [ "mnew, rnew, cnew = mdef_1.change_definition(m=1e12, mdef=mdef_2)\n", - "print(\"Mass in new definition is %.2f x 10^12 Msun / h\"%(mnew/1e12))\n", - "print(\"Radius of halo in new definition is %.2f Mpc/h\"%rnew)\n", - "print(\"Concentration of halo in new definition is %.2f\"%cnew)" + "print(\"Mass in new definition is %.2f x 10^12 Msun / h\" % (mnew / 1e12))\n", + "print(\"Radius of halo in new definition is %.2f Mpc/h\" % rnew)\n", + "print(\"Concentration of halo in new definition is %.2f\" % cnew)" ] }, { @@ -273,10 +278,10 @@ } ], "source": [ - "mnew, rnew, cnew = mdef_1.change_definition(m=1e12, mdef=mdef_2, c = 5.0)\n", - "print(\"Mass in new definition is %.2f x 10^12 Msun / h\"%(mnew/1e12))\n", - "print(\"Radius of halo in new definition is %.2f Mpc/h\"%rnew)\n", - "print(\"Concentration of halo in new definition is %.2f\"%cnew)" + "mnew, rnew, cnew = mdef_1.change_definition(m=1e12, mdef=mdef_2, c=5.0)\n", + "print(\"Mass in new definition is %.2f x 10^12 Msun / h\" % (mnew / 1e12))\n", + "print(\"Radius of halo in new definition is %.2f Mpc/h\" % rnew)\n", + "print(\"Concentration of halo in new definition is %.2f\" % cnew)" ] }, { @@ -318,7 +323,7 @@ }, "outputs": [], "source": [ - "from hmf.mass_function.fitting_functions import SMT, Tinker08, Jenkins" + "from hmf.mass_function.fitting_functions import SMT, Jenkins, Tinker08" ] }, { @@ -338,8 +343,10 @@ ], "source": [ "print(SMT.sim_definition.halo_finder_type, SMT.sim_definition.halo_overdensity)\n", - "print(Tinker08.sim_definition.halo_finder_type, Tinker08.sim_definition.halo_overdensity)\n", - "print(Jenkins.sim_definition.halo_finder_type, Jenkins.sim_definition.halo_overdensity)\n" + "print(\n", + " Tinker08.sim_definition.halo_finder_type, Tinker08.sim_definition.halo_overdensity\n", + ")\n", + "print(Jenkins.sim_definition.halo_finder_type, Jenkins.sim_definition.halo_overdensity)" ] }, { @@ -376,27 +383,17 @@ "dndm0 = mf.dndm\n", "\n", "# Change the mass definition to 300rho_mean\n", - "mf.update(\n", - " mdef_model = \"SOMean\", \n", - " mdef_params = {\n", - " \"overdensity\": 300 \n", - " }\n", - ")\n", + "mf.update(mdef_model=\"SOMean\", mdef_params={\"overdensity\": 300})\n", "\n", - "plt.plot(mf.m, mf.dndm/dndm0, label=r\"300 $\\rho_m$\", lw=3)\n", + "plt.plot(mf.m, mf.dndm / dndm0, label=r\"300 $\\rho_m$\", lw=3)\n", "\n", "# Change the mass definition to 500rho_crit\n", - "mf.update(\n", - " mdef_model = \"SOCritical\", \n", - " mdef_params = {\n", - " \"overdensity\": 500 \n", - " }\n", - ")\n", + "mf.update(mdef_model=\"SOCritical\", mdef_params={\"overdensity\": 500})\n", "\n", - "plt.plot(mf.m, mf.dndm/dndm0, label=r\"500 $\\rho_c$\", lw=3)\n", + "plt.plot(mf.m, mf.dndm / dndm0, label=r\"500 $\\rho_c$\", lw=3)\n", "\n", - "plt.xscale('log')\n", - "plt.yscale('log')\n", + "plt.xscale(\"log\")\n", + "plt.yscale(\"log\")\n", "plt.xlabel(r\"Mass, $M_\\odot/h$\", fontsize=15)\n", "plt.ylabel(r\"Ratio of $dn/dm$ to $200 \\rho_m$\", fontsize=15)\n", "plt.grid(True)\n", @@ -440,30 +437,20 @@ ], "source": [ "# Default mass function object.\n", - "mf = hmf.MassFunction(hmf_model = \"SMT\", Mmax=15, disable_mass_conversion=False)\n", + "mf = hmf.MassFunction(hmf_model=\"SMT\", Mmax=15, disable_mass_conversion=False)\n", "dndm0 = mf.dndm\n", "\n", "# Change the mass definition to 300rho_mean\n", - "mf.update(\n", - " mdef_model = \"SOMean\", \n", - " mdef_params = {\n", - " \"overdensity\": 300 \n", - " }\n", - ")\n", - "plt.plot(mf.m, mf.dndm/dndm0, label=r\"300 $\\rho_m$\", lw=3)\n", + "mf.update(mdef_model=\"SOMean\", mdef_params={\"overdensity\": 300})\n", + "plt.plot(mf.m, mf.dndm / dndm0, label=r\"300 $\\rho_m$\", lw=3)\n", "\n", "\n", "# Change the mass definition to 500rho_crit\n", - "mf.update(\n", - " mdef_model = \"SOCritical\", \n", - " mdef_params = {\n", - " \"overdensity\": 500 \n", - " }\n", - ")\n", - "plt.plot(mf.m, mf.dndm/dndm0, label=r\"500 $\\rho_c$\", lw=3)\n", + "mf.update(mdef_model=\"SOCritical\", mdef_params={\"overdensity\": 500})\n", + "plt.plot(mf.m, mf.dndm / dndm0, label=r\"500 $\\rho_c$\", lw=3)\n", "\n", - "plt.xscale('log')\n", - "plt.yscale('log')\n", + "plt.xscale(\"log\")\n", + "plt.yscale(\"log\")\n", "plt.xlabel(r\"Mass, $M_\\odot/h$\", fontsize=15)\n", "plt.ylabel(r\"Ratio of $dn/dm$ to virial\", fontsize=15)\n", "plt.grid(True)\n", @@ -509,29 +496,24 @@ ], "source": [ "# Default mass function object.\n", - "mf = hmf.MassFunction(hmf_model = \"Jenkins\", disable_mass_conversion=False)\n", + "mf = hmf.MassFunction(hmf_model=\"Jenkins\", disable_mass_conversion=False)\n", "dndm0 = mf.dndm\n", "\n", "# Change the mass definition to 300rho_mean\n", - "mf.update(\n", - " mdef_model = \"FOF\", \n", - " mdef_params = {\n", - " \"linking_length\": 0.3 \n", - " }\n", - ")\n", - "plt.plot(mf.m, mf.dndm/dndm0, label=r\"FoF $b=0.3$\", lw=3)\n", + "mf.update(mdef_model=\"FOF\", mdef_params={\"linking_length\": 0.3})\n", + "plt.plot(mf.m, mf.dndm / dndm0, label=r\"FoF $b=0.3$\", lw=3)\n", "\n", "\n", "# Change the mass definition to 500rho_crit\n", "mf.update(\n", - " mdef_model = \"SOVirial\",\n", - " mdef_params = {} # NOTE: we need to pass an empty dict here \n", - " # so that the \"linking_length\" argument is removed.\n", + " mdef_model=\"SOVirial\",\n", + " mdef_params={}, # NOTE: we need to pass an empty dict here\n", + " # so that the \"linking_length\" argument is removed.\n", ")\n", - "plt.plot(mf.m, mf.dndm/dndm0, label=r\"SO Virial\", lw=3)\n", + "plt.plot(mf.m, mf.dndm / dndm0, label=r\"SO Virial\", lw=3)\n", "\n", - "plt.xscale('log')\n", - "plt.yscale('log')\n", + "plt.xscale(\"log\")\n", + "plt.yscale(\"log\")\n", "plt.xlabel(r\"Mass, $M_\\odot/h$\", fontsize=15)\n", "plt.ylabel(r\"Ratio of $dn/dm$ to FoF $b=0.2$\", fontsize=15)\n", "plt.grid(True)\n", @@ -575,30 +557,50 @@ ], "source": [ "# Default mass function object.\n", - "mf200c_conv = hmf.MassFunction(hmf_model = \"Bocquet200mDMOnly\", mdef_model='SOCritical', mdef_params={'overdensity': 200}, disable_mass_conversion=False)\n", - "mf500c_conv = hmf.MassFunction(hmf_model = \"Bocquet200mDMOnly\", mdef_model='SOCritical', mdef_params={'overdensity': 500}, disable_mass_conversion=False)\n", - "mf200c_refit = hmf.MassFunction(hmf_model = \"Bocquet200cDMOnly\")\n", - "mf500c_refit = hmf.MassFunction(hmf_model = \"Bocquet500cDMOnly\")\n", + "mf200c_conv = hmf.MassFunction(\n", + " hmf_model=\"Bocquet200mDMOnly\",\n", + " mdef_model=\"SOCritical\",\n", + " mdef_params={\"overdensity\": 200},\n", + " disable_mass_conversion=False,\n", + ")\n", + "mf500c_conv = hmf.MassFunction(\n", + " hmf_model=\"Bocquet200mDMOnly\",\n", + " mdef_model=\"SOCritical\",\n", + " mdef_params={\"overdensity\": 500},\n", + " disable_mass_conversion=False,\n", + ")\n", + "mf200c_refit = hmf.MassFunction(hmf_model=\"Bocquet200cDMOnly\")\n", + "mf500c_refit = hmf.MassFunction(hmf_model=\"Bocquet500cDMOnly\")\n", "\n", "m = mf200c_conv.m\n", "\n", "fig, ax = plt.subplots(1, 1, sharex=True)\n", "ax = [ax]\n", - "ax[0].plot(m, mf200c_conv.dndm/mf200c_refit.dndm - 1, color='k', label='200c')\n", - "ax[0].plot(m, mf200c_conv.fsigma/(mf200c_refit.fsigma/mf200c_refit.hmf.convert_mass()) - 1, color='r')\n", + "ax[0].plot(m, mf200c_conv.dndm / mf200c_refit.dndm - 1, color=\"k\", label=\"200c\")\n", + "ax[0].plot(\n", + " m,\n", + " mf200c_conv.fsigma / (mf200c_refit.fsigma / mf200c_refit.hmf.convert_mass()) - 1,\n", + " color=\"r\",\n", + ")\n", "\n", - "ax[0].plot(m, mf500c_conv.dndm/mf500c_refit.dndm - 1, ls='--', color='k', label='500c')\n", - "ax[0].plot(m, mf500c_conv.fsigma/(mf500c_refit.fsigma/mf500c_refit.hmf.convert_mass()) - 1, color='r', ls='--')\n", + "ax[0].plot(\n", + " m, mf500c_conv.dndm / mf500c_refit.dndm - 1, ls=\"--\", color=\"k\", label=\"500c\"\n", + ")\n", + "ax[0].plot(\n", + " m,\n", + " mf500c_conv.fsigma / (mf500c_refit.fsigma / mf500c_refit.hmf.convert_mass()) - 1,\n", + " color=\"r\",\n", + " ls=\"--\",\n", + ")\n", "\n", - "ax[0].set_xscale('log')\n", + "ax[0].set_xscale(\"log\")\n", "ax[0].set_xlabel(r\"Mass, $M_\\odot/h$\", fontsize=15)\n", "ax[0].set_ylabel(r\"dn/dm\", fontsize=15)\n", "ax[0].grid(True)\n", - "ax[0].legend();\n", - "\n", + "ax[0].legend()\n", "ax[0].set_ylim(-0.5, 0.5)\n", "ax[0].set_ylabel(\"Fractional Diff.\")\n", - "ax[0].set_title(\"Comparison of Mass Conversion to Refit\");\n", + "ax[0].set_title(\"Comparison of Mass Conversion to Refit\")\n", "plt.savefig(\"/home/steven/Desktop/comparison_of_massconv_to_refit.pdf\")" ] }, diff --git a/docs/examples/fitting.ipynb b/docs/examples/fitting.ipynb index 33ccf343..ea17f1fc 100644 --- a/docs/examples/fitting.ipynb +++ b/docs/examples/fitting.ipynb @@ -22,17 +22,15 @@ "metadata": {}, "outputs": [], "source": [ - "import emcee\n", - "import hmf\n", - "import numpy as np\n", + "from multiprocessing import Pool\n", "\n", + "import emcee\n", "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "from IPython.display import Markdown, display\n", "from scipy.stats import poisson\n", - "from multiprocessing import Pool\n", - "\n", "\n", - "\n", - "from IPython.display import display, Markdown\n", + "import hmf\n", "\n", "%matplotlib inline" ] @@ -97,7 +95,7 @@ "metadata": {}, "outputs": [], "source": [ - "model = hmf.MassFunction(z=1.5, transfer_model='EH')" + "model = hmf.MassFunction(z=1.5, transfer_model=\"EH\")" ] }, { @@ -113,7 +111,7 @@ "metadata": {}, "outputs": [], "source": [ - "volume = 100 ** 3 # Mpc^3 / h^3" + "volume = 100**3 # Mpc^3 / h^3" ] }, { @@ -146,8 +144,8 @@ "source": [ "plt.plot(model.m, model.dndlog10m * volume * model.dlog10m)\n", "plt.plot(model.m, counts_per_bin)\n", - "plt.xscale('log')\n", - "plt.yscale('log')" + "plt.xscale(\"log\")\n", + "plt.yscale(\"log\")" ] }, { @@ -171,7 +169,7 @@ "outputs": [], "source": [ "def log_likelihood(model, data, volume, dlog10m):\n", - " return np.sum(poisson.logpmf(data, mu=model*volume*dlog10m))" + " return np.sum(poisson.logpmf(data, mu=model * volume * dlog10m))" ] }, { @@ -212,21 +210,22 @@ "source": [ "def flat_to_nested_dict(dct: dict) -> dict:\n", " \"\"\"Convert a dct of key: value pairs into a nested dict.\n", - " \n", + "\n", " Keys that have dots in them indicate nested structure.\n", - " \"\"\" \n", + " \"\"\"\n", + "\n", " def key_to_dct(key, val, dct):\n", - " if '.' in key:\n", - " key, parts = key.split('.', maxsplit=1)\n", - " \n", + " if \".\" in key:\n", + " key, parts = key.split(\".\", maxsplit=1)\n", + "\n", " if key not in dct:\n", " dct[key] = {}\n", - " \n", + "\n", " key_to_dct(parts, val, dct[key])\n", " else:\n", " dct[key] = val\n", - " \n", - " out = {} \n", + "\n", + " out = {}\n", " for k, v in dct.items():\n", " key_to_dct(k, v, out)\n", "\n", @@ -257,14 +256,7 @@ } ], "source": [ - "flat_to_nested_dict(\n", - " {\n", - " 'nested.key': 1,\n", - " 'nested.key2': 2,\n", - " 'non_nested': 3\n", - " \n", - " }\n", - ")" + "flat_to_nested_dict({\"nested.key\": 1, \"nested.key2\": 2, \"non_nested\": 3})" ] }, { @@ -285,12 +277,12 @@ " params = flat_to_nested_dict(dict(zip(param_names, param_values)))\n", "\n", " model.update(**params)\n", - " \n", + "\n", " if derived is not None:\n", " derived = [getattr(model, d) for d in derived]\n", " else:\n", " derived = []\n", - " \n", + "\n", " return log_likelihood(model.dndlog10m, data, volume, model.dlog10m), derived" ] }, @@ -318,7 +310,7 @@ } ], "source": [ - "log_prob([0.9], ['sigma_8'], counts_per_bin, model, volume, derived=['mass_nonlinear'])" + "log_prob([0.9], [\"sigma_8\"], counts_per_bin, model, volume, derived=[\"mass_nonlinear\"])" ] }, { @@ -362,17 +354,17 @@ ], "source": [ "sampler = emcee.EnsembleSampler(\n", - " nwalkers = 100,\n", - " ndim = 2,\n", - " log_prob_fn = log_prob,\n", - " kwargs = {\n", - " 'param_names': ['sigma_8', 'n'], \n", - " 'data': counts_per_bin, \n", - " 'model': model, \n", - " 'volume': volume, \n", - " 'derived': ['mass_nonlinear']\n", + " nwalkers=100,\n", + " ndim=2,\n", + " log_prob_fn=log_prob,\n", + " kwargs={\n", + " \"param_names\": [\"sigma_8\", \"n\"],\n", + " \"data\": counts_per_bin,\n", + " \"model\": model,\n", + " \"volume\": volume,\n", + " \"derived\": [\"mass_nonlinear\"],\n", " },\n", - " pool = Pool(4),\n", + " pool=Pool(4),\n", ")" ] }, @@ -389,7 +381,9 @@ "metadata": {}, "outputs": [], "source": [ - "initialpos = np.array([fiducial_model.sigma_8, fiducial_model.n]) + 1e-4 * np.random.normal(size=(sampler.nwalkers, sampler.ndim))" + "initialpos = np.array(\n", + " [fiducial_model.sigma_8, fiducial_model.n]\n", + ") + 1e-4 * np.random.normal(size=(sampler.nwalkers, sampler.ndim))" ] }, { @@ -719,9 +713,9 @@ } ], "source": [ - "plt.hexbin(sampler.chain[:,500:, 0].flatten(), sampler.chain[:,500:, 1].flatten())\n", - "plt.axvline(fiducial_model.sigma_8, color='white')\n", - "plt.axhline(fiducial_model.n, color='white')\n", + "plt.hexbin(sampler.chain[:, 500:, 0].flatten(), sampler.chain[:, 500:, 1].flatten())\n", + "plt.axvline(fiducial_model.sigma_8, color=\"white\")\n", + "plt.axhline(fiducial_model.n, color=\"white\")\n", "plt.colorbar()" ] }, @@ -752,7 +746,7 @@ "metadata": {}, "outputs": [], "source": [ - "fiducial_model = hmf.MassFunction(z=0, hmf_model='SMT', dlog10m=0.2, Mmin=10, Mmax=16)" + "fiducial_model = hmf.MassFunction(z=0, hmf_model=\"SMT\", dlog10m=0.2, Mmin=10, Mmax=16)" ] }, { @@ -837,14 +831,16 @@ } ], "source": [ - "volume = 500 ** 3 # Mpc^3 / h^3\n", + "volume = 500**3 # Mpc^3 / h^3\n", "\n", - "counts_per_bin = np.random.poisson(fiducial_model.dndlog10m * volume * fiducial_model.dlog10m)\n", + "counts_per_bin = np.random.poisson(\n", + " fiducial_model.dndlog10m * volume * fiducial_model.dlog10m\n", + ")\n", "\n", "plt.plot(fiducial_model.m, fiducial_model.dndlog10m * volume * fiducial_model.dlog10m)\n", "plt.plot(fiducial_model.m, counts_per_bin)\n", - "plt.xscale('log')\n", - "plt.yscale('log')" + "plt.xscale(\"log\")\n", + "plt.yscale(\"log\")" ] }, { @@ -870,17 +866,17 @@ "outputs": [], "source": [ "sampler_hmf = emcee.EnsembleSampler(\n", - " nwalkers = 50,\n", - " ndim = 3,\n", - " log_prob_fn = log_prob,\n", - " kwargs = {\n", - " 'param_names': ['hmf_params.a', 'hmf_params.p', 'hmf_params.A'], \n", - " 'data': counts_per_bin, \n", - " 'model': smt_model, \n", - " 'volume': volume, \n", - " 'derived': ['dndlog10m']\n", + " nwalkers=50,\n", + " ndim=3,\n", + " log_prob_fn=log_prob,\n", + " kwargs={\n", + " \"param_names\": [\"hmf_params.a\", \"hmf_params.p\", \"hmf_params.A\"],\n", + " \"data\": counts_per_bin,\n", + " \"model\": smt_model,\n", + " \"volume\": volume,\n", + " \"derived\": [\"dndlog10m\"],\n", " },\n", - " pool = Pool(4),\n", + " pool=Pool(4),\n", ")" ] }, @@ -890,13 +886,9 @@ "metadata": {}, "outputs": [], "source": [ - "init_pos = (\n", - " np.array([\n", - " smt_model.hmf.params['a'], \n", - " smt_model.hmf.params['p'], \n", - " smt_model.hmf.params['A']]) + \n", - " 1e-4 * np.random.normal(size=(sampler_hmf.nwalkers, sampler_hmf.ndim))\n", - ")" + "init_pos = np.array(\n", + " [smt_model.hmf.params[\"a\"], smt_model.hmf.params[\"p\"], smt_model.hmf.params[\"A\"]]\n", + ") + 1e-4 * np.random.normal(size=(sampler_hmf.nwalkers, sampler_hmf.ndim))" ] }, { @@ -1131,7 +1123,7 @@ } ], "source": [ - "sampler_hmf.run_mcmc(init_pos, nsteps=300, progress='notebook')" + "sampler_hmf.run_mcmc(init_pos, nsteps=300, progress=\"notebook\")" ] }, { @@ -1170,7 +1162,14 @@ } ], "source": [ - "fig, ax = plt.subplots(2, 2, sharex='col', sharey='row', figsize=(10, 10), gridspec_kw={\"hspace\":0, 'wspace': 0})\n", + "fig, ax = plt.subplots(\n", + " 2,\n", + " 2,\n", + " sharex=\"col\",\n", + " sharey=\"row\",\n", + " figsize=(10, 10),\n", + " gridspec_kw={\"hspace\": 0, \"wspace\": 0},\n", + ")\n", "\n", "flatchain = sampler_hmf.chain[:, 100:, :].reshape((-1, 3))\n", "\n", @@ -1181,7 +1180,7 @@ "ax[1, 0].set_xlabel(\"a\", fontsize=15)\n", "ax[1, 0].set_ylabel(\"A\", fontsize=15)\n", "ax[1, 1].set_xlabel(\"p\", fontsize=15)\n", - "ax[0, 0].set_ylabel(\"p\", fontsize=15)\n" + "ax[0, 0].set_ylabel(\"p\", fontsize=15)" ] }, { @@ -1245,11 +1244,13 @@ } ], "source": [ - "plt.fill_between(fiducial_model.m, percentiles[0]/percentiles[1], percentiles[2]/percentiles[1])\n", - "plt.xscale('log')\n", + "plt.fill_between(\n", + " fiducial_model.m, percentiles[0] / percentiles[1], percentiles[2] / percentiles[1]\n", + ")\n", + "plt.xscale(\"log\")\n", "plt.ylabel(\"Fractional difference to Median\")\n", "plt.xlabel(\"Mass\")\n", - "#plt.yscale('log')" + "# plt.yscale('log')" ] } ], diff --git a/docs/examples/plugins_and_extending.ipynb b/docs/examples/plugins_and_extending.ipynb index 86ac77f4..c5c01127 100644 --- a/docs/examples/plugins_and_extending.ipynb +++ b/docs/examples/plugins_and_extending.ipynb @@ -54,9 +54,9 @@ "metadata": {}, "outputs": [], "source": [ - "from hmf.mass_function import FittingFunction, PS\n", + "from hmf import MassFunction\n", "from hmf.halos import MassDefinition\n", - "from hmf import MassFunction" + "from hmf.mass_function import PS, FittingFunction" ] }, { @@ -144,7 +144,7 @@ "metadata": {}, "outputs": [], "source": [ - "mf = MassFunction(hmf_model='Behroozi')" + "mf = MassFunction(hmf_model=\"Behroozi\")" ] }, { @@ -286,13 +286,13 @@ } ], "source": [ - "mf = MassFunction(hmf_model=MyNewFit, transfer_model='EH')\n", + "mf = MassFunction(hmf_model=MyNewFit, transfer_model=\"EH\")\n", "plt.plot(mf.m, mf.dndm)\n", "\n", "mf.hmf_model = PS\n", "plt.plot(mf.m, mf.dndm)\n", - "plt.xscale('log')\n", - "plt.yscale('log')\n", + "plt.xscale(\"log\")\n", + "plt.yscale(\"log\")\n", "plt.xlabel(\"Mass\")\n", "plt.ylabel(\"dndm\")" ] @@ -325,11 +325,11 @@ "outputs": [], "source": [ "class MyNewFitParameterized(FittingFunction):\n", - " _defaults = {'a': 0.5}\n", - " \n", + " _defaults = {\"a\": 0.5}\n", + "\n", " @property\n", " def fsigma(self):\n", - " return np.sqrt(2.0 / np.pi) * self.nu * np.exp(-self.params['a'] * self.nu2)" + " return np.sqrt(2.0 / np.pi) * self.nu * np.exp(-self.params[\"a\"] * self.nu2)" ] }, { @@ -352,7 +352,9 @@ "metadata": {}, "outputs": [], "source": [ - "mf = MassFunction(hmf_model=MyNewFitParameterized, hmf_params={'a':0.55}, transfer_model='EH')" + "mf = MassFunction(\n", + " hmf_model=MyNewFitParameterized, hmf_params={\"a\": 0.55}, transfer_model=\"EH\"\n", + ")" ] }, { @@ -384,13 +386,13 @@ } ], "source": [ - "for a in np.arange(0.4,0.6,0.02):\n", - " mf.hmf_params = {'a':a}\n", - " \n", + "for a in np.arange(0.4, 0.6, 0.02):\n", + " mf.hmf_params = {\"a\": a}\n", + "\n", " plt.plot(mf.m, mf.dndm)\n", - " \n", - "plt.xscale('log')\n", - "plt.yscale('log')\n", + "\n", + "plt.xscale(\"log\")\n", + "plt.yscale(\"log\")\n", "plt.xlabel(\"Mass\")\n", "plt.ylabel(\"dndm\")" ] @@ -464,7 +466,7 @@ "metadata": {}, "outputs": [], "source": [ - "mf = MassFunction(hmf_model = 'MyNewFit')" + "mf = MassFunction(hmf_model=\"MyNewFit\")" ] }, { diff --git a/hmf_cfg.toml b/hmf_cfg.toml deleted file mode 100644 index 87ea6d05..00000000 --- a/hmf_cfg.toml +++ /dev/null @@ -1,92 +0,0 @@ -created_on = 2022-09-12T09:16:26.539419 -hmf_version = "3.3.5.dev49+gba93c5d" -quantities = [ "m", "dndm", "sigma",] - -[params] -cosmo_model = "Planck15" -n = 0.9667 -sigma_8 = 0.8159 -lnk_min = -18.420680743952364 -lnk_max = 9.903487552536127 -dlnk = 0.05 -z = 1.0 -transfer_model = "EH" -takahashi = true -growth_model = "GrowthFactor" -hmf_model = "Tinker08" -Mmin = 10.0 -Mmax = 15.0 -dlog10m = 0.01 -mdef_model = "SOMean" -delta_c = 1.686 -filter_model = "TopHat" -disable_mass_conversion = true - -[params.cosmo_params] -Om0 = 0.3075 -Neff = 3.046 -Ob0 = 0.0486 -name = "Planck15" - -[params.growth_params] -dlna = 0.01 -amin = 1e-8 - -[params.transfer_params] - -[params.mdef_params] -overdensity = 200 - -[params.hmf_params] -A_200 = 0.1858659 -A_300 = 0.1995973 -A_400 = 0.2115659 -A_600 = 0.2184113 -A_800 = 0.2480968 -A_1200 = 0.2546053 -A_1600 = 0.26 -A_2400 = 0.26 -A_3200 = 0.26 -a_200 = 1.466904 -a_300 = 1.521782 -a_400 = 1.559186 -a_600 = 1.614585 -a_800 = 1.869936 -a_1200 = 2.128056 -a_1600 = 2.301275 -a_2400 = 2.529241 -a_3200 = 2.661983 -b_200 = 2.571104 -b_300 = 2.254217 -b_400 = 2.048674 -b_600 = 1.869559 -b_800 = 1.588649 -b_1200 = 1.507134 -b_1600 = 1.464374 -b_2400 = 1.436827 -b_3200 = 1.40521 -c_200 = 1.193958 -c_300 = 1.270316 -c_400 = 1.335191 -c_600 = 1.446266 -c_800 = 1.581345 -c_1200 = 1.79505 -c_1600 = 1.965613 -c_2400 = 2.237466 -c_3200 = 2.439729 -A_exp = 0.14 -a_exp = 0.06 - -[params.filter_params] - -[params.cosmo_params.H0] -value = 67.74 -unit = "km / (Mpc s)" - -[params.cosmo_params.Tcmb0] -value = 2.7255 -unit = "K" - -[params.cosmo_params.m_nu] -value = [ 0.0, 0.0, 0.06,] -unit = "eV" diff --git a/hmf_dndm.txt b/hmf_dndm.txt deleted file mode 100644 index 318297b0..00000000 --- a/hmf_dndm.txt +++ /dev/null @@ -1,500 +0,0 @@ -2.641378300251275688e-11 -2.528199430446134032e-11 -2.419788200019788986e-11 -2.315952238507770661e-11 -2.216525967487555841e-11 -2.121394419810399458e-11 -2.030375145277264744e-11 -1.943252728769268931e-11 -1.859841555442850577e-11 -1.780024037545444841e-11 -1.703649961710146371e-11 -1.630589611896644284e-11 -1.560716074180377017e-11 -1.493867016199004304e-11 -1.429850274903284985e-11 -1.368528313647543323e-11 -1.309793393797994445e-11 -1.253550948769421849e-11 -1.199737214808127443e-11 -1.148250672552949640e-11 -1.098968713320955448e-11 -1.051785326041090117e-11 -1.006634444056130400e-11 -9.634315411503668490e-12 -9.221029996806699880e-12 -8.825778913365039635e-12 -8.447647134586981509e-12 -8.085543394794546591e-12 -7.738673041120919234e-12 -7.406432848293228326e-12 -7.088282481312724547e-12 -6.783868182028715232e-12 -6.492625663933386763e-12 -6.213856968798961183e-12 -5.946956477548194825e-12 -5.691552559844983062e-12 -5.447169818675640379e-12 -5.213390249335879391e-12 -4.989817538228819255e-12 -4.775935905555905603e-12 -4.571125654391053187e-12 -4.374927331251404040e-12 -4.187003290654322111e-12 -4.007044682887099419e-12 -3.834855162016619272e-12 -3.670121444603836530e-12 -3.512446183126513402e-12 -3.361483320677028337e-12 -3.217023572434731169e-12 -3.078799703843432512e-12 -2.946574276862906542e-12 -2.820125885487562536e-12 -2.699163833191682060e-12 -2.583336229783204626e-12 -2.472377281626216382e-12 -2.366098045364428825e-12 -2.264321940091732652e-12 -2.166939926724888481e-12 -2.073778308193598686e-12 -1.984610873295815746e-12 -1.899239850271683804e-12 -1.817547238742329037e-12 -1.739382907864798190e-12 -1.664611944329757506e-12 -1.593110673052252645e-12 -1.524715299002365759e-12 -1.459226019505377819e-12 -1.396489013128620789e-12 -1.336398569516912773e-12 -1.278853716820064316e-12 -1.223793864224231720e-12 -1.171122843869696819e-12 -1.120711887257948552e-12 -1.072447960788589136e-12 -1.026264446056571380e-12 -9.820770601243396156e-13 -9.398091257899628476e-13 -8.993915708264173741e-13 -8.607321353175670866e-13 -8.237173903507061780e-13 -7.882582951076261748e-13 -7.542957106482147095e-13 -7.217719051456736470e-13 -6.906531850639846129e-13 -6.608863850082241841e-13 -6.323982239804004320e-13 -6.051241040581975569e-13 -5.790263587755176392e-13 -5.540577137964540036e-13 -5.301745811408007196e-13 -5.073383947081111450e-13 -4.854972058976356034e-13 -4.645866422667412903e-13 -4.445551554347582804e-13 -4.253696599270659542e-13 -4.069971589421924953e-13 -3.894188975464537043e-13 -3.726055310556159991e-13 -3.565153721553785672e-13 -3.411115124381680091e-13 -3.263726176771533077e-13 -3.122722033498580744e-13 -2.987854853836637063e-13 -2.858909392983821773e-13 -2.735593248502590154e-13 -2.617541300708925405e-13 -2.504455112088853087e-13 -2.396149587525689661e-13 -2.292436216408894197e-13 -2.193210500079945247e-13 -2.098310742425170686e-13 -2.007499922306539968e-13 -1.920567264751193746e-13 -1.837391673822869044e-13 -1.757825009871139327e-13 -1.681726318092233529e-13 -1.608975515097194512e-13 -1.539408102326008168e-13 -1.472817130420071767e-13 -1.409029835763555197e-13 -1.347942687779834733e-13 -1.289448031145587378e-13 -1.233487596690250850e-13 -1.179972438076167863e-13 -1.128767886382263047e-13 -1.079753660129080354e-13 -1.032860858005918338e-13 -9.880067777150671364e-14 -9.451112442078199674e-14 -9.041072832475231076e-14 -8.649024252564204025e-14 -8.273794686763029490e-14 -7.914384332891099803e-14 -7.570214219958198686e-14 -7.240669880200104861e-14 -6.925426105974027658e-14 -6.623994548417069568e-14 -6.335610717058802290e-14 -6.059588830779048791e-14 -5.795535893385080330e-14 -5.542991200741253493e-14 -5.301498738442849564e-14 -5.070685059380025209e-14 -4.850030894012380029e-14 -4.638873143912311451e-14 -4.436633580102793130e-14 -4.242988460291307781e-14 -4.057587314838444659e-14 -3.880248469450488340e-14 -3.710704366172973660e-14 -3.548521460720421125e-14 -3.393309194150753428e-14 -3.244842891649018309e-14 -3.102866505241623074e-14 -2.967120744307944641e-14 -2.837397408904433199e-14 -2.713405266172133820e-14 -2.594769596062183135e-14 -2.481156305338651819e-14 -2.372384374513201141e-14 -2.268254092698041026e-14 -2.168663874190416146e-14 -2.073467443190119869e-14 -1.982419263370223970e-14 -1.895297185989891108e-14 -1.811972514822427724e-14 -1.732303285851741685e-14 -1.656142145420132385e-14 -1.583373037619500609e-14 -1.513832867637371394e-14 -1.447310188777649032e-14 -1.383612216375465457e-14 -1.322637740114070218e-14 -1.264273088690804161e-14 -1.208461397682686679e-14 -1.155122874571717000e-14 -1.104118695020258777e-14 -1.055322682877515883e-14 -1.008660999400411047e-14 -9.640551408690747058e-15 -9.214214265645629318e-15 -8.806951787076149110e-15 -8.417852148256103569e-15 -8.045724366814427527e-15 -7.689457887259104069e-15 -7.348486815610991903e-15 -7.022165192895724927e-15 -6.710174221237952282e-15 -6.412079689787739532e-15 -6.127098274676419534e-15 -5.854514552736013100e-15 -5.593904343249561480e-15 -5.344834771587077353e-15 -5.106831074300226735e-15 -4.879532896805246751e-15 -4.662431472435868413e-15 -4.454857413510917408e-15 -4.256172383843193325e-15 -4.066059930277125712e-15 -3.884153761800058243e-15 -3.710274792785547693e-15 -3.544187323783480044e-15 -3.385450433211586200e-15 -3.233659304160039740e-15 -3.088570075590587028e-15 -2.949944762516463821e-15 -2.817514358165395799e-15 -2.691078153773810263e-15 -2.570352921439218655e-15 -2.454963411845468436e-15 -2.344543700707899081e-15 -2.238916819720975050e-15 -2.137875609338020216e-15 -2.041319235194698707e-15 -1.949120064692309138e-15 -1.861030638114478147e-15 -1.776822439130331637e-15 -1.696355260544341125e-15 -1.619498658143463223e-15 -1.546100476400306925e-15 -1.476048957677634894e-15 -1.409186859427944006e-15 -1.345304462363980633e-15 -1.284192695293207742e-15 -1.225752602090326362e-15 -1.169867392758545505e-15 -1.116480149439129878e-15 -1.065521922011535607e-15 -1.016854309321217692e-15 -9.703486694664232825e-16 -9.259244598783042541e-16 -8.835103930024146258e-16 -8.430205994808588527e-16 -8.043928748155363320e-16 -7.675401926137657815e-16 -7.323457690651031234e-16 -6.986906365118202754e-16 -6.665194749371905272e-16 -6.357666851023591201e-16 -6.064000632735247997e-16 -5.783824375728535706e-16 -5.516367146848661672e-16 -5.260907156059381669e-16 -5.016982536676385495e-16 -4.784204830856800206e-16 -4.562090836604557469e-16 -4.350294458149460131e-16 -4.148335761248741619e-16 -3.955567208067482880e-16 -3.771315231876064652e-16 -3.595270697146703236e-16 -3.427066710946234014e-16 -3.266520727297827713e-16 -3.113432655346571349e-16 -2.967375101755942455e-16 -2.827944663830018407e-16 -2.694877230049329372e-16 -2.567961728866347818e-16 -2.446927224627950430e-16 -2.331581273528174070e-16 -2.221660268219520076e-16 -2.116806964101016312e-16 -2.016642333436210007e-16 -1.920993769454458649e-16 -1.829657074385605317e-16 -1.742528637085286933e-16 -1.659500843157547950e-16 -1.580338072192285585e-16 -1.504815915816189721e-16 -1.432783954135261631e-16 -1.364127817319213630e-16 -1.298696246396199361e-16 -1.236382343498300328e-16 -1.177041977948304063e-16 -1.120479233624000924e-16 -1.066482371094339692e-16 -1.014955168565358513e-16 -9.657846234742457748e-17 -9.189118917251613991e-17 -8.742790882502948965e-17 -8.317571730608599351e-17 -7.912220103616234279e-17 -7.525883911766039736e-17 -7.157945031697375041e-17 -6.807563456896293617e-17 -6.474146368154575736e-17 -6.156909738006503665e-17 -5.854786746115387513e-17 -5.566604760193249871e-17 -5.291828698807930255e-17 -5.029837363355342733e-17 -4.780296712857143432e-17 -4.542895029132563943e-17 -4.316931115025261980e-17 -4.101722910500991325e-17 -3.896791054887292748e-17 -3.701802260149721100e-17 -3.516293069754787375e-17 -3.339935541075743592e-17 -3.172305658439636174e-17 -3.012827343900524398e-17 -2.860857911036494391e-17 -2.716100847412827609e-17 -2.578217323299636144e-17 -2.447018093196159378e-17 -2.322334967909669216e-17 -2.203790350062009346e-17 -2.091012564731697917e-17 -1.983734253580692962e-17 -1.881776113673976948e-17 -1.784884502660577435e-17 -1.692878649751409288e-17 -1.605530781979664572e-17 -1.522532867687447341e-17 -1.443537010839805054e-17 -1.368379714715105744e-17 -1.296877859008399610e-17 -1.228924647596859791e-17 -1.164429145265087908e-17 -1.103190103569208880e-17 -1.045007038616338481e-17 -9.897324039986761029e-18 -9.372699772542742626e-18 -8.874823149258716629e-18 -8.402702739706088357e-18 -7.955124842457732113e-18 -7.530461334756094799e-18 -7.126856496357829824e-18 -6.743415005215418549e-18 -6.379158021842150621e-18 -6.033486609908818250e-18 -5.705908368992590169e-18 -5.395363399813479345e-18 -5.100783756465201690e-18 -4.821365589966784691e-18 -4.556594290229051361e-18 -4.305733890683955681e-18 -4.068244720158776084e-18 -3.843486276665931212e-18 -3.630609677890424969e-18 -3.428642155286283796e-18 -3.237098037049443781e-18 -3.055460937030334384e-18 -2.883398058558442510e-18 -2.720642788301593112e-18 -2.566644698094502420e-18 -2.420843478105070244e-18 -2.282808019098182156e-18 -2.152264567664914017e-18 -2.028824627631697813e-18 -1.912197573477758946e-18 -1.802049393367088603e-18 -1.697944596029934527e-18 -1.599383624670365188e-18 -1.506106439990913105e-18 -1.417844840022955676e-18 -1.334416342171188948e-18 -1.255677030655296218e-18 -1.181345796760398484e-18 -1.111134020552686171e-18 -1.044814916823332006e-18 -9.822440457327936442e-19 -9.232198996407461359e-19 -8.675882509531052381e-19 -8.151775156601468996e-19 -7.657685485462373814e-19 -7.191109526929698700e-19 -6.750679252731121527e-19 -6.335027501342343756e-19 -5.943171669118164775e-19 -5.574341205640354262e-19 -5.227128978423611350e-19 -4.900081218556584729e-19 -4.592032830922112306e-19 -4.302231254786196945e-19 -4.029653717724415182e-19 -3.773497842397099052e-19 -3.532898974157734014e-19 -3.306779773841124304e-19 -3.093920582470180058e-19 -2.893618333441052932e-19 -2.705191724351470762e-19 -2.528124409766352523e-19 -2.362010040382990419e-19 -2.206161262624395965e-19 -2.059865701817891546e-19 -1.922541892110127302e-19 -1.793805125052721602e-19 -1.673150148690496795e-19 -1.560170395703008265e-19 -1.454440813039899118e-19 -1.355446752453649074e-19 -1.262613934869345000e-19 -1.175591938557854304e-19 -1.094050608834203910e-19 -1.017727150524968506e-19 -9.464124872289920560e-20 -8.797808795009632813e-20 -8.174949263396005260e-20 -7.592746075826454051e-20 -7.049286602719350530e-20 -6.542158455221527881e-20 -6.069371953262355429e-20 -5.628903991115575557e-20 -5.218382421653578855e-20 -4.835210701982270522e-20 -4.477709848524459392e-20 -4.144335630426777147e-20 -3.833804655168393344e-20 -3.545079796063451551e-20 -3.276675065233662439e-20 -3.027058792898414019e-20 -2.794940967040927295e-20 -2.579407258494737541e-20 -2.379354662070968163e-20 -2.193852607875572968e-20 -2.021978189340387481e-20 -1.862686155245439042e-20 -1.714858848297994559e-20 -1.577731398621772469e-20 -1.450613712569590796e-20 -1.332911463475673062e-20 -1.224135731307310627e-20 -1.123640911587911909e-20 -1.030767782694427081e-20 -9.449541977287737241e-21 -8.657858802885513407e-21 -7.927857411803243641e-21 -7.255433826404138310e-21 -6.636606599470358084e-21 -6.067026893076590138e-21 -5.542166589588067977e-21 -5.058758476908026733e-21 -4.613896303462759642e-21 -4.205009193605705346e-21 -3.829944390472211545e-21 -3.486068874732652773e-21 -3.170731000232185081e-21 -2.881647410212760158e-21 -2.617070863783683730e-21 -2.375080119997395115e-21 -2.153997433567477432e-21 -1.952226701358050147e-21 -1.768087319228471184e-21 -1.599878736610853042e-21 -1.446315286450357920e-21 -1.306264647393055504e-21 -1.178707549316497419e-21 -1.062777190465535834e-21 -9.574847624643569983e-22 -8.618520260666120071e-22 -7.750310620329310529e-22 -6.963510992805276563e-22 -6.251066754931952800e-22 -5.606757026696051240e-22 -5.024768767093172182e-22 -4.499198788596948867e-22 -4.024247779973049538e-22 -3.595359951593318857e-22 -3.208551376892722866e-22 -2.860206545015448785e-22 -2.547215823926846250e-22 -2.266244980021398788e-22 -2.014064908250574695e-22 -1.787869012164518273e-22 -1.585377573901208190e-22 -1.404291507600588203e-22 -1.242576023216304622e-22 -1.098362374667055425e-22 -9.698185301155591854e-23 -8.551975847536445375e-23 -7.530876697627307510e-23 -6.622619062025633667e-23 -5.816076451586706933e-23 -5.101624375882788138e-23 -4.469492160838728143e-23 -3.910444321706772237e-23 -3.416468863644073211e-23 -2.980940486311282580e-23 -2.597436152248221528e-23 -2.260288222423209957e-23 -1.964384432499255101e-23 -1.704882261700323753e-23 -1.477300418683833656e-23 -1.277953220314056400e-23 -1.103662615897111449e-23 -9.515719425965993116e-24 -8.192127910598171606e-24 -7.041985972081389781e-24 -6.043338137891051372e-24 -5.177276950281848488e-24 -4.428039538886027879e-24 -3.780911167671754929e-24 -3.223037058259271372e-24 -2.743054062274929585e-24 -2.330560963801296838e-24 -1.976222232715963185e-24 -1.672313254410106653e-24 -1.412248822907588022e-24 -1.190207217515051952e-24 diff --git a/hmf_m.txt b/hmf_m.txt deleted file mode 100644 index 6e138490..00000000 --- a/hmf_m.txt +++ /dev/null @@ -1,500 +0,0 @@ -1.000000000000000000e+10 -1.023292992280753708e+10 -1.047128548050898552e+10 -1.071519305237604904e+10 -1.096478196143182945e+10 -1.122018454301960754e+10 -1.148153621496879387e+10 -1.174897554939525414e+10 -1.202264434617408180e+10 -1.230268770812376022e+10 -1.258925411794161034e+10 -1.288249551693127060e+10 -1.318256738556399345e+10 -1.348962882591645050e+10 -1.380384264602875328e+10 -1.412537544622743988e+10 -1.445439770745916176e+10 -1.479108388168195152e+10 -1.513561248436194801e+10 -1.548816618912466812e+10 -1.584893192461097908e+10 -1.621810097358913231e+10 -1.659586907437542725e+10 -1.698243652461725235e+10 -1.737800828749354935e+10 -1.778279410038901138e+10 -1.819700858609960175e+10 -1.862087136662842941e+10 -1.905460717963220978e+10 -1.949844599758017731e+10 -1.995262314968850327e+10 -2.041737944669498444e+10 -2.089296130854006577e+10 -2.137962089502197647e+10 -2.187761623949515915e+10 -2.238721138568301010e+10 -2.290867652767732620e+10 -2.344228815319879532e+10 -2.398832919019445801e+10 -2.454708915684983444e+10 -2.511886431509530640e+10 -2.570395782768812180e+10 -2.630267991895327759e+10 -2.691534803926858902e+10 -2.754228703338106918e+10 -2.818382931264391708e+10 -2.884031503126540756e+10 -2.951209226666317749e+10 -3.019951720401945114e+10 -3.090295432513516235e+10 -3.162277660168301773e+10 -3.235936569296201706e+10 -3.311311214825826263e+10 -3.388441561391937256e+10 -3.467368504525224304e+10 -3.548133892335659027e+10 -3.630780547700914001e+10 -3.715352290971621704e+10 -3.801893963205503845e+10 -3.890451449942693329e+10 -3.981071705534854889e+10 -4.073802778041005707e+10 -4.168693834703227234e+10 -4.265795188015794373e+10 -4.365158322401522827e+10 -4.466835921509488678e+10 -4.570881896148602295e+10 -4.677351412871828461e+10 -4.786300923226223755e+10 -4.897788193684296417e+10 -5.011872336272550964e+10 -5.128613839913469696e+10 -5.248074602497540283e+10 -5.370317963702334595e+10 -5.495408738576045990e+10 -5.623413251903283691e+10 -5.754399373371354675e+10 -5.888436553555667114e+10 -6.025595860743346405e+10 -6.165950018614582825e+10 -6.309573444801684570e+10 -6.456542290346298218e+10 -6.606934480075694275e+10 -6.760829753919541931e+10 -6.918309709189079285e+10 -7.079457843841084290e+10 -7.244359600749594116e+10 -7.413102413008859253e+10 -7.585775750291510010e+10 -7.762471166286578369e+10 -7.943282347242463684e+10 -8.128305161640629578e+10 -8.317637711026335144e+10 -8.511380382023376465e+10 -8.709635899560404968e+10 -8.912509381337039185e+10 -9.120108393558666992e+10 -9.332543007969465637e+10 -9.549925860213900757e+10 -9.772372209557632446e+10 -9.999999999999508667e+10 -1.023292992280703430e+11 -1.047128548050847168e+11 -1.071519305237552185e+11 -1.096478196143128967e+11 -1.122018454301905670e+11 -1.148153621496822968e+11 -1.174897554939467773e+11 -1.202264434617349243e+11 -1.230268770812315674e+11 -1.258925411794099274e+11 -1.288249551693063812e+11 -1.318256738556334686e+11 -1.348962882591578827e+11 -1.380384264602807617e+11 -1.412537544622674561e+11 -1.445439770745845337e+11 -1.479108388168122559e+11 -1.513561248436120605e+11 -1.548816618912390747e+11 -1.584893192461020203e+11 -1.621810097358833618e+11 -1.659586907437461243e+11 -1.698243652461641846e+11 -1.737800828749269714e+11 -1.778279410038813782e+11 -1.819700858609870911e+11 -1.862087136662751465e+11 -1.905460717963127441e+11 -1.949844599757921753e+11 -1.995262314968752136e+11 -2.041737944669398193e+11 -2.089296130853904114e+11 -2.137962089502092590e+11 -2.187761623949408569e+11 -2.238721138568191223e+11 -2.290867652767620239e+11 -2.344228815319764404e+11 -2.398832919019328003e+11 -2.454708915684862976e+11 -2.511886431509407654e+11 -2.570395782768685913e+11 -2.630267991895198669e+11 -2.691534803926726685e+11 -2.754228703337971802e+11 -2.818382931264253540e+11 -2.884031503126399536e+11 -2.951209226666172485e+11 -3.019951720401796875e+11 -3.090295432513364258e+11 -3.162277660168146362e+11 -3.235936569296043091e+11 -3.311311214825664062e+11 -3.388441561391771240e+11 -3.467368504525054321e+11 -3.548133892335484619e+11 -3.630780547700735474e+11 -3.715352290971439209e+11 -3.801893963205317383e+11 -3.890451449942502441e+11 -3.981071705534660034e+11 -4.073802778040805664e+11 -4.168693834703022461e+11 -4.265795188015585327e+11 -4.365158322401308594e+11 -4.466835921509269409e+11 -4.570881896148377686e+11 -4.677351412871598511e+11 -4.786300923225988770e+11 -4.897788193684055786e+11 -5.011872336272304688e+11 -5.128613839913218384e+11 -5.248074602497282715e+11 -5.370317963702071533e+11 -5.495408738575776367e+11 -5.623413251903007812e+11 -5.754399373371071777e+11 -5.888436553555378418e+11 -6.025595860743050537e+11 -6.165950018614279785e+11 -6.309573444801374512e+11 -6.456542290345981445e+11 -6.606934480075369873e+11 -6.760829753919210205e+11 -6.918309709188740234e+11 -7.079457843840736084e+11 -7.244359600749239502e+11 -7.413102413008494873e+11 -7.585775750291137695e+11 -7.762471166286197510e+11 -7.943282347242073975e+11 -8.128305161640230713e+11 -8.317637711025926514e+11 -8.511380382022958984e+11 -8.709635899559976807e+11 -8.912509381336602783e+11 -9.120108393558220215e+11 -9.332543007969007568e+11 -9.549925860213431396e+11 -9.772372209557152100e+11 -9.999999999999018555e+11 -1.023292992280653198e+12 -1.047128548050795654e+12 -1.071519305237499634e+12 -1.096478196143075195e+12 -1.122018454301850586e+12 -1.148153621496766602e+12 -1.174897554939410156e+12 -1.202264434617290283e+12 -1.230268770812255371e+12 -1.258925411794037354e+12 -1.288249551693000488e+12 -1.318256738556270020e+12 -1.348962882591512695e+12 -1.380384264602739746e+12 -1.412537544622605225e+12 -1.445439770745774170e+12 -1.479108388168049805e+12 -1.513561248436046143e+12 -1.548816618912314941e+12 -1.584893192460942383e+12 -1.621810097358754150e+12 -1.659586907437379883e+12 -1.698243652461558594e+12 -1.737800828749184326e+12 -1.778279410038726318e+12 -1.819700858609781494e+12 -1.862087136662659912e+12 -1.905460717963033936e+12 -1.949844599757826172e+12 -1.995262314968654297e+12 -2.041737944669297852e+12 -2.089296130853801514e+12 -2.137962089501987549e+12 -2.187761623949301270e+12 -2.238721138568081543e+12 -2.290867652767507812e+12 -2.344228815319649414e+12 -2.398832919019210449e+12 -2.454708915684742188e+12 -2.511886431509284180e+12 -2.570395782768559570e+12 -2.630267991895069336e+12 -2.691534803926594727e+12 -2.754228703337836426e+12 -2.818382931264114746e+12 -2.884031503126257812e+12 -2.951209226666027832e+12 -3.019951720401648438e+12 -3.090295432513212891e+12 -3.162277660167991211e+12 -3.235936569295883789e+12 -3.311311214825501465e+12 -3.388441561391604492e+12 -3.467368504524884277e+12 -3.548133892335310547e+12 -3.630780547700557129e+12 -3.715352290971256836e+12 -3.801893963205130371e+12 -3.890451449942311523e+12 -3.981071705534464355e+12 -4.073802778040605469e+12 -4.168693834702817871e+12 -4.265795188015375977e+12 -4.365158322401094238e+12 -4.466835921509049805e+12 -4.570881896148153320e+12 -4.677351412871369141e+12 -4.786300923225753906e+12 -4.897788193683815430e+12 -5.011872336272058594e+12 -5.128613839912966797e+12 -5.248074602497025391e+12 -5.370317963701807617e+12 -5.495408738575506836e+12 -5.623413251902731445e+12 -5.754399373370790039e+12 -5.888436553555088867e+12 -6.025595860742754883e+12 -6.165950018613977539e+12 -6.309573444801065430e+12 -6.456542290345665039e+12 -6.606934480075045898e+12 -6.760829753918878906e+12 -6.918309709188400391e+12 -7.079457843840388672e+12 -7.244359600748883789e+12 -7.413102413008130859e+12 -7.585775750290765625e+12 -7.762471166285816406e+12 -7.943282347241684570e+12 -8.128305161639831055e+12 -8.317637711025517578e+12 -8.511380382022541016e+12 -8.709635899559549805e+12 -8.912509381336164062e+12 -9.120108393557771484e+12 -9.332543007968550781e+12 -9.549925860212962891e+12 -9.772372209556671875e+12 -9.999999999998527344e+12 -1.023292992280602930e+13 -1.047128548050744336e+13 -1.071519305237447070e+13 -1.096478196143021484e+13 -1.122018454301795508e+13 -1.148153621496710352e+13 -1.174897554939352539e+13 -1.202264434617231250e+13 -1.230268770812194922e+13 -1.258925411793975586e+13 -1.288249551692937305e+13 -1.318256738556205273e+13 -1.348962882591446289e+13 -1.380384264602672070e+13 -1.412537544622535938e+13 -1.445439770745703320e+13 -1.479108388167977344e+13 -1.513561248435971875e+13 -1.548816618912238867e+13 -1.584893192460864648e+13 -1.621810097358674414e+13 -1.659586907437298438e+13 -1.698243652461475195e+13 -1.737800828749099023e+13 -1.778279410038639062e+13 -1.819700858609692188e+13 -1.862087136662568750e+13 -1.905460717962940234e+13 -1.949844599757730469e+13 -1.995262314968556250e+13 -2.041737944669197656e+13 -2.089296130853699219e+13 -2.137962089501882812e+13 -2.187761623949193750e+13 -2.238721138567971484e+13 -2.290867652767395312e+13 -2.344228815319534375e+13 -2.398832919019092578e+13 -2.454708915684621875e+13 -2.511886431509160938e+13 -2.570395782768433594e+13 -2.630267991894940234e+13 -2.691534803926462500e+13 -2.754228703337701562e+13 -2.818382931263976562e+13 -2.884031503126116016e+13 -2.951209226665883203e+13 -3.019951720401500391e+13 -3.090295432513061328e+13 -3.162277660167835938e+13 -3.235936569295725000e+13 -3.311311214825338672e+13 -3.388441561391438281e+13 -3.467368504524714062e+13 -3.548133892335136719e+13 -3.630780547700378906e+13 -3.715352290971074219e+13 -3.801893963204943750e+13 -3.890451449942120312e+13 -3.981071705534268750e+13 -4.073802778040405469e+13 -4.168693834702613281e+13 -4.265795188015166406e+13 -4.365158322400879688e+13 -4.466835921508831250e+13 -4.570881896147928906e+13 -4.677351412871139062e+13 -4.786300923225518750e+13 -4.897788193683575000e+13 -5.011872336271812500e+13 -5.128613839912714844e+13 -5.248074602496767969e+13 -5.370317963701543750e+13 -5.495408738575236719e+13 -5.623413251902455469e+13 -5.754399373370507031e+13 -5.888436553554800000e+13 -6.025595860742459375e+13 -6.165950018613675000e+13 -6.309573444800755469e+13 -6.456542290345347656e+13 -6.606934480074721094e+13 -6.760829753918546875e+13 -6.918309709188060938e+13 -7.079457843840040625e+13 -7.244359600748528125e+13 -7.413102413007767188e+13 -7.585775750290393750e+13 -7.762471166285435938e+13 -7.943282347241293750e+13 -8.128305161639432812e+13 -8.317637711025109375e+13 -8.511380382022123438e+13 -8.709635899559121875e+13 -8.912509381335728125e+13 -9.120108393557325000e+13 -9.332543007968092188e+13 -9.549925860212493750e+13 -9.772372209556193750e+13 -9.999999999998035938e+13 -1.023292992280552656e+14 -1.047128548050692969e+14 -1.071519305237394531e+14 -1.096478196142967656e+14 -1.122018454301740469e+14 -1.148153621496653906e+14 -1.174897554939294844e+14 -1.202264434617172188e+14 -1.230268770812134531e+14 -1.258925411793913906e+14 -1.288249551692874062e+14 -1.318256738556140469e+14 -1.348962882591380156e+14 -1.380384264602604375e+14 -1.412537544622466562e+14 -1.445439770745632500e+14 -1.479108388167904688e+14 -1.513561248435897500e+14 -1.548816618912162812e+14 -1.584893192460786875e+14 -1.621810097358595000e+14 -1.659586907437216875e+14 -1.698243652461391875e+14 -1.737800828749013750e+14 -1.778279410038551875e+14 -1.819700858609602812e+14 -1.862087136662477188e+14 -1.905460717962846875e+14 -1.949844599757634688e+14 -1.995262314968458438e+14 -2.041737944669097500e+14 -2.089296130853596562e+14 -2.137962089501777812e+14 -2.187761623949086562e+14 -2.238721138567861562e+14 -2.290867652767282812e+14 -2.344228815319419375e+14 -2.398832919018974688e+14 -2.454708915684501562e+14 -2.511886431509037500e+14 -2.570395782768307500e+14 -2.630267991894811250e+14 -2.691534803926330625e+14 -2.754228703337566250e+14 -2.818382931263838125e+14 -2.884031503125974375e+14 -2.951209226665738125e+14 -3.019951720401351875e+14 -3.090295432512909375e+14 -3.162277660167680625e+14 -3.235936569295566250e+14 -3.311311214825176250e+14 -3.388441561391271875e+14 -3.467368504524543750e+14 -3.548133892334962500e+14 -3.630780547700200625e+14 -3.715352290970891875e+14 -3.801893963204757500e+14 -3.890451449941929375e+14 -3.981071705534073750e+14 -4.073802778040205625e+14 -4.168693834702408750e+14 -4.265795188014956875e+14 -4.365158322400665625e+14 -4.466835921508611875e+14 -4.570881896147705000e+14 -4.677351412870910000e+14 -4.786300923225283750e+14 -4.897788193683334375e+14 -5.011872336271566875e+14 -5.128613839912463125e+14 -5.248074602496510000e+14 -5.370317963701280625e+14 -5.495408738574966875e+14 -5.623413251902180000e+14 -5.754399373370225000e+14 -5.888436553554511250e+14 -6.025595860742163750e+14 -6.165950018613372500e+14 -6.309573444800446250e+14 -6.456542290345031250e+14 -6.606934480074397500e+14 -6.760829753918215000e+14 -6.918309709187721250e+14 -7.079457843839693750e+14 -7.244359600748172500e+14 -7.413102413007403750e+14 -7.585775750290021250e+14 -7.762471166285053750e+14 -7.943282347240905000e+14 -8.128305161639033750e+14 -8.317637711024701250e+14 -8.511380382021705000e+14 -8.709635899558695000e+14 -8.912509381335290000e+14 -9.120108393556877500e+14 -9.332543007967633750e+14 -9.549925860212025000e+14 -9.772372209555713750e+14 diff --git a/hmf_sigma.txt b/hmf_sigma.txt deleted file mode 100644 index 9639b61f..00000000 --- a/hmf_sigma.txt +++ /dev/null @@ -1,500 +0,0 @@ -2.281768024184851029e+00 -2.276184656950273055e+00 -2.270606566579973951e+00 -2.265033931068528794e+00 -2.259466919883088565e+00 -2.253905560402794439e+00 -2.248349760961377175e+00 -2.242799501932677408e+00 -2.237254850822361529e+00 -2.231715833545400152e+00 -2.226182399971586179e+00 -2.220654472596780504e+00 -2.215131887920624099e+00 -2.209614488762446705e+00 -2.204102275274641087e+00 -2.198595440946998991e+00 -2.193094165543960639e+00 -2.187598621696941414e+00 -2.182108842277617367e+00 -2.176624734992132826e+00 -2.171146277016788417e+00 -2.165673534999639216e+00 -2.160206538880731664e+00 -2.154745238797908247e+00 -2.149289558776330544e+00 -2.143839335912036237e+00 -2.138394409321507261e+00 -2.132954772365231566e+00 -2.127520618000774633e+00 -2.122092127897898362e+00 -2.116669477748524653e+00 -2.111252706020983361e+00 -2.105841719948749358e+00 -2.100436493393678994e+00 -2.095037092009982782e+00 -2.089643549805392908e+00 -2.084255817215710849e+00 -2.078873819713462190e+00 -2.073497395066744797e+00 -2.068126378695335443e+00 -2.062760757102683140e+00 -2.057400722448298858e+00 -2.052046458446559640e+00 -2.046698143745277143e+00 -2.041355822508398088e+00 -2.036019401656090633e+00 -2.030688851616029744e+00 -2.025364236910584648e+00 -2.020045595649035963e+00 -2.014732878599407861e+00 -2.009426012595334932e+00 -2.004124836149953293e+00 -1.998829180988561438e+00 -1.993539026690538840e+00 -1.988254564342037511e+00 -1.982975979844592507e+00 -1.977703454697099739e+00 -1.972437038852116631e+00 -1.967176639080918887e+00 -1.961922222254109727e+00 -1.956673851622289018e+00 -1.951431569421634427e+00 -1.946195326790633562e+00 -1.940965051834133925e+00 -1.935740583879528964e+00 -1.930521750956905258e+00 -1.925308525651389990e+00 -1.920101097691987668e+00 -1.914899655312202187e+00 -1.909704382757644758e+00 -1.904515335856751701e+00 -1.899332421400923510e+00 -1.894155602577878961e+00 -1.888984941224604031e+00 -1.883820483720783034e+00 -1.878662181617763105e+00 -1.873509964198298849e+00 -1.868363671669120762e+00 -1.863223128361840564e+00 -1.858088299793100084e+00 -1.852959374043328333e+00 -1.847836541823722367e+00 -1.842719990024085153e+00 -1.837609780430478956e+00 -1.832505820027180654e+00 -1.827408068190682133e+00 -1.822316585201254169e+00 -1.817231421588965112e+00 -1.812152529365157028e+00 -1.807079838893914436e+00 -1.802013191322628272e+00 -1.796952407277877750e+00 -1.791897445129801092e+00 -1.786848491011395978e+00 -1.781805738256832417e+00 -1.776769376301502001e+00 -1.771739472965137896e+00 -1.766715935600670084e+00 -1.761698719643133959e+00 -1.756687883672319872e+00 -1.751683482364275068e+00 -1.746685468244005612e+00 -1.741693772656331518e+00 -1.736708237748072481e+00 -1.731728680429193368e+00 -1.726755051842983724e+00 -1.721787535868107621e+00 -1.716826328606004592e+00 -1.711871621944457633e+00 -1.706923489807159910e+00 -1.701981840094484832e+00 -1.697046624167657836e+00 -1.692117898763204398e+00 -1.687195722684804444e+00 -1.682280049034352132e+00 -1.677370810031756809e+00 -1.672467848879880759e+00 -1.667570978755105848e+00 -1.662680143491981122e+00 -1.657795524398835596e+00 -1.652917320489027730e+00 -1.648045726013806167e+00 -1.643180821067714348e+00 -1.638322514279259234e+00 -1.633470752801626125e+00 -1.628625591388090488e+00 -1.623787092934867005e+00 -1.618955211196255073e+00 -1.614129879156520397e+00 -1.609310941128120120e+00 -1.604498206533146565e+00 -1.599691611813189196e+00 -1.594891335380754782e+00 -1.590097579307354403e+00 -1.585310540122395695e+00 -1.580530304156399612e+00 -1.575756780948663893e+00 -1.570989913308261654e+00 -1.566229753868879637e+00 -1.561476369566098921e+00 -1.556729714896363470e+00 -1.551989723492916973e+00 -1.547256240827492135e+00 -1.542529072544935431e+00 -1.537808147606521958e+00 -1.533093641194638090e+00 -1.528385758586356946e+00 -1.523684698508422475e+00 -1.518990553591433867e+00 -1.514303234471290782e+00 -1.509622679474592388e+00 -1.504948938983206919e+00 -1.500282083900876806e+00 -1.495622069570817336e+00 -1.490968830156419900e+00 -1.486322212334083126e+00 -1.481682017947399954e+00 -1.477048168385903359e+00 -1.472420835260139560e+00 -1.467800227200677599e+00 -1.463186545055825682e+00 -1.458579887821028098e+00 -1.453980167418445157e+00 -1.449387317551611210e+00 -1.444801386222301920e+00 -1.440222448214602435e+00 -1.435650459837886972e+00 -1.431085355664786896e+00 -1.426526983617284916e+00 -1.421975141713632818e+00 -1.417429743676124954e+00 -1.412890957194576913e+00 -1.408358994401841313e+00 -1.403834058197739987e+00 -1.399316254009530081e+00 -1.394805495239049176e+00 -1.390301710825635473e+00 -1.385804946265349891e+00 -1.381315280120010369e+00 -1.376832669799691766e+00 -1.372357050163666603e+00 -1.367888270416730556e+00 -1.363426124727654232e+00 -1.358970519052457027e+00 -1.354521616804281292e+00 -1.350079633767951481e+00 -1.345644774831934232e+00 -1.341217151924603002e+00 -1.336796680125986958e+00 -1.332383283470147228e+00 -1.327977004823886586e+00 -1.323577926410063776e+00 -1.319186006890641139e+00 -1.314801181287104770e+00 -1.310423300121423607e+00 -1.306052153689181150e+00 -1.301687640077406671e+00 -1.297329918060395215e+00 -1.292979207224524973e+00 -1.288635714394526399e+00 -1.284299558070719049e+00 -1.279970655216849273e+00 -1.275648924821082497e+00 -1.271334406999443889e+00 -1.267027187506305497e+00 -1.262727226424153804e+00 -1.258434458811042767e+00 -1.254148736538524211e+00 -1.249869846006575802e+00 -1.245597677327039854e+00 -1.241332384267026079e+00 -1.237074190364131576e+00 -1.232823304340426862e+00 -1.228579851340459994e+00 -1.224343750425447963e+00 -1.220114915398916366e+00 -1.215893383506052805e+00 -1.211679243892094027e+00 -1.207472458246675373e+00 -1.203272961538901731e+00 -1.199080607020968081e+00 -1.194895177177459189e+00 -1.190716554035616159e+00 -1.186544885980416186e+00 -1.182380400651484864e+00 -1.178223308645348411e+00 -1.174073741825020001e+00 -1.169931621573073510e+00 -1.165796856372965706e+00 -1.161669480478917604e+00 -1.157549586278339149e+00 -1.153437137273137569e+00 -1.149332068219342862e+00 -1.145234233780083821e+00 -1.141143412509267208e+00 -1.137059478236524201e+00 -1.132982573583400487e+00 -1.128912930444100127e+00 -1.124850761284905687e+00 -1.120796204764434423e+00 -1.116749184822521501e+00 -1.112709604490760507e+00 -1.108677494910824901e+00 -1.104652951558602103e+00 -1.100635939971695620e+00 -1.096626394571622809e+00 -1.092624171462162508e+00 -1.088629045256263250e+00 -1.084640881469340234e+00 -1.080659816572512977e+00 -1.076686086868362979e+00 -1.072719906707485293e+00 -1.068761421626312602e+00 -1.064810558370717253e+00 -1.060867214392639202e+00 -1.056931417596728151e+00 -1.053003266390662551e+00 -1.049082728590162716e+00 -1.045169738164893003e+00 -1.041264152688018640e+00 -1.037365742826954262e+00 -1.033474365661825711e+00 -1.029590151122300457e+00 -1.025713340073797886e+00 -1.021844148785840956e+00 -1.017982729762135330e+00 -1.014129012817384989e+00 -1.010282889700708564e+00 -1.006444384950190951e+00 -1.002613599748027884e+00 -9.987905044506135699e-01 -9.949750324626751574e-01 -9.911670428551883072e-01 -9.873663023511162207e-01 -9.835726594690281654e-01 -9.797862372018707466e-01 -9.760072811338043053e-01 -9.722360095087421161e-01 -9.684725818955283172e-01 -9.647169314547241470e-01 -9.609689441152754474e-01 -9.572286409117429784e-01 -9.534961256452688660e-01 -9.497713714962041642e-01 -9.460543111954496931e-01 -9.423448053404355207e-01 -9.386426167157716494e-01 -9.349475851474136068e-01 -9.312598262908333702e-01 -9.275795906069225216e-01 -9.239070983917131441e-01 -9.202425163863445778e-01 -9.165857813885054384e-01 -9.129367733975386479e-01 -9.092955097974704248e-01 -9.056620968563167118e-01 -9.020365108823231726e-01 -8.984186838284056176e-01 -8.948084778476880219e-01 -8.912056517962652080e-01 -8.876100366710489853e-01 -8.840217403839216725e-01 -8.804410184310867971e-01 -8.768680932619521418e-01 -8.733031389074680240e-01 -8.697460961076290964e-01 -8.661968388317136114e-01 -8.626553806529964064e-01 -8.591218301588431361e-01 -8.555961671090265286e-01 -8.520783225804932082e-01 -8.485681603109010984e-01 -8.450654352397983793e-01 -8.415699693915269508e-01 -8.380818625235347819e-01 -8.346013753235627108e-01 -8.311287325204294030e-01 -8.276641155633119862e-01 -8.242074694547022462e-01 -8.207586620402059774e-01 -8.173177029074365496e-01 -8.138847028198720190e-01 -8.104596453311508908e-01 -8.070424605521987482e-01 -8.036330138311762461e-01 -8.002310562044666620e-01 -7.968364005708962194e-01 -7.934491381174482161e-01 -7.900695348735353729e-01 -7.866978180004101651e-01 -7.833341765038880355e-01 -7.799785599856255969e-01 -7.766308300765507600e-01 -7.732909921881127024e-01 -7.699591591190477757e-01 -7.666353185761854983e-01 -7.633193996215505983e-01 -7.600112692339774378e-01 -7.567106745591688499e-01 -7.534174192030712591e-01 -7.501315853591997707e-01 -7.468534445349565010e-01 -7.435832265058182067e-01 -7.403211279783904475e-01 -7.370671035047620112e-01 -7.338210084073016892e-01 -7.305828437105399420e-01 -7.273527241048708403e-01 -7.241306418247425158e-01 -7.209165248013200689e-01 -7.177102416564886678e-01 -7.145115356520720384e-01 -7.113202009131804893e-01 -7.081363102074182958e-01 -7.049601406359118361e-01 -7.017919248006150301e-01 -6.986318672567676247e-01 -6.954799278718553079e-01 -6.923359555626696915e-01 -6.891999467311923366e-01 -6.860720178136939795e-01 -6.829521659630078956e-01 -6.798403178977353578e-01 -6.767363438882673110e-01 -6.736399833153019490e-01 -6.705510206111949811e-01 -6.674695186766013144e-01 -6.643957602999152057e-01 -6.613299811568177367e-01 -6.582723938032787325e-01 -6.552229638026580982e-01 -6.521815335661673707e-01 -6.491480946089133175e-01 -6.461227649657824701e-01 -6.431055471138251711e-01 -6.400963664759803384e-01 -6.370950949675386887e-01 -6.341014680860560526e-01 -6.311152603271181771e-01 -6.281365242716069330e-01 -6.251655484602224311e-01 -6.222025719238564179e-01 -6.192478153720395451e-01 -6.163012504566708349e-01 -6.133627129757737162e-01 -6.104321892564433805e-01 -6.075097987799938926e-01 -6.045955497638285658e-01 -6.016893662463829173e-01 -5.987911217711451295e-01 -5.959005479433344687e-01 -5.930174090386738373e-01 -5.901417468481867656e-01 -5.872738557000805049e-01 -5.844139782953051698e-01 -5.815623436511404565e-01 -5.787189299130982567e-01 -5.758835661512012871e-01 -5.730562331637641948e-01 -5.702370517213886103e-01 -5.674260362099771138e-01 -5.646231091894574616e-01 -5.618281458031165743e-01 -5.590408737472140066e-01 -5.562610467542981052e-01 -5.534886953334449133e-01 -5.507241196064752708e-01 -5.479675662943872538e-01 -5.452192728762920160e-01 -5.424792244111766859e-01 -5.397472431167572582e-01 -5.370233038778177148e-01 -5.343075285903058358e-01 -5.315999382490457226e-01 -5.289004538349056928e-01 -5.262089520508340668e-01 -5.235251566599132822e-01 -5.208488104862928347e-01 -5.181799322396469787e-01 -5.155188278144566816e-01 -5.128657483432622621e-01 -5.102209399230110964e-01 -5.075843949693601420e-01 -5.049559287177218803e-01 -5.023355097117435664e-01 -4.997232608077949445e-01 -4.971192100683828330e-01 -4.945232767957932762e-01 -4.919353392053869567e-01 -4.893551171009360434e-01 -4.867823419938057117e-01 -4.842170202506542176e-01 -4.816594634950825959e-01 -4.791099277092167319e-01 -4.765686677689935924e-01 -4.740356839176293469e-01 -4.715107842727326304e-01 -4.689939305630283495e-01 -4.664852464351936789e-01 -4.639847674962415680e-01 -4.614924112700959369e-01 -4.590080574245025691e-01 -4.565314217711354816e-01 -4.540622240586054126e-01 -4.516004577290795852e-01 -4.491464400634057053e-01 -4.467004323739903748e-01 -4.442626984784450173e-01 -4.418332469424730014e-01 -4.394118786209548766e-01 -4.369985478998082984e-01 -4.345933790330752666e-01 -4.321964156667145729e-01 -4.298075734456432984e-01 -4.274267334122421880e-01 -4.250536073451928187e-01 -4.226879027310149195e-01 -4.203295994562512572e-01 -4.179790203542376736e-01 -4.156364325880513300e-01 -4.133021090726193281e-01 -4.109760672073149435e-01 -4.086581004150200425e-01 -4.063481551349564236e-01 -4.040463560052401926e-01 -4.017527551987430390e-01 -3.994672663485803743e-01 -3.971897717372609993e-01 -3.949199790216779138e-01 -3.926575828292536152e-01 -3.904025487548321016e-01 -3.881552049949761329e-01 -3.859158250733817908e-01 -3.836846911004280214e-01 -3.814618297886389620e-01 -3.792470268843738390e-01 -3.770402201524230557e-01 -3.748415343070823358e-01 -3.726510304990519051e-01 -3.704686201566719239e-01 -3.682941865944104887e-01 -3.661274332021398070e-01 -3.639680410502381114e-01 -3.618159606043101495e-01 -3.596715251679540870e-01 -3.575350151585026670e-01 -3.554067219624785223e-01 -3.532866821026554582e-01 -3.511746733836033085e-01 -3.490706240994644882e-01 -3.469746587122550796e-01 -3.448868478384979896e-01 -3.428071005188947917e-01 -3.407353008927825888e-01 -3.386711479569566863e-01 -3.366143084934853924e-01 -3.345647169623747752e-01 -3.325227115161836222e-01 -3.304885800921394945e-01 -3.284626234767689668e-01 diff --git a/pyproject.toml b/pyproject.toml index 1cd983f7..de321d7b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,172 @@ [build-system] -requires = ["setuptools>=42", "wheel", "setuptools_scm[toml]>=3.4"] -build-backend = "setuptools.build_meta" +requires = ["hatchling", "uv-dynamic-versioning"] +build-backend = "hatchling.build" -[tool.setuptools_scm] +[tool.hatch.version] +source = "uv-dynamic-versioning" + +[project] +name = "hmf" +description = "A halo mass function calculator" +requires-python = ">=3.11" +authors = [{name = "Steven Murray", email = "murray.steveng@gmail.com"}] +license = "MIT" +urls = {Documentation = "https://hmf.readthedocs.org"} + +# Add here all kinds of additional classifiers as defined under +# https://pypi.python.org/pypi?%3Aaction=list_classifiers +classifiers = [ + "Development Status :: 6 - Mature", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Intended Audience :: Science/Research", + "License :: OSI Approved", + "License :: OSI Approved :: MIT License", + "Natural Language :: English", + "Topic :: Scientific/Engineering :: Physics", + "Topic :: Scientific/Engineering :: Astronomy" +] +dynamic = ["version"] + +dependencies = [ + "numpy>=1.6.2", + "scipy>=0.12.0", + "astropy>=1.1", + "deprecation", + "click", + "toml>=0.10.1", + "rich", + "cached_property", + "camb>=1.0.0" +] + +[project.optional-dependencies] +docs = [ + "Sphinx>=1.7.5", + "numpydoc>=0.8.0", + "nbsphinx" +] + +tests = [ + "coverage>=4.5.1", + "pytest>=3.5.1", + "pytest-cov>=2.5.1", + "mpmath>=1.0.0", + "colossus>=1.2.1", + "halomod>=1.4.6", + "numba", +] + +dev = [ + "hmf[docs,tests]", + "ruff", + "pre-commit", +] +cosmo = [ + "colossus>=1.2.1" +] +fit = [ + "emcee>=3.0" +] +all = [ + "hmf[dev,cosmo,fit]" +] + +[project.scripts] +hmf = "hmf._cli:main" + +[tool.pytest.ini_options] +addopts = [ + "--cov=hmf", + "--cov-report=term-missing", + "--verbose" +] +norecursedirs = [ + "dist", + "build", + ".tox" +] +testpaths = [ + "tests" +] + + + +[tool.ruff] +# exclude = [ +# "*.ipynb", # for now +# ] +line-length=88 +target-version="py311" + +[tool.ruff.lint] +extend-select = [ + "UP", # pyupgrade + "E", # pycodestyle + "W", # pycodestyle warning + "F", # pyflakes + "C90", # mccabe complexity + "I", # isort + "N", # pep8-naming + "D", # docstyle + # "ANN" # type annotations + "B", # bugbear + "A", # builtins + "C4", # comprehensions + "DTZ", # datetime + "FA", # future annotations + "PIE", # flake8-pie + "T", # print statements + "PT", # pytest-style + "Q", # quotes + "SIM", # simplify + "PTH", # use Pathlib + "ERA", # kill commented code + "NPY", # numpy-specific rules + "PERF", # performance + # "FURB", # refurb + "RUF", # ruff-specific rules + "RET", # return statements + "RSE", # exception raises + "TRY201", # verbose raise +] +# ignore = [ +# # "DTZ007", # use %z in strptime +# # "DTZ001", # require tzinfo in datetime +# # "B008", # do not performa function call in argument defaults +# # "PTH207", # allow glob.glob() because when we use it, it's necessary +# # "A003", # class attribute shadowing builtins +# # "RUF009", # don;e perform function call in dataclass defaults +# # "N806", # Variable name should be lower case. We have some single-letter variables that make more sense to be caps. +# # "D401", # First line should be in imperative mood -- cached_properties don't fit this bill. +# # "N815", +# # "N807", # Allow method names to start and end with __ +# # "RUF012", # mutable class attributes annotation +# # # The rest should be un-commented when possible... +# # "PTH123", +# # "PT011", +# # "A005", # module name shadows builtin +# # "RUF067", # allow defining new variables in __Init__ files +# ] + +[tool.ruff.lint.per-file-ignores] +"tests/*.py" = [ + "D1", + "T", # print statements +] +"docs/conf.py" = [ + "A", # conf.py can shadow builtins + "ERA", + "DTZ", +] +"**/*.ipynb" = [ + "T201", "DTZ", "D", "PTH119", "ERA" +] + +[tool.ruff.lint.pydocstyle] +convention = 'numpy' +property-decorators = ["pytest.fixture"] + +[tool.ruff.lint.mccabe] +max-complexity = 21 \ No newline at end of file diff --git a/requirements_dev.txt b/requirements_dev.txt deleted file mode 100644 index 2b57360a..00000000 --- a/requirements_dev.txt +++ /dev/null @@ -1,19 +0,0 @@ -colossus>=1.2.1 -coverage==4.5.1 -coveralls -cryptography==42.0.4 -flake8==2.6.0 -halomod @ git+git://github.com/steven-murray/hmf.git@unit-tests -mpmath==1.3.0 -nbsphinx -numpydoc==0.8.0 -pip -pytest==3.5.1 -pytest-cov==2.5.1 -pytest-runner==4.2 -PyYAML==5.4 -Sphinx==1.7.5 -sphinx_rtd_theme -sympy==1.1.1 -tox==3.0.0 -wheel==0.38.1 diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 2a181dbd..00000000 --- a/setup.cfg +++ /dev/null @@ -1,119 +0,0 @@ -# This file is used to configure your project. -# Read more about the various options under: -# http://setuptools.readthedocs.io/en/latest/setuptools.html#configuring-setup-using-setup-cfg-files - -[metadata] -name = hmf -description = A halo mass function calculator -author = Steven Murray -author_email = steven.g.murray@asu.edu -license = mit -long_description = file: README.rst -long_description_content_type = text/x-rst; charset=UTF-8 -url = https://github.com/steven-murray/hmf -project_urls = - Documentation = https://hmf.readthedocs.org -# Change if running only on Windows, Mac or Linux (comma-separated) -platforms = any -# Add here all kinds of additional classifiers as defined under -# https://pypi.python.org/pypi?%3Aaction=list_classifiers -classifiers = - Development Status :: 6 - Mature - Programming Language :: Python :: 3.8 - Programming Language :: Python :: 3.9 - Programming Language :: Python :: 3.10 - Intended Audience :: Science/Research - License :: OSI Approved - License :: OSI Approved :: MIT License - Natural Language :: English - Topic :: Scientific/Engineering :: Physics - Topic :: Scientific/Engineering :: Astronomy - -[options] -zip_safe = False -packages = find: -include_package_data = True -package_dir = - =src -# Add here dependencies of your project (semicolon/line-separated), e.g. -install_requires = - numpy>=1.6.2 - scipy>=0.12.0 - astropy>=1.1 - deprecation - click - toml>=0.10.1 - rich - deprecation - importlib_metadata; python_version<'3.8' - cached_property - camb>=1.0.0 - -[options.packages.find] -where = src -exclude = - tests - -[options.extras_require] -# Add here additional requirements for extra features, to install with: -# `pip install cal_coefficients[PDF]` like: -# PDF = ReportLab; RXP -# Add here test requirements (semicolon/line-separated) -docs = - Sphinx>=1.7.5 - numpydoc>=0.8.0 - nbsphinx -tests = - coverage>=4.5.1 - pytest>=3.5.1 - pytest-cov>=2.5.1 - pre-commit - mpmath>=1.0.0 - colossus>=1.2.1 - halomod>=1.4.6 - numba -dev = - hmf[docs,tests] - setuptools_scm -cosmo = - colossus>=1.2.1 -fit = - emcee>=3.0 -all = - hmf[dev,cosmo,fit] - -[options.entry_points] -# Add here console scripts like: -console_scripts = - hmf = hmf._cli:main - -[tool:pytest] -# Options for py.test: -# Specify command line options as you would do when invoking py.test directly. -# e.g. --cov-report html (or xml) for html/xml output or --junitxml junit.xml -# in order to write a coverage file that can be read by Jenkins. -addopts = - --cov hmf --cov-report term-missing - --verbose -norecursedirs = - dist - build - .tox -testpaths = tests - -[aliases] -dists = bdist_wheel - -[bdist_wheel] -# Use this option if your package is pure-python -universal = 1 - -[build_sphinx] -source_dir = docs -build_dir = build/sphinx - -[devpi:upload] -# Options for the devpi: PyPI server and packaging tool -# VCS export must be deactivated since we are using setuptools-scm -no-vcs = 1 -formats = bdist_wheel diff --git a/src/hmf/_cli.py b/src/hmf/_cli.py index 8d95cd1f..e550098a 100644 --- a/src/hmf/_cli.py +++ b/src/hmf/_cli.py @@ -1,17 +1,18 @@ """Module that contains the command line app.""" -import click import importlib +from pathlib import Path +from time import time + +import click import numpy as np import toml from astropy.units import Quantity -from pathlib import Path from rich import box from rich.console import Console from rich.panel import Panel from rich.rule import Rule from rich.table import Table -from time import time import hmf from hmf.helpers.functional import get_hmf diff --git a/src/hmf/_internals/_cache.py b/src/hmf/_internals/_cache.py index c6b67e7e..e7324365 100644 --- a/src/hmf/_internals/_cache.py +++ b/src/hmf/_internals/_cache.py @@ -10,6 +10,7 @@ import warnings from copy import deepcopy from functools import update_wrapper + from numpy import array_equal @@ -93,7 +94,7 @@ def _get_property(self): return getattr(self, prop) # Otherwise, if its in recalc, and needs updating, just update it - elif name in recalc: + if name in recalc: value = f(self) setattr(self, prop, value) @@ -324,9 +325,11 @@ def _get_property(self): def subframework(f): """ A quantity that is essentially a sub-framework + Parameters ---------- f + Returns ------- """ diff --git a/src/hmf/_internals/_framework.py b/src/hmf/_internals/_framework.py index 936af196..e6f5e70c 100644 --- a/src/hmf/_internals/_framework.py +++ b/src/hmf/_internals/_framework.py @@ -1,11 +1,11 @@ """Classes defining the overall structure of the hmf framework.""" import copy -import deprecation import logging import sys import warnings -from typing import Dict, List, Optional, Type, Union + +import deprecation logger = logging.getLogger(__name__) @@ -39,17 +39,17 @@ def __init__(self, **model_params): self.params.update(model_params) @classmethod - def get_models(cls) -> Dict[str, Type]: + def get_models(cls) -> dict[str, type]: """Get a dictionary of all implemented models for this component.""" return cls._plugins -def get_base_components() -> List[Type[Component]]: +def get_base_components() -> list[type[Component]]: """Get a list of classes defining base components.""" return Component.__subclasses__() -def get_base_component(name: [str, Type[Component]]) -> Type[Component]: +def get_base_component(name: [str, type[Component]]) -> type[Component]: """Return an actual class representing a component. Parameters @@ -75,12 +75,11 @@ def get_base_component(name: [str, Type[Component]]) -> Type[Component]: f"More than one component called '{name}'. Returning {avail[-1]}." ) return avail[-1] - else: - try: - assert issubclass(name, Component) - return name - except TypeError: - raise ValueError(f"{name} must be str or a Component subclass") + try: + assert issubclass(name, Component) + return name + except TypeError: + raise ValueError(f"{name} must be str or a Component subclass") def pluggable(cls): @@ -99,9 +98,9 @@ def init_sc(kls, abstract=False): def get_mdl( - name: Union[str, Type[Component]], - kind: Optional[Union[str, Type[Component]]] = None, -) -> Type[Component]: + name: str | type[Component], + kind: str | type[Component] | None = None, +) -> type[Component]: """Return a defined model with given name. Parameters @@ -219,7 +218,6 @@ class Framework(metaclass=_Validator): def validate(self): """Perform validation of the input parameters as they relate to each other.""" - pass def update(self, **kwargs): """ diff --git a/src/hmf/alternatives/wdm.py b/src/hmf/alternatives/wdm.py index 63363217..cf648218 100644 --- a/src/hmf/alternatives/wdm.py +++ b/src/hmf/alternatives/wdm.py @@ -158,7 +158,6 @@ def m_hm(self): class Bode01(Viel05): """The WDM model of Bode et al. (2001).""" - pass viel_model = Viel05(mx=1.0) @@ -193,7 +192,6 @@ def __init__(self, m, dndm0, wdm=viel_model, **model_parameters): def dndm_alter(self): """Alter the CDM dn/dm to impose WDM modeling.""" - pass class Schneider12_vCDM(WDMRecalibrateMF): diff --git a/src/hmf/cosmology/cosmo.py b/src/hmf/cosmology/cosmo.py index c4b5b045..fabcf20e 100644 --- a/src/hmf/cosmology/cosmo.py +++ b/src/hmf/cosmology/cosmo.py @@ -11,9 +11,10 @@ may be used as inputs. """ +import sys + import astropy.units as u import deprecation -import sys from astropy.cosmology import ( # noqa FLRW, WMAP5, @@ -92,8 +93,7 @@ def cosmo_model(self, val): raise ValueError( "cosmo_model must be an instance of astropy.cosmology.FLRW" ) - else: - return val + return val @_cache.parameter("param") def cosmo_params(self, val): @@ -147,5 +147,4 @@ def get_cosmo(name): """ if isinstance(getattr(sys.modules[__name__], name), FLRW): return getattr(sys.modules[__name__], name) - else: - raise ValueError("%s is not a valid cosmology" % name) + raise ValueError("%s is not a valid cosmology" % name) diff --git a/src/hmf/cosmology/growth_factor.py b/src/hmf/cosmology/growth_factor.py index 65adfaaa..5f2dbc8c 100644 --- a/src/hmf/cosmology/growth_factor.py +++ b/src/hmf/cosmology/growth_factor.py @@ -7,11 +7,11 @@ may be implemented. """ +from functools import cached_property + import numpy as np from astropy import cosmology -from functools import cached_property from scipy.interpolate import InterpolatedUnivariateSpline as _spline -from typing import Union from .._internals._framework import Component as Cmpt from .._internals._framework import pluggable @@ -89,7 +89,7 @@ def integral(self): a, 2.5 * self.cosmo.Om0 / (a * self.cosmo.efunc(self._zvec)) ** 3 ).antiderivative() - def _d_plus(self, z: Union[float, np.ndarray]) -> Union[float, np.ndarray]: + def _d_plus(self, z: float | np.ndarray) -> float | np.ndarray: r""" Finds the factor :math:`D^+(a)`, from Lukic et. al. 2007, eq. 8. @@ -154,7 +154,6 @@ def growth_factor_fn(self, zmin=0.0, inverse=False): The normalised growth factor as a function of redshift, or redshift as a function of growth factor if ``inverse`` is True. """ - if not inverse: return self.growth_factor @@ -327,7 +326,7 @@ def _d_plus(self, z): This is not implemented in this class. It is not required to calculate :meth:`growth_factor`. """ - raise NotImplementedError() # pragma: nocover + raise NotImplementedError # pragma: nocover def _general_case(self, w, x): x = np.atleast_1d(x) @@ -365,24 +364,23 @@ def growth_factor(self, z): if self.cosmo.Om0 == 1: return a - elif self.cosmo.Ode0 > 0: + if self.cosmo.Ode0 > 0: xn = (2.0 * w) ** (1.0 / 3) aofxn = self._general_case(w, xn) x = a * xn aofx = self._general_case(w, x) return aofx / aofxn - else: - dn = ( - 1 - + 3 / w - + (3 * ((1 + w) ** 0.5) / w**1.5) * np.log((1 + w) ** 0.5 - w**0.5) - ) - x = w * a - return ( - 1 - + 3 / x - + (3 * ((1 + x) ** 0.5) / x**1.5) * np.log((1 + x) ** 0.5 - x**0.5) - ) / dn + dn = ( + 1 + + 3 / w + + (3 * ((1 + w) ** 0.5) / w**1.5) * np.log((1 + w) ** 0.5 - w**0.5) + ) + x = w * a + return ( + 1 + + 3 / x + + (3 * ((1 + x) ** 0.5) / x**1.5) * np.log((1 + x) ** 0.5 - x**0.5) + ) / dn @_inherit @@ -520,8 +518,7 @@ def growth_factor(self, z): ) if len(growth) == 1: return growth[0] - else: - return growth + return growth def __getstate__(self): dct = self.__dict__.copy() diff --git a/src/hmf/density_field/filters.py b/src/hmf/density_field/filters.py index b006ead5..2006d984 100644 --- a/src/hmf/density_field/filters.py +++ b/src/hmf/density_field/filters.py @@ -1,9 +1,10 @@ """A module containing various smoothing filter Component models.""" import collections +import warnings + import numpy as np import scipy.integrate as intg -import warnings from scipy.interpolate import InterpolatedUnivariateSpline as _spline from .._internals import _framework, _utils @@ -74,7 +75,6 @@ def real_space(self, R, r): r : array_like The radial co-ordinate """ - pass def k_space(self, kr): r""" @@ -90,7 +90,6 @@ def k_space(self, kr): w : array_like The filter in fourier space, ``len(kr)`` """ - pass def mass_to_radius(self, m, rho_mean): r""" @@ -112,7 +111,6 @@ def mass_to_radius(self, m, rho_mean): ----- The units of `m` don't matter as long as they are consistent with `rho_mean`. """ - pass def radius_to_mass(self, r, rho_mean): r""" @@ -134,7 +132,6 @@ def radius_to_mass(self, r, rho_mean): ----- The units of `r` don't matter as long as they are consistent with `rho_mean`. """ - pass def dw_dlnkr(self, kr): r""" @@ -152,7 +149,6 @@ def dw_dlnkr(self, kr): .. math:: w\frac{dw}{d\ln r} = \frac{2}{r}\frac{dw^2}{dm}\frac{dm}{dr}. """ - pass def dlnss_dlnr(self, r): r""" diff --git a/src/hmf/density_field/halofit.py b/src/hmf/density_field/halofit.py index cc6cb7c8..7249b3fc 100644 --- a/src/hmf/density_field/halofit.py +++ b/src/hmf/density_field/halofit.py @@ -7,19 +7,19 @@ been modified to improve its integration with this package. """ -import numpy as np import warnings + +import numpy as np from scipy.integrate import simpson as _simps from scipy.interpolate import InterpolatedUnivariateSpline as _spline from scipy.optimize import minimize -from typing import Tuple from ..cosmology.cosmo import Cosmology as csm def _get_spec( k: np.ndarray, delta_k: np.ndarray, sigma_8=None -) -> Tuple[float, float, float]: +) -> tuple[float, float, float]: """ Calculate nonlinear wavenumber, effective spectral index and curvature of the power spectrum. diff --git a/src/hmf/density_field/transfer.py b/src/hmf/density_field/transfer.py index 6ff83bab..faa29812 100644 --- a/src/hmf/density_field/transfer.py +++ b/src/hmf/density_field/transfer.py @@ -88,9 +88,9 @@ def __init__( # =========================================================================== def validate(self): super().validate() - assert ( - self.lnk_min < self.lnk_max - ), f"lnk_min >= lnk_max: {self.lnk_min}, {self.lnk_max}" + assert self.lnk_min < self.lnk_max, ( + f"lnk_min >= lnk_max: {self.lnk_min}, {self.lnk_max}" + ) assert len(self.k) > 1, f"len(k) < 2: {len(self.k)}" @parameter("model") @@ -291,8 +291,7 @@ def growth_factor(self): r"""The growth factor.""" if self.use_splined_growth: return self._growth_factor_fn(self.z) - else: - return self.growth.growth_factor(self.z) + return self.growth.growth_factor(self.z) @cached_quantity def power(self): diff --git a/src/hmf/density_field/transfer_models.py b/src/hmf/density_field/transfer_models.py index 8b2717e5..9f80a573 100644 --- a/src/hmf/density_field/transfer_models.py +++ b/src/hmf/density_field/transfer_models.py @@ -5,11 +5,12 @@ in :mod:`hmf.transfer`. """ -import numpy as np import pickle import warnings -from astropy import cosmology from copy import deepcopy + +import numpy as np +from astropy import cosmology from scipy.interpolate import InterpolatedUnivariateSpline as spline from .._internals._framework import Component, pluggable @@ -60,7 +61,6 @@ def lnt(self, lnk): lnt : array_like The log of the transfer function at lnk. """ - pass class FromFile(TransferComponent): @@ -254,7 +254,6 @@ def lnt(self, lnk): lnt : array_like The log of the transfer function at lnk. """ - camb_transfers = camb.get_transfer_functions(self.params["camb_params"]) T = camb_transfers.get_matter_transfer_data().transfer_data T = np.log(T[[0, 6], :, 0]) @@ -507,7 +506,7 @@ def _set_params(self): 1.0 + (45.0 * self.Omh2) ** (-0.582) ) self.alpha_c = alpha_c_a1 ** (-self.f_baryon) * alpha_c_a2 ** ( - -self.f_baryon**3 + -(self.f_baryon**3) ) beta_c_b1 = 0.944 / (1.0 + (458.0 * self.Omh2) ** -0.708) @@ -784,7 +783,6 @@ def lnt(self, lnk): lnt : array_like The log of the transfer function at lnk. """ - scale = (0.3 * 0.75**2) / (self.cosmo.Om0 * self.cosmo.h) a = self.params["a"] * scale @@ -798,4 +796,3 @@ def lnt(self, lnk): class EH(EH_BAO): """Alias of :class:`EH_BAO`.""" - pass diff --git a/src/hmf/halos/mass_definitions.py b/src/hmf/halos/mass_definitions.py index 2a11b00a..40833240 100644 --- a/src/hmf/halos/mass_definitions.py +++ b/src/hmf/halos/mass_definitions.py @@ -4,12 +4,12 @@ https://bdiemer.bitbucket.io/colossus/halo_mass_defs.html """ +import warnings + import astropy.units as u import numpy as np import scipy as sp -import warnings from astropy.cosmology import Planck15 -from typing import Optional from .._internals import _framework from ..cosmology import Cosmology @@ -214,8 +214,6 @@ def __eq__(self, other): class SphericalOverdensity(MassDefinition): """An abstract base class for all spherical overdensity mass definitions.""" - pass - def __str__(self): """Describe the overdensity in standard notation.""" return f"{self.__class__.__name__}({self.params['overdensity']})" @@ -224,7 +222,7 @@ def __str__(self): class SOGeneric(SphericalOverdensity): """A generic SO definition which can claim equality with any SO.""" - def __init__(self, preferred: Optional[SphericalOverdensity] = None, **kwargs): + def __init__(self, preferred: SphericalOverdensity | None = None, **kwargs): super().__init__(**kwargs) self.preferred = preferred @@ -319,14 +317,13 @@ def __str__(self): def from_colossus_name(name): if name == "vir": return SOVirial() - elif name.endswith("c"): + if name.endswith("c"): return SOCritical(overdensity=int(name[:-1])) - elif name.endswith("m"): + if name.endswith("m"): return SOMean(overdensity=int(name[:-1])) - elif name == "fof": + if name == "fof": return FOF() - else: - raise ValueError(f"name '{name}' is an unknown mass definition to colossus.") + raise ValueError(f"name '{name}' is an unknown mass definition to colossus.") def _find_new_concentration(rho_s, halo_density, h=None, x_guess=5.0): @@ -353,7 +350,6 @@ def _find_new_concentration(rho_s, halo_density, h=None, x_guess=5.0): The radius in units of the scale radius, :math:`x=r/r_{\\rm s}`, where the enclosed density reaches ``density_threshold``. """ - # A priori, we have no idea at what radius the result will come out, but we need to # provide lower and upper limits for the root finder. To balance stability and # performance, we do so iteratively: if there is no result within relatively @@ -393,4 +389,3 @@ def fnc(x): class OptimizationException(Exception): """Exception class related to failed optimization.""" - pass diff --git a/src/hmf/helpers/cfg_utils.py b/src/hmf/helpers/cfg_utils.py index a7b41376..631afe60 100644 --- a/src/hmf/helpers/cfg_utils.py +++ b/src/hmf/helpers/cfg_utils.py @@ -1,9 +1,10 @@ """Utilities for interacting with hmf TOML configs.""" -from astropy.units import Quantity from datetime import datetime from inspect import signature +from astropy.units import Quantity + from hmf._internals._framework import Framework from .. import __version__ @@ -11,7 +12,6 @@ def framework_to_dict(obj: Framework) -> dict: """Serialize a framework instance to a simple TOML-able dictionary.""" - out = {"created_on": datetime.now(), "hmf_version": __version__, "params": {}} for k, v in obj.parameter_values.items(): diff --git a/src/hmf/helpers/functional.py b/src/hmf/helpers/functional.py index 2f00b193..9b4a3723 100644 --- a/src/hmf/helpers/functional.py +++ b/src/hmf/helpers/functional.py @@ -196,8 +196,10 @@ def get_hmf( for vv in v: x.update(**{k: vv}) if get_label: - yield [getattr(x, a) for a in req_qauntities], x, _make_label( - {k: vv}, kind=label_kind, **label_kwargs + yield ( + [getattr(x, a) for a in req_qauntities], + x, + _make_label({k: vv}, kind=label_kind, **label_kwargs), ) else: yield [getattr(x, a) for a in req_qauntities], x diff --git a/src/hmf/mass_function/fitting_functions.py b/src/hmf/mass_function/fitting_functions.py index 36bf4d7f..dfe8b0ed 100644 --- a/src/hmf/mass_function/fitting_functions.py +++ b/src/hmf/mass_function/fitting_functions.py @@ -5,12 +5,12 @@ listed here, please advise via GitHub. """ -import numpy as np -import scipy.special as sp import warnings from copy import copy + +import numpy as np +import scipy.special as sp from scipy.interpolate import InterpolatedUnivariateSpline as _spline -from typing import Union from .._internals import _framework from ..cosmology import cosmo as csm @@ -117,19 +117,20 @@ def _makedoc(pdocs, lname, sname, eq, ref): %s mass function fit. For details on attributes, see documentation for :class:`FittingFunction`. - """ % lname + """ + % lname + pdocs - + r""" + + rf""" Notes ----- - The {} [1]_ form is: + The {lname} [1]_ form is: - .. math:: f_{{\rm {}}}(\sigma) = {} + .. math:: f_{{\rm {sname}}}(\sigma) = {eq} References ---------- - .. [1] {} - """.format(lname, sname, eq, ref) + .. [1] {ref} + """ ) @@ -219,10 +220,10 @@ class FittingFunction(_framework.Component): def __init__( self, nu2: np.ndarray, - m: Union[None, np.ndarray] = None, + m: None | np.ndarray = None, z: float = 0.0, - n_eff: Union[None, np.ndarray] = None, - mass_definition: Union[None, md.MassDefinition] = None, + n_eff: None | np.ndarray = None, + mass_definition: None | md.MassDefinition = None, cosmo: csm.FLRW = csm.Planck15, delta_c: float = 1.686, **model_parameters, @@ -320,7 +321,6 @@ def cutmask(self): @property def fsigma(self): r"""The function :math:`f(\sigma)\equiv\nu f(\nu)`.""" - pass class PS(FittingFunction): @@ -409,7 +409,6 @@ def norm(self): class ST(SMT): """Alias of :class:`SMT`.""" - pass class Jenkins(FittingFunction): @@ -454,7 +453,7 @@ def fsigma(self): A = self.params["A"] b = self.params["b"] c = self.params["c"] - return A * np.exp(-np.abs(self.lnsigma + b) ** c) + return A * np.exp(-(np.abs(self.lnsigma + b) ** c)) class Warren(FittingFunction): @@ -1304,8 +1303,7 @@ def __init__(self, **model_parameters): raise ValueError( "The Tinker fitting function is a spherical-overdensity function." ) - else: - delta_halo = self.mass_definition.halo_overdensity_mean(self.z, self.cosmo) + delta_halo = self.mass_definition.halo_overdensity_mean(self.z, self.cosmo) if delta_halo not in self.delta_virs: A_array = np.array([self.params["A_%s" % d] for d in self.delta_virs]) @@ -1348,10 +1346,9 @@ def cutmask(self): return np.logical_and( self.lnsigma / np.log(10) > -0.6, self.lnsigma / np.log(10) < 0.4 ) - else: - return np.logical_and( - self.lnsigma / np.log(10) > -0.2, self.lnsigma / np.log(10) < 0.4 - ) + return np.logical_and( + self.lnsigma / np.log(10) > -0.2, self.lnsigma / np.log(10) < 0.4 + ) class Tinker10(FittingFunction): @@ -1482,42 +1479,37 @@ def __init__(self, **model_parameters): if self.gamma <= 0: if self.terminate: raise ValueError("gamma must be > 0, got " + str(self.gamma)) - else: - self.gamma = 1e-3 + self.gamma = 1e-3 # eta >-0.5 if self.eta <= -0.5: if self.terminate: raise ValueError("eta must be > -0.5, got " + str(self.eta)) - else: - self.eta = -0.499 + self.eta = -0.499 # eta-phi >-0.5 if self.eta - self.phi <= -0.5: if self.terminate: raise ValueError( "eta-phi must be > -0.5, got " + str(self.eta - self.phi) ) - else: - self.phi = self.eta + 0.499 + self.phi = self.eta + 0.499 if self.beta <= 0: if self.terminate: raise ValueError("beta must be > 0, got " + str(self.beta)) - else: - self.beta = 1e-3 + self.beta = 1e-3 @property def normalise(self): if int(self.delta_halo) in self.delta_virs and self.z == 0: return self.params["alpha_%s" % (int(self.delta_halo))] - else: - return 1 / ( - 2 ** (self.eta - self.phi - 0.5) - * self.beta ** (-2 * self.phi) - * self.gamma ** (-0.5 - self.eta) - * ( - 2**self.phi * self.beta ** (2 * self.phi) * sp.gamma(self.eta + 0.5) - + self.gamma**self.phi * sp.gamma(0.5 + self.eta - self.phi) - ) + return 1 / ( + 2 ** (self.eta - self.phi - 0.5) + * self.beta ** (-2 * self.phi) + * self.gamma ** (-0.5 - self.eta) + * ( + 2**self.phi * self.beta ** (2 * self.phi) * sp.gamma(self.eta + 0.5) + + self.gamma**self.phi * sp.gamma(0.5 + self.eta - self.phi) ) + ) @property def fsigma(self): @@ -1535,29 +1527,25 @@ def cutmask(self): return np.logical_and( self.lnsigma / np.log(10) > -0.6, self.lnsigma / np.log(10) < 0.4 ) - else: - return np.logical_and( - self.lnsigma / np.log(10) > -0.2, self.lnsigma / np.log(10) < 0.4 - ) + return np.logical_and( + self.lnsigma / np.log(10) > -0.2, self.lnsigma / np.log(10) < 0.4 + ) class Behroozi(Tinker08): _ref = r"""Behroozi, P., Weschler, R. and Conroy, C., ApJ, 2013, http://arxiv.org/abs/1207.6105""" - __doc__ = r""" + __doc__ = rf""" Behroozi mass function fit [1]_. This is an empirical modification to the :class:`Tinker08` fit, to improve accuracy at high redshift. - {} + {FittingFunction._pdocs} References ---------- - .. [1] {} - """.format( - FittingFunction._pdocs, - _ref, - ) + .. [1] {_ref} + """ normalized = False sim_definition = SimDetails( diff --git a/src/hmf/mass_function/hmf.py b/src/hmf/mass_function/hmf.py index 60603f9a..97e129e7 100644 --- a/src/hmf/mass_function/hmf.py +++ b/src/hmf/mass_function/hmf.py @@ -6,11 +6,12 @@ """ import copy -import numpy as np import warnings +from typing import Any + +import numpy as np from scipy.interpolate import InterpolatedUnivariateSpline as spline from scipy.optimize import minimize -from typing import Any, Dict, Optional, Union from .._internals._cache import cached_quantity, parameter from .._internals._framework import get_mdl @@ -99,13 +100,13 @@ def __init__( Mmin: float = 10.0, Mmax: float = 15.0, dlog10m: float = 0.01, - hmf_model: Union[str, ff.FittingFunction] = ff.Tinker08, - hmf_params: Optional[Dict[str, Any]] = None, - mdef_model: Union[None, str, md] = None, - mdef_params: Union[dict, None] = None, + hmf_model: str | ff.FittingFunction = ff.Tinker08, + hmf_params: dict[str, Any] | None = None, + mdef_model: None | str | md = None, + mdef_params: dict | None = None, delta_c: float = 1.686, - filter_model: Union[str, Filter] = TopHat, - filter_params: Union[dict, None] = None, + filter_model: str | Filter = TopHat, + filter_params: dict | None = None, disable_mass_conversion: bool = True, **transfer_kwargs, ): @@ -412,8 +413,8 @@ def mass_nonlinear(self): else: startr = np.log(self.radii.max()) - model = ( - lambda lnr: ( + model = lambda lnr: ( + ( self.filter.sigma(np.exp(lnr)) * self._normalisation * self.growth_factor @@ -432,12 +433,10 @@ def mass_nonlinear(self): if res.success: r = np.exp(res.x[0]) return self.filter.radius_to_mass(r, self.mean_density0) - else: - warnings.warn("Minimization failed :(") - return 0 - else: - nu = spline(self.nu, self.m, k=5) - return nu(1) + warnings.warn("Minimization failed :(") + return 0 + nu = spline(self.nu, self.m, k=5) + return nu(1) @cached_quantity def lnsigma(self): diff --git a/src/hmf/mass_function/integrate_hmf.py b/src/hmf/mass_function/integrate_hmf.py index 5fe6d13b..b1bfb830 100644 --- a/src/hmf/mass_function/integrate_hmf.py +++ b/src/hmf/mass_function/integrate_hmf.py @@ -10,7 +10,6 @@ class NaNException(Exception): """Integrator hit a NaN.""" - pass def hmf_integral_gtm(m, dndm, mass_density=False): diff --git a/tests/conftest.py b/tests/conftest.py index 25bb6308..172098d5 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,7 +1,7 @@ -import pytest - from pathlib import Path +import pytest + @pytest.fixture(scope="session") def datadir(): diff --git a/tests/test_cli.py b/tests/test_cli.py index 42cf7b98..b05c0328 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -1,8 +1,8 @@ -import pytest +from pathlib import Path import numpy as np +import pytest from click.testing import CliRunner -from pathlib import Path from hmf._cli import main diff --git a/tests/test_cosmo.py b/tests/test_cosmo.py index e39a99bb..7de8d313 100644 --- a/tests/test_cosmo.py +++ b/tests/test_cosmo.py @@ -1,7 +1,6 @@ -import pytest - import deprecation import numpy as np +import pytest from astropy.cosmology import WMAP7 from hmf.cosmology.cosmo import Cosmology, astropy_to_colossus diff --git a/tests/test_fcoll.py b/tests/test_fcoll.py index 8233d0ea..95ca4b06 100644 --- a/tests/test_fcoll.py +++ b/tests/test_fcoll.py @@ -4,9 +4,8 @@ As such, it is the best test of all calculations after sigma. """ -import pytest - import numpy as np +import pytest from scipy.special import erfc from hmf import MassFunction diff --git a/tests/test_filters.py b/tests/test_filters.py index fa20e2a0..3331e798 100644 --- a/tests/test_filters.py +++ b/tests/test_filters.py @@ -2,10 +2,10 @@ Analytic functions for this test are defined in "analytic_filter.ipynb" in the development/ directory. """ -import pytest +import warnings import numpy as np -import warnings +import pytest from numpy import cos, pi, sin from hmf.density_field import filters diff --git a/tests/test_fits.py b/tests/test_fits.py index 3abda5f5..37985c92 100644 --- a/tests/test_fits.py +++ b/tests/test_fits.py @@ -1,9 +1,9 @@ -import pytest -from pytest import raises - import inspect import itertools + import numpy as np +import pytest +from pytest import raises from hmf import MassFunction from hmf.mass_function import fitting_functions as ff @@ -12,10 +12,12 @@ o for n, o in inspect.getmembers( ff, - lambda member: inspect.isclass(member) - and issubclass(member, ff.FittingFunction) - and member is not ff.FittingFunction - and member is not ff.PS, + lambda member: ( + inspect.isclass(member) + and issubclass(member, ff.FittingFunction) + and member is not ff.FittingFunction + and member is not ff.PS + ), ) ] diff --git a/tests/test_framework.py b/tests/test_framework.py index 99819842..c95b8aa9 100644 --- a/tests/test_framework.py +++ b/tests/test_framework.py @@ -1,7 +1,6 @@ import pytest -from pytest import raises - from deprecation import fail_if_not_removed +from pytest import raises import hmf from hmf import GrowthFactor, MassFunction diff --git a/tests/test_genmf.py b/tests/test_genmf.py index 08062e58..5bde3a5d 100644 --- a/tests/test_genmf.py +++ b/tests/test_genmf.py @@ -42,11 +42,11 @@ 'transfer__kmax':100.0 """ -import pytest +from itertools import product import numpy as np +import pytest from astropy.cosmology import LambdaCDM -from itertools import product from hmf import MassFunction diff --git a/tests/test_growth.py b/tests/test_growth.py index aec9aa25..b1f6fe3a 100644 --- a/tests/test_growth.py +++ b/tests/test_growth.py @@ -1,7 +1,7 @@ -import pytest - import copy + import numpy as np +import pytest from astropy.cosmology import Planck13, w0waCDM from hmf.cosmology import growth_factor diff --git a/tests/test_hmf.py b/tests/test_hmf.py index e0195518..8be18a0e 100644 --- a/tests/test_hmf.py +++ b/tests/test_hmf.py @@ -1,10 +1,9 @@ """Tests of HMF.""" +import numpy as np import pytest from pytest import raises -import numpy as np - from hmf import MassFunction diff --git a/tests/test_mdef.py b/tests/test_mdef.py index 204fc1be..f127a979 100644 --- a/tests/test_mdef.py +++ b/tests/test_mdef.py @@ -1,6 +1,5 @@ -import pytest - import numpy as np +import pytest from colossus.cosmology.cosmology import setCosmology # require colossus for this test diff --git a/tests/test_transfer.py b/tests/test_transfer.py index 72455692..316994a4 100644 --- a/tests/test_transfer.py +++ b/tests/test_transfer.py @@ -1,7 +1,6 @@ -import pytest - import camb import numpy as np +import pytest from astropy.cosmology import FlatLambdaCDM, LambdaCDM, w0waCDM, wCDM from hmf.density_field.transfer import Transfer diff --git a/tests/test_wcdm.py b/tests/test_wcdm.py index 2e3701eb..9e8e1533 100644 --- a/tests/test_wcdm.py +++ b/tests/test_wcdm.py @@ -1,6 +1,5 @@ -import pytest - import numpy as np +import pytest from astropy.cosmology import FlatLambdaCDM, FlatwCDM from hmf.cosmology.growth_factor import CambGrowth diff --git a/tests/test_wdm.py b/tests/test_wdm.py index 9424a841..7a5c01c0 100644 --- a/tests/test_wdm.py +++ b/tests/test_wdm.py @@ -1,6 +1,5 @@ -from pytest import raises - import numpy as np +from pytest import raises import hmf from hmf.alternatives import wdm diff --git a/uv.lock b/uv.lock new file mode 100644 index 00000000..dd0d4402 --- /dev/null +++ b/uv.lock @@ -0,0 +1,1893 @@ +version = 1 +revision = 3 +requires-python = ">=3.11" +resolution-markers = [ + "python_full_version >= '3.12'", + "python_full_version < '3.12'", +] + +[[package]] +name = "alabaster" +version = "1.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a6/f8/d9c74d0daf3f742840fd818d69cfae176fa332022fd44e3469487d5a9420/alabaster-1.0.0.tar.gz", hash = "sha256:c00dca57bca26fa62a6d7d0a9fcce65f3e026e9bfe33e9c538fd3fbb2144fd9e", size = 24210, upload-time = "2024-07-26T18:15:03.762Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/b3/6b4067be973ae96ba0d615946e314c5ae35f9f993eca561b356540bb0c2b/alabaster-1.0.0-py3-none-any.whl", hash = "sha256:fc6786402dc3fcb2de3cabd5fe455a2db534b371124f1f21de8731783dec828b", size = 13929, upload-time = "2024-07-26T18:15:02.05Z" }, +] + +[[package]] +name = "astropy" +version = "7.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "astropy-iers-data" }, + { name = "numpy" }, + { name = "packaging" }, + { name = "pyerfa" }, + { name = "pyyaml" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/7b/92/2dce2d48347efc3346d08ca7995b152d242ebd170c571f7c9346468d8427/astropy-7.2.0.tar.gz", hash = "sha256:ae48bc26b1feaeb603cd94bd1fa1aa39137a115fe931b7f13787ab420e8c3070", size = 7057774, upload-time = "2025-11-25T22:36:41.916Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b4/6d/6330a844bad8dfc4875e0f2fa1db1fee87837ba9805aa8a8d048c071363a/astropy-7.2.0-cp311-abi3-macosx_10_9_x86_64.whl", hash = "sha256:efac04df4cc488efe630c2fff1992d6516dfb16a06e197fb68bc9e8e3b85def1", size = 6442332, upload-time = "2025-11-25T22:36:23.6Z" }, + { url = "https://files.pythonhosted.org/packages/a6/ba/3418133ba144dfcd1530bca5a6b695f4cdd21a8abaaa2ac4e5450d11b028/astropy-7.2.0-cp311-abi3-macosx_11_0_arm64.whl", hash = "sha256:52e9a7d9c86b21f1af911a2930cd0c4a275fb302d455c89e11eedaffef6f2ad0", size = 6413656, upload-time = "2025-11-25T22:36:26.548Z" }, + { url = "https://files.pythonhosted.org/packages/be/ba/05e43b5a7d738316a097fa78524d3eaaff5986294b4a052d4adb3c45e7c0/astropy-7.2.0-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:97c370421b9bb13d4c762c7af06d172bad7c01bd5bcf88314f6913c3c235b770", size = 9758867, upload-time = "2025-11-25T22:36:28.661Z" }, + { url = "https://files.pythonhosted.org/packages/c3/1c/f06ad85180e7dd9855aa5ede901bfc2be858d7bee17d4e978a14c0ecec14/astropy-7.2.0-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2f39ce2c80211fbceb005d377a5478cd0d66c42aa1498d252f2239fe5a025c24", size = 9789007, upload-time = "2025-11-25T22:36:31.063Z" }, + { url = "https://files.pythonhosted.org/packages/f8/fb/e4d35194a5009d7a73333079481a4ef1380a255d67b9c1db578151a5fb50/astropy-7.2.0-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:ad4d71db994d45f046a1a5449000cf0f88ab6367cb67658500654a0586d6ab19", size = 9748547, upload-time = "2025-11-25T22:36:33.154Z" }, + { url = "https://files.pythonhosted.org/packages/36/ea/f990730978ae0a7a34705f885d2f3806928c5f0bc22eefd6a1a23539cc32/astropy-7.2.0-cp311-abi3-win32.whl", hash = "sha256:95161f26602433176483e8bde8ab1a8ca09148f5b4bf5190569a26d381091598", size = 6237228, upload-time = "2025-11-25T22:36:35.236Z" }, + { url = "https://files.pythonhosted.org/packages/ec/bc/f4378f586dd63902c37d16f68f35f7d555b3b32e08ac6b1d633eb0a48805/astropy-7.2.0-cp311-abi3-win_amd64.whl", hash = "sha256:dc7c340ba1713e55c93071b32033f3153470a0f663a4d539c03a7c9b44020790", size = 6362868, upload-time = "2025-11-25T22:36:37.784Z" }, + { url = "https://files.pythonhosted.org/packages/77/79/b6d4bf01913cfd4ce0cd4c1be5916beccdb92b2970bab8c827984231eae6/astropy-7.2.0-cp311-abi3-win_arm64.whl", hash = "sha256:0c428735a3f15b05c2095bc6ccb5f98a64bc99fb7015866af19ff8492420ddaf", size = 6221756, upload-time = "2025-11-25T22:36:39.852Z" }, +] + +[[package]] +name = "astropy-iers-data" +version = "0.2026.2.16.0.48.25" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/dc/ce/9aed8765e4dcb2e12afd545c7ce63f2b9bcad592afcb9a0d5437d872060d/astropy_iers_data-0.2026.2.16.0.48.25.tar.gz", hash = "sha256:be14512844e71536a15e165d729385f3cb4865d7822172509e68c4ac79322067", size = 1926145, upload-time = "2026-02-16T00:49:11.138Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/49/94/dcdac330d2c26776956555610ef584147584acc6b060e451aa65dd9142d9/astropy_iers_data-0.2026.2.16.0.48.25-py3-none-any.whl", hash = "sha256:180d1c3f59d18aa616345560799c2d88ec6e5164b8c45c746380acf892946136", size = 1982562, upload-time = "2026-02-16T00:49:09.602Z" }, +] + +[[package]] +name = "attrs" +version = "25.4.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/6b/5c/685e6633917e101e5dcb62b9dd76946cbb57c26e133bae9e0cd36033c0a9/attrs-25.4.0.tar.gz", hash = "sha256:16d5969b87f0859ef33a48b35d55ac1be6e42ae49d5e853b597db70c35c57e11", size = 934251, upload-time = "2025-10-06T13:54:44.725Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3a/2a/7cc015f5b9f5db42b7d48157e23356022889fc354a2813c15934b7cb5c0e/attrs-25.4.0-py3-none-any.whl", hash = "sha256:adcf7e2a1fb3b36ac48d97835bb6d8ade15b8dcce26aba8bf1d14847b57a3373", size = 67615, upload-time = "2025-10-06T13:54:43.17Z" }, +] + +[[package]] +name = "babel" +version = "2.18.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7d/b2/51899539b6ceeeb420d40ed3cd4b7a40519404f9baf3d4ac99dc413a834b/babel-2.18.0.tar.gz", hash = "sha256:b80b99a14bd085fcacfa15c9165f651fbb3406e66cc603abf11c5750937c992d", size = 9959554, upload-time = "2026-02-01T12:30:56.078Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/77/f5/21d2de20e8b8b0408f0681956ca2c69f1320a3848ac50e6e7f39c6159675/babel-2.18.0-py3-none-any.whl", hash = "sha256:e2b422b277c2b9a9630c1d7903c2a00d0830c409c59ac8cae9081c92f1aeba35", size = 10196845, upload-time = "2026-02-01T12:30:53.445Z" }, +] + +[[package]] +name = "beautifulsoup4" +version = "4.14.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "soupsieve" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c3/b0/1c6a16426d389813b48d95e26898aff79abbde42ad353958ad95cc8c9b21/beautifulsoup4-4.14.3.tar.gz", hash = "sha256:6292b1c5186d356bba669ef9f7f051757099565ad9ada5dd630bd9de5fa7fb86", size = 627737, upload-time = "2025-11-30T15:08:26.084Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1a/39/47f9197bdd44df24d67ac8893641e16f386c984a0619ef2ee4c51fbbc019/beautifulsoup4-4.14.3-py3-none-any.whl", hash = "sha256:0918bfe44902e6ad8d57732ba310582e98da931428d231a5ecb9e7c703a735bb", size = 107721, upload-time = "2025-11-30T15:08:24.087Z" }, +] + +[[package]] +name = "bleach" +version = "6.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "webencodings" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/07/18/3c8523962314be6bf4c8989c79ad9531c825210dd13a8669f6b84336e8bd/bleach-6.3.0.tar.gz", hash = "sha256:6f3b91b1c0a02bb9a78b5a454c92506aa0fdf197e1d5e114d2e00c6f64306d22", size = 203533, upload-time = "2025-10-27T17:57:39.211Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cd/3a/577b549de0cc09d95f11087ee63c739bba856cd3952697eec4c4bb91350a/bleach-6.3.0-py3-none-any.whl", hash = "sha256:fe10ec77c93ddf3d13a73b035abaac7a9f5e436513864ccdad516693213c65d6", size = 164437, upload-time = "2025-10-27T17:57:37.538Z" }, +] + +[package.optional-dependencies] +css = [ + { name = "tinycss2" }, +] + +[[package]] +name = "cached-property" +version = "2.0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/76/4b/3d870836119dbe9a5e3c9a61af8cc1a8b69d75aea564572e385882d5aefb/cached_property-2.0.1.tar.gz", hash = "sha256:484d617105e3ee0e4f1f58725e72a8ef9e93deee462222dbd51cd91230897641", size = 10574, upload-time = "2024-10-25T15:43:55.667Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/11/0e/7d8225aab3bc1a0f5811f8e1b557aa034ac04bdf641925b30d3caf586b28/cached_property-2.0.1-py3-none-any.whl", hash = "sha256:f617d70ab1100b7bcf6e42228f9ddcb78c676ffa167278d9f730d1c2fba69ccb", size = 7428, upload-time = "2024-10-25T15:43:54.711Z" }, +] + +[[package]] +name = "camb" +version = "1.6.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, + { name = "packaging" }, + { name = "scipy" }, + { name = "sympy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/91/06/92e52a466195a97d26dafba1c4197e753a724793cb2b4a34800e975e3ab3/camb-1.6.5.tar.gz", hash = "sha256:402c14e76faf541a383bdc5a0fcc56e5d8fdf1636fc9a8fa082ab0fa8a0c4a05", size = 796973, upload-time = "2025-11-10T14:25:25.421Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/42/13/5aa1b8ea0812cda841215ed2773765bbc0b2ae50bb44314fca4c86e6fb05/camb-1.6.5-py3-none-macosx_13_0_arm64.whl", hash = "sha256:b417bab6e014048e3df2db6a182af6383dad42e7b10b616db047fefd95d1c636", size = 1327857, upload-time = "2025-11-10T14:25:10.49Z" }, + { url = "https://files.pythonhosted.org/packages/c5/92/d833a4bc27d4efcb9bcc92295ce6f8c11da9c44b755b92003fb092d00920/camb-1.6.5-py3-none-macosx_13_0_x86_64.whl", hash = "sha256:e53b7a1b212a6f77ffe2d5e12e3f5fd19d0897152d92fce62ab1b9d65225135d", size = 1373676, upload-time = "2025-11-10T14:25:12.462Z" }, + { url = "https://files.pythonhosted.org/packages/62/54/52749d8d59e864e3e5f4bbfd98069b918521f4d37159b60f8a3c2e10805f/camb-1.6.5-py3-none-macosx_14_0_arm64.whl", hash = "sha256:3130246d5ed8eaf4bfa614e9870710837d070b48820bcd435cd563ddedba2a23", size = 1327912, upload-time = "2025-11-10T14:25:13.727Z" }, + { url = "https://files.pythonhosted.org/packages/31/2e/d420bc44bb3915e28287fa1016c8b7d8dd5e89b510314949bd7aef0cb9e2/camb-1.6.5-py3-none-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:64c92fd9d38a8ae7e40a3a28c61b4ac3cbc8df6ece10bc703348d50e6d013d64", size = 1587695, upload-time = "2025-11-10T14:25:15.251Z" }, + { url = "https://files.pythonhosted.org/packages/9a/f6/659bd4eea67afc4b5584fc77bc50f8f7160cca70555ec03c2f20d9e63e7d/camb-1.6.5-py3-none-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:32851453fc0ff45d283bca6012d43ca38a0eee19faa90a4833d2d8202b4c265f", size = 2351425, upload-time = "2025-11-10T14:25:17.985Z" }, + { url = "https://files.pythonhosted.org/packages/2b/78/471218a4b457fc14cf0f0a628b2ba305a5a19108c8640e2cbcc2f7fb8937/camb-1.6.5-py3-none-win_amd64.whl", hash = "sha256:dc98ded515040ca2b26309ac2092c8fadddd024f2f38c99db30fc991e330bca0", size = 1484895, upload-time = "2025-11-10T14:25:19.349Z" }, +] + +[[package]] +name = "certifi" +version = "2026.1.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e0/2d/a891ca51311197f6ad14a7ef42e2399f36cf2f9bd44752b3dc4eab60fdc5/certifi-2026.1.4.tar.gz", hash = "sha256:ac726dd470482006e014ad384921ed6438c457018f4b3d204aea4281258b2120", size = 154268, upload-time = "2026-01-04T02:42:41.825Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e6/ad/3cc14f097111b4de0040c83a525973216457bbeeb63739ef1ed275c1c021/certifi-2026.1.4-py3-none-any.whl", hash = "sha256:9943707519e4add1115f44c2bc244f782c0249876bf51b6599fee1ffbedd685c", size = 152900, upload-time = "2026-01-04T02:42:40.15Z" }, +] + +[[package]] +name = "cffi" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pycparser", marker = "implementation_name != 'PyPy'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/eb/56/b1ba7935a17738ae8453301356628e8147c79dbb825bcbc73dc7401f9846/cffi-2.0.0.tar.gz", hash = "sha256:44d1b5909021139fe36001ae048dbdde8214afa20200eda0f64c068cac5d5529", size = 523588, upload-time = "2025-09-08T23:24:04.541Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/12/4a/3dfd5f7850cbf0d06dc84ba9aa00db766b52ca38d8b86e3a38314d52498c/cffi-2.0.0-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:b4c854ef3adc177950a8dfc81a86f5115d2abd545751a304c5bcf2c2c7283cfe", size = 184344, upload-time = "2025-09-08T23:22:26.456Z" }, + { url = "https://files.pythonhosted.org/packages/4f/8b/f0e4c441227ba756aafbe78f117485b25bb26b1c059d01f137fa6d14896b/cffi-2.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2de9a304e27f7596cd03d16f1b7c72219bd944e99cc52b84d0145aefb07cbd3c", size = 180560, upload-time = "2025-09-08T23:22:28.197Z" }, + { url = "https://files.pythonhosted.org/packages/b1/b7/1200d354378ef52ec227395d95c2576330fd22a869f7a70e88e1447eb234/cffi-2.0.0-cp311-cp311-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:baf5215e0ab74c16e2dd324e8ec067ef59e41125d3eade2b863d294fd5035c92", size = 209613, upload-time = "2025-09-08T23:22:29.475Z" }, + { url = "https://files.pythonhosted.org/packages/b8/56/6033f5e86e8cc9bb629f0077ba71679508bdf54a9a5e112a3c0b91870332/cffi-2.0.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:730cacb21e1bdff3ce90babf007d0a0917cc3e6492f336c2f0134101e0944f93", size = 216476, upload-time = "2025-09-08T23:22:31.063Z" }, + { url = "https://files.pythonhosted.org/packages/dc/7f/55fecd70f7ece178db2f26128ec41430d8720f2d12ca97bf8f0a628207d5/cffi-2.0.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:6824f87845e3396029f3820c206e459ccc91760e8fa24422f8b0c3d1731cbec5", size = 203374, upload-time = "2025-09-08T23:22:32.507Z" }, + { url = "https://files.pythonhosted.org/packages/84/ef/a7b77c8bdc0f77adc3b46888f1ad54be8f3b7821697a7b89126e829e676a/cffi-2.0.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:9de40a7b0323d889cf8d23d1ef214f565ab154443c42737dfe52ff82cf857664", size = 202597, upload-time = "2025-09-08T23:22:34.132Z" }, + { url = "https://files.pythonhosted.org/packages/d7/91/500d892b2bf36529a75b77958edfcd5ad8e2ce4064ce2ecfeab2125d72d1/cffi-2.0.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8941aaadaf67246224cee8c3803777eed332a19d909b47e29c9842ef1e79ac26", size = 215574, upload-time = "2025-09-08T23:22:35.443Z" }, + { url = "https://files.pythonhosted.org/packages/44/64/58f6255b62b101093d5df22dcb752596066c7e89dd725e0afaed242a61be/cffi-2.0.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:a05d0c237b3349096d3981b727493e22147f934b20f6f125a3eba8f994bec4a9", size = 218971, upload-time = "2025-09-08T23:22:36.805Z" }, + { url = "https://files.pythonhosted.org/packages/ab/49/fa72cebe2fd8a55fbe14956f9970fe8eb1ac59e5df042f603ef7c8ba0adc/cffi-2.0.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:94698a9c5f91f9d138526b48fe26a199609544591f859c870d477351dc7b2414", size = 211972, upload-time = "2025-09-08T23:22:38.436Z" }, + { url = "https://files.pythonhosted.org/packages/0b/28/dd0967a76aab36731b6ebfe64dec4e981aff7e0608f60c2d46b46982607d/cffi-2.0.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:5fed36fccc0612a53f1d4d9a816b50a36702c28a2aa880cb8a122b3466638743", size = 217078, upload-time = "2025-09-08T23:22:39.776Z" }, + { url = "https://files.pythonhosted.org/packages/2b/c0/015b25184413d7ab0a410775fdb4a50fca20f5589b5dab1dbbfa3baad8ce/cffi-2.0.0-cp311-cp311-win32.whl", hash = "sha256:c649e3a33450ec82378822b3dad03cc228b8f5963c0c12fc3b1e0ab940f768a5", size = 172076, upload-time = "2025-09-08T23:22:40.95Z" }, + { url = "https://files.pythonhosted.org/packages/ae/8f/dc5531155e7070361eb1b7e4c1a9d896d0cb21c49f807a6c03fd63fc877e/cffi-2.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:66f011380d0e49ed280c789fbd08ff0d40968ee7b665575489afa95c98196ab5", size = 182820, upload-time = "2025-09-08T23:22:42.463Z" }, + { url = "https://files.pythonhosted.org/packages/95/5c/1b493356429f9aecfd56bc171285a4c4ac8697f76e9bbbbb105e537853a1/cffi-2.0.0-cp311-cp311-win_arm64.whl", hash = "sha256:c6638687455baf640e37344fe26d37c404db8b80d037c3d29f58fe8d1c3b194d", size = 177635, upload-time = "2025-09-08T23:22:43.623Z" }, + { url = "https://files.pythonhosted.org/packages/ea/47/4f61023ea636104d4f16ab488e268b93008c3d0bb76893b1b31db1f96802/cffi-2.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6d02d6655b0e54f54c4ef0b94eb6be0607b70853c45ce98bd278dc7de718be5d", size = 185271, upload-time = "2025-09-08T23:22:44.795Z" }, + { url = "https://files.pythonhosted.org/packages/df/a2/781b623f57358e360d62cdd7a8c681f074a71d445418a776eef0aadb4ab4/cffi-2.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8eca2a813c1cb7ad4fb74d368c2ffbbb4789d377ee5bb8df98373c2cc0dee76c", size = 181048, upload-time = "2025-09-08T23:22:45.938Z" }, + { url = "https://files.pythonhosted.org/packages/ff/df/a4f0fbd47331ceeba3d37c2e51e9dfc9722498becbeec2bd8bc856c9538a/cffi-2.0.0-cp312-cp312-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:21d1152871b019407d8ac3985f6775c079416c282e431a4da6afe7aefd2bccbe", size = 212529, upload-time = "2025-09-08T23:22:47.349Z" }, + { url = "https://files.pythonhosted.org/packages/d5/72/12b5f8d3865bf0f87cf1404d8c374e7487dcf097a1c91c436e72e6badd83/cffi-2.0.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:b21e08af67b8a103c71a250401c78d5e0893beff75e28c53c98f4de42f774062", size = 220097, upload-time = "2025-09-08T23:22:48.677Z" }, + { url = "https://files.pythonhosted.org/packages/c2/95/7a135d52a50dfa7c882ab0ac17e8dc11cec9d55d2c18dda414c051c5e69e/cffi-2.0.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:1e3a615586f05fc4065a8b22b8152f0c1b00cdbc60596d187c2a74f9e3036e4e", size = 207983, upload-time = "2025-09-08T23:22:50.06Z" }, + { url = "https://files.pythonhosted.org/packages/3a/c8/15cb9ada8895957ea171c62dc78ff3e99159ee7adb13c0123c001a2546c1/cffi-2.0.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:81afed14892743bbe14dacb9e36d9e0e504cd204e0b165062c488942b9718037", size = 206519, upload-time = "2025-09-08T23:22:51.364Z" }, + { url = "https://files.pythonhosted.org/packages/78/2d/7fa73dfa841b5ac06c7b8855cfc18622132e365f5b81d02230333ff26e9e/cffi-2.0.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3e17ed538242334bf70832644a32a7aae3d83b57567f9fd60a26257e992b79ba", size = 219572, upload-time = "2025-09-08T23:22:52.902Z" }, + { url = "https://files.pythonhosted.org/packages/07/e0/267e57e387b4ca276b90f0434ff88b2c2241ad72b16d31836adddfd6031b/cffi-2.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3925dd22fa2b7699ed2617149842d2e6adde22b262fcbfada50e3d195e4b3a94", size = 222963, upload-time = "2025-09-08T23:22:54.518Z" }, + { url = "https://files.pythonhosted.org/packages/b6/75/1f2747525e06f53efbd878f4d03bac5b859cbc11c633d0fb81432d98a795/cffi-2.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2c8f814d84194c9ea681642fd164267891702542f028a15fc97d4674b6206187", size = 221361, upload-time = "2025-09-08T23:22:55.867Z" }, + { url = "https://files.pythonhosted.org/packages/7b/2b/2b6435f76bfeb6bbf055596976da087377ede68df465419d192acf00c437/cffi-2.0.0-cp312-cp312-win32.whl", hash = "sha256:da902562c3e9c550df360bfa53c035b2f241fed6d9aef119048073680ace4a18", size = 172932, upload-time = "2025-09-08T23:22:57.188Z" }, + { url = "https://files.pythonhosted.org/packages/f8/ed/13bd4418627013bec4ed6e54283b1959cf6db888048c7cf4b4c3b5b36002/cffi-2.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:da68248800ad6320861f129cd9c1bf96ca849a2771a59e0344e88681905916f5", size = 183557, upload-time = "2025-09-08T23:22:58.351Z" }, + { url = "https://files.pythonhosted.org/packages/95/31/9f7f93ad2f8eff1dbc1c3656d7ca5bfd8fb52c9d786b4dcf19b2d02217fa/cffi-2.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:4671d9dd5ec934cb9a73e7ee9676f9362aba54f7f34910956b84d727b0d73fb6", size = 177762, upload-time = "2025-09-08T23:22:59.668Z" }, + { url = "https://files.pythonhosted.org/packages/4b/8d/a0a47a0c9e413a658623d014e91e74a50cdd2c423f7ccfd44086ef767f90/cffi-2.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:00bdf7acc5f795150faa6957054fbbca2439db2f775ce831222b66f192f03beb", size = 185230, upload-time = "2025-09-08T23:23:00.879Z" }, + { url = "https://files.pythonhosted.org/packages/4a/d2/a6c0296814556c68ee32009d9c2ad4f85f2707cdecfd7727951ec228005d/cffi-2.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:45d5e886156860dc35862657e1494b9bae8dfa63bf56796f2fb56e1679fc0bca", size = 181043, upload-time = "2025-09-08T23:23:02.231Z" }, + { url = "https://files.pythonhosted.org/packages/b0/1e/d22cc63332bd59b06481ceaac49d6c507598642e2230f201649058a7e704/cffi-2.0.0-cp313-cp313-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:07b271772c100085dd28b74fa0cd81c8fb1a3ba18b21e03d7c27f3436a10606b", size = 212446, upload-time = "2025-09-08T23:23:03.472Z" }, + { url = "https://files.pythonhosted.org/packages/a9/f5/a2c23eb03b61a0b8747f211eb716446c826ad66818ddc7810cc2cc19b3f2/cffi-2.0.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d48a880098c96020b02d5a1f7d9251308510ce8858940e6fa99ece33f610838b", size = 220101, upload-time = "2025-09-08T23:23:04.792Z" }, + { url = "https://files.pythonhosted.org/packages/f2/7f/e6647792fc5850d634695bc0e6ab4111ae88e89981d35ac269956605feba/cffi-2.0.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:f93fd8e5c8c0a4aa1f424d6173f14a892044054871c771f8566e4008eaa359d2", size = 207948, upload-time = "2025-09-08T23:23:06.127Z" }, + { url = "https://files.pythonhosted.org/packages/cb/1e/a5a1bd6f1fb30f22573f76533de12a00bf274abcdc55c8edab639078abb6/cffi-2.0.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:dd4f05f54a52fb558f1ba9f528228066954fee3ebe629fc1660d874d040ae5a3", size = 206422, upload-time = "2025-09-08T23:23:07.753Z" }, + { url = "https://files.pythonhosted.org/packages/98/df/0a1755e750013a2081e863e7cd37e0cdd02664372c754e5560099eb7aa44/cffi-2.0.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c8d3b5532fc71b7a77c09192b4a5a200ea992702734a2e9279a37f2478236f26", size = 219499, upload-time = "2025-09-08T23:23:09.648Z" }, + { url = "https://files.pythonhosted.org/packages/50/e1/a969e687fcf9ea58e6e2a928ad5e2dd88cc12f6f0ab477e9971f2309b57c/cffi-2.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d9b29c1f0ae438d5ee9acb31cadee00a58c46cc9c0b2f9038c6b0b3470877a8c", size = 222928, upload-time = "2025-09-08T23:23:10.928Z" }, + { url = "https://files.pythonhosted.org/packages/36/54/0362578dd2c9e557a28ac77698ed67323ed5b9775ca9d3fe73fe191bb5d8/cffi-2.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6d50360be4546678fc1b79ffe7a66265e28667840010348dd69a314145807a1b", size = 221302, upload-time = "2025-09-08T23:23:12.42Z" }, + { url = "https://files.pythonhosted.org/packages/eb/6d/bf9bda840d5f1dfdbf0feca87fbdb64a918a69bca42cfa0ba7b137c48cb8/cffi-2.0.0-cp313-cp313-win32.whl", hash = "sha256:74a03b9698e198d47562765773b4a8309919089150a0bb17d829ad7b44b60d27", size = 172909, upload-time = "2025-09-08T23:23:14.32Z" }, + { url = "https://files.pythonhosted.org/packages/37/18/6519e1ee6f5a1e579e04b9ddb6f1676c17368a7aba48299c3759bbc3c8b3/cffi-2.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:19f705ada2530c1167abacb171925dd886168931e0a7b78f5bffcae5c6b5be75", size = 183402, upload-time = "2025-09-08T23:23:15.535Z" }, + { url = "https://files.pythonhosted.org/packages/cb/0e/02ceeec9a7d6ee63bb596121c2c8e9b3a9e150936f4fbef6ca1943e6137c/cffi-2.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:256f80b80ca3853f90c21b23ee78cd008713787b1b1e93eae9f3d6a7134abd91", size = 177780, upload-time = "2025-09-08T23:23:16.761Z" }, + { url = "https://files.pythonhosted.org/packages/92/c4/3ce07396253a83250ee98564f8d7e9789fab8e58858f35d07a9a2c78de9f/cffi-2.0.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:fc33c5141b55ed366cfaad382df24fe7dcbc686de5be719b207bb248e3053dc5", size = 185320, upload-time = "2025-09-08T23:23:18.087Z" }, + { url = "https://files.pythonhosted.org/packages/59/dd/27e9fa567a23931c838c6b02d0764611c62290062a6d4e8ff7863daf9730/cffi-2.0.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c654de545946e0db659b3400168c9ad31b5d29593291482c43e3564effbcee13", size = 181487, upload-time = "2025-09-08T23:23:19.622Z" }, + { url = "https://files.pythonhosted.org/packages/d6/43/0e822876f87ea8a4ef95442c3d766a06a51fc5298823f884ef87aaad168c/cffi-2.0.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:24b6f81f1983e6df8db3adc38562c83f7d4a0c36162885ec7f7b77c7dcbec97b", size = 220049, upload-time = "2025-09-08T23:23:20.853Z" }, + { url = "https://files.pythonhosted.org/packages/b4/89/76799151d9c2d2d1ead63c2429da9ea9d7aac304603de0c6e8764e6e8e70/cffi-2.0.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:12873ca6cb9b0f0d3a0da705d6086fe911591737a59f28b7936bdfed27c0d47c", size = 207793, upload-time = "2025-09-08T23:23:22.08Z" }, + { url = "https://files.pythonhosted.org/packages/bb/dd/3465b14bb9e24ee24cb88c9e3730f6de63111fffe513492bf8c808a3547e/cffi-2.0.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:d9b97165e8aed9272a6bb17c01e3cc5871a594a446ebedc996e2397a1c1ea8ef", size = 206300, upload-time = "2025-09-08T23:23:23.314Z" }, + { url = "https://files.pythonhosted.org/packages/47/d9/d83e293854571c877a92da46fdec39158f8d7e68da75bf73581225d28e90/cffi-2.0.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:afb8db5439b81cf9c9d0c80404b60c3cc9c3add93e114dcae767f1477cb53775", size = 219244, upload-time = "2025-09-08T23:23:24.541Z" }, + { url = "https://files.pythonhosted.org/packages/2b/0f/1f177e3683aead2bb00f7679a16451d302c436b5cbf2505f0ea8146ef59e/cffi-2.0.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:737fe7d37e1a1bffe70bd5754ea763a62a066dc5913ca57e957824b72a85e205", size = 222828, upload-time = "2025-09-08T23:23:26.143Z" }, + { url = "https://files.pythonhosted.org/packages/c6/0f/cafacebd4b040e3119dcb32fed8bdef8dfe94da653155f9d0b9dc660166e/cffi-2.0.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:38100abb9d1b1435bc4cc340bb4489635dc2f0da7456590877030c9b3d40b0c1", size = 220926, upload-time = "2025-09-08T23:23:27.873Z" }, + { url = "https://files.pythonhosted.org/packages/3e/aa/df335faa45b395396fcbc03de2dfcab242cd61a9900e914fe682a59170b1/cffi-2.0.0-cp314-cp314-win32.whl", hash = "sha256:087067fa8953339c723661eda6b54bc98c5625757ea62e95eb4898ad5e776e9f", size = 175328, upload-time = "2025-09-08T23:23:44.61Z" }, + { url = "https://files.pythonhosted.org/packages/bb/92/882c2d30831744296ce713f0feb4c1cd30f346ef747b530b5318715cc367/cffi-2.0.0-cp314-cp314-win_amd64.whl", hash = "sha256:203a48d1fb583fc7d78a4c6655692963b860a417c0528492a6bc21f1aaefab25", size = 185650, upload-time = "2025-09-08T23:23:45.848Z" }, + { url = "https://files.pythonhosted.org/packages/9f/2c/98ece204b9d35a7366b5b2c6539c350313ca13932143e79dc133ba757104/cffi-2.0.0-cp314-cp314-win_arm64.whl", hash = "sha256:dbd5c7a25a7cb98f5ca55d258b103a2054f859a46ae11aaf23134f9cc0d356ad", size = 180687, upload-time = "2025-09-08T23:23:47.105Z" }, + { url = "https://files.pythonhosted.org/packages/3e/61/c768e4d548bfa607abcda77423448df8c471f25dbe64fb2ef6d555eae006/cffi-2.0.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:9a67fc9e8eb39039280526379fb3a70023d77caec1852002b4da7e8b270c4dd9", size = 188773, upload-time = "2025-09-08T23:23:29.347Z" }, + { url = "https://files.pythonhosted.org/packages/2c/ea/5f76bce7cf6fcd0ab1a1058b5af899bfbef198bea4d5686da88471ea0336/cffi-2.0.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7a66c7204d8869299919db4d5069a82f1561581af12b11b3c9f48c584eb8743d", size = 185013, upload-time = "2025-09-08T23:23:30.63Z" }, + { url = "https://files.pythonhosted.org/packages/be/b4/c56878d0d1755cf9caa54ba71e5d049479c52f9e4afc230f06822162ab2f/cffi-2.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7cc09976e8b56f8cebd752f7113ad07752461f48a58cbba644139015ac24954c", size = 221593, upload-time = "2025-09-08T23:23:31.91Z" }, + { url = "https://files.pythonhosted.org/packages/e0/0d/eb704606dfe8033e7128df5e90fee946bbcb64a04fcdaa97321309004000/cffi-2.0.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:92b68146a71df78564e4ef48af17551a5ddd142e5190cdf2c5624d0c3ff5b2e8", size = 209354, upload-time = "2025-09-08T23:23:33.214Z" }, + { url = "https://files.pythonhosted.org/packages/d8/19/3c435d727b368ca475fb8742ab97c9cb13a0de600ce86f62eab7fa3eea60/cffi-2.0.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:b1e74d11748e7e98e2f426ab176d4ed720a64412b6a15054378afdb71e0f37dc", size = 208480, upload-time = "2025-09-08T23:23:34.495Z" }, + { url = "https://files.pythonhosted.org/packages/d0/44/681604464ed9541673e486521497406fadcc15b5217c3e326b061696899a/cffi-2.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:28a3a209b96630bca57cce802da70c266eb08c6e97e5afd61a75611ee6c64592", size = 221584, upload-time = "2025-09-08T23:23:36.096Z" }, + { url = "https://files.pythonhosted.org/packages/25/8e/342a504ff018a2825d395d44d63a767dd8ebc927ebda557fecdaca3ac33a/cffi-2.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:7553fb2090d71822f02c629afe6042c299edf91ba1bf94951165613553984512", size = 224443, upload-time = "2025-09-08T23:23:37.328Z" }, + { url = "https://files.pythonhosted.org/packages/e1/5e/b666bacbbc60fbf415ba9988324a132c9a7a0448a9a8f125074671c0f2c3/cffi-2.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:6c6c373cfc5c83a975506110d17457138c8c63016b563cc9ed6e056a82f13ce4", size = 223437, upload-time = "2025-09-08T23:23:38.945Z" }, + { url = "https://files.pythonhosted.org/packages/a0/1d/ec1a60bd1a10daa292d3cd6bb0b359a81607154fb8165f3ec95fe003b85c/cffi-2.0.0-cp314-cp314t-win32.whl", hash = "sha256:1fc9ea04857caf665289b7a75923f2c6ed559b8298a1b8c49e59f7dd95c8481e", size = 180487, upload-time = "2025-09-08T23:23:40.423Z" }, + { url = "https://files.pythonhosted.org/packages/bf/41/4c1168c74fac325c0c8156f04b6749c8b6a8f405bbf91413ba088359f60d/cffi-2.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:d68b6cef7827e8641e8ef16f4494edda8b36104d79773a334beaa1e3521430f6", size = 191726, upload-time = "2025-09-08T23:23:41.742Z" }, + { url = "https://files.pythonhosted.org/packages/ae/3a/dbeec9d1ee0844c679f6bb5d6ad4e9f198b1224f4e7a32825f47f6192b0c/cffi-2.0.0-cp314-cp314t-win_arm64.whl", hash = "sha256:0a1527a803f0a659de1af2e1fd700213caba79377e27e4693648c2923da066f9", size = 184195, upload-time = "2025-09-08T23:23:43.004Z" }, +] + +[[package]] +name = "cfgv" +version = "3.5.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/4e/b5/721b8799b04bf9afe054a3899c6cf4e880fcf8563cc71c15610242490a0c/cfgv-3.5.0.tar.gz", hash = "sha256:d5b1034354820651caa73ede66a6294d6e95c1b00acc5e9b098e917404669132", size = 7334, upload-time = "2025-11-19T20:55:51.612Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/db/3c/33bac158f8ab7f89b2e59426d5fe2e4f63f7ed25df84c036890172b412b5/cfgv-3.5.0-py2.py3-none-any.whl", hash = "sha256:a8dc6b26ad22ff227d2634a65cb388215ce6cc96bbcc5cfde7641ae87e8dacc0", size = 7445, upload-time = "2025-11-19T20:55:50.744Z" }, +] + +[[package]] +name = "charset-normalizer" +version = "3.4.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/13/69/33ddede1939fdd074bce5434295f38fae7136463422fe4fd3e0e89b98062/charset_normalizer-3.4.4.tar.gz", hash = "sha256:94537985111c35f28720e43603b8e7b43a6ecfb2ce1d3058bbe955b73404e21a", size = 129418, upload-time = "2025-10-14T04:42:32.879Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ed/27/c6491ff4954e58a10f69ad90aca8a1b6fe9c5d3c6f380907af3c37435b59/charset_normalizer-3.4.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6e1fcf0720908f200cd21aa4e6750a48ff6ce4afe7ff5a79a90d5ed8a08296f8", size = 206988, upload-time = "2025-10-14T04:40:33.79Z" }, + { url = "https://files.pythonhosted.org/packages/94/59/2e87300fe67ab820b5428580a53cad894272dbb97f38a7a814a2a1ac1011/charset_normalizer-3.4.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5f819d5fe9234f9f82d75bdfa9aef3a3d72c4d24a6e57aeaebba32a704553aa0", size = 147324, upload-time = "2025-10-14T04:40:34.961Z" }, + { url = "https://files.pythonhosted.org/packages/07/fb/0cf61dc84b2b088391830f6274cb57c82e4da8bbc2efeac8c025edb88772/charset_normalizer-3.4.4-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:a59cb51917aa591b1c4e6a43c132f0cdc3c76dbad6155df4e28ee626cc77a0a3", size = 142742, upload-time = "2025-10-14T04:40:36.105Z" }, + { url = "https://files.pythonhosted.org/packages/62/8b/171935adf2312cd745d290ed93cf16cf0dfe320863ab7cbeeae1dcd6535f/charset_normalizer-3.4.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8ef3c867360f88ac904fd3f5e1f902f13307af9052646963ee08ff4f131adafc", size = 160863, upload-time = "2025-10-14T04:40:37.188Z" }, + { url = "https://files.pythonhosted.org/packages/09/73/ad875b192bda14f2173bfc1bc9a55e009808484a4b256748d931b6948442/charset_normalizer-3.4.4-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d9e45d7faa48ee908174d8fe84854479ef838fc6a705c9315372eacbc2f02897", size = 157837, upload-time = "2025-10-14T04:40:38.435Z" }, + { url = "https://files.pythonhosted.org/packages/6d/fc/de9cce525b2c5b94b47c70a4b4fb19f871b24995c728e957ee68ab1671ea/charset_normalizer-3.4.4-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:840c25fb618a231545cbab0564a799f101b63b9901f2569faecd6b222ac72381", size = 151550, upload-time = "2025-10-14T04:40:40.053Z" }, + { url = "https://files.pythonhosted.org/packages/55/c2/43edd615fdfba8c6f2dfbd459b25a6b3b551f24ea21981e23fb768503ce1/charset_normalizer-3.4.4-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ca5862d5b3928c4940729dacc329aa9102900382fea192fc5e52eb69d6093815", size = 149162, upload-time = "2025-10-14T04:40:41.163Z" }, + { url = "https://files.pythonhosted.org/packages/03/86/bde4ad8b4d0e9429a4e82c1e8f5c659993a9a863ad62c7df05cf7b678d75/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d9c7f57c3d666a53421049053eaacdd14bbd0a528e2186fcb2e672effd053bb0", size = 150019, upload-time = "2025-10-14T04:40:42.276Z" }, + { url = "https://files.pythonhosted.org/packages/1f/86/a151eb2af293a7e7bac3a739b81072585ce36ccfb4493039f49f1d3cae8c/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:277e970e750505ed74c832b4bf75dac7476262ee2a013f5574dd49075879e161", size = 143310, upload-time = "2025-10-14T04:40:43.439Z" }, + { url = "https://files.pythonhosted.org/packages/b5/fe/43dae6144a7e07b87478fdfc4dbe9efd5defb0e7ec29f5f58a55aeef7bf7/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:31fd66405eaf47bb62e8cd575dc621c56c668f27d46a61d975a249930dd5e2a4", size = 162022, upload-time = "2025-10-14T04:40:44.547Z" }, + { url = "https://files.pythonhosted.org/packages/80/e6/7aab83774f5d2bca81f42ac58d04caf44f0cc2b65fc6db2b3b2e8a05f3b3/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:0d3d8f15c07f86e9ff82319b3d9ef6f4bf907608f53fe9d92b28ea9ae3d1fd89", size = 149383, upload-time = "2025-10-14T04:40:46.018Z" }, + { url = "https://files.pythonhosted.org/packages/4f/e8/b289173b4edae05c0dde07f69f8db476a0b511eac556dfe0d6bda3c43384/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:9f7fcd74d410a36883701fafa2482a6af2ff5ba96b9a620e9e0721e28ead5569", size = 159098, upload-time = "2025-10-14T04:40:47.081Z" }, + { url = "https://files.pythonhosted.org/packages/d8/df/fe699727754cae3f8478493c7f45f777b17c3ef0600e28abfec8619eb49c/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ebf3e58c7ec8a8bed6d66a75d7fb37b55e5015b03ceae72a8e7c74495551e224", size = 152991, upload-time = "2025-10-14T04:40:48.246Z" }, + { url = "https://files.pythonhosted.org/packages/1a/86/584869fe4ddb6ffa3bd9f491b87a01568797fb9bd8933f557dba9771beaf/charset_normalizer-3.4.4-cp311-cp311-win32.whl", hash = "sha256:eecbc200c7fd5ddb9a7f16c7decb07b566c29fa2161a16cf67b8d068bd21690a", size = 99456, upload-time = "2025-10-14T04:40:49.376Z" }, + { url = "https://files.pythonhosted.org/packages/65/f6/62fdd5feb60530f50f7e38b4f6a1d5203f4d16ff4f9f0952962c044e919a/charset_normalizer-3.4.4-cp311-cp311-win_amd64.whl", hash = "sha256:5ae497466c7901d54b639cf42d5b8c1b6a4fead55215500d2f486d34db48d016", size = 106978, upload-time = "2025-10-14T04:40:50.844Z" }, + { url = "https://files.pythonhosted.org/packages/7a/9d/0710916e6c82948b3be62d9d398cb4fcf4e97b56d6a6aeccd66c4b2f2bd5/charset_normalizer-3.4.4-cp311-cp311-win_arm64.whl", hash = "sha256:65e2befcd84bc6f37095f5961e68a6f077bf44946771354a28ad434c2cce0ae1", size = 99969, upload-time = "2025-10-14T04:40:52.272Z" }, + { url = "https://files.pythonhosted.org/packages/f3/85/1637cd4af66fa687396e757dec650f28025f2a2f5a5531a3208dc0ec43f2/charset_normalizer-3.4.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0a98e6759f854bd25a58a73fa88833fba3b7c491169f86ce1180c948ab3fd394", size = 208425, upload-time = "2025-10-14T04:40:53.353Z" }, + { url = "https://files.pythonhosted.org/packages/9d/6a/04130023fef2a0d9c62d0bae2649b69f7b7d8d24ea5536feef50551029df/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b5b290ccc2a263e8d185130284f8501e3e36c5e02750fc6b6bdeb2e9e96f1e25", size = 148162, upload-time = "2025-10-14T04:40:54.558Z" }, + { url = "https://files.pythonhosted.org/packages/78/29/62328d79aa60da22c9e0b9a66539feae06ca0f5a4171ac4f7dc285b83688/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74bb723680f9f7a6234dcf67aea57e708ec1fbdf5699fb91dfd6f511b0a320ef", size = 144558, upload-time = "2025-10-14T04:40:55.677Z" }, + { url = "https://files.pythonhosted.org/packages/86/bb/b32194a4bf15b88403537c2e120b817c61cd4ecffa9b6876e941c3ee38fe/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f1e34719c6ed0b92f418c7c780480b26b5d9c50349e9a9af7d76bf757530350d", size = 161497, upload-time = "2025-10-14T04:40:57.217Z" }, + { url = "https://files.pythonhosted.org/packages/19/89/a54c82b253d5b9b111dc74aca196ba5ccfcca8242d0fb64146d4d3183ff1/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2437418e20515acec67d86e12bf70056a33abdacb5cb1655042f6538d6b085a8", size = 159240, upload-time = "2025-10-14T04:40:58.358Z" }, + { url = "https://files.pythonhosted.org/packages/c0/10/d20b513afe03acc89ec33948320a5544d31f21b05368436d580dec4e234d/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:11d694519d7f29d6cd09f6ac70028dba10f92f6cdd059096db198c283794ac86", size = 153471, upload-time = "2025-10-14T04:40:59.468Z" }, + { url = "https://files.pythonhosted.org/packages/61/fa/fbf177b55bdd727010f9c0a3c49eefa1d10f960e5f09d1d887bf93c2e698/charset_normalizer-3.4.4-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ac1c4a689edcc530fc9d9aa11f5774b9e2f33f9a0c6a57864e90908f5208d30a", size = 150864, upload-time = "2025-10-14T04:41:00.623Z" }, + { url = "https://files.pythonhosted.org/packages/05/12/9fbc6a4d39c0198adeebbde20b619790e9236557ca59fc40e0e3cebe6f40/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:21d142cc6c0ec30d2efee5068ca36c128a30b0f2c53c1c07bd78cb6bc1d3be5f", size = 150647, upload-time = "2025-10-14T04:41:01.754Z" }, + { url = "https://files.pythonhosted.org/packages/ad/1f/6a9a593d52e3e8c5d2b167daf8c6b968808efb57ef4c210acb907c365bc4/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:5dbe56a36425d26d6cfb40ce79c314a2e4dd6211d51d6d2191c00bed34f354cc", size = 145110, upload-time = "2025-10-14T04:41:03.231Z" }, + { url = "https://files.pythonhosted.org/packages/30/42/9a52c609e72471b0fc54386dc63c3781a387bb4fe61c20231a4ebcd58bdd/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:5bfbb1b9acf3334612667b61bd3002196fe2a1eb4dd74d247e0f2a4d50ec9bbf", size = 162839, upload-time = "2025-10-14T04:41:04.715Z" }, + { url = "https://files.pythonhosted.org/packages/c4/5b/c0682bbf9f11597073052628ddd38344a3d673fda35a36773f7d19344b23/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:d055ec1e26e441f6187acf818b73564e6e6282709e9bcb5b63f5b23068356a15", size = 150667, upload-time = "2025-10-14T04:41:05.827Z" }, + { url = "https://files.pythonhosted.org/packages/e4/24/a41afeab6f990cf2daf6cb8c67419b63b48cf518e4f56022230840c9bfb2/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:af2d8c67d8e573d6de5bc30cdb27e9b95e49115cd9baad5ddbd1a6207aaa82a9", size = 160535, upload-time = "2025-10-14T04:41:06.938Z" }, + { url = "https://files.pythonhosted.org/packages/2a/e5/6a4ce77ed243c4a50a1fecca6aaaab419628c818a49434be428fe24c9957/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:780236ac706e66881f3b7f2f32dfe90507a09e67d1d454c762cf642e6e1586e0", size = 154816, upload-time = "2025-10-14T04:41:08.101Z" }, + { url = "https://files.pythonhosted.org/packages/a8/ef/89297262b8092b312d29cdb2517cb1237e51db8ecef2e9af5edbe7b683b1/charset_normalizer-3.4.4-cp312-cp312-win32.whl", hash = "sha256:5833d2c39d8896e4e19b689ffc198f08ea58116bee26dea51e362ecc7cd3ed26", size = 99694, upload-time = "2025-10-14T04:41:09.23Z" }, + { url = "https://files.pythonhosted.org/packages/3d/2d/1e5ed9dd3b3803994c155cd9aacb60c82c331bad84daf75bcb9c91b3295e/charset_normalizer-3.4.4-cp312-cp312-win_amd64.whl", hash = "sha256:a79cfe37875f822425b89a82333404539ae63dbdddf97f84dcbc3d339aae9525", size = 107131, upload-time = "2025-10-14T04:41:10.467Z" }, + { url = "https://files.pythonhosted.org/packages/d0/d9/0ed4c7098a861482a7b6a95603edce4c0d9db2311af23da1fb2b75ec26fc/charset_normalizer-3.4.4-cp312-cp312-win_arm64.whl", hash = "sha256:376bec83a63b8021bb5c8ea75e21c4ccb86e7e45ca4eb81146091b56599b80c3", size = 100390, upload-time = "2025-10-14T04:41:11.915Z" }, + { url = "https://files.pythonhosted.org/packages/97/45/4b3a1239bbacd321068ea6e7ac28875b03ab8bc0aa0966452db17cd36714/charset_normalizer-3.4.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:e1f185f86a6f3403aa2420e815904c67b2f9ebc443f045edd0de921108345794", size = 208091, upload-time = "2025-10-14T04:41:13.346Z" }, + { url = "https://files.pythonhosted.org/packages/7d/62/73a6d7450829655a35bb88a88fca7d736f9882a27eacdca2c6d505b57e2e/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b39f987ae8ccdf0d2642338faf2abb1862340facc796048b604ef14919e55ed", size = 147936, upload-time = "2025-10-14T04:41:14.461Z" }, + { url = "https://files.pythonhosted.org/packages/89/c5/adb8c8b3d6625bef6d88b251bbb0d95f8205831b987631ab0c8bb5d937c2/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3162d5d8ce1bb98dd51af660f2121c55d0fa541b46dff7bb9b9f86ea1d87de72", size = 144180, upload-time = "2025-10-14T04:41:15.588Z" }, + { url = "https://files.pythonhosted.org/packages/91/ed/9706e4070682d1cc219050b6048bfd293ccf67b3d4f5a4f39207453d4b99/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:81d5eb2a312700f4ecaa977a8235b634ce853200e828fbadf3a9c50bab278328", size = 161346, upload-time = "2025-10-14T04:41:16.738Z" }, + { url = "https://files.pythonhosted.org/packages/d5/0d/031f0d95e4972901a2f6f09ef055751805ff541511dc1252ba3ca1f80cf5/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5bd2293095d766545ec1a8f612559f6b40abc0eb18bb2f5d1171872d34036ede", size = 158874, upload-time = "2025-10-14T04:41:17.923Z" }, + { url = "https://files.pythonhosted.org/packages/f5/83/6ab5883f57c9c801ce5e5677242328aa45592be8a00644310a008d04f922/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a8a8b89589086a25749f471e6a900d3f662d1d3b6e2e59dcecf787b1cc3a1894", size = 153076, upload-time = "2025-10-14T04:41:19.106Z" }, + { url = "https://files.pythonhosted.org/packages/75/1e/5ff781ddf5260e387d6419959ee89ef13878229732732ee73cdae01800f2/charset_normalizer-3.4.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:bc7637e2f80d8530ee4a78e878bce464f70087ce73cf7c1caf142416923b98f1", size = 150601, upload-time = "2025-10-14T04:41:20.245Z" }, + { url = "https://files.pythonhosted.org/packages/d7/57/71be810965493d3510a6ca79b90c19e48696fb1ff964da319334b12677f0/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f8bf04158c6b607d747e93949aa60618b61312fe647a6369f88ce2ff16043490", size = 150376, upload-time = "2025-10-14T04:41:21.398Z" }, + { url = "https://files.pythonhosted.org/packages/e5/d5/c3d057a78c181d007014feb7e9f2e65905a6c4ef182c0ddf0de2924edd65/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:554af85e960429cf30784dd47447d5125aaa3b99a6f0683589dbd27e2f45da44", size = 144825, upload-time = "2025-10-14T04:41:22.583Z" }, + { url = "https://files.pythonhosted.org/packages/e6/8c/d0406294828d4976f275ffbe66f00266c4b3136b7506941d87c00cab5272/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:74018750915ee7ad843a774364e13a3db91682f26142baddf775342c3f5b1133", size = 162583, upload-time = "2025-10-14T04:41:23.754Z" }, + { url = "https://files.pythonhosted.org/packages/d7/24/e2aa1f18c8f15c4c0e932d9287b8609dd30ad56dbe41d926bd846e22fb8d/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:c0463276121fdee9c49b98908b3a89c39be45d86d1dbaa22957e38f6321d4ce3", size = 150366, upload-time = "2025-10-14T04:41:25.27Z" }, + { url = "https://files.pythonhosted.org/packages/e4/5b/1e6160c7739aad1e2df054300cc618b06bf784a7a164b0f238360721ab86/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:362d61fd13843997c1c446760ef36f240cf81d3ebf74ac62652aebaf7838561e", size = 160300, upload-time = "2025-10-14T04:41:26.725Z" }, + { url = "https://files.pythonhosted.org/packages/7a/10/f882167cd207fbdd743e55534d5d9620e095089d176d55cb22d5322f2afd/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9a26f18905b8dd5d685d6d07b0cdf98a79f3c7a918906af7cc143ea2e164c8bc", size = 154465, upload-time = "2025-10-14T04:41:28.322Z" }, + { url = "https://files.pythonhosted.org/packages/89/66/c7a9e1b7429be72123441bfdbaf2bc13faab3f90b933f664db506dea5915/charset_normalizer-3.4.4-cp313-cp313-win32.whl", hash = "sha256:9b35f4c90079ff2e2edc5b26c0c77925e5d2d255c42c74fdb70fb49b172726ac", size = 99404, upload-time = "2025-10-14T04:41:29.95Z" }, + { url = "https://files.pythonhosted.org/packages/c4/26/b9924fa27db384bdcd97ab83b4f0a8058d96ad9626ead570674d5e737d90/charset_normalizer-3.4.4-cp313-cp313-win_amd64.whl", hash = "sha256:b435cba5f4f750aa6c0a0d92c541fb79f69a387c91e61f1795227e4ed9cece14", size = 107092, upload-time = "2025-10-14T04:41:31.188Z" }, + { url = "https://files.pythonhosted.org/packages/af/8f/3ed4bfa0c0c72a7ca17f0380cd9e4dd842b09f664e780c13cff1dcf2ef1b/charset_normalizer-3.4.4-cp313-cp313-win_arm64.whl", hash = "sha256:542d2cee80be6f80247095cc36c418f7bddd14f4a6de45af91dfad36d817bba2", size = 100408, upload-time = "2025-10-14T04:41:32.624Z" }, + { url = "https://files.pythonhosted.org/packages/2a/35/7051599bd493e62411d6ede36fd5af83a38f37c4767b92884df7301db25d/charset_normalizer-3.4.4-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:da3326d9e65ef63a817ecbcc0df6e94463713b754fe293eaa03da99befb9a5bd", size = 207746, upload-time = "2025-10-14T04:41:33.773Z" }, + { url = "https://files.pythonhosted.org/packages/10/9a/97c8d48ef10d6cd4fcead2415523221624bf58bcf68a802721a6bc807c8f/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8af65f14dc14a79b924524b1e7fffe304517b2bff5a58bf64f30b98bbc5079eb", size = 147889, upload-time = "2025-10-14T04:41:34.897Z" }, + { url = "https://files.pythonhosted.org/packages/10/bf/979224a919a1b606c82bd2c5fa49b5c6d5727aa47b4312bb27b1734f53cd/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74664978bb272435107de04e36db5a9735e78232b85b77d45cfb38f758efd33e", size = 143641, upload-time = "2025-10-14T04:41:36.116Z" }, + { url = "https://files.pythonhosted.org/packages/ba/33/0ad65587441fc730dc7bd90e9716b30b4702dc7b617e6ba4997dc8651495/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:752944c7ffbfdd10c074dc58ec2d5a8a4cd9493b314d367c14d24c17684ddd14", size = 160779, upload-time = "2025-10-14T04:41:37.229Z" }, + { url = "https://files.pythonhosted.org/packages/67/ed/331d6b249259ee71ddea93f6f2f0a56cfebd46938bde6fcc6f7b9a3d0e09/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d1f13550535ad8cff21b8d757a3257963e951d96e20ec82ab44bc64aeb62a191", size = 159035, upload-time = "2025-10-14T04:41:38.368Z" }, + { url = "https://files.pythonhosted.org/packages/67/ff/f6b948ca32e4f2a4576aa129d8bed61f2e0543bf9f5f2b7fc3758ed005c9/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ecaae4149d99b1c9e7b88bb03e3221956f68fd6d50be2ef061b2381b61d20838", size = 152542, upload-time = "2025-10-14T04:41:39.862Z" }, + { url = "https://files.pythonhosted.org/packages/16/85/276033dcbcc369eb176594de22728541a925b2632f9716428c851b149e83/charset_normalizer-3.4.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:cb6254dc36b47a990e59e1068afacdcd02958bdcce30bb50cc1700a8b9d624a6", size = 149524, upload-time = "2025-10-14T04:41:41.319Z" }, + { url = "https://files.pythonhosted.org/packages/9e/f2/6a2a1f722b6aba37050e626530a46a68f74e63683947a8acff92569f979a/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c8ae8a0f02f57a6e61203a31428fa1d677cbe50c93622b4149d5c0f319c1d19e", size = 150395, upload-time = "2025-10-14T04:41:42.539Z" }, + { url = "https://files.pythonhosted.org/packages/60/bb/2186cb2f2bbaea6338cad15ce23a67f9b0672929744381e28b0592676824/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:47cc91b2f4dd2833fddaedd2893006b0106129d4b94fdb6af1f4ce5a9965577c", size = 143680, upload-time = "2025-10-14T04:41:43.661Z" }, + { url = "https://files.pythonhosted.org/packages/7d/a5/bf6f13b772fbb2a90360eb620d52ed8f796f3c5caee8398c3b2eb7b1c60d/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:82004af6c302b5d3ab2cfc4cc5f29db16123b1a8417f2e25f9066f91d4411090", size = 162045, upload-time = "2025-10-14T04:41:44.821Z" }, + { url = "https://files.pythonhosted.org/packages/df/c5/d1be898bf0dc3ef9030c3825e5d3b83f2c528d207d246cbabe245966808d/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:2b7d8f6c26245217bd2ad053761201e9f9680f8ce52f0fcd8d0755aeae5b2152", size = 149687, upload-time = "2025-10-14T04:41:46.442Z" }, + { url = "https://files.pythonhosted.org/packages/a5/42/90c1f7b9341eef50c8a1cb3f098ac43b0508413f33affd762855f67a410e/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:799a7a5e4fb2d5898c60b640fd4981d6a25f1c11790935a44ce38c54e985f828", size = 160014, upload-time = "2025-10-14T04:41:47.631Z" }, + { url = "https://files.pythonhosted.org/packages/76/be/4d3ee471e8145d12795ab655ece37baed0929462a86e72372fd25859047c/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:99ae2cffebb06e6c22bdc25801d7b30f503cc87dbd283479e7b606f70aff57ec", size = 154044, upload-time = "2025-10-14T04:41:48.81Z" }, + { url = "https://files.pythonhosted.org/packages/b0/6f/8f7af07237c34a1defe7defc565a9bc1807762f672c0fde711a4b22bf9c0/charset_normalizer-3.4.4-cp314-cp314-win32.whl", hash = "sha256:f9d332f8c2a2fcbffe1378594431458ddbef721c1769d78e2cbc06280d8155f9", size = 99940, upload-time = "2025-10-14T04:41:49.946Z" }, + { url = "https://files.pythonhosted.org/packages/4b/51/8ade005e5ca5b0d80fb4aff72a3775b325bdc3d27408c8113811a7cbe640/charset_normalizer-3.4.4-cp314-cp314-win_amd64.whl", hash = "sha256:8a6562c3700cce886c5be75ade4a5db4214fda19fede41d9792d100288d8f94c", size = 107104, upload-time = "2025-10-14T04:41:51.051Z" }, + { url = "https://files.pythonhosted.org/packages/da/5f/6b8f83a55bb8278772c5ae54a577f3099025f9ade59d0136ac24a0df4bde/charset_normalizer-3.4.4-cp314-cp314-win_arm64.whl", hash = "sha256:de00632ca48df9daf77a2c65a484531649261ec9f25489917f09e455cb09ddb2", size = 100743, upload-time = "2025-10-14T04:41:52.122Z" }, + { url = "https://files.pythonhosted.org/packages/0a/4c/925909008ed5a988ccbb72dcc897407e5d6d3bd72410d69e051fc0c14647/charset_normalizer-3.4.4-py3-none-any.whl", hash = "sha256:7a32c560861a02ff789ad905a2fe94e3f840803362c84fecf1851cb4cf3dc37f", size = 53402, upload-time = "2025-10-14T04:42:31.76Z" }, +] + +[[package]] +name = "click" +version = "8.3.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/3d/fa/656b739db8587d7b5dfa22e22ed02566950fbfbcdc20311993483657a5c0/click-8.3.1.tar.gz", hash = "sha256:12ff4785d337a1bb490bb7e9c2b1ee5da3112e94a8622f26a6c77f5d2fc6842a", size = 295065, upload-time = "2025-11-15T20:45:42.706Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/98/78/01c019cdb5d6498122777c1a43056ebb3ebfeef2076d9d026bfe15583b2b/click-8.3.1-py3-none-any.whl", hash = "sha256:981153a64e25f12d547d3426c367a4857371575ee7ad18df2a6183ab0545b2a6", size = 108274, upload-time = "2025-11-15T20:45:41.139Z" }, +] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, +] + +[[package]] +name = "colossus" +version = "1.3.12" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, + { name = "scipy" }, + { name = "six" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/5f/34/0059ec6c9b67701ea82fb86e7f143edbdadd14e3593784130f16291cefe4/colossus-1.3.12-py2.py3-none-any.whl", hash = "sha256:208c7d6bd5f43d71b9153e8118a37925aaa5dd9e19052e64e20e89184de09f62", size = 199665, upload-time = "2026-01-29T13:53:33.616Z" }, +] + +[[package]] +name = "coverage" +version = "7.13.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/24/56/95b7e30fa389756cb56630faa728da46a27b8c6eb46f9d557c68fff12b65/coverage-7.13.4.tar.gz", hash = "sha256:e5c8f6ed1e61a8b2dcdf31eb0b9bbf0130750ca79c1c49eb898e2ad86f5ccc91", size = 827239, upload-time = "2026-02-09T12:59:03.86Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b4/ad/b59e5b451cf7172b8d1043dc0fa718f23aab379bc1521ee13d4bd9bfa960/coverage-7.13.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d490ba50c3f35dd7c17953c68f3270e7ccd1c6642e2d2afe2d8e720b98f5a053", size = 219278, upload-time = "2026-02-09T12:56:31.673Z" }, + { url = "https://files.pythonhosted.org/packages/f1/17/0cb7ca3de72e5f4ef2ec2fa0089beafbcaaaead1844e8b8a63d35173d77d/coverage-7.13.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:19bc3c88078789f8ef36acb014d7241961dbf883fd2533d18cb1e7a5b4e28b11", size = 219783, upload-time = "2026-02-09T12:56:33.104Z" }, + { url = "https://files.pythonhosted.org/packages/ab/63/325d8e5b11e0eaf6d0f6a44fad444ae58820929a9b0de943fa377fe73e85/coverage-7.13.4-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:3998e5a32e62fdf410c0dbd3115df86297995d6e3429af80b8798aad894ca7aa", size = 250200, upload-time = "2026-02-09T12:56:34.474Z" }, + { url = "https://files.pythonhosted.org/packages/76/53/c16972708cbb79f2942922571a687c52bd109a7bd51175aeb7558dff2236/coverage-7.13.4-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:8e264226ec98e01a8e1054314af91ee6cde0eacac4f465cc93b03dbe0bce2fd7", size = 252114, upload-time = "2026-02-09T12:56:35.749Z" }, + { url = "https://files.pythonhosted.org/packages/eb/c2/7ab36d8b8cc412bec9ea2d07c83c48930eb4ba649634ba00cb7e4e0f9017/coverage-7.13.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a3aa4e7b9e416774b21797365b358a6e827ffadaaca81b69ee02946852449f00", size = 254220, upload-time = "2026-02-09T12:56:37.796Z" }, + { url = "https://files.pythonhosted.org/packages/d6/4d/cf52c9a3322c89a0e6febdfbc83bb45c0ed3c64ad14081b9503adee702e7/coverage-7.13.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:71ca20079dd8f27fcf808817e281e90220475cd75115162218d0e27549f95fef", size = 256164, upload-time = "2026-02-09T12:56:39.016Z" }, + { url = "https://files.pythonhosted.org/packages/78/e9/eb1dd17bd6de8289df3580e967e78294f352a5df8a57ff4671ee5fc3dcd0/coverage-7.13.4-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e2f25215f1a359ab17320b47bcdaca3e6e6356652e8256f2441e4ef972052903", size = 250325, upload-time = "2026-02-09T12:56:40.668Z" }, + { url = "https://files.pythonhosted.org/packages/71/07/8c1542aa873728f72267c07278c5cc0ec91356daf974df21335ccdb46368/coverage-7.13.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d65b2d373032411e86960604dc4edac91fdfb5dca539461cf2cbe78327d1e64f", size = 251913, upload-time = "2026-02-09T12:56:41.97Z" }, + { url = "https://files.pythonhosted.org/packages/74/d7/c62e2c5e4483a748e27868e4c32ad3daa9bdddbba58e1bc7a15e252baa74/coverage-7.13.4-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:94eb63f9b363180aff17de3e7c8760c3ba94664ea2695c52f10111244d16a299", size = 249974, upload-time = "2026-02-09T12:56:43.323Z" }, + { url = "https://files.pythonhosted.org/packages/98/9f/4c5c015a6e98ced54efd0f5cf8d31b88e5504ecb6857585fc0161bb1e600/coverage-7.13.4-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:e856bf6616714c3a9fbc270ab54103f4e685ba236fa98c054e8f87f266c93505", size = 253741, upload-time = "2026-02-09T12:56:45.155Z" }, + { url = "https://files.pythonhosted.org/packages/bd/59/0f4eef89b9f0fcd9633b5d350016f54126ab49426a70ff4c4e87446cabdc/coverage-7.13.4-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:65dfcbe305c3dfe658492df2d85259e0d79ead4177f9ae724b6fb245198f55d6", size = 249695, upload-time = "2026-02-09T12:56:46.636Z" }, + { url = "https://files.pythonhosted.org/packages/b5/2c/b7476f938deb07166f3eb281a385c262675d688ff4659ad56c6c6b8e2e70/coverage-7.13.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b507778ae8a4c915436ed5c2e05b4a6cecfa70f734e19c22a005152a11c7b6a9", size = 250599, upload-time = "2026-02-09T12:56:48.13Z" }, + { url = "https://files.pythonhosted.org/packages/b8/34/c3420709d9846ee3785b9f2831b4d94f276f38884032dca1457fa83f7476/coverage-7.13.4-cp311-cp311-win32.whl", hash = "sha256:784fc3cf8be001197b652d51d3fd259b1e2262888693a4636e18879f613a62a9", size = 221780, upload-time = "2026-02-09T12:56:50.479Z" }, + { url = "https://files.pythonhosted.org/packages/61/08/3d9c8613079d2b11c185b865de9a4c1a68850cfda2b357fae365cf609f29/coverage-7.13.4-cp311-cp311-win_amd64.whl", hash = "sha256:2421d591f8ca05b308cf0092807308b2facbefe54af7c02ac22548b88b95c98f", size = 222715, upload-time = "2026-02-09T12:56:51.815Z" }, + { url = "https://files.pythonhosted.org/packages/18/1a/54c3c80b2f056164cc0a6cdcb040733760c7c4be9d780fe655f356f433e4/coverage-7.13.4-cp311-cp311-win_arm64.whl", hash = "sha256:79e73a76b854d9c6088fe5d8b2ebe745f8681c55f7397c3c0a016192d681045f", size = 221385, upload-time = "2026-02-09T12:56:53.194Z" }, + { url = "https://files.pythonhosted.org/packages/d1/81/4ce2fdd909c5a0ed1f6dedb88aa57ab79b6d1fbd9b588c1ac7ef45659566/coverage-7.13.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:02231499b08dabbe2b96612993e5fc34217cdae907a51b906ac7fca8027a4459", size = 219449, upload-time = "2026-02-09T12:56:54.889Z" }, + { url = "https://files.pythonhosted.org/packages/5d/96/5238b1efc5922ddbdc9b0db9243152c09777804fb7c02ad1741eb18a11c0/coverage-7.13.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40aa8808140e55dc022b15d8aa7f651b6b3d68b365ea0398f1441e0b04d859c3", size = 219810, upload-time = "2026-02-09T12:56:56.33Z" }, + { url = "https://files.pythonhosted.org/packages/78/72/2f372b726d433c9c35e56377cf1d513b4c16fe51841060d826b95caacec1/coverage-7.13.4-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:5b856a8ccf749480024ff3bd7310adaef57bf31fd17e1bfc404b7940b6986634", size = 251308, upload-time = "2026-02-09T12:56:57.858Z" }, + { url = "https://files.pythonhosted.org/packages/5d/a0/2ea570925524ef4e00bb6c82649f5682a77fac5ab910a65c9284de422600/coverage-7.13.4-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:2c048ea43875fbf8b45d476ad79f179809c590ec7b79e2035c662e7afa3192e3", size = 254052, upload-time = "2026-02-09T12:56:59.754Z" }, + { url = "https://files.pythonhosted.org/packages/e8/ac/45dc2e19a1939098d783c846e130b8f862fbb50d09e0af663988f2f21973/coverage-7.13.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b7b38448866e83176e28086674fe7368ab8590e4610fb662b44e345b86d63ffa", size = 255165, upload-time = "2026-02-09T12:57:01.287Z" }, + { url = "https://files.pythonhosted.org/packages/2d/4d/26d236ff35abc3b5e63540d3386e4c3b192168c1d96da5cb2f43c640970f/coverage-7.13.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:de6defc1c9badbf8b9e67ae90fd00519186d6ab64e5cc5f3d21359c2a9b2c1d3", size = 257432, upload-time = "2026-02-09T12:57:02.637Z" }, + { url = "https://files.pythonhosted.org/packages/ec/55/14a966c757d1348b2e19caf699415a2a4c4f7feaa4bbc6326a51f5c7dd1b/coverage-7.13.4-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:7eda778067ad7ffccd23ecffce537dface96212576a07924cbf0d8799d2ded5a", size = 251716, upload-time = "2026-02-09T12:57:04.056Z" }, + { url = "https://files.pythonhosted.org/packages/77/33/50116647905837c66d28b2af1321b845d5f5d19be9655cb84d4a0ea806b4/coverage-7.13.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e87f6c587c3f34356c3759f0420693e35e7eb0e2e41e4c011cb6ec6ecbbf1db7", size = 253089, upload-time = "2026-02-09T12:57:05.503Z" }, + { url = "https://files.pythonhosted.org/packages/c2/b4/8efb11a46e3665d92635a56e4f2d4529de6d33f2cb38afd47d779d15fc99/coverage-7.13.4-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:8248977c2e33aecb2ced42fef99f2d319e9904a36e55a8a68b69207fb7e43edc", size = 251232, upload-time = "2026-02-09T12:57:06.879Z" }, + { url = "https://files.pythonhosted.org/packages/51/24/8cd73dd399b812cc76bb0ac260e671c4163093441847ffe058ac9fda1e32/coverage-7.13.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:25381386e80ae727608e662474db537d4df1ecd42379b5ba33c84633a2b36d47", size = 255299, upload-time = "2026-02-09T12:57:08.245Z" }, + { url = "https://files.pythonhosted.org/packages/03/94/0a4b12f1d0e029ce1ccc1c800944a9984cbe7d678e470bb6d3c6bc38a0da/coverage-7.13.4-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:ee756f00726693e5ba94d6df2bdfd64d4852d23b09bb0bc700e3b30e6f333985", size = 250796, upload-time = "2026-02-09T12:57:10.142Z" }, + { url = "https://files.pythonhosted.org/packages/73/44/6002fbf88f6698ca034360ce474c406be6d5a985b3fdb3401128031eef6b/coverage-7.13.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fdfc1e28e7c7cdce44985b3043bc13bbd9c747520f94a4d7164af8260b3d91f0", size = 252673, upload-time = "2026-02-09T12:57:12.197Z" }, + { url = "https://files.pythonhosted.org/packages/de/c6/a0279f7c00e786be75a749a5674e6fa267bcbd8209cd10c9a450c655dfa7/coverage-7.13.4-cp312-cp312-win32.whl", hash = "sha256:01d4cbc3c283a17fc1e42d614a119f7f438eabb593391283adca8dc86eff1246", size = 221990, upload-time = "2026-02-09T12:57:14.085Z" }, + { url = "https://files.pythonhosted.org/packages/77/4e/c0a25a425fcf5557d9abd18419c95b63922e897bc86c1f327f155ef234a9/coverage-7.13.4-cp312-cp312-win_amd64.whl", hash = "sha256:9401ebc7ef522f01d01d45532c68c5ac40fb27113019b6b7d8b208f6e9baa126", size = 222800, upload-time = "2026-02-09T12:57:15.944Z" }, + { url = "https://files.pythonhosted.org/packages/47/ac/92da44ad9a6f4e3a7debd178949d6f3769bedca33830ce9b1dcdab589a37/coverage-7.13.4-cp312-cp312-win_arm64.whl", hash = "sha256:b1ec7b6b6e93255f952e27ab58fbc68dcc468844b16ecbee881aeb29b6ab4d8d", size = 221415, upload-time = "2026-02-09T12:57:17.497Z" }, + { url = "https://files.pythonhosted.org/packages/db/23/aad45061a31677d68e47499197a131eea55da4875d16c1f42021ab963503/coverage-7.13.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b66a2da594b6068b48b2692f043f35d4d3693fb639d5ea8b39533c2ad9ac3ab9", size = 219474, upload-time = "2026-02-09T12:57:19.332Z" }, + { url = "https://files.pythonhosted.org/packages/a5/70/9b8b67a0945f3dfec1fd896c5cefb7c19d5a3a6d74630b99a895170999ae/coverage-7.13.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3599eb3992d814d23b35c536c28df1a882caa950f8f507cef23d1cbf334995ac", size = 219844, upload-time = "2026-02-09T12:57:20.66Z" }, + { url = "https://files.pythonhosted.org/packages/97/fd/7e859f8fab324cef6c4ad7cff156ca7c489fef9179d5749b0c8d321281c2/coverage-7.13.4-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:93550784d9281e374fb5a12bf1324cc8a963fd63b2d2f223503ef0fd4aa339ea", size = 250832, upload-time = "2026-02-09T12:57:22.007Z" }, + { url = "https://files.pythonhosted.org/packages/e4/dc/b2442d10020c2f52617828862d8b6ee337859cd8f3a1f13d607dddda9cf7/coverage-7.13.4-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:b720ce6a88a2755f7c697c23268ddc47a571b88052e6b155224347389fdf6a3b", size = 253434, upload-time = "2026-02-09T12:57:23.339Z" }, + { url = "https://files.pythonhosted.org/packages/5a/88/6728a7ad17428b18d836540630487231f5470fb82454871149502f5e5aa2/coverage-7.13.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7b322db1284a2ed3aa28ffd8ebe3db91c929b7a333c0820abec3d838ef5b3525", size = 254676, upload-time = "2026-02-09T12:57:24.774Z" }, + { url = "https://files.pythonhosted.org/packages/7c/bc/21244b1b8cedf0dff0a2b53b208015fe798d5f2a8d5348dbfece04224fff/coverage-7.13.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f4594c67d8a7c89cf922d9df0438c7c7bb022ad506eddb0fdb2863359ff78242", size = 256807, upload-time = "2026-02-09T12:57:26.125Z" }, + { url = "https://files.pythonhosted.org/packages/97/a0/ddba7ed3251cff51006737a727d84e05b61517d1784a9988a846ba508877/coverage-7.13.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:53d133df809c743eb8bce33b24bcababb371f4441340578cd406e084d94a6148", size = 251058, upload-time = "2026-02-09T12:57:27.614Z" }, + { url = "https://files.pythonhosted.org/packages/9b/55/e289addf7ff54d3a540526f33751951bf0878f3809b47f6dfb3def69c6f7/coverage-7.13.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:76451d1978b95ba6507a039090ba076105c87cc76fc3efd5d35d72093964d49a", size = 252805, upload-time = "2026-02-09T12:57:29.066Z" }, + { url = "https://files.pythonhosted.org/packages/13/4e/cc276b1fa4a59be56d96f1dabddbdc30f4ba22e3b1cd42504c37b3313255/coverage-7.13.4-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:7f57b33491e281e962021de110b451ab8a24182589be17e12a22c79047935e23", size = 250766, upload-time = "2026-02-09T12:57:30.522Z" }, + { url = "https://files.pythonhosted.org/packages/94/44/1093b8f93018f8b41a8cf29636c9292502f05e4a113d4d107d14a3acd044/coverage-7.13.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:1731dc33dc276dafc410a885cbf5992f1ff171393e48a21453b78727d090de80", size = 254923, upload-time = "2026-02-09T12:57:31.946Z" }, + { url = "https://files.pythonhosted.org/packages/8b/55/ea2796da2d42257f37dbea1aab239ba9263b31bd91d5527cdd6db5efe174/coverage-7.13.4-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:bd60d4fe2f6fa7dff9223ca1bbc9f05d2b6697bc5961072e5d3b952d46e1b1ea", size = 250591, upload-time = "2026-02-09T12:57:33.842Z" }, + { url = "https://files.pythonhosted.org/packages/d4/fa/7c4bb72aacf8af5020675aa633e59c1fbe296d22aed191b6a5b711eb2bc7/coverage-7.13.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9181a3ccead280b828fae232df12b16652702b49d41e99d657f46cc7b1f6ec7a", size = 252364, upload-time = "2026-02-09T12:57:35.743Z" }, + { url = "https://files.pythonhosted.org/packages/5c/38/a8d2ec0146479c20bbaa7181b5b455a0c41101eed57f10dd19a78ab44c80/coverage-7.13.4-cp313-cp313-win32.whl", hash = "sha256:f53d492307962561ac7de4cd1de3e363589b000ab69617c6156a16ba7237998d", size = 222010, upload-time = "2026-02-09T12:57:37.25Z" }, + { url = "https://files.pythonhosted.org/packages/e2/0c/dbfafbe90a185943dcfbc766fe0e1909f658811492d79b741523a414a6cc/coverage-7.13.4-cp313-cp313-win_amd64.whl", hash = "sha256:e6f70dec1cc557e52df5306d051ef56003f74d56e9c4dd7ddb07e07ef32a84dd", size = 222818, upload-time = "2026-02-09T12:57:38.734Z" }, + { url = "https://files.pythonhosted.org/packages/04/d1/934918a138c932c90d78301f45f677fb05c39a3112b96fd2c8e60503cdc7/coverage-7.13.4-cp313-cp313-win_arm64.whl", hash = "sha256:fb07dc5da7e849e2ad31a5d74e9bece81f30ecf5a42909d0a695f8bd1874d6af", size = 221438, upload-time = "2026-02-09T12:57:40.223Z" }, + { url = "https://files.pythonhosted.org/packages/52/57/ee93ced533bcb3e6df961c0c6e42da2fc6addae53fb95b94a89b1e33ebd7/coverage-7.13.4-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:40d74da8e6c4b9ac18b15331c4b5ebc35a17069410cad462ad4f40dcd2d50c0d", size = 220165, upload-time = "2026-02-09T12:57:41.639Z" }, + { url = "https://files.pythonhosted.org/packages/c5/e0/969fc285a6fbdda49d91af278488d904dcd7651b2693872f0ff94e40e84a/coverage-7.13.4-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:4223b4230a376138939a9173f1bdd6521994f2aff8047fae100d6d94d50c5a12", size = 220516, upload-time = "2026-02-09T12:57:44.215Z" }, + { url = "https://files.pythonhosted.org/packages/b1/b8/9531944e16267e2735a30a9641ff49671f07e8138ecf1ca13db9fd2560c7/coverage-7.13.4-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:1d4be36a5114c499f9f1f9195e95ebf979460dbe2d88e6816ea202010ba1c34b", size = 261804, upload-time = "2026-02-09T12:57:45.989Z" }, + { url = "https://files.pythonhosted.org/packages/8a/f3/e63df6d500314a2a60390d1989240d5f27318a7a68fa30ad3806e2a9323e/coverage-7.13.4-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:200dea7d1e8095cc6e98cdabe3fd1d21ab17d3cee6dab00cadbb2fe35d9c15b9", size = 263885, upload-time = "2026-02-09T12:57:47.42Z" }, + { url = "https://files.pythonhosted.org/packages/f3/67/7654810de580e14b37670b60a09c599fa348e48312db5b216d730857ffe6/coverage-7.13.4-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b8eb931ee8e6d8243e253e5ed7336deea6904369d2fd8ae6e43f68abbf167092", size = 266308, upload-time = "2026-02-09T12:57:49.345Z" }, + { url = "https://files.pythonhosted.org/packages/37/6f/39d41eca0eab3cc82115953ad41c4e77935286c930e8fad15eaed1389d83/coverage-7.13.4-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:75eab1ebe4f2f64d9509b984f9314d4aa788540368218b858dad56dc8f3e5eb9", size = 267452, upload-time = "2026-02-09T12:57:50.811Z" }, + { url = "https://files.pythonhosted.org/packages/50/6d/39c0fbb8fc5cd4d2090811e553c2108cf5112e882f82505ee7495349a6bf/coverage-7.13.4-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c35eb28c1d085eb7d8c9b3296567a1bebe03ce72962e932431b9a61f28facf26", size = 261057, upload-time = "2026-02-09T12:57:52.447Z" }, + { url = "https://files.pythonhosted.org/packages/a4/a2/60010c669df5fa603bb5a97fb75407e191a846510da70ac657eb696b7fce/coverage-7.13.4-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:eb88b316ec33760714a4720feb2816a3a59180fd58c1985012054fa7aebee4c2", size = 263875, upload-time = "2026-02-09T12:57:53.938Z" }, + { url = "https://files.pythonhosted.org/packages/3e/d9/63b22a6bdbd17f1f96e9ed58604c2a6b0e72a9133e37d663bef185877cf6/coverage-7.13.4-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:7d41eead3cc673cbd38a4417deb7fd0b4ca26954ff7dc6078e33f6ff97bed940", size = 261500, upload-time = "2026-02-09T12:57:56.012Z" }, + { url = "https://files.pythonhosted.org/packages/70/bf/69f86ba1ad85bc3ad240e4c0e57a2e620fbc0e1645a47b5c62f0e941ad7f/coverage-7.13.4-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:fb26a934946a6afe0e326aebe0730cdff393a8bc0bbb65a2f41e30feddca399c", size = 265212, upload-time = "2026-02-09T12:57:57.5Z" }, + { url = "https://files.pythonhosted.org/packages/ae/f2/5f65a278a8c2148731831574c73e42f57204243d33bedaaf18fa79c5958f/coverage-7.13.4-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:dae88bc0fc77edaa65c14be099bd57ee140cf507e6bfdeea7938457ab387efb0", size = 260398, upload-time = "2026-02-09T12:57:59.027Z" }, + { url = "https://files.pythonhosted.org/packages/ef/80/6e8280a350ee9fea92f14b8357448a242dcaa243cb2c72ab0ca591f66c8c/coverage-7.13.4-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:845f352911777a8e722bfce168958214951e07e47e5d5d9744109fa5fe77f79b", size = 262584, upload-time = "2026-02-09T12:58:01.129Z" }, + { url = "https://files.pythonhosted.org/packages/22/63/01ff182fc95f260b539590fb12c11ad3e21332c15f9799cb5e2386f71d9f/coverage-7.13.4-cp313-cp313t-win32.whl", hash = "sha256:2fa8d5f8de70688a28240de9e139fa16b153cc3cbb01c5f16d88d6505ebdadf9", size = 222688, upload-time = "2026-02-09T12:58:02.736Z" }, + { url = "https://files.pythonhosted.org/packages/a9/43/89de4ef5d3cd53b886afa114065f7e9d3707bdb3e5efae13535b46ae483d/coverage-7.13.4-cp313-cp313t-win_amd64.whl", hash = "sha256:9351229c8c8407645840edcc277f4a2d44814d1bc34a2128c11c2a031d45a5dd", size = 223746, upload-time = "2026-02-09T12:58:05.362Z" }, + { url = "https://files.pythonhosted.org/packages/35/39/7cf0aa9a10d470a5309b38b289b9bb07ddeac5d61af9b664fe9775a4cb3e/coverage-7.13.4-cp313-cp313t-win_arm64.whl", hash = "sha256:30b8d0512f2dc8c8747557e8fb459d6176a2c9e5731e2b74d311c03b78451997", size = 222003, upload-time = "2026-02-09T12:58:06.952Z" }, + { url = "https://files.pythonhosted.org/packages/92/11/a9cf762bb83386467737d32187756a42094927150c3e107df4cb078e8590/coverage-7.13.4-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:300deaee342f90696ed186e3a00c71b5b3d27bffe9e827677954f4ee56969601", size = 219522, upload-time = "2026-02-09T12:58:08.623Z" }, + { url = "https://files.pythonhosted.org/packages/d3/28/56e6d892b7b052236d67c95f1936b6a7cf7c3e2634bf27610b8cbd7f9c60/coverage-7.13.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:29e3220258d682b6226a9b0925bc563ed9a1ebcff3cad30f043eceea7eaf2689", size = 219855, upload-time = "2026-02-09T12:58:10.176Z" }, + { url = "https://files.pythonhosted.org/packages/e5/69/233459ee9eb0c0d10fcc2fe425a029b3fa5ce0f040c966ebce851d030c70/coverage-7.13.4-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:391ee8f19bef69210978363ca930f7328081c6a0152f1166c91f0b5fdd2a773c", size = 250887, upload-time = "2026-02-09T12:58:12.503Z" }, + { url = "https://files.pythonhosted.org/packages/06/90/2cdab0974b9b5bbc1623f7876b73603aecac11b8d95b85b5b86b32de5eab/coverage-7.13.4-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:0dd7ab8278f0d58a0128ba2fca25824321f05d059c1441800e934ff2efa52129", size = 253396, upload-time = "2026-02-09T12:58:14.615Z" }, + { url = "https://files.pythonhosted.org/packages/ac/15/ea4da0f85bf7d7b27635039e649e99deb8173fe551096ea15017f7053537/coverage-7.13.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:78cdf0d578b15148b009ccf18c686aa4f719d887e76e6b40c38ffb61d264a552", size = 254745, upload-time = "2026-02-09T12:58:16.162Z" }, + { url = "https://files.pythonhosted.org/packages/99/11/bb356e86920c655ca4d61daee4e2bbc7258f0a37de0be32d233b561134ff/coverage-7.13.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:48685fee12c2eb3b27c62f2658e7ea21e9c3239cba5a8a242801a0a3f6a8c62a", size = 257055, upload-time = "2026-02-09T12:58:17.892Z" }, + { url = "https://files.pythonhosted.org/packages/c9/0f/9ae1f8cb17029e09da06ca4e28c9e1d5c1c0a511c7074592e37e0836c915/coverage-7.13.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:4e83efc079eb39480e6346a15a1bcb3e9b04759c5202d157e1dd4303cd619356", size = 250911, upload-time = "2026-02-09T12:58:19.495Z" }, + { url = "https://files.pythonhosted.org/packages/89/3a/adfb68558fa815cbc29747b553bc833d2150228f251b127f1ce97e48547c/coverage-7.13.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ecae9737b72408d6a950f7e525f30aca12d4bd8dd95e37342e5beb3a2a8c4f71", size = 252754, upload-time = "2026-02-09T12:58:21.064Z" }, + { url = "https://files.pythonhosted.org/packages/32/b1/540d0c27c4e748bd3cd0bd001076ee416eda993c2bae47a73b7cc9357931/coverage-7.13.4-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:ae4578f8528569d3cf303fef2ea569c7f4c4059a38c8667ccef15c6e1f118aa5", size = 250720, upload-time = "2026-02-09T12:58:22.622Z" }, + { url = "https://files.pythonhosted.org/packages/c7/95/383609462b3ffb1fe133014a7c84fc0dd01ed55ac6140fa1093b5af7ebb1/coverage-7.13.4-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:6fdef321fdfbb30a197efa02d48fcd9981f0d8ad2ae8903ac318adc653f5df98", size = 254994, upload-time = "2026-02-09T12:58:24.548Z" }, + { url = "https://files.pythonhosted.org/packages/f7/ba/1761138e86c81680bfc3c49579d66312865457f9fe405b033184e5793cb3/coverage-7.13.4-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:2b0f6ccf3dbe577170bebfce1318707d0e8c3650003cb4b3a9dd744575daa8b5", size = 250531, upload-time = "2026-02-09T12:58:26.271Z" }, + { url = "https://files.pythonhosted.org/packages/f8/8e/05900df797a9c11837ab59c4d6fe94094e029582aab75c3309a93e6fb4e3/coverage-7.13.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:75fcd519f2a5765db3f0e391eb3b7d150cce1a771bf4c9f861aeab86c767a3c0", size = 252189, upload-time = "2026-02-09T12:58:27.807Z" }, + { url = "https://files.pythonhosted.org/packages/00/bd/29c9f2db9ea4ed2738b8a9508c35626eb205d51af4ab7bf56a21a2e49926/coverage-7.13.4-cp314-cp314-win32.whl", hash = "sha256:8e798c266c378da2bd819b0677df41ab46d78065fb2a399558f3f6cae78b2fbb", size = 222258, upload-time = "2026-02-09T12:58:29.441Z" }, + { url = "https://files.pythonhosted.org/packages/a7/4d/1f8e723f6829977410efeb88f73673d794075091c8c7c18848d273dc9d73/coverage-7.13.4-cp314-cp314-win_amd64.whl", hash = "sha256:245e37f664d89861cf2329c9afa2c1fe9e6d4e1a09d872c947e70718aeeac505", size = 223073, upload-time = "2026-02-09T12:58:31.026Z" }, + { url = "https://files.pythonhosted.org/packages/51/5b/84100025be913b44e082ea32abcf1afbf4e872f5120b7a1cab1d331b1e13/coverage-7.13.4-cp314-cp314-win_arm64.whl", hash = "sha256:ad27098a189e5838900ce4c2a99f2fe42a0bf0c2093c17c69b45a71579e8d4a2", size = 221638, upload-time = "2026-02-09T12:58:32.599Z" }, + { url = "https://files.pythonhosted.org/packages/a7/e4/c884a405d6ead1370433dad1e3720216b4f9fd8ef5b64bfd984a2a60a11a/coverage-7.13.4-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:85480adfb35ffc32d40918aad81b89c69c9cc5661a9b8a81476d3e645321a056", size = 220246, upload-time = "2026-02-09T12:58:34.181Z" }, + { url = "https://files.pythonhosted.org/packages/81/5c/4d7ed8b23b233b0fffbc9dfec53c232be2e695468523242ea9fd30f97ad2/coverage-7.13.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:79be69cf7f3bf9b0deeeb062eab7ac7f36cd4cc4c4dd694bd28921ba4d8596cc", size = 220514, upload-time = "2026-02-09T12:58:35.704Z" }, + { url = "https://files.pythonhosted.org/packages/2f/6f/3284d4203fd2f28edd73034968398cd2d4cb04ab192abc8cff007ea35679/coverage-7.13.4-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:caa421e2684e382c5d8973ac55e4f36bed6821a9bad5c953494de960c74595c9", size = 261877, upload-time = "2026-02-09T12:58:37.864Z" }, + { url = "https://files.pythonhosted.org/packages/09/aa/b672a647bbe1556a85337dc95bfd40d146e9965ead9cc2fe81bde1e5cbce/coverage-7.13.4-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:14375934243ee05f56c45393fe2ce81fe5cc503c07cee2bdf1725fb8bef3ffaf", size = 264004, upload-time = "2026-02-09T12:58:39.492Z" }, + { url = "https://files.pythonhosted.org/packages/79/a1/aa384dbe9181f98bba87dd23dda436f0c6cf2e148aecbb4e50fc51c1a656/coverage-7.13.4-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:25a41c3104d08edb094d9db0d905ca54d0cd41c928bb6be3c4c799a54753af55", size = 266408, upload-time = "2026-02-09T12:58:41.852Z" }, + { url = "https://files.pythonhosted.org/packages/53/5e/5150bf17b4019bc600799f376bb9606941e55bd5a775dc1e096b6ffea952/coverage-7.13.4-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:6f01afcff62bf9a08fb32b2c1d6e924236c0383c02c790732b6537269e466a72", size = 267544, upload-time = "2026-02-09T12:58:44.093Z" }, + { url = "https://files.pythonhosted.org/packages/e0/ed/f1de5c675987a4a7a672250d2c5c9d73d289dbf13410f00ed7181d8017dd/coverage-7.13.4-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:eb9078108fbf0bcdde37c3f4779303673c2fa1fe8f7956e68d447d0dd426d38a", size = 260980, upload-time = "2026-02-09T12:58:45.721Z" }, + { url = "https://files.pythonhosted.org/packages/b3/e3/fe758d01850aa172419a6743fe76ba8b92c29d181d4f676ffe2dae2ba631/coverage-7.13.4-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:0e086334e8537ddd17e5f16a344777c1ab8194986ec533711cbe6c41cde841b6", size = 263871, upload-time = "2026-02-09T12:58:47.334Z" }, + { url = "https://files.pythonhosted.org/packages/b6/76/b829869d464115e22499541def9796b25312b8cf235d3bb00b39f1675395/coverage-7.13.4-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:725d985c5ab621268b2edb8e50dfe57633dc69bda071abc470fed55a14935fd3", size = 261472, upload-time = "2026-02-09T12:58:48.995Z" }, + { url = "https://files.pythonhosted.org/packages/14/9e/caedb1679e73e2f6ad240173f55218488bfe043e38da577c4ec977489915/coverage-7.13.4-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:3c06f0f1337c667b971ca2f975523347e63ec5e500b9aa5882d91931cd3ef750", size = 265210, upload-time = "2026-02-09T12:58:51.178Z" }, + { url = "https://files.pythonhosted.org/packages/3a/10/0dd02cb009b16ede425b49ec344aba13a6ae1dc39600840ea6abcb085ac4/coverage-7.13.4-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:590c0ed4bf8e85f745e6b805b2e1c457b2e33d5255dd9729743165253bc9ad39", size = 260319, upload-time = "2026-02-09T12:58:53.081Z" }, + { url = "https://files.pythonhosted.org/packages/92/8e/234d2c927af27c6d7a5ffad5bd2cf31634c46a477b4c7adfbfa66baf7ebb/coverage-7.13.4-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:eb30bf180de3f632cd043322dad5751390e5385108b2807368997d1a92a509d0", size = 262638, upload-time = "2026-02-09T12:58:55.258Z" }, + { url = "https://files.pythonhosted.org/packages/2f/64/e5547c8ff6964e5965c35a480855911b61509cce544f4d442caa759a0702/coverage-7.13.4-cp314-cp314t-win32.whl", hash = "sha256:c4240e7eded42d131a2d2c4dec70374b781b043ddc79a9de4d55ca71f8e98aea", size = 223040, upload-time = "2026-02-09T12:58:56.936Z" }, + { url = "https://files.pythonhosted.org/packages/c7/96/38086d58a181aac86d503dfa9c47eb20715a79c3e3acbdf786e92e5c09a8/coverage-7.13.4-cp314-cp314t-win_amd64.whl", hash = "sha256:4c7d3cc01e7350f2f0f6f7036caaf5673fb56b6998889ccfe9e1c1fe75a9c932", size = 224148, upload-time = "2026-02-09T12:58:58.645Z" }, + { url = "https://files.pythonhosted.org/packages/ce/72/8d10abd3740a0beb98c305e0c3faf454366221c0f37a8bcf8f60020bb65a/coverage-7.13.4-cp314-cp314t-win_arm64.whl", hash = "sha256:23e3f687cf945070d1c90f85db66d11e3025665d8dafa831301a0e0038f3db9b", size = 222172, upload-time = "2026-02-09T12:59:00.396Z" }, + { url = "https://files.pythonhosted.org/packages/0d/4a/331fe2caf6799d591109bb9c08083080f6de90a823695d412a935622abb2/coverage-7.13.4-py3-none-any.whl", hash = "sha256:1af1641e57cf7ba1bd67d677c9abdbcd6cc2ab7da3bca7fa1e2b7e50e65f2ad0", size = 211242, upload-time = "2026-02-09T12:59:02.032Z" }, +] + +[package.optional-dependencies] +toml = [ + { name = "tomli", marker = "python_full_version <= '3.11'" }, +] + +[[package]] +name = "defusedxml" +version = "0.7.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0f/d5/c66da9b79e5bdb124974bfe172b4daf3c984ebd9c2a06e2b8a4dc7331c72/defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69", size = 75520, upload-time = "2021-03-08T10:59:26.269Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/07/6c/aa3f2f849e01cb6a001cd8554a88d4c77c5c1a31c95bdf1cf9301e6d9ef4/defusedxml-0.7.1-py2.py3-none-any.whl", hash = "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61", size = 25604, upload-time = "2021-03-08T10:59:24.45Z" }, +] + +[[package]] +name = "deprecation" +version = "2.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "packaging" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5a/d3/8ae2869247df154b64c1884d7346d412fed0c49df84db635aab2d1c40e62/deprecation-2.1.0.tar.gz", hash = "sha256:72b3bde64e5d778694b0cf68178aed03d15e15477116add3fb773e581f9518ff", size = 173788, upload-time = "2020-04-20T14:23:38.738Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/02/c3/253a89ee03fc9b9682f1541728eb66db7db22148cd94f89ab22528cd1e1b/deprecation-2.1.0-py2.py3-none-any.whl", hash = "sha256:a10811591210e1fb0e768a8c25517cabeabcba6f0bf96564f8ff45189f90b14a", size = 11178, upload-time = "2020-04-20T14:23:36.581Z" }, +] + +[[package]] +name = "distlib" +version = "0.4.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/96/8e/709914eb2b5749865801041647dc7f4e6d00b549cfe88b65ca192995f07c/distlib-0.4.0.tar.gz", hash = "sha256:feec40075be03a04501a973d81f633735b4b69f98b05450592310c0f401a4e0d", size = 614605, upload-time = "2025-07-17T16:52:00.465Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/33/6b/e0547afaf41bf2c42e52430072fa5658766e3d65bd4b03a563d1b6336f57/distlib-0.4.0-py2.py3-none-any.whl", hash = "sha256:9659f7d87e46584a30b5780e43ac7a2143098441670ff0a49d5f9034c54a6c16", size = 469047, upload-time = "2025-07-17T16:51:58.613Z" }, +] + +[[package]] +name = "docutils" +version = "0.22.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ae/b6/03bb70946330e88ffec97aefd3ea75ba575cb2e762061e0e62a213befee8/docutils-0.22.4.tar.gz", hash = "sha256:4db53b1fde9abecbb74d91230d32ab626d94f6badfc575d6db9194a49df29968", size = 2291750, upload-time = "2025-12-18T19:00:26.443Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/02/10/5da547df7a391dcde17f59520a231527b8571e6f46fc8efb02ccb370ab12/docutils-0.22.4-py3-none-any.whl", hash = "sha256:d0013f540772d1420576855455d050a2180186c91c15779301ac2ccb3eeb68de", size = 633196, upload-time = "2025-12-18T19:00:18.077Z" }, +] + +[[package]] +name = "emcee" +version = "3.1.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/cb/53/1045ee878cb24281387079f8ee4f0ade1622c6aae1ed1fd91a53e4fa5b19/emcee-3.1.6.tar.gz", hash = "sha256:11af4daf6ab8f9ca69681e3c29054665db7bbd87fd4eb8e437d2c3a1248c637d", size = 2871117, upload-time = "2024-04-19T10:03:19.555Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f9/ef/2196b9bf88ffa1bde45853c72df021fbd07a8fa91a0f59a22d14a050dc04/emcee-3.1.6-py2.py3-none-any.whl", hash = "sha256:f2d63752023bdccf744461450e512a5b417ae7d28f18e12acd76a33de87580cb", size = 47351, upload-time = "2024-04-19T10:03:17.522Z" }, +] + +[[package]] +name = "fastjsonschema" +version = "2.21.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/20/b5/23b216d9d985a956623b6bd12d4086b60f0059b27799f23016af04a74ea1/fastjsonschema-2.21.2.tar.gz", hash = "sha256:b1eb43748041c880796cd077f1a07c3d94e93ae84bba5ed36800a33554ae05de", size = 374130, upload-time = "2025-08-14T18:49:36.666Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cb/a8/20d0723294217e47de6d9e2e40fd4a9d2f7c4b6ef974babd482a59743694/fastjsonschema-2.21.2-py3-none-any.whl", hash = "sha256:1c797122d0a86c5cace2e54bf4e819c36223b552017172f32c5c024a6b77e463", size = 24024, upload-time = "2025-08-14T18:49:34.776Z" }, +] + +[[package]] +name = "filelock" +version = "3.24.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/73/92/a8e2479937ff39185d20dd6a851c1a63e55849e447a55e798cc2e1f49c65/filelock-3.24.3.tar.gz", hash = "sha256:011a5644dc937c22699943ebbfc46e969cdde3e171470a6e40b9533e5a72affa", size = 37935, upload-time = "2026-02-19T00:48:20.543Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9c/0f/5d0c71a1aefeb08efff26272149e07ab922b64f46c63363756224bd6872e/filelock-3.24.3-py3-none-any.whl", hash = "sha256:426e9a4660391f7f8a810d71b0555bce9008b0a1cc342ab1f6947d37639e002d", size = 24331, upload-time = "2026-02-19T00:48:18.465Z" }, +] + +[[package]] +name = "halomod" +version = "2.2.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colossus" }, + { name = "hankel" }, + { name = "hmf" }, + { name = "mpmath" }, + { name = "numpy" }, + { name = "scipy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/37/53/add0844375062121033b679bda018705134d9a1668a8438f2ec2b426e499/halomod-2.2.2.tar.gz", hash = "sha256:bc6298a65921bc3136f5ad4386c2e1824e106dbdeb7fd9e7502dd3f9a18c4a04", size = 24513443, upload-time = "2024-12-03T10:04:36.039Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d2/f0/ecd42f3645ac65d8251ae0a4507db767f28c88c9e37eb8e1b94820c2318a/halomod-2.2.2-py3-none-any.whl", hash = "sha256:c825c968cbb335a34925020d51576a52070fbde2ed6fd64c899541d0639f4012", size = 6929536, upload-time = "2024-12-03T10:04:33.193Z" }, +] + +[[package]] +name = "hankel" +version = "1.2.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mpmath" }, + { name = "numpy" }, + { name = "scipy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c8/1e/499e211d69eeb165677ecaf853daae7d38d0a29b0ce0c274e5d664516d7f/hankel-1.2.2.tar.gz", hash = "sha256:ce1d1cd1f5a621a23c5fb49d66d67c10659e844b0c4191dbfdd0de6515766045", size = 6500138, upload-time = "2023-07-27T13:37:30.574Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/07/a7/81c1fd58eb86c34c3c9613414f98080f8b5aaf575c7d7b463e59635e0631/hankel-1.2.2-py3-none-any.whl", hash = "sha256:9f4d40e0f4ce01f1013288edeba542ac455bf07bf40a79ec6278b980bdc3efb2", size = 12114, upload-time = "2023-07-27T13:37:28.49Z" }, +] + +[[package]] +name = "hmf" +source = { editable = "." } +dependencies = [ + { name = "astropy" }, + { name = "cached-property" }, + { name = "camb" }, + { name = "click" }, + { name = "deprecation" }, + { name = "numpy" }, + { name = "rich" }, + { name = "scipy" }, + { name = "toml" }, +] + +[package.optional-dependencies] +all = [ + { name = "colossus" }, + { name = "coverage" }, + { name = "emcee" }, + { name = "halomod" }, + { name = "mpmath" }, + { name = "nbsphinx" }, + { name = "numba" }, + { name = "numpydoc" }, + { name = "pre-commit" }, + { name = "pytest" }, + { name = "pytest-cov" }, + { name = "ruff" }, + { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12'" }, + { name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, +] +cosmo = [ + { name = "colossus" }, +] +dev = [ + { name = "colossus" }, + { name = "coverage" }, + { name = "halomod" }, + { name = "mpmath" }, + { name = "nbsphinx" }, + { name = "numba" }, + { name = "numpydoc" }, + { name = "pre-commit" }, + { name = "pytest" }, + { name = "pytest-cov" }, + { name = "ruff" }, + { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12'" }, + { name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, +] +docs = [ + { name = "nbsphinx" }, + { name = "numpydoc" }, + { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12'" }, + { name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, +] +fit = [ + { name = "emcee" }, +] +tests = [ + { name = "colossus" }, + { name = "coverage" }, + { name = "halomod" }, + { name = "mpmath" }, + { name = "numba" }, + { name = "pytest" }, + { name = "pytest-cov" }, +] + +[package.metadata] +requires-dist = [ + { name = "astropy", specifier = ">=1.1" }, + { name = "cached-property" }, + { name = "camb", specifier = ">=1.0.0" }, + { name = "click" }, + { name = "colossus", marker = "extra == 'all'", specifier = ">=1.2.1" }, + { name = "colossus", marker = "extra == 'cosmo'", specifier = ">=1.2.1" }, + { name = "colossus", marker = "extra == 'dev'", specifier = ">=1.2.1" }, + { name = "colossus", marker = "extra == 'tests'", specifier = ">=1.2.1" }, + { name = "coverage", marker = "extra == 'all'", specifier = ">=4.5.1" }, + { name = "coverage", marker = "extra == 'dev'", specifier = ">=4.5.1" }, + { name = "coverage", marker = "extra == 'tests'", specifier = ">=4.5.1" }, + { name = "deprecation" }, + { name = "emcee", marker = "extra == 'all'", specifier = ">=3.0" }, + { name = "emcee", marker = "extra == 'fit'", specifier = ">=3.0" }, + { name = "halomod", marker = "extra == 'all'", specifier = ">=1.4.6" }, + { name = "halomod", marker = "extra == 'dev'", specifier = ">=1.4.6" }, + { name = "halomod", marker = "extra == 'tests'", specifier = ">=1.4.6" }, + { name = "mpmath", marker = "extra == 'all'", specifier = ">=1.0.0" }, + { name = "mpmath", marker = "extra == 'dev'", specifier = ">=1.0.0" }, + { name = "mpmath", marker = "extra == 'tests'", specifier = ">=1.0.0" }, + { name = "nbsphinx", marker = "extra == 'all'" }, + { name = "nbsphinx", marker = "extra == 'dev'" }, + { name = "nbsphinx", marker = "extra == 'docs'" }, + { name = "numba", marker = "extra == 'all'" }, + { name = "numba", marker = "extra == 'dev'" }, + { name = "numba", marker = "extra == 'tests'" }, + { name = "numpy", specifier = ">=1.6.2" }, + { name = "numpydoc", marker = "extra == 'all'", specifier = ">=0.8.0" }, + { name = "numpydoc", marker = "extra == 'dev'", specifier = ">=0.8.0" }, + { name = "numpydoc", marker = "extra == 'docs'", specifier = ">=0.8.0" }, + { name = "pre-commit", marker = "extra == 'all'" }, + { name = "pre-commit", marker = "extra == 'dev'" }, + { name = "pytest", marker = "extra == 'all'", specifier = ">=3.5.1" }, + { name = "pytest", marker = "extra == 'dev'", specifier = ">=3.5.1" }, + { name = "pytest", marker = "extra == 'tests'", specifier = ">=3.5.1" }, + { name = "pytest-cov", marker = "extra == 'all'", specifier = ">=2.5.1" }, + { name = "pytest-cov", marker = "extra == 'dev'", specifier = ">=2.5.1" }, + { name = "pytest-cov", marker = "extra == 'tests'", specifier = ">=2.5.1" }, + { name = "rich" }, + { name = "ruff", marker = "extra == 'all'" }, + { name = "ruff", marker = "extra == 'dev'" }, + { name = "scipy", specifier = ">=0.12.0" }, + { name = "sphinx", marker = "extra == 'all'", specifier = ">=1.7.5" }, + { name = "sphinx", marker = "extra == 'dev'", specifier = ">=1.7.5" }, + { name = "sphinx", marker = "extra == 'docs'", specifier = ">=1.7.5" }, + { name = "toml", specifier = ">=0.10.1" }, +] +provides-extras = ["all", "cosmo", "dev", "docs", "fit", "tests"] + +[[package]] +name = "identify" +version = "2.6.16" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/5b/8d/e8b97e6bd3fb6fb271346f7981362f1e04d6a7463abd0de79e1fda17c067/identify-2.6.16.tar.gz", hash = "sha256:846857203b5511bbe94d5a352a48ef2359532bc8f6727b5544077a0dcfb24980", size = 99360, upload-time = "2026-01-12T18:58:58.201Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b8/58/40fbbcefeda82364720eba5cf2270f98496bdfa19ea75b4cccae79c698e6/identify-2.6.16-py2.py3-none-any.whl", hash = "sha256:391ee4d77741d994189522896270b787aed8670389bfd60f326d677d64a6dfb0", size = 99202, upload-time = "2026-01-12T18:58:56.627Z" }, +] + +[[package]] +name = "idna" +version = "3.11" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/6f/6d/0703ccc57f3a7233505399edb88de3cbd678da106337b9fcde432b65ed60/idna-3.11.tar.gz", hash = "sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902", size = 194582, upload-time = "2025-10-12T14:55:20.501Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl", hash = "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea", size = 71008, upload-time = "2025-10-12T14:55:18.883Z" }, +] + +[[package]] +name = "imagesize" +version = "1.4.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a7/84/62473fb57d61e31fef6e36d64a179c8781605429fd927b5dd608c997be31/imagesize-1.4.1.tar.gz", hash = "sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a", size = 1280026, upload-time = "2022-07-01T12:21:05.687Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ff/62/85c4c919272577931d407be5ba5d71c20f0b616d31a0befe0ae45bb79abd/imagesize-1.4.1-py2.py3-none-any.whl", hash = "sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b", size = 8769, upload-time = "2022-07-01T12:21:02.467Z" }, +] + +[[package]] +name = "iniconfig" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", size = 20503, upload-time = "2025-10-18T21:55:43.219Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" }, +] + +[[package]] +name = "jinja2" +version = "3.1.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markupsafe" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/df/bf/f7da0350254c0ed7c72f3e33cef02e048281fec7ecec5f032d4aac52226b/jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d", size = 245115, upload-time = "2025-03-05T20:05:02.478Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899, upload-time = "2025-03-05T20:05:00.369Z" }, +] + +[[package]] +name = "jsonschema" +version = "4.26.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "attrs" }, + { name = "jsonschema-specifications" }, + { name = "referencing" }, + { name = "rpds-py" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b3/fc/e067678238fa451312d4c62bf6e6cf5ec56375422aee02f9cb5f909b3047/jsonschema-4.26.0.tar.gz", hash = "sha256:0c26707e2efad8aa1bfc5b7ce170f3fccc2e4918ff85989ba9ffa9facb2be326", size = 366583, upload-time = "2026-01-07T13:41:07.246Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/69/90/f63fb5873511e014207a475e2bb4e8b2e570d655b00ac19a9a0ca0a385ee/jsonschema-4.26.0-py3-none-any.whl", hash = "sha256:d489f15263b8d200f8387e64b4c3a75f06629559fb73deb8fdfb525f2dab50ce", size = 90630, upload-time = "2026-01-07T13:41:05.306Z" }, +] + +[[package]] +name = "jsonschema-specifications" +version = "2025.9.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "referencing" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/19/74/a633ee74eb36c44aa6d1095e7cc5569bebf04342ee146178e2d36600708b/jsonschema_specifications-2025.9.1.tar.gz", hash = "sha256:b540987f239e745613c7a9176f3edb72b832a4ac465cf02712288397832b5e8d", size = 32855, upload-time = "2025-09-08T01:34:59.186Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/41/45/1a4ed80516f02155c51f51e8cedb3c1902296743db0bbc66608a0db2814f/jsonschema_specifications-2025.9.1-py3-none-any.whl", hash = "sha256:98802fee3a11ee76ecaca44429fda8a41bff98b00a0f2838151b113f210cc6fe", size = 18437, upload-time = "2025-09-08T01:34:57.871Z" }, +] + +[[package]] +name = "jupyter-client" +version = "8.8.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jupyter-core" }, + { name = "python-dateutil" }, + { name = "pyzmq" }, + { name = "tornado" }, + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/05/e4/ba649102a3bc3fbca54e7239fb924fd434c766f855693d86de0b1f2bec81/jupyter_client-8.8.0.tar.gz", hash = "sha256:d556811419a4f2d96c869af34e854e3f059b7cc2d6d01a9cd9c85c267691be3e", size = 348020, upload-time = "2026-01-08T13:55:47.938Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2d/0b/ceb7694d864abc0a047649aec263878acb9f792e1fec3e676f22dc9015e3/jupyter_client-8.8.0-py3-none-any.whl", hash = "sha256:f93a5b99c5e23a507b773d3a1136bd6e16c67883ccdbd9a829b0bbdb98cd7d7a", size = 107371, upload-time = "2026-01-08T13:55:45.562Z" }, +] + +[[package]] +name = "jupyter-core" +version = "5.9.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "platformdirs" }, + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/02/49/9d1284d0dc65e2c757b74c6687b6d319b02f822ad039e5c512df9194d9dd/jupyter_core-5.9.1.tar.gz", hash = "sha256:4d09aaff303b9566c3ce657f580bd089ff5c91f5f89cf7d8846c3cdf465b5508", size = 89814, upload-time = "2025-10-16T19:19:18.444Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e7/e7/80988e32bf6f73919a113473a604f5a8f09094de312b9d52b79c2df7612b/jupyter_core-5.9.1-py3-none-any.whl", hash = "sha256:ebf87fdc6073d142e114c72c9e29a9d7ca03fad818c5d300ce2adc1fb0743407", size = 29032, upload-time = "2025-10-16T19:19:16.783Z" }, +] + +[[package]] +name = "jupyterlab-pygments" +version = "0.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/90/51/9187be60d989df97f5f0aba133fa54e7300f17616e065d1ada7d7646b6d6/jupyterlab_pygments-0.3.0.tar.gz", hash = "sha256:721aca4d9029252b11cfa9d185e5b5af4d54772bb8072f9b7036f4170054d35d", size = 512900, upload-time = "2023-11-23T09:26:37.44Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b1/dd/ead9d8ea85bf202d90cc513b533f9c363121c7792674f78e0d8a854b63b4/jupyterlab_pygments-0.3.0-py3-none-any.whl", hash = "sha256:841a89020971da1d8693f1a99997aefc5dc424bb1b251fd6322462a1b8842780", size = 15884, upload-time = "2023-11-23T09:26:34.325Z" }, +] + +[[package]] +name = "llvmlite" +version = "0.46.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/74/cd/08ae687ba099c7e3d21fe2ea536500563ef1943c5105bf6ab4ee3829f68e/llvmlite-0.46.0.tar.gz", hash = "sha256:227c9fd6d09dce2783c18b754b7cd9d9b3b3515210c46acc2d3c5badd9870ceb", size = 193456, upload-time = "2025-12-08T18:15:36.295Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7a/a1/2ad4b2367915faeebe8447f0a057861f646dbf5fbbb3561db42c65659cf3/llvmlite-0.46.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:82f3d39b16f19aa1a56d5fe625883a6ab600d5cc9ea8906cca70ce94cabba067", size = 37232766, upload-time = "2025-12-08T18:14:48.836Z" }, + { url = "https://files.pythonhosted.org/packages/12/b5/99cf8772fdd846c07da4fd70f07812a3c8fd17ea2409522c946bb0f2b277/llvmlite-0.46.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:a3df43900119803bbc52720e758c76f316a9a0f34612a886862dfe0a5591a17e", size = 56275175, upload-time = "2025-12-08T18:14:51.604Z" }, + { url = "https://files.pythonhosted.org/packages/38/f2/ed806f9c003563732da156139c45d970ee435bd0bfa5ed8de87ba972b452/llvmlite-0.46.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:de183fefc8022d21b0aa37fc3e90410bc3524aed8617f0ff76732fc6c3af5361", size = 55128630, upload-time = "2025-12-08T18:14:55.107Z" }, + { url = "https://files.pythonhosted.org/packages/19/0c/8f5a37a65fc9b7b17408508145edd5f86263ad69c19d3574e818f533a0eb/llvmlite-0.46.0-cp311-cp311-win_amd64.whl", hash = "sha256:e8b10bc585c58bdffec9e0c309bb7d51be1f2f15e169a4b4d42f2389e431eb93", size = 38138652, upload-time = "2025-12-08T18:14:58.171Z" }, + { url = "https://files.pythonhosted.org/packages/2b/f8/4db016a5e547d4e054ff2f3b99203d63a497465f81ab78ec8eb2ff7b2304/llvmlite-0.46.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6b9588ad4c63b4f0175a3984b85494f0c927c6b001e3a246a3a7fb3920d9a137", size = 37232767, upload-time = "2025-12-08T18:15:00.737Z" }, + { url = "https://files.pythonhosted.org/packages/aa/85/4890a7c14b4fa54400945cb52ac3cd88545bbdb973c440f98ca41591cdc5/llvmlite-0.46.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3535bd2bb6a2d7ae4012681ac228e5132cdb75fefb1bcb24e33f2f3e0c865ed4", size = 56275176, upload-time = "2025-12-08T18:15:03.936Z" }, + { url = "https://files.pythonhosted.org/packages/6a/07/3d31d39c1a1a08cd5337e78299fca77e6aebc07c059fbd0033e3edfab45c/llvmlite-0.46.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4cbfd366e60ff87ea6cc62f50bc4cd800ebb13ed4c149466f50cf2163a473d1e", size = 55128630, upload-time = "2025-12-08T18:15:07.196Z" }, + { url = "https://files.pythonhosted.org/packages/2a/6b/d139535d7590a1bba1ceb68751bef22fadaa5b815bbdf0e858e3875726b2/llvmlite-0.46.0-cp312-cp312-win_amd64.whl", hash = "sha256:398b39db462c39563a97b912d4f2866cd37cba60537975a09679b28fbbc0fb38", size = 38138940, upload-time = "2025-12-08T18:15:10.162Z" }, + { url = "https://files.pythonhosted.org/packages/e6/ff/3eba7eb0aed4b6fca37125387cd417e8c458e750621fce56d2c541f67fa8/llvmlite-0.46.0-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:30b60892d034bc560e0ec6654737aaa74e5ca327bd8114d82136aa071d611172", size = 37232767, upload-time = "2025-12-08T18:15:13.22Z" }, + { url = "https://files.pythonhosted.org/packages/0e/54/737755c0a91558364b9200702c3c9c15d70ed63f9b98a2c32f1c2aa1f3ba/llvmlite-0.46.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:6cc19b051753368a9c9f31dc041299059ee91aceec81bd57b0e385e5d5bf1a54", size = 56275176, upload-time = "2025-12-08T18:15:16.339Z" }, + { url = "https://files.pythonhosted.org/packages/e6/91/14f32e1d70905c1c0aa4e6609ab5d705c3183116ca02ac6df2091868413a/llvmlite-0.46.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bca185892908f9ede48c0acd547fe4dc1bafefb8a4967d47db6cf664f9332d12", size = 55128629, upload-time = "2025-12-08T18:15:19.493Z" }, + { url = "https://files.pythonhosted.org/packages/4a/a7/d526ae86708cea531935ae777b6dbcabe7db52718e6401e0fb9c5edea80e/llvmlite-0.46.0-cp313-cp313-win_amd64.whl", hash = "sha256:67438fd30e12349ebb054d86a5a1a57fd5e87d264d2451bcfafbbbaa25b82a35", size = 38138941, upload-time = "2025-12-08T18:15:22.536Z" }, + { url = "https://files.pythonhosted.org/packages/95/ae/af0ffb724814cc2ea64445acad05f71cff5f799bb7efb22e47ee99340dbc/llvmlite-0.46.0-cp314-cp314-macosx_12_0_arm64.whl", hash = "sha256:d252edfb9f4ac1fcf20652258e3f102b26b03eef738dc8a6ffdab7d7d341d547", size = 37232768, upload-time = "2025-12-08T18:15:25.055Z" }, + { url = "https://files.pythonhosted.org/packages/c9/19/5018e5352019be753b7b07f7759cdabb69ca5779fea2494be8839270df4c/llvmlite-0.46.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:379fdd1c59badeff8982cb47e4694a6143bec3bb49aa10a466e095410522064d", size = 56275173, upload-time = "2025-12-08T18:15:28.109Z" }, + { url = "https://files.pythonhosted.org/packages/9f/c9/d57877759d707e84c082163c543853245f91b70c804115a5010532890f18/llvmlite-0.46.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2e8cbfff7f6db0fa2c771ad24154e2a7e457c2444d7673e6de06b8b698c3b269", size = 55128628, upload-time = "2025-12-08T18:15:31.098Z" }, + { url = "https://files.pythonhosted.org/packages/30/a8/e61a8c2b3cc7a597073d9cde1fcbb567e9d827f1db30c93cf80422eac70d/llvmlite-0.46.0-cp314-cp314-win_amd64.whl", hash = "sha256:7821eda3ec1f18050f981819756631d60b6d7ab1a6cf806d9efefbe3f4082d61", size = 39153056, upload-time = "2025-12-08T18:15:33.938Z" }, +] + +[[package]] +name = "markdown-it-py" +version = "4.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mdurl" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5b/f5/4ec618ed16cc4f8fb3b701563655a69816155e79e24a17b651541804721d/markdown_it_py-4.0.0.tar.gz", hash = "sha256:cb0a2b4aa34f932c007117b194e945bd74e0ec24133ceb5bac59009cda1cb9f3", size = 73070, upload-time = "2025-08-11T12:57:52.854Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl", hash = "sha256:87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147", size = 87321, upload-time = "2025-08-11T12:57:51.923Z" }, +] + +[[package]] +name = "markupsafe" +version = "3.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7e/99/7690b6d4034fffd95959cbe0c02de8deb3098cc577c67bb6a24fe5d7caa7/markupsafe-3.0.3.tar.gz", hash = "sha256:722695808f4b6457b320fdc131280796bdceb04ab50fe1795cd540799ebe1698", size = 80313, upload-time = "2025-09-27T18:37:40.426Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/08/db/fefacb2136439fc8dd20e797950e749aa1f4997ed584c62cfb8ef7c2be0e/markupsafe-3.0.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1cc7ea17a6824959616c525620e387f6dd30fec8cb44f649e31712db02123dad", size = 11631, upload-time = "2025-09-27T18:36:18.185Z" }, + { url = "https://files.pythonhosted.org/packages/e1/2e/5898933336b61975ce9dc04decbc0a7f2fee78c30353c5efba7f2d6ff27a/markupsafe-3.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4bd4cd07944443f5a265608cc6aab442e4f74dff8088b0dfc8238647b8f6ae9a", size = 12058, upload-time = "2025-09-27T18:36:19.444Z" }, + { url = "https://files.pythonhosted.org/packages/1d/09/adf2df3699d87d1d8184038df46a9c80d78c0148492323f4693df54e17bb/markupsafe-3.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b5420a1d9450023228968e7e6a9ce57f65d148ab56d2313fcd589eee96a7a50", size = 24287, upload-time = "2025-09-27T18:36:20.768Z" }, + { url = "https://files.pythonhosted.org/packages/30/ac/0273f6fcb5f42e314c6d8cd99effae6a5354604d461b8d392b5ec9530a54/markupsafe-3.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0bf2a864d67e76e5c9a34dc26ec616a66b9888e25e7b9460e1c76d3293bd9dbf", size = 22940, upload-time = "2025-09-27T18:36:22.249Z" }, + { url = "https://files.pythonhosted.org/packages/19/ae/31c1be199ef767124c042c6c3e904da327a2f7f0cd63a0337e1eca2967a8/markupsafe-3.0.3-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:bc51efed119bc9cfdf792cdeaa4d67e8f6fcccab66ed4bfdd6bde3e59bfcbb2f", size = 21887, upload-time = "2025-09-27T18:36:23.535Z" }, + { url = "https://files.pythonhosted.org/packages/b2/76/7edcab99d5349a4532a459e1fe64f0b0467a3365056ae550d3bcf3f79e1e/markupsafe-3.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:068f375c472b3e7acbe2d5318dea141359e6900156b5b2ba06a30b169086b91a", size = 23692, upload-time = "2025-09-27T18:36:24.823Z" }, + { url = "https://files.pythonhosted.org/packages/a4/28/6e74cdd26d7514849143d69f0bf2399f929c37dc2b31e6829fd2045b2765/markupsafe-3.0.3-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:7be7b61bb172e1ed687f1754f8e7484f1c8019780f6f6b0786e76bb01c2ae115", size = 21471, upload-time = "2025-09-27T18:36:25.95Z" }, + { url = "https://files.pythonhosted.org/packages/62/7e/a145f36a5c2945673e590850a6f8014318d5577ed7e5920a4b3448e0865d/markupsafe-3.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f9e130248f4462aaa8e2552d547f36ddadbeaa573879158d721bbd33dfe4743a", size = 22923, upload-time = "2025-09-27T18:36:27.109Z" }, + { url = "https://files.pythonhosted.org/packages/0f/62/d9c46a7f5c9adbeeeda52f5b8d802e1094e9717705a645efc71b0913a0a8/markupsafe-3.0.3-cp311-cp311-win32.whl", hash = "sha256:0db14f5dafddbb6d9208827849fad01f1a2609380add406671a26386cdf15a19", size = 14572, upload-time = "2025-09-27T18:36:28.045Z" }, + { url = "https://files.pythonhosted.org/packages/83/8a/4414c03d3f891739326e1783338e48fb49781cc915b2e0ee052aa490d586/markupsafe-3.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:de8a88e63464af587c950061a5e6a67d3632e36df62b986892331d4620a35c01", size = 15077, upload-time = "2025-09-27T18:36:29.025Z" }, + { url = "https://files.pythonhosted.org/packages/35/73/893072b42e6862f319b5207adc9ae06070f095b358655f077f69a35601f0/markupsafe-3.0.3-cp311-cp311-win_arm64.whl", hash = "sha256:3b562dd9e9ea93f13d53989d23a7e775fdfd1066c33494ff43f5418bc8c58a5c", size = 13876, upload-time = "2025-09-27T18:36:29.954Z" }, + { url = "https://files.pythonhosted.org/packages/5a/72/147da192e38635ada20e0a2e1a51cf8823d2119ce8883f7053879c2199b5/markupsafe-3.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d53197da72cc091b024dd97249dfc7794d6a56530370992a5e1a08983ad9230e", size = 11615, upload-time = "2025-09-27T18:36:30.854Z" }, + { url = "https://files.pythonhosted.org/packages/9a/81/7e4e08678a1f98521201c3079f77db69fb552acd56067661f8c2f534a718/markupsafe-3.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1872df69a4de6aead3491198eaf13810b565bdbeec3ae2dc8780f14458ec73ce", size = 12020, upload-time = "2025-09-27T18:36:31.971Z" }, + { url = "https://files.pythonhosted.org/packages/1e/2c/799f4742efc39633a1b54a92eec4082e4f815314869865d876824c257c1e/markupsafe-3.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3a7e8ae81ae39e62a41ec302f972ba6ae23a5c5396c8e60113e9066ef893da0d", size = 24332, upload-time = "2025-09-27T18:36:32.813Z" }, + { url = "https://files.pythonhosted.org/packages/3c/2e/8d0c2ab90a8c1d9a24f0399058ab8519a3279d1bd4289511d74e909f060e/markupsafe-3.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d6dd0be5b5b189d31db7cda48b91d7e0a9795f31430b7f271219ab30f1d3ac9d", size = 22947, upload-time = "2025-09-27T18:36:33.86Z" }, + { url = "https://files.pythonhosted.org/packages/2c/54/887f3092a85238093a0b2154bd629c89444f395618842e8b0c41783898ea/markupsafe-3.0.3-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:94c6f0bb423f739146aec64595853541634bde58b2135f27f61c1ffd1cd4d16a", size = 21962, upload-time = "2025-09-27T18:36:35.099Z" }, + { url = "https://files.pythonhosted.org/packages/c9/2f/336b8c7b6f4a4d95e91119dc8521402461b74a485558d8f238a68312f11c/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:be8813b57049a7dc738189df53d69395eba14fb99345e0a5994914a3864c8a4b", size = 23760, upload-time = "2025-09-27T18:36:36.001Z" }, + { url = "https://files.pythonhosted.org/packages/32/43/67935f2b7e4982ffb50a4d169b724d74b62a3964bc1a9a527f5ac4f1ee2b/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:83891d0e9fb81a825d9a6d61e3f07550ca70a076484292a70fde82c4b807286f", size = 21529, upload-time = "2025-09-27T18:36:36.906Z" }, + { url = "https://files.pythonhosted.org/packages/89/e0/4486f11e51bbba8b0c041098859e869e304d1c261e59244baa3d295d47b7/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:77f0643abe7495da77fb436f50f8dab76dbc6e5fd25d39589a0f1fe6548bfa2b", size = 23015, upload-time = "2025-09-27T18:36:37.868Z" }, + { url = "https://files.pythonhosted.org/packages/2f/e1/78ee7a023dac597a5825441ebd17170785a9dab23de95d2c7508ade94e0e/markupsafe-3.0.3-cp312-cp312-win32.whl", hash = "sha256:d88b440e37a16e651bda4c7c2b930eb586fd15ca7406cb39e211fcff3bf3017d", size = 14540, upload-time = "2025-09-27T18:36:38.761Z" }, + { url = "https://files.pythonhosted.org/packages/aa/5b/bec5aa9bbbb2c946ca2733ef9c4ca91c91b6a24580193e891b5f7dbe8e1e/markupsafe-3.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:26a5784ded40c9e318cfc2bdb30fe164bdb8665ded9cd64d500a34fb42067b1c", size = 15105, upload-time = "2025-09-27T18:36:39.701Z" }, + { url = "https://files.pythonhosted.org/packages/e5/f1/216fc1bbfd74011693a4fd837e7026152e89c4bcf3e77b6692fba9923123/markupsafe-3.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:35add3b638a5d900e807944a078b51922212fb3dedb01633a8defc4b01a3c85f", size = 13906, upload-time = "2025-09-27T18:36:40.689Z" }, + { url = "https://files.pythonhosted.org/packages/38/2f/907b9c7bbba283e68f20259574b13d005c121a0fa4c175f9bed27c4597ff/markupsafe-3.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e1cf1972137e83c5d4c136c43ced9ac51d0e124706ee1c8aa8532c1287fa8795", size = 11622, upload-time = "2025-09-27T18:36:41.777Z" }, + { url = "https://files.pythonhosted.org/packages/9c/d9/5f7756922cdd676869eca1c4e3c0cd0df60ed30199ffd775e319089cb3ed/markupsafe-3.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:116bb52f642a37c115f517494ea5feb03889e04df47eeff5b130b1808ce7c219", size = 12029, upload-time = "2025-09-27T18:36:43.257Z" }, + { url = "https://files.pythonhosted.org/packages/00/07/575a68c754943058c78f30db02ee03a64b3c638586fba6a6dd56830b30a3/markupsafe-3.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:133a43e73a802c5562be9bbcd03d090aa5a1fe899db609c29e8c8d815c5f6de6", size = 24374, upload-time = "2025-09-27T18:36:44.508Z" }, + { url = "https://files.pythonhosted.org/packages/a9/21/9b05698b46f218fc0e118e1f8168395c65c8a2c750ae2bab54fc4bd4e0e8/markupsafe-3.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ccfcd093f13f0f0b7fdd0f198b90053bf7b2f02a3927a30e63f3ccc9df56b676", size = 22980, upload-time = "2025-09-27T18:36:45.385Z" }, + { url = "https://files.pythonhosted.org/packages/7f/71/544260864f893f18b6827315b988c146b559391e6e7e8f7252839b1b846a/markupsafe-3.0.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:509fa21c6deb7a7a273d629cf5ec029bc209d1a51178615ddf718f5918992ab9", size = 21990, upload-time = "2025-09-27T18:36:46.916Z" }, + { url = "https://files.pythonhosted.org/packages/c2/28/b50fc2f74d1ad761af2f5dcce7492648b983d00a65b8c0e0cb457c82ebbe/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4afe79fb3de0b7097d81da19090f4df4f8d3a2b3adaa8764138aac2e44f3af1", size = 23784, upload-time = "2025-09-27T18:36:47.884Z" }, + { url = "https://files.pythonhosted.org/packages/ed/76/104b2aa106a208da8b17a2fb72e033a5a9d7073c68f7e508b94916ed47a9/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:795e7751525cae078558e679d646ae45574b47ed6e7771863fcc079a6171a0fc", size = 21588, upload-time = "2025-09-27T18:36:48.82Z" }, + { url = "https://files.pythonhosted.org/packages/b5/99/16a5eb2d140087ebd97180d95249b00a03aa87e29cc224056274f2e45fd6/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8485f406a96febb5140bfeca44a73e3ce5116b2501ac54fe953e488fb1d03b12", size = 23041, upload-time = "2025-09-27T18:36:49.797Z" }, + { url = "https://files.pythonhosted.org/packages/19/bc/e7140ed90c5d61d77cea142eed9f9c303f4c4806f60a1044c13e3f1471d0/markupsafe-3.0.3-cp313-cp313-win32.whl", hash = "sha256:bdd37121970bfd8be76c5fb069c7751683bdf373db1ed6c010162b2a130248ed", size = 14543, upload-time = "2025-09-27T18:36:51.584Z" }, + { url = "https://files.pythonhosted.org/packages/05/73/c4abe620b841b6b791f2edc248f556900667a5a1cf023a6646967ae98335/markupsafe-3.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:9a1abfdc021a164803f4d485104931fb8f8c1efd55bc6b748d2f5774e78b62c5", size = 15113, upload-time = "2025-09-27T18:36:52.537Z" }, + { url = "https://files.pythonhosted.org/packages/f0/3a/fa34a0f7cfef23cf9500d68cb7c32dd64ffd58a12b09225fb03dd37d5b80/markupsafe-3.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:7e68f88e5b8799aa49c85cd116c932a1ac15caaa3f5db09087854d218359e485", size = 13911, upload-time = "2025-09-27T18:36:53.513Z" }, + { url = "https://files.pythonhosted.org/packages/e4/d7/e05cd7efe43a88a17a37b3ae96e79a19e846f3f456fe79c57ca61356ef01/markupsafe-3.0.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:218551f6df4868a8d527e3062d0fb968682fe92054e89978594c28e642c43a73", size = 11658, upload-time = "2025-09-27T18:36:54.819Z" }, + { url = "https://files.pythonhosted.org/packages/99/9e/e412117548182ce2148bdeacdda3bb494260c0b0184360fe0d56389b523b/markupsafe-3.0.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3524b778fe5cfb3452a09d31e7b5adefeea8c5be1d43c4f810ba09f2ceb29d37", size = 12066, upload-time = "2025-09-27T18:36:55.714Z" }, + { url = "https://files.pythonhosted.org/packages/bc/e6/fa0ffcda717ef64a5108eaa7b4f5ed28d56122c9a6d70ab8b72f9f715c80/markupsafe-3.0.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4e885a3d1efa2eadc93c894a21770e4bc67899e3543680313b09f139e149ab19", size = 25639, upload-time = "2025-09-27T18:36:56.908Z" }, + { url = "https://files.pythonhosted.org/packages/96/ec/2102e881fe9d25fc16cb4b25d5f5cde50970967ffa5dddafdb771237062d/markupsafe-3.0.3-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8709b08f4a89aa7586de0aadc8da56180242ee0ada3999749b183aa23df95025", size = 23569, upload-time = "2025-09-27T18:36:57.913Z" }, + { url = "https://files.pythonhosted.org/packages/4b/30/6f2fce1f1f205fc9323255b216ca8a235b15860c34b6798f810f05828e32/markupsafe-3.0.3-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b8512a91625c9b3da6f127803b166b629725e68af71f8184ae7e7d54686a56d6", size = 23284, upload-time = "2025-09-27T18:36:58.833Z" }, + { url = "https://files.pythonhosted.org/packages/58/47/4a0ccea4ab9f5dcb6f79c0236d954acb382202721e704223a8aafa38b5c8/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9b79b7a16f7fedff2495d684f2b59b0457c3b493778c9eed31111be64d58279f", size = 24801, upload-time = "2025-09-27T18:36:59.739Z" }, + { url = "https://files.pythonhosted.org/packages/6a/70/3780e9b72180b6fecb83a4814d84c3bf4b4ae4bf0b19c27196104149734c/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:12c63dfb4a98206f045aa9563db46507995f7ef6d83b2f68eda65c307c6829eb", size = 22769, upload-time = "2025-09-27T18:37:00.719Z" }, + { url = "https://files.pythonhosted.org/packages/98/c5/c03c7f4125180fc215220c035beac6b9cb684bc7a067c84fc69414d315f5/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8f71bc33915be5186016f675cd83a1e08523649b0e33efdb898db577ef5bb009", size = 23642, upload-time = "2025-09-27T18:37:01.673Z" }, + { url = "https://files.pythonhosted.org/packages/80/d6/2d1b89f6ca4bff1036499b1e29a1d02d282259f3681540e16563f27ebc23/markupsafe-3.0.3-cp313-cp313t-win32.whl", hash = "sha256:69c0b73548bc525c8cb9a251cddf1931d1db4d2258e9599c28c07ef3580ef354", size = 14612, upload-time = "2025-09-27T18:37:02.639Z" }, + { url = "https://files.pythonhosted.org/packages/2b/98/e48a4bfba0a0ffcf9925fe2d69240bfaa19c6f7507b8cd09c70684a53c1e/markupsafe-3.0.3-cp313-cp313t-win_amd64.whl", hash = "sha256:1b4b79e8ebf6b55351f0d91fe80f893b4743f104bff22e90697db1590e47a218", size = 15200, upload-time = "2025-09-27T18:37:03.582Z" }, + { url = "https://files.pythonhosted.org/packages/0e/72/e3cc540f351f316e9ed0f092757459afbc595824ca724cbc5a5d4263713f/markupsafe-3.0.3-cp313-cp313t-win_arm64.whl", hash = "sha256:ad2cf8aa28b8c020ab2fc8287b0f823d0a7d8630784c31e9ee5edea20f406287", size = 13973, upload-time = "2025-09-27T18:37:04.929Z" }, + { url = "https://files.pythonhosted.org/packages/33/8a/8e42d4838cd89b7dde187011e97fe6c3af66d8c044997d2183fbd6d31352/markupsafe-3.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:eaa9599de571d72e2daf60164784109f19978b327a3910d3e9de8c97b5b70cfe", size = 11619, upload-time = "2025-09-27T18:37:06.342Z" }, + { url = "https://files.pythonhosted.org/packages/b5/64/7660f8a4a8e53c924d0fa05dc3a55c9cee10bbd82b11c5afb27d44b096ce/markupsafe-3.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c47a551199eb8eb2121d4f0f15ae0f923d31350ab9280078d1e5f12b249e0026", size = 12029, upload-time = "2025-09-27T18:37:07.213Z" }, + { url = "https://files.pythonhosted.org/packages/da/ef/e648bfd021127bef5fa12e1720ffed0c6cbb8310c8d9bea7266337ff06de/markupsafe-3.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f34c41761022dd093b4b6896d4810782ffbabe30f2d443ff5f083e0cbbb8c737", size = 24408, upload-time = "2025-09-27T18:37:09.572Z" }, + { url = "https://files.pythonhosted.org/packages/41/3c/a36c2450754618e62008bf7435ccb0f88053e07592e6028a34776213d877/markupsafe-3.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:457a69a9577064c05a97c41f4e65148652db078a3a509039e64d3467b9e7ef97", size = 23005, upload-time = "2025-09-27T18:37:10.58Z" }, + { url = "https://files.pythonhosted.org/packages/bc/20/b7fdf89a8456b099837cd1dc21974632a02a999ec9bf7ca3e490aacd98e7/markupsafe-3.0.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e8afc3f2ccfa24215f8cb28dcf43f0113ac3c37c2f0f0806d8c70e4228c5cf4d", size = 22048, upload-time = "2025-09-27T18:37:11.547Z" }, + { url = "https://files.pythonhosted.org/packages/9a/a7/591f592afdc734f47db08a75793a55d7fbcc6902a723ae4cfbab61010cc5/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ec15a59cf5af7be74194f7ab02d0f59a62bdcf1a537677ce67a2537c9b87fcda", size = 23821, upload-time = "2025-09-27T18:37:12.48Z" }, + { url = "https://files.pythonhosted.org/packages/7d/33/45b24e4f44195b26521bc6f1a82197118f74df348556594bd2262bda1038/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:0eb9ff8191e8498cca014656ae6b8d61f39da5f95b488805da4bb029cccbfbaf", size = 21606, upload-time = "2025-09-27T18:37:13.485Z" }, + { url = "https://files.pythonhosted.org/packages/ff/0e/53dfaca23a69fbfbbf17a4b64072090e70717344c52eaaaa9c5ddff1e5f0/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2713baf880df847f2bece4230d4d094280f4e67b1e813eec43b4c0e144a34ffe", size = 23043, upload-time = "2025-09-27T18:37:14.408Z" }, + { url = "https://files.pythonhosted.org/packages/46/11/f333a06fc16236d5238bfe74daccbca41459dcd8d1fa952e8fbd5dccfb70/markupsafe-3.0.3-cp314-cp314-win32.whl", hash = "sha256:729586769a26dbceff69f7a7dbbf59ab6572b99d94576a5592625d5b411576b9", size = 14747, upload-time = "2025-09-27T18:37:15.36Z" }, + { url = "https://files.pythonhosted.org/packages/28/52/182836104b33b444e400b14f797212f720cbc9ed6ba34c800639d154e821/markupsafe-3.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:bdc919ead48f234740ad807933cdf545180bfbe9342c2bb451556db2ed958581", size = 15341, upload-time = "2025-09-27T18:37:16.496Z" }, + { url = "https://files.pythonhosted.org/packages/6f/18/acf23e91bd94fd7b3031558b1f013adfa21a8e407a3fdb32745538730382/markupsafe-3.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:5a7d5dc5140555cf21a6fefbdbf8723f06fcd2f63ef108f2854de715e4422cb4", size = 14073, upload-time = "2025-09-27T18:37:17.476Z" }, + { url = "https://files.pythonhosted.org/packages/3c/f0/57689aa4076e1b43b15fdfa646b04653969d50cf30c32a102762be2485da/markupsafe-3.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:1353ef0c1b138e1907ae78e2f6c63ff67501122006b0f9abad68fda5f4ffc6ab", size = 11661, upload-time = "2025-09-27T18:37:18.453Z" }, + { url = "https://files.pythonhosted.org/packages/89/c3/2e67a7ca217c6912985ec766c6393b636fb0c2344443ff9d91404dc4c79f/markupsafe-3.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1085e7fbddd3be5f89cc898938f42c0b3c711fdcb37d75221de2666af647c175", size = 12069, upload-time = "2025-09-27T18:37:19.332Z" }, + { url = "https://files.pythonhosted.org/packages/f0/00/be561dce4e6ca66b15276e184ce4b8aec61fe83662cce2f7d72bd3249d28/markupsafe-3.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1b52b4fb9df4eb9ae465f8d0c228a00624de2334f216f178a995ccdcf82c4634", size = 25670, upload-time = "2025-09-27T18:37:20.245Z" }, + { url = "https://files.pythonhosted.org/packages/50/09/c419f6f5a92e5fadde27efd190eca90f05e1261b10dbd8cbcb39cd8ea1dc/markupsafe-3.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fed51ac40f757d41b7c48425901843666a6677e3e8eb0abcff09e4ba6e664f50", size = 23598, upload-time = "2025-09-27T18:37:21.177Z" }, + { url = "https://files.pythonhosted.org/packages/22/44/a0681611106e0b2921b3033fc19bc53323e0b50bc70cffdd19f7d679bb66/markupsafe-3.0.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f190daf01f13c72eac4efd5c430a8de82489d9cff23c364c3ea822545032993e", size = 23261, upload-time = "2025-09-27T18:37:22.167Z" }, + { url = "https://files.pythonhosted.org/packages/5f/57/1b0b3f100259dc9fffe780cfb60d4be71375510e435efec3d116b6436d43/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e56b7d45a839a697b5eb268c82a71bd8c7f6c94d6fd50c3d577fa39a9f1409f5", size = 24835, upload-time = "2025-09-27T18:37:23.296Z" }, + { url = "https://files.pythonhosted.org/packages/26/6a/4bf6d0c97c4920f1597cc14dd720705eca0bf7c787aebc6bb4d1bead5388/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:f3e98bb3798ead92273dc0e5fd0f31ade220f59a266ffd8a4f6065e0a3ce0523", size = 22733, upload-time = "2025-09-27T18:37:24.237Z" }, + { url = "https://files.pythonhosted.org/packages/14/c7/ca723101509b518797fedc2fdf79ba57f886b4aca8a7d31857ba3ee8281f/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5678211cb9333a6468fb8d8be0305520aa073f50d17f089b5b4b477ea6e67fdc", size = 23672, upload-time = "2025-09-27T18:37:25.271Z" }, + { url = "https://files.pythonhosted.org/packages/fb/df/5bd7a48c256faecd1d36edc13133e51397e41b73bb77e1a69deab746ebac/markupsafe-3.0.3-cp314-cp314t-win32.whl", hash = "sha256:915c04ba3851909ce68ccc2b8e2cd691618c4dc4c4232fb7982bca3f41fd8c3d", size = 14819, upload-time = "2025-09-27T18:37:26.285Z" }, + { url = "https://files.pythonhosted.org/packages/1a/8a/0402ba61a2f16038b48b39bccca271134be00c5c9f0f623208399333c448/markupsafe-3.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4faffd047e07c38848ce017e8725090413cd80cbc23d86e55c587bf979e579c9", size = 15426, upload-time = "2025-09-27T18:37:27.316Z" }, + { url = "https://files.pythonhosted.org/packages/70/bc/6f1c2f612465f5fa89b95bead1f44dcb607670fd42891d8fdcd5d039f4f4/markupsafe-3.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:32001d6a8fc98c8cb5c947787c5d08b0a50663d139f1305bac5885d98d9b40fa", size = 14146, upload-time = "2025-09-27T18:37:28.327Z" }, +] + +[[package]] +name = "mdurl" +version = "0.1.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729, upload-time = "2022-08-14T12:40:10.846Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" }, +] + +[[package]] +name = "mistune" +version = "3.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9d/55/d01f0c4b45ade6536c51170b9043db8b2ec6ddf4a35c7ea3f5f559ac935b/mistune-3.2.0.tar.gz", hash = "sha256:708487c8a8cdd99c9d90eb3ed4c3ed961246ff78ac82f03418f5183ab70e398a", size = 95467, upload-time = "2025-12-23T11:36:34.994Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9b/f7/4a5e785ec9fbd65146a27b6b70b6cdc161a66f2024e4b04ac06a67f5578b/mistune-3.2.0-py3-none-any.whl", hash = "sha256:febdc629a3c78616b94393c6580551e0e34cc289987ec6c35ed3f4be42d0eee1", size = 53598, upload-time = "2025-12-23T11:36:33.211Z" }, +] + +[[package]] +name = "mpmath" +version = "1.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e0/47/dd32fa426cc72114383ac549964eecb20ecfd886d1e5ccf5340b55b02f57/mpmath-1.3.0.tar.gz", hash = "sha256:7a28eb2a9774d00c7bc92411c19a89209d5da7c4c9a9e227be8330a23a25b91f", size = 508106, upload-time = "2023-03-07T16:47:11.061Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/43/e3/7d92a15f894aa0c9c4b49b8ee9ac9850d6e63b03c9c32c0367a13ae62209/mpmath-1.3.0-py3-none-any.whl", hash = "sha256:a0b2b9fe80bbcd81a6647ff13108738cfb482d481d826cc0e02f5b35e5c88d2c", size = 536198, upload-time = "2023-03-07T16:47:09.197Z" }, +] + +[[package]] +name = "nbclient" +version = "0.10.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jupyter-client" }, + { name = "jupyter-core" }, + { name = "nbformat" }, + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/56/91/1c1d5a4b9a9ebba2b4e32b8c852c2975c872aec1fe42ab5e516b2cecd193/nbclient-0.10.4.tar.gz", hash = "sha256:1e54091b16e6da39e297b0ece3e10f6f29f4ac4e8ee515d29f8a7099bd6553c9", size = 62554, upload-time = "2025-12-23T07:45:46.369Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/83/a0/5b0c2f11142ed1dddec842457d3f65eaf71a0080894eb6f018755b319c3a/nbclient-0.10.4-py3-none-any.whl", hash = "sha256:9162df5a7373d70d606527300a95a975a47c137776cd942e52d9c7e29ff83440", size = 25465, upload-time = "2025-12-23T07:45:44.51Z" }, +] + +[[package]] +name = "nbconvert" +version = "7.17.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "beautifulsoup4" }, + { name = "bleach", extra = ["css"] }, + { name = "defusedxml" }, + { name = "jinja2" }, + { name = "jupyter-core" }, + { name = "jupyterlab-pygments" }, + { name = "markupsafe" }, + { name = "mistune" }, + { name = "nbclient" }, + { name = "nbformat" }, + { name = "packaging" }, + { name = "pandocfilters" }, + { name = "pygments" }, + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/38/47/81f886b699450d0569f7bc551df2b1673d18df7ff25cc0c21ca36ed8a5ff/nbconvert-7.17.0.tar.gz", hash = "sha256:1b2696f1b5be12309f6c7d707c24af604b87dfaf6d950794c7b07acab96dda78", size = 862855, upload-time = "2026-01-29T16:37:48.478Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0d/4b/8d5f796a792f8a25f6925a96032f098789f448571eb92011df1ae59e8ea8/nbconvert-7.17.0-py3-none-any.whl", hash = "sha256:4f99a63b337b9a23504347afdab24a11faa7d86b405e5c8f9881cd313336d518", size = 261510, upload-time = "2026-01-29T16:37:46.322Z" }, +] + +[[package]] +name = "nbformat" +version = "5.10.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "fastjsonschema" }, + { name = "jsonschema" }, + { name = "jupyter-core" }, + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/6d/fd/91545e604bc3dad7dca9ed03284086039b294c6b3d75c0d2fa45f9e9caf3/nbformat-5.10.4.tar.gz", hash = "sha256:322168b14f937a5d11362988ecac2a4952d3d8e3a2cbeb2319584631226d5b3a", size = 142749, upload-time = "2024-04-04T11:20:37.371Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a9/82/0340caa499416c78e5d8f5f05947ae4bc3cba53c9f038ab6e9ed964e22f1/nbformat-5.10.4-py3-none-any.whl", hash = "sha256:3b48d6c8fbca4b299bf3982ea7db1af21580e4fec269ad087b9e81588891200b", size = 78454, upload-time = "2024-04-04T11:20:34.895Z" }, +] + +[[package]] +name = "nbsphinx" +version = "0.9.8" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "docutils" }, + { name = "jinja2" }, + { name = "nbconvert" }, + { name = "nbformat" }, + { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12'" }, + { name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e7/d1/82081750f8a78ad0399c6ed831d42623b891904e8e7b8a75878225cf1dce/nbsphinx-0.9.8.tar.gz", hash = "sha256:d0765908399a8ee2b57be7ae881cf2ea58d66db3af7bbf33e6eb48f83bea5495", size = 417469, upload-time = "2025-11-28T17:41:02.336Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/03/78/843bcf0cf31f88d2f8a9a063d2d80817b1901657d83d65b89b3aa835732e/nbsphinx-0.9.8-py3-none-any.whl", hash = "sha256:92d95ee91784e56bc633b60b767a6b6f23a0445f891e24641ce3c3f004759ccf", size = 31961, upload-time = "2025-11-28T17:41:00.796Z" }, +] + +[[package]] +name = "nodeenv" +version = "1.10.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/24/bf/d1bda4f6168e0b2e9e5958945e01910052158313224ada5ce1fb2e1113b8/nodeenv-1.10.0.tar.gz", hash = "sha256:996c191ad80897d076bdfba80a41994c2b47c68e224c542b48feba42ba00f8bb", size = 55611, upload-time = "2025-12-20T14:08:54.006Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/88/b2/d0896bdcdc8d28a7fc5717c305f1a861c26e18c05047949fb371034d98bd/nodeenv-1.10.0-py2.py3-none-any.whl", hash = "sha256:5bb13e3eed2923615535339b3c620e76779af4cb4c6a90deccc9e36b274d3827", size = 23438, upload-time = "2025-12-20T14:08:52.782Z" }, +] + +[[package]] +name = "numba" +version = "0.64.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "llvmlite" }, + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/23/c9/a0fb41787d01d621046138da30f6c2100d80857bf34b3390dd68040f27a3/numba-0.64.0.tar.gz", hash = "sha256:95e7300af648baa3308127b1955b52ce6d11889d16e8cfe637b4f85d2fca52b1", size = 2765679, upload-time = "2026-02-18T18:41:20.974Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/89/a3/1a4286a1c16136c8896d8e2090d950e79b3ec626d3a8dc9620f6234d5a38/numba-0.64.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:766156ee4b8afeeb2b2e23c81307c5d19031f18d5ce76ae2c5fb1429e72fa92b", size = 2682938, upload-time = "2026-02-18T18:40:52.897Z" }, + { url = "https://files.pythonhosted.org/packages/19/16/aa6e3ba3cd45435c117d1101b278b646444ed05b7c712af631b91353f573/numba-0.64.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d17071b4ffc9d39b75d8e6c101a36f0c81b646123859898c9799cb31807c8f78", size = 3747376, upload-time = "2026-02-18T18:40:54.925Z" }, + { url = "https://files.pythonhosted.org/packages/c0/f1/dd2f25e18d75fdf897f730b78c5a7b00cc4450f2405564dbebfaf359f21f/numba-0.64.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4ead5630434133bac87fa67526eacb264535e4e9a2d5ec780e0b4fc381a7d275", size = 3453292, upload-time = "2026-02-18T18:40:56.818Z" }, + { url = "https://files.pythonhosted.org/packages/31/29/e09d5630578a50a2b3fa154990b6b839cf95327aa0709e2d50d0b6816cd1/numba-0.64.0-cp311-cp311-win_amd64.whl", hash = "sha256:f2b1fd93e7aaac07d6fbaed059c00679f591f2423885c206d8c1b55d65ca3f2d", size = 2749824, upload-time = "2026-02-18T18:40:58.392Z" }, + { url = "https://files.pythonhosted.org/packages/70/a6/9fc52cb4f0d5e6d8b5f4d81615bc01012e3cf24e1052a60f17a68deb8092/numba-0.64.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:69440a8e8bc1a81028446f06b363e28635aa67bd51b1e498023f03b812e0ce68", size = 2683418, upload-time = "2026-02-18T18:40:59.886Z" }, + { url = "https://files.pythonhosted.org/packages/9b/89/1a74ea99b180b7a5587b0301ed1b183a2937c4b4b67f7994689b5d36fc34/numba-0.64.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f13721011f693ba558b8dd4e4db7f2640462bba1b855bdc804be45bbeb55031a", size = 3804087, upload-time = "2026-02-18T18:41:01.699Z" }, + { url = "https://files.pythonhosted.org/packages/91/e1/583c647404b15f807410510fec1eb9b80cb8474165940b7749f026f21cbc/numba-0.64.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e0b180b1133f2b5d8b3f09d96b6d7a9e51a7da5dda3c09e998b5bcfac85d222c", size = 3504309, upload-time = "2026-02-18T18:41:03.252Z" }, + { url = "https://files.pythonhosted.org/packages/85/23/0fce5789b8a5035e7ace21216a468143f3144e02013252116616c58339aa/numba-0.64.0-cp312-cp312-win_amd64.whl", hash = "sha256:e63dc94023b47894849b8b106db28ccb98b49d5498b98878fac1a38f83ac007a", size = 2752740, upload-time = "2026-02-18T18:41:05.097Z" }, + { url = "https://files.pythonhosted.org/packages/52/80/2734de90f9300a6e2503b35ee50d9599926b90cbb7ac54f9e40074cd07f1/numba-0.64.0-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:3bab2c872194dcd985f1153b70782ec0fbbe348fffef340264eacd3a76d59fd6", size = 2683392, upload-time = "2026-02-18T18:41:06.563Z" }, + { url = "https://files.pythonhosted.org/packages/42/e8/14b5853ebefd5b37723ef365c5318a30ce0702d39057eaa8d7d76392859d/numba-0.64.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:703a246c60832cad231d2e73c1182f25bf3cc8b699759ec8fe58a2dbc689a70c", size = 3812245, upload-time = "2026-02-18T18:41:07.963Z" }, + { url = "https://files.pythonhosted.org/packages/8a/a2/f60dc6c96d19b7185144265a5fbf01c14993d37ff4cd324b09d0212aa7ce/numba-0.64.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7e2e49a7900ee971d32af7609adc0cfe6aa7477c6f6cccdf6d8138538cf7756f", size = 3511328, upload-time = "2026-02-18T18:41:09.504Z" }, + { url = "https://files.pythonhosted.org/packages/9c/2a/fe7003ea7e7237ee7014f8eaeeb7b0d228a2db22572ca85bab2648cf52cb/numba-0.64.0-cp313-cp313-win_amd64.whl", hash = "sha256:396f43c3f77e78d7ec84cdfc6b04969c78f8f169351b3c4db814b97e7acf4245", size = 2752668, upload-time = "2026-02-18T18:41:11.455Z" }, + { url = "https://files.pythonhosted.org/packages/3d/8a/77d26afe0988c592dd97cb8d4e80bfb3dfc7dbdacfca7d74a7c5c81dd8c2/numba-0.64.0-cp314-cp314-macosx_12_0_arm64.whl", hash = "sha256:f565d55eaeff382cbc86c63c8c610347453af3d1e7afb2b6569aac1c9b5c93ce", size = 2683590, upload-time = "2026-02-18T18:41:12.897Z" }, + { url = "https://files.pythonhosted.org/packages/8e/4b/600b8b7cdbc7f9cebee9ea3d13bb70052a79baf28944024ffcb59f0712e3/numba-0.64.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:9b55169b18892c783f85e9ad9e6f5297a6d12967e4414e6b71361086025ff0bb", size = 3781163, upload-time = "2026-02-18T18:41:15.377Z" }, + { url = "https://files.pythonhosted.org/packages/ff/73/53f2d32bfa45b7175e9944f6b816d8c32840178c3eee9325033db5bf838e/numba-0.64.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:196bcafa02c9dd1707e068434f6d5cedde0feb787e3432f7f1f0e993cc336c4c", size = 3481172, upload-time = "2026-02-18T18:41:17.281Z" }, + { url = "https://files.pythonhosted.org/packages/b5/00/aebd2f7f1e11e38814bb96e95a27580817a7b340608d3ac085fdbab83174/numba-0.64.0-cp314-cp314-win_amd64.whl", hash = "sha256:213e9acbe7f1c05090592e79020315c1749dd52517b90e94c517dca3f014d4a1", size = 2754700, upload-time = "2026-02-18T18:41:19.277Z" }, +] + +[[package]] +name = "numpy" +version = "2.4.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/57/fd/0005efbd0af48e55eb3c7208af93f2862d4b1a56cd78e84309a2d959208d/numpy-2.4.2.tar.gz", hash = "sha256:659a6107e31a83c4e33f763942275fd278b21d095094044eb35569e86a21ddae", size = 20723651, upload-time = "2026-01-31T23:13:10.135Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d3/44/71852273146957899753e69986246d6a176061ea183407e95418c2aa4d9a/numpy-2.4.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:e7e88598032542bd49af7c4747541422884219056c268823ef6e5e89851c8825", size = 16955478, upload-time = "2026-01-31T23:10:25.623Z" }, + { url = "https://files.pythonhosted.org/packages/74/41/5d17d4058bd0cd96bcbd4d9ff0fb2e21f52702aab9a72e4a594efa18692f/numpy-2.4.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7edc794af8b36ca37ef5fcb5e0d128c7e0595c7b96a2318d1badb6fcd8ee86b1", size = 14965467, upload-time = "2026-01-31T23:10:28.186Z" }, + { url = "https://files.pythonhosted.org/packages/49/48/fb1ce8136c19452ed15f033f8aee91d5defe515094e330ce368a0647846f/numpy-2.4.2-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:6e9f61981ace1360e42737e2bae58b27bf28a1b27e781721047d84bd754d32e7", size = 5475172, upload-time = "2026-01-31T23:10:30.848Z" }, + { url = "https://files.pythonhosted.org/packages/40/a9/3feb49f17bbd1300dd2570432961f5c8a4ffeff1db6f02c7273bd020a4c9/numpy-2.4.2-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:cb7bbb88aa74908950d979eeaa24dbdf1a865e3c7e45ff0121d8f70387b55f73", size = 6805145, upload-time = "2026-01-31T23:10:32.352Z" }, + { url = "https://files.pythonhosted.org/packages/3f/39/fdf35cbd6d6e2fcad42fcf85ac04a85a0d0fbfbf34b30721c98d602fd70a/numpy-2.4.2-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4f069069931240b3fc703f1e23df63443dbd6390614c8c44a87d96cd0ec81eb1", size = 15966084, upload-time = "2026-01-31T23:10:34.502Z" }, + { url = "https://files.pythonhosted.org/packages/1b/46/6fa4ea94f1ddf969b2ee941290cca6f1bfac92b53c76ae5f44afe17ceb69/numpy-2.4.2-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c02ef4401a506fb60b411467ad501e1429a3487abca4664871d9ae0b46c8ba32", size = 16899477, upload-time = "2026-01-31T23:10:37.075Z" }, + { url = "https://files.pythonhosted.org/packages/09/a1/2a424e162b1a14a5bd860a464ab4e07513916a64ab1683fae262f735ccd2/numpy-2.4.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2653de5c24910e49c2b106499803124dde62a5a1fe0eedeaecf4309a5f639390", size = 17323429, upload-time = "2026-01-31T23:10:39.704Z" }, + { url = "https://files.pythonhosted.org/packages/ce/a2/73014149ff250628df72c58204822ac01d768697913881aacf839ff78680/numpy-2.4.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1ae241bbfc6ae276f94a170b14785e561cb5e7f626b6688cf076af4110887413", size = 18635109, upload-time = "2026-01-31T23:10:41.924Z" }, + { url = "https://files.pythonhosted.org/packages/6c/0c/73e8be2f1accd56df74abc1c5e18527822067dced5ec0861b5bb882c2ce0/numpy-2.4.2-cp311-cp311-win32.whl", hash = "sha256:df1b10187212b198dd45fa943d8985a3c8cf854aed4923796e0e019e113a1bda", size = 6237915, upload-time = "2026-01-31T23:10:45.26Z" }, + { url = "https://files.pythonhosted.org/packages/76/ae/e0265e0163cf127c24c3969d29f1c4c64551a1e375d95a13d32eab25d364/numpy-2.4.2-cp311-cp311-win_amd64.whl", hash = "sha256:b9c618d56a29c9cb1c4da979e9899be7578d2e0b3c24d52079c166324c9e8695", size = 12607972, upload-time = "2026-01-31T23:10:47.021Z" }, + { url = "https://files.pythonhosted.org/packages/29/a5/c43029af9b8014d6ea157f192652c50042e8911f4300f8f6ed3336bf437f/numpy-2.4.2-cp311-cp311-win_arm64.whl", hash = "sha256:47c5a6ed21d9452b10227e5e8a0e1c22979811cad7dcc19d8e3e2fb8fa03f1a3", size = 10485763, upload-time = "2026-01-31T23:10:50.087Z" }, + { url = "https://files.pythonhosted.org/packages/51/6e/6f394c9c77668153e14d4da83bcc247beb5952f6ead7699a1a2992613bea/numpy-2.4.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:21982668592194c609de53ba4933a7471880ccbaadcc52352694a59ecc860b3a", size = 16667963, upload-time = "2026-01-31T23:10:52.147Z" }, + { url = "https://files.pythonhosted.org/packages/1f/f8/55483431f2b2fd015ae6ed4fe62288823ce908437ed49db5a03d15151678/numpy-2.4.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40397bda92382fcec844066efb11f13e1c9a3e2a8e8f318fb72ed8b6db9f60f1", size = 14693571, upload-time = "2026-01-31T23:10:54.789Z" }, + { url = "https://files.pythonhosted.org/packages/2f/20/18026832b1845cdc82248208dd929ca14c9d8f2bac391f67440707fff27c/numpy-2.4.2-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:b3a24467af63c67829bfaa61eecf18d5432d4f11992688537be59ecd6ad32f5e", size = 5203469, upload-time = "2026-01-31T23:10:57.343Z" }, + { url = "https://files.pythonhosted.org/packages/7d/33/2eb97c8a77daaba34eaa3fa7241a14ac5f51c46a6bd5911361b644c4a1e2/numpy-2.4.2-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:805cc8de9fd6e7a22da5aed858e0ab16be5a4db6c873dde1d7451c541553aa27", size = 6550820, upload-time = "2026-01-31T23:10:59.429Z" }, + { url = "https://files.pythonhosted.org/packages/b1/91/b97fdfd12dc75b02c44e26c6638241cc004d4079a0321a69c62f51470c4c/numpy-2.4.2-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6d82351358ffbcdcd7b686b90742a9b86632d6c1c051016484fa0b326a0a1548", size = 15663067, upload-time = "2026-01-31T23:11:01.291Z" }, + { url = "https://files.pythonhosted.org/packages/f5/c6/a18e59f3f0b8071cc85cbc8d80cd02d68aa9710170b2553a117203d46936/numpy-2.4.2-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9e35d3e0144137d9fdae62912e869136164534d64a169f86438bc9561b6ad49f", size = 16619782, upload-time = "2026-01-31T23:11:03.669Z" }, + { url = "https://files.pythonhosted.org/packages/b7/83/9751502164601a79e18847309f5ceec0b1446d7b6aa12305759b72cf98b2/numpy-2.4.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:adb6ed2ad29b9e15321d167d152ee909ec73395901b70936f029c3bc6d7f4460", size = 17013128, upload-time = "2026-01-31T23:11:05.913Z" }, + { url = "https://files.pythonhosted.org/packages/61/c4/c4066322256ec740acc1c8923a10047818691d2f8aec254798f3dd90f5f2/numpy-2.4.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8906e71fd8afcb76580404e2a950caef2685df3d2a57fe82a86ac8d33cc007ba", size = 18345324, upload-time = "2026-01-31T23:11:08.248Z" }, + { url = "https://files.pythonhosted.org/packages/ab/af/6157aa6da728fa4525a755bfad486ae7e3f76d4c1864138003eb84328497/numpy-2.4.2-cp312-cp312-win32.whl", hash = "sha256:ec055f6dae239a6299cace477b479cca2fc125c5675482daf1dd886933a1076f", size = 5960282, upload-time = "2026-01-31T23:11:10.497Z" }, + { url = "https://files.pythonhosted.org/packages/92/0f/7ceaaeaacb40567071e94dbf2c9480c0ae453d5bb4f52bea3892c39dc83c/numpy-2.4.2-cp312-cp312-win_amd64.whl", hash = "sha256:209fae046e62d0ce6435fcfe3b1a10537e858249b3d9b05829e2a05218296a85", size = 12314210, upload-time = "2026-01-31T23:11:12.176Z" }, + { url = "https://files.pythonhosted.org/packages/2f/a3/56c5c604fae6dd40fa2ed3040d005fca97e91bd320d232ac9931d77ba13c/numpy-2.4.2-cp312-cp312-win_arm64.whl", hash = "sha256:fbde1b0c6e81d56f5dccd95dd4a711d9b95df1ae4009a60887e56b27e8d903fa", size = 10220171, upload-time = "2026-01-31T23:11:14.684Z" }, + { url = "https://files.pythonhosted.org/packages/a1/22/815b9fe25d1d7ae7d492152adbc7226d3eff731dffc38fe970589fcaaa38/numpy-2.4.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:25f2059807faea4b077a2b6837391b5d830864b3543627f381821c646f31a63c", size = 16663696, upload-time = "2026-01-31T23:11:17.516Z" }, + { url = "https://files.pythonhosted.org/packages/09/f0/817d03a03f93ba9c6c8993de509277d84e69f9453601915e4a69554102a1/numpy-2.4.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:bd3a7a9f5847d2fb8c2c6d1c862fa109c31a9abeca1a3c2bd5a64572955b2979", size = 14688322, upload-time = "2026-01-31T23:11:19.883Z" }, + { url = "https://files.pythonhosted.org/packages/da/b4/f805ab79293c728b9a99438775ce51885fd4f31b76178767cfc718701a39/numpy-2.4.2-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:8e4549f8a3c6d13d55041925e912bfd834285ef1dd64d6bc7d542583355e2e98", size = 5198157, upload-time = "2026-01-31T23:11:22.375Z" }, + { url = "https://files.pythonhosted.org/packages/74/09/826e4289844eccdcd64aac27d13b0fd3f32039915dd5b9ba01baae1f436c/numpy-2.4.2-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:aea4f66ff44dfddf8c2cffd66ba6538c5ec67d389285292fe428cb2c738c8aef", size = 6546330, upload-time = "2026-01-31T23:11:23.958Z" }, + { url = "https://files.pythonhosted.org/packages/19/fb/cbfdbfa3057a10aea5422c558ac57538e6acc87ec1669e666d32ac198da7/numpy-2.4.2-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c3cd545784805de05aafe1dde61752ea49a359ccba9760c1e5d1c88a93bbf2b7", size = 15660968, upload-time = "2026-01-31T23:11:25.713Z" }, + { url = "https://files.pythonhosted.org/packages/04/dc/46066ce18d01645541f0186877377b9371b8fa8017fa8262002b4ef22612/numpy-2.4.2-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d0d9b7c93578baafcbc5f0b83eaf17b79d345c6f36917ba0c67f45226911d499", size = 16607311, upload-time = "2026-01-31T23:11:28.117Z" }, + { url = "https://files.pythonhosted.org/packages/14/d9/4b5adfc39a43fa6bf918c6d544bc60c05236cc2f6339847fc5b35e6cb5b0/numpy-2.4.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f74f0f7779cc7ae07d1810aab8ac6b1464c3eafb9e283a40da7309d5e6e48fbb", size = 17012850, upload-time = "2026-01-31T23:11:30.888Z" }, + { url = "https://files.pythonhosted.org/packages/b7/20/adb6e6adde6d0130046e6fdfb7675cc62bc2f6b7b02239a09eb58435753d/numpy-2.4.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:c7ac672d699bf36275c035e16b65539931347d68b70667d28984c9fb34e07fa7", size = 18334210, upload-time = "2026-01-31T23:11:33.214Z" }, + { url = "https://files.pythonhosted.org/packages/78/0e/0a73b3dff26803a8c02baa76398015ea2a5434d9b8265a7898a6028c1591/numpy-2.4.2-cp313-cp313-win32.whl", hash = "sha256:8e9afaeb0beff068b4d9cd20d322ba0ee1cecfb0b08db145e4ab4dd44a6b5110", size = 5958199, upload-time = "2026-01-31T23:11:35.385Z" }, + { url = "https://files.pythonhosted.org/packages/43/bc/6352f343522fcb2c04dbaf94cb30cca6fd32c1a750c06ad6231b4293708c/numpy-2.4.2-cp313-cp313-win_amd64.whl", hash = "sha256:7df2de1e4fba69a51c06c28f5a3de36731eb9639feb8e1cf7e4a7b0daf4cf622", size = 12310848, upload-time = "2026-01-31T23:11:38.001Z" }, + { url = "https://files.pythonhosted.org/packages/6e/8d/6da186483e308da5da1cc6918ce913dcfe14ffde98e710bfeff2a6158d4e/numpy-2.4.2-cp313-cp313-win_arm64.whl", hash = "sha256:0fece1d1f0a89c16b03442eae5c56dc0be0c7883b5d388e0c03f53019a4bfd71", size = 10221082, upload-time = "2026-01-31T23:11:40.392Z" }, + { url = "https://files.pythonhosted.org/packages/25/a1/9510aa43555b44781968935c7548a8926274f815de42ad3997e9e83680dd/numpy-2.4.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5633c0da313330fd20c484c78cdd3f9b175b55e1a766c4a174230c6b70ad8262", size = 14815866, upload-time = "2026-01-31T23:11:42.495Z" }, + { url = "https://files.pythonhosted.org/packages/36/30/6bbb5e76631a5ae46e7923dd16ca9d3f1c93cfa8d4ed79a129814a9d8db3/numpy-2.4.2-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:d9f64d786b3b1dd742c946c42d15b07497ed14af1a1f3ce840cce27daa0ce913", size = 5325631, upload-time = "2026-01-31T23:11:44.7Z" }, + { url = "https://files.pythonhosted.org/packages/46/00/3a490938800c1923b567b3a15cd17896e68052e2145d8662aaf3e1ffc58f/numpy-2.4.2-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:b21041e8cb6a1eb5312dd1d2f80a94d91efffb7a06b70597d44f1bd2dfc315ab", size = 6646254, upload-time = "2026-01-31T23:11:46.341Z" }, + { url = "https://files.pythonhosted.org/packages/d3/e9/fac0890149898a9b609caa5af7455a948b544746e4b8fe7c212c8edd71f8/numpy-2.4.2-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:00ab83c56211a1d7c07c25e3217ea6695e50a3e2f255053686b081dc0b091a82", size = 15720138, upload-time = "2026-01-31T23:11:48.082Z" }, + { url = "https://files.pythonhosted.org/packages/ea/5c/08887c54e68e1e28df53709f1893ce92932cc6f01f7c3d4dc952f61ffd4e/numpy-2.4.2-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2fb882da679409066b4603579619341c6d6898fc83a8995199d5249f986e8e8f", size = 16655398, upload-time = "2026-01-31T23:11:50.293Z" }, + { url = "https://files.pythonhosted.org/packages/4d/89/253db0fa0e66e9129c745e4ef25631dc37d5f1314dad2b53e907b8538e6d/numpy-2.4.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:66cb9422236317f9d44b67b4d18f44efe6e9c7f8794ac0462978513359461554", size = 17079064, upload-time = "2026-01-31T23:11:52.927Z" }, + { url = "https://files.pythonhosted.org/packages/2a/d5/cbade46ce97c59c6c3da525e8d95b7abe8a42974a1dc5c1d489c10433e88/numpy-2.4.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:0f01dcf33e73d80bd8dc0f20a71303abbafa26a19e23f6b68d1aa9990af90257", size = 18379680, upload-time = "2026-01-31T23:11:55.22Z" }, + { url = "https://files.pythonhosted.org/packages/40/62/48f99ae172a4b63d981babe683685030e8a3df4f246c893ea5c6ef99f018/numpy-2.4.2-cp313-cp313t-win32.whl", hash = "sha256:52b913ec40ff7ae845687b0b34d8d93b60cb66dcee06996dd5c99f2fc9328657", size = 6082433, upload-time = "2026-01-31T23:11:58.096Z" }, + { url = "https://files.pythonhosted.org/packages/07/38/e054a61cfe48ad9f1ed0d188e78b7e26859d0b60ef21cd9de4897cdb5326/numpy-2.4.2-cp313-cp313t-win_amd64.whl", hash = "sha256:5eea80d908b2c1f91486eb95b3fb6fab187e569ec9752ab7d9333d2e66bf2d6b", size = 12451181, upload-time = "2026-01-31T23:11:59.782Z" }, + { url = "https://files.pythonhosted.org/packages/6e/a4/a05c3a6418575e185dd84d0b9680b6bb2e2dc3e4202f036b7b4e22d6e9dc/numpy-2.4.2-cp313-cp313t-win_arm64.whl", hash = "sha256:fd49860271d52127d61197bb50b64f58454e9f578cb4b2c001a6de8b1f50b0b1", size = 10290756, upload-time = "2026-01-31T23:12:02.438Z" }, + { url = "https://files.pythonhosted.org/packages/18/88/b7df6050bf18fdcfb7046286c6535cabbdd2064a3440fca3f069d319c16e/numpy-2.4.2-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:444be170853f1f9d528428eceb55f12918e4fda5d8805480f36a002f1415e09b", size = 16663092, upload-time = "2026-01-31T23:12:04.521Z" }, + { url = "https://files.pythonhosted.org/packages/25/7a/1fee4329abc705a469a4afe6e69b1ef7e915117747886327104a8493a955/numpy-2.4.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:d1240d50adff70c2a88217698ca844723068533f3f5c5fa6ee2e3220e3bdb000", size = 14698770, upload-time = "2026-01-31T23:12:06.96Z" }, + { url = "https://files.pythonhosted.org/packages/fb/0b/f9e49ba6c923678ad5bc38181c08ac5e53b7a5754dbca8e581aa1a56b1ff/numpy-2.4.2-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:7cdde6de52fb6664b00b056341265441192d1291c130e99183ec0d4b110ff8b1", size = 5208562, upload-time = "2026-01-31T23:12:09.632Z" }, + { url = "https://files.pythonhosted.org/packages/7d/12/d7de8f6f53f9bb76997e5e4c069eda2051e3fe134e9181671c4391677bb2/numpy-2.4.2-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:cda077c2e5b780200b6b3e09d0b42205a3d1c68f30c6dceb90401c13bff8fe74", size = 6543710, upload-time = "2026-01-31T23:12:11.969Z" }, + { url = "https://files.pythonhosted.org/packages/09/63/c66418c2e0268a31a4cf8a8b512685748200f8e8e8ec6c507ce14e773529/numpy-2.4.2-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d30291931c915b2ab5717c2974bb95ee891a1cf22ebc16a8006bd59cd210d40a", size = 15677205, upload-time = "2026-01-31T23:12:14.33Z" }, + { url = "https://files.pythonhosted.org/packages/5d/6c/7f237821c9642fb2a04d2f1e88b4295677144ca93285fd76eff3bcba858d/numpy-2.4.2-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bba37bc29d4d85761deed3954a1bc62be7cf462b9510b51d367b769a8c8df325", size = 16611738, upload-time = "2026-01-31T23:12:16.525Z" }, + { url = "https://files.pythonhosted.org/packages/c2/a7/39c4cdda9f019b609b5c473899d87abff092fc908cfe4d1ecb2fcff453b0/numpy-2.4.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:b2f0073ed0868db1dcd86e052d37279eef185b9c8db5bf61f30f46adac63c909", size = 17028888, upload-time = "2026-01-31T23:12:19.306Z" }, + { url = "https://files.pythonhosted.org/packages/da/b3/e84bb64bdfea967cc10950d71090ec2d84b49bc691df0025dddb7c26e8e3/numpy-2.4.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:7f54844851cdb630ceb623dcec4db3240d1ac13d4990532446761baede94996a", size = 18339556, upload-time = "2026-01-31T23:12:21.816Z" }, + { url = "https://files.pythonhosted.org/packages/88/f5/954a291bc1192a27081706862ac62bb5920fbecfbaa302f64682aa90beed/numpy-2.4.2-cp314-cp314-win32.whl", hash = "sha256:12e26134a0331d8dbd9351620f037ec470b7c75929cb8a1537f6bfe411152a1a", size = 6006899, upload-time = "2026-01-31T23:12:24.14Z" }, + { url = "https://files.pythonhosted.org/packages/05/cb/eff72a91b2efdd1bc98b3b8759f6a1654aa87612fc86e3d87d6fe4f948c4/numpy-2.4.2-cp314-cp314-win_amd64.whl", hash = "sha256:068cdb2d0d644cdb45670810894f6a0600797a69c05f1ac478e8d31670b8ee75", size = 12443072, upload-time = "2026-01-31T23:12:26.33Z" }, + { url = "https://files.pythonhosted.org/packages/37/75/62726948db36a56428fce4ba80a115716dc4fad6a3a4352487f8bb950966/numpy-2.4.2-cp314-cp314-win_arm64.whl", hash = "sha256:6ed0be1ee58eef41231a5c943d7d1375f093142702d5723ca2eb07db9b934b05", size = 10494886, upload-time = "2026-01-31T23:12:28.488Z" }, + { url = "https://files.pythonhosted.org/packages/36/2f/ee93744f1e0661dc267e4b21940870cabfae187c092e1433b77b09b50ac4/numpy-2.4.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:98f16a80e917003a12c0580f97b5f875853ebc33e2eaa4bccfc8201ac6869308", size = 14818567, upload-time = "2026-01-31T23:12:30.709Z" }, + { url = "https://files.pythonhosted.org/packages/a7/24/6535212add7d76ff938d8bdc654f53f88d35cddedf807a599e180dcb8e66/numpy-2.4.2-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:20abd069b9cda45874498b245c8015b18ace6de8546bf50dfa8cea1696ed06ef", size = 5328372, upload-time = "2026-01-31T23:12:32.962Z" }, + { url = "https://files.pythonhosted.org/packages/5e/9d/c48f0a035725f925634bf6b8994253b43f2047f6778a54147d7e213bc5a7/numpy-2.4.2-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:e98c97502435b53741540a5717a6749ac2ada901056c7db951d33e11c885cc7d", size = 6649306, upload-time = "2026-01-31T23:12:34.797Z" }, + { url = "https://files.pythonhosted.org/packages/81/05/7c73a9574cd4a53a25907bad38b59ac83919c0ddc8234ec157f344d57d9a/numpy-2.4.2-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:da6cad4e82cb893db4b69105c604d805e0c3ce11501a55b5e9f9083b47d2ffe8", size = 15722394, upload-time = "2026-01-31T23:12:36.565Z" }, + { url = "https://files.pythonhosted.org/packages/35/fa/4de10089f21fc7d18442c4a767ab156b25c2a6eaf187c0db6d9ecdaeb43f/numpy-2.4.2-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9e4424677ce4b47fe73c8b5556d876571f7c6945d264201180db2dc34f676ab5", size = 16653343, upload-time = "2026-01-31T23:12:39.188Z" }, + { url = "https://files.pythonhosted.org/packages/b8/f9/d33e4ffc857f3763a57aa85650f2e82486832d7492280ac21ba9efda80da/numpy-2.4.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:2b8f157c8a6f20eb657e240f8985cc135598b2b46985c5bccbde7616dc9c6b1e", size = 17078045, upload-time = "2026-01-31T23:12:42.041Z" }, + { url = "https://files.pythonhosted.org/packages/c8/b8/54bdb43b6225badbea6389fa038c4ef868c44f5890f95dd530a218706da3/numpy-2.4.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5daf6f3914a733336dab21a05cdec343144600e964d2fcdabaac0c0269874b2a", size = 18380024, upload-time = "2026-01-31T23:12:44.331Z" }, + { url = "https://files.pythonhosted.org/packages/a5/55/6e1a61ded7af8df04016d81b5b02daa59f2ea9252ee0397cb9f631efe9e5/numpy-2.4.2-cp314-cp314t-win32.whl", hash = "sha256:8c50dd1fc8826f5b26a5ee4d77ca55d88a895f4e4819c7ecc2a9f5905047a443", size = 6153937, upload-time = "2026-01-31T23:12:47.229Z" }, + { url = "https://files.pythonhosted.org/packages/45/aa/fa6118d1ed6d776b0983f3ceac9b1a5558e80df9365b1c3aa6d42bf9eee4/numpy-2.4.2-cp314-cp314t-win_amd64.whl", hash = "sha256:fcf92bee92742edd401ba41135185866f7026c502617f422eb432cfeca4fe236", size = 12631844, upload-time = "2026-01-31T23:12:48.997Z" }, + { url = "https://files.pythonhosted.org/packages/32/0a/2ec5deea6dcd158f254a7b372fb09cfba5719419c8d66343bab35237b3fb/numpy-2.4.2-cp314-cp314t-win_arm64.whl", hash = "sha256:1f92f53998a17265194018d1cc321b2e96e900ca52d54c7c77837b71b9465181", size = 10565379, upload-time = "2026-01-31T23:12:51.345Z" }, + { url = "https://files.pythonhosted.org/packages/f4/f8/50e14d36d915ef64d8f8bc4a087fc8264d82c785eda6711f80ab7e620335/numpy-2.4.2-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:89f7268c009bc492f506abd6f5265defa7cb3f7487dc21d357c3d290add45082", size = 16833179, upload-time = "2026-01-31T23:12:53.5Z" }, + { url = "https://files.pythonhosted.org/packages/17/17/809b5cad63812058a8189e91a1e2d55a5a18fd04611dbad244e8aeae465c/numpy-2.4.2-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:e6dee3bb76aa4009d5a912180bf5b2de012532998d094acee25d9cb8dee3e44a", size = 14889755, upload-time = "2026-01-31T23:12:55.933Z" }, + { url = "https://files.pythonhosted.org/packages/3e/ea/181b9bcf7627fc8371720316c24db888dcb9829b1c0270abf3d288b2e29b/numpy-2.4.2-pp311-pypy311_pp73-macosx_14_0_arm64.whl", hash = "sha256:cd2bd2bbed13e213d6b55dc1d035a4f91748a7d3edc9480c13898b0353708920", size = 5399500, upload-time = "2026-01-31T23:12:58.671Z" }, + { url = "https://files.pythonhosted.org/packages/33/9f/413adf3fc955541ff5536b78fcf0754680b3c6d95103230252a2c9408d23/numpy-2.4.2-pp311-pypy311_pp73-macosx_14_0_x86_64.whl", hash = "sha256:cf28c0c1d4c4bf00f509fa7eb02c58d7caf221b50b467bcb0d9bbf1584d5c821", size = 6714252, upload-time = "2026-01-31T23:13:00.518Z" }, + { url = "https://files.pythonhosted.org/packages/91/da/643aad274e29ccbdf42ecd94dafe524b81c87bcb56b83872d54827f10543/numpy-2.4.2-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e04ae107ac591763a47398bb45b568fc38f02dbc4aa44c063f67a131f99346cb", size = 15797142, upload-time = "2026-01-31T23:13:02.219Z" }, + { url = "https://files.pythonhosted.org/packages/66/27/965b8525e9cb5dc16481b30a1b3c21e50c7ebf6e9dbd48d0c4d0d5089c7e/numpy-2.4.2-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:602f65afdef699cda27ec0b9224ae5dc43e328f4c24c689deaf77133dbee74d0", size = 16727979, upload-time = "2026-01-31T23:13:04.62Z" }, + { url = "https://files.pythonhosted.org/packages/de/e5/b7d20451657664b07986c2f6e3be564433f5dcaf3482d68eaecd79afaf03/numpy-2.4.2-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:be71bf1edb48ebbbf7f6337b5bfd2f895d1902f6335a5830b20141fc126ffba0", size = 12502577, upload-time = "2026-01-31T23:13:07.08Z" }, +] + +[[package]] +name = "numpydoc" +version = "1.10.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12'" }, + { name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e9/3c/dfccc9e7dee357fb2aa13c3890d952a370dd0ed071e0f7ed62ed0df567c1/numpydoc-1.10.0.tar.gz", hash = "sha256:3f7970f6eee30912260a6b31ac72bba2432830cd6722569ec17ee8d3ef5ffa01", size = 94027, upload-time = "2025-12-02T16:39:12.937Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/62/5e/3a6a3e90f35cea3853c45e5d5fb9b7192ce4384616f932cf7591298ab6e1/numpydoc-1.10.0-py3-none-any.whl", hash = "sha256:3149da9874af890bcc2a82ef7aae5484e5aa81cb2778f08e3c307ba6d963721b", size = 69255, upload-time = "2025-12-02T16:39:11.561Z" }, +] + +[[package]] +name = "packaging" +version = "26.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/65/ee/299d360cdc32edc7d2cf530f3accf79c4fca01e96ffc950d8a52213bd8e4/packaging-26.0.tar.gz", hash = "sha256:00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4", size = 143416, upload-time = "2026-01-21T20:50:39.064Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl", hash = "sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529", size = 74366, upload-time = "2026-01-21T20:50:37.788Z" }, +] + +[[package]] +name = "pandocfilters" +version = "1.5.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/70/6f/3dd4940bbe001c06a65f88e36bad298bc7a0de5036115639926b0c5c0458/pandocfilters-1.5.1.tar.gz", hash = "sha256:002b4a555ee4ebc03f8b66307e287fa492e4a77b4ea14d3f934328297bb4939e", size = 8454, upload-time = "2024-01-18T20:08:13.726Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ef/af/4fbc8cab944db5d21b7e2a5b8e9211a03a79852b1157e2c102fcc61ac440/pandocfilters-1.5.1-py2.py3-none-any.whl", hash = "sha256:93be382804a9cdb0a7267585f157e5d1731bbe5545a85b268d6f5fe6232de2bc", size = 8663, upload-time = "2024-01-18T20:08:11.28Z" }, +] + +[[package]] +name = "platformdirs" +version = "4.9.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1b/04/fea538adf7dbbd6d186f551d595961e564a3b6715bdf276b477460858672/platformdirs-4.9.2.tar.gz", hash = "sha256:9a33809944b9db043ad67ca0db94b14bf452cc6aeaac46a88ea55b26e2e9d291", size = 28394, upload-time = "2026-02-16T03:56:10.574Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/48/31/05e764397056194206169869b50cf2fee4dbbbc71b344705b9c0d878d4d8/platformdirs-4.9.2-py3-none-any.whl", hash = "sha256:9170634f126f8efdae22fb58ae8a0eaa86f38365bc57897a6c4f781d1f5875bd", size = 21168, upload-time = "2026-02-16T03:56:08.891Z" }, +] + +[[package]] +name = "pluggy" +version = "1.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, +] + +[[package]] +name = "pre-commit" +version = "4.5.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cfgv" }, + { name = "identify" }, + { name = "nodeenv" }, + { name = "pyyaml" }, + { name = "virtualenv" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/40/f1/6d86a29246dfd2e9b6237f0b5823717f60cad94d47ddc26afa916d21f525/pre_commit-4.5.1.tar.gz", hash = "sha256:eb545fcff725875197837263e977ea257a402056661f09dae08e4b149b030a61", size = 198232, upload-time = "2025-12-16T21:14:33.552Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5d/19/fd3ef348460c80af7bb4669ea7926651d1f95c23ff2df18b9d24bab4f3fa/pre_commit-4.5.1-py2.py3-none-any.whl", hash = "sha256:3b3afd891e97337708c1674210f8eba659b52a38ea5f822ff142d10786221f77", size = 226437, upload-time = "2025-12-16T21:14:32.409Z" }, +] + +[[package]] +name = "pycparser" +version = "3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1b/7d/92392ff7815c21062bea51aa7b87d45576f649f16458d78b7cf94b9ab2e6/pycparser-3.0.tar.gz", hash = "sha256:600f49d217304a5902ac3c37e1281c9fe94e4d0489de643a9504c5cdfdfc6b29", size = 103492, upload-time = "2026-01-21T14:26:51.89Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0c/c3/44f3fbbfa403ea2a7c779186dc20772604442dde72947e7d01069cbe98e3/pycparser-3.0-py3-none-any.whl", hash = "sha256:b727414169a36b7d524c1c3e31839a521725078d7b2ff038656844266160a992", size = 48172, upload-time = "2026-01-21T14:26:50.693Z" }, +] + +[[package]] +name = "pyerfa" +version = "2.0.1.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/71/39/63cc8291b0cf324ae710df41527faf7d331bce573899199d926b3e492260/pyerfa-2.0.1.5.tar.gz", hash = "sha256:17d6b24fe4846c65d5e7d8c362dcb08199dc63b30a236aedd73875cc83e1f6c0", size = 818430, upload-time = "2024-11-11T15:22:30.852Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7d/d9/3448a57cb5bd19950de6d6ab08bd8fbb3df60baa71726de91d73d76c481b/pyerfa-2.0.1.5-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:b282d7c60c4c47cf629c484c17ac504fcb04abd7b3f4dfcf53ee042afc3a5944", size = 341818, upload-time = "2024-11-11T15:22:16.467Z" }, + { url = "https://files.pythonhosted.org/packages/11/4a/31a363370478b63c6289a34743f2ba2d3ae1bd8223e004d18ab28fb92385/pyerfa-2.0.1.5-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:be1aeb70390dd03a34faf96749d5cabc58437410b4aab7213c512323932427df", size = 329370, upload-time = "2024-11-11T15:22:17.829Z" }, + { url = "https://files.pythonhosted.org/packages/cb/96/b6210fc624123c8ae13e1eecb68fb75e3f3adff216d95eee1c7b05843e3e/pyerfa-2.0.1.5-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b0603e8e1b839327d586c8a627cdc634b795e18b007d84f0cda5500a0908254e", size = 692794, upload-time = "2024-11-11T15:22:19.429Z" }, + { url = "https://files.pythonhosted.org/packages/e5/e0/050018d855d26d3c0b4a7d1b2ed692be758ce276d8289e2a2b44ba1014a5/pyerfa-2.0.1.5-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e43c7194e3242083f2350b46c09fd4bf8ba1bcc0ebd1460b98fc47fe2389906", size = 738711, upload-time = "2024-11-11T15:22:20.661Z" }, + { url = "https://files.pythonhosted.org/packages/b9/f5/ff91ee77308793ae32fa1e1de95e9edd4551456dd888b4e87c5938657ca5/pyerfa-2.0.1.5-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:07b80cd70701f5d066b1ac8cce406682cfcd667a1186ec7d7ade597239a6021d", size = 722966, upload-time = "2024-11-11T15:22:21.905Z" }, + { url = "https://files.pythonhosted.org/packages/2c/56/b22b35c8551d2228ff8d445e63787112927ca13f6dc9e2c04f69d742c95b/pyerfa-2.0.1.5-cp39-abi3-win32.whl", hash = "sha256:d30b9b0df588ed5467e529d851ea324a67239096dd44703125072fd11b351ea2", size = 339955, upload-time = "2024-11-11T15:22:23.087Z" }, + { url = "https://files.pythonhosted.org/packages/b4/11/97233cf23ad5411ac6f13b1d6ee3888f90ace4f974d9bf9db887aa428912/pyerfa-2.0.1.5-cp39-abi3-win_amd64.whl", hash = "sha256:66292d437dcf75925b694977aa06eb697126e7b86553e620371ed3e48b5e0ad0", size = 349410, upload-time = "2024-11-11T15:22:24.817Z" }, +] + +[[package]] +name = "pygments" +version = "2.19.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", size = 4968631, upload-time = "2025-06-21T13:39:12.283Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b", size = 1225217, upload-time = "2025-06-21T13:39:07.939Z" }, +] + +[[package]] +name = "pytest" +version = "9.0.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "iniconfig" }, + { name = "packaging" }, + { name = "pluggy" }, + { name = "pygments" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/d1/db/7ef3487e0fb0049ddb5ce41d3a49c235bf9ad299b6a25d5780a89f19230f/pytest-9.0.2.tar.gz", hash = "sha256:75186651a92bd89611d1d9fc20f0b4345fd827c41ccd5c299a868a05d70edf11", size = 1568901, upload-time = "2025-12-06T21:30:51.014Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3b/ab/b3226f0bd7cdcf710fbede2b3548584366da3b19b5021e74f5bde2a8fa3f/pytest-9.0.2-py3-none-any.whl", hash = "sha256:711ffd45bf766d5264d487b917733b453d917afd2b0ad65223959f59089f875b", size = 374801, upload-time = "2025-12-06T21:30:49.154Z" }, +] + +[[package]] +name = "pytest-cov" +version = "7.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "coverage", extra = ["toml"] }, + { name = "pluggy" }, + { name = "pytest" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5e/f7/c933acc76f5208b3b00089573cf6a2bc26dc80a8aece8f52bb7d6b1855ca/pytest_cov-7.0.0.tar.gz", hash = "sha256:33c97eda2e049a0c5298e91f519302a1334c26ac65c1a483d6206fd458361af1", size = 54328, upload-time = "2025-09-09T10:57:02.113Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ee/49/1377b49de7d0c1ce41292161ea0f721913fa8722c19fb9c1e3aa0367eecb/pytest_cov-7.0.0-py3-none-any.whl", hash = "sha256:3b8e9558b16cc1479da72058bdecf8073661c7f57f7d3c5f22a1c23507f2d861", size = 22424, upload-time = "2025-09-09T10:57:00.695Z" }, +] + +[[package]] +name = "python-dateutil" +version = "2.9.0.post0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "six" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432, upload-time = "2024-03-01T18:36:20.211Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" }, +] + +[[package]] +name = "pyyaml" +version = "6.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f", size = 130960, upload-time = "2025-09-25T21:33:16.546Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6d/16/a95b6757765b7b031c9374925bb718d55e0a9ba8a1b6a12d25962ea44347/pyyaml-6.0.3-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:44edc647873928551a01e7a563d7452ccdebee747728c1080d881d68af7b997e", size = 185826, upload-time = "2025-09-25T21:31:58.655Z" }, + { url = "https://files.pythonhosted.org/packages/16/19/13de8e4377ed53079ee996e1ab0a9c33ec2faf808a4647b7b4c0d46dd239/pyyaml-6.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:652cb6edd41e718550aad172851962662ff2681490a8a711af6a4d288dd96824", size = 175577, upload-time = "2025-09-25T21:32:00.088Z" }, + { url = "https://files.pythonhosted.org/packages/0c/62/d2eb46264d4b157dae1275b573017abec435397aa59cbcdab6fc978a8af4/pyyaml-6.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:10892704fc220243f5305762e276552a0395f7beb4dbf9b14ec8fd43b57f126c", size = 775556, upload-time = "2025-09-25T21:32:01.31Z" }, + { url = "https://files.pythonhosted.org/packages/10/cb/16c3f2cf3266edd25aaa00d6c4350381c8b012ed6f5276675b9eba8d9ff4/pyyaml-6.0.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:850774a7879607d3a6f50d36d04f00ee69e7fc816450e5f7e58d7f17f1ae5c00", size = 882114, upload-time = "2025-09-25T21:32:03.376Z" }, + { url = "https://files.pythonhosted.org/packages/71/60/917329f640924b18ff085ab889a11c763e0b573da888e8404ff486657602/pyyaml-6.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b8bb0864c5a28024fac8a632c443c87c5aa6f215c0b126c449ae1a150412f31d", size = 806638, upload-time = "2025-09-25T21:32:04.553Z" }, + { url = "https://files.pythonhosted.org/packages/dd/6f/529b0f316a9fd167281a6c3826b5583e6192dba792dd55e3203d3f8e655a/pyyaml-6.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1d37d57ad971609cf3c53ba6a7e365e40660e3be0e5175fa9f2365a379d6095a", size = 767463, upload-time = "2025-09-25T21:32:06.152Z" }, + { url = "https://files.pythonhosted.org/packages/f2/6a/b627b4e0c1dd03718543519ffb2f1deea4a1e6d42fbab8021936a4d22589/pyyaml-6.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:37503bfbfc9d2c40b344d06b2199cf0e96e97957ab1c1b546fd4f87e53e5d3e4", size = 794986, upload-time = "2025-09-25T21:32:07.367Z" }, + { url = "https://files.pythonhosted.org/packages/45/91/47a6e1c42d9ee337c4839208f30d9f09caa9f720ec7582917b264defc875/pyyaml-6.0.3-cp311-cp311-win32.whl", hash = "sha256:8098f252adfa6c80ab48096053f512f2321f0b998f98150cea9bd23d83e1467b", size = 142543, upload-time = "2025-09-25T21:32:08.95Z" }, + { url = "https://files.pythonhosted.org/packages/da/e3/ea007450a105ae919a72393cb06f122f288ef60bba2dc64b26e2646fa315/pyyaml-6.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:9f3bfb4965eb874431221a3ff3fdcddc7e74e3b07799e0e84ca4a0f867d449bf", size = 158763, upload-time = "2025-09-25T21:32:09.96Z" }, + { url = "https://files.pythonhosted.org/packages/d1/33/422b98d2195232ca1826284a76852ad5a86fe23e31b009c9886b2d0fb8b2/pyyaml-6.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7f047e29dcae44602496db43be01ad42fc6f1cc0d8cd6c83d342306c32270196", size = 182063, upload-time = "2025-09-25T21:32:11.445Z" }, + { url = "https://files.pythonhosted.org/packages/89/a0/6cf41a19a1f2f3feab0e9c0b74134aa2ce6849093d5517a0c550fe37a648/pyyaml-6.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fc09d0aa354569bc501d4e787133afc08552722d3ab34836a80547331bb5d4a0", size = 173973, upload-time = "2025-09-25T21:32:12.492Z" }, + { url = "https://files.pythonhosted.org/packages/ed/23/7a778b6bd0b9a8039df8b1b1d80e2e2ad78aa04171592c8a5c43a56a6af4/pyyaml-6.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9149cad251584d5fb4981be1ecde53a1ca46c891a79788c0df828d2f166bda28", size = 775116, upload-time = "2025-09-25T21:32:13.652Z" }, + { url = "https://files.pythonhosted.org/packages/65/30/d7353c338e12baef4ecc1b09e877c1970bd3382789c159b4f89d6a70dc09/pyyaml-6.0.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5fdec68f91a0c6739b380c83b951e2c72ac0197ace422360e6d5a959d8d97b2c", size = 844011, upload-time = "2025-09-25T21:32:15.21Z" }, + { url = "https://files.pythonhosted.org/packages/8b/9d/b3589d3877982d4f2329302ef98a8026e7f4443c765c46cfecc8858c6b4b/pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ba1cc08a7ccde2d2ec775841541641e4548226580ab850948cbfda66a1befcdc", size = 807870, upload-time = "2025-09-25T21:32:16.431Z" }, + { url = "https://files.pythonhosted.org/packages/05/c0/b3be26a015601b822b97d9149ff8cb5ead58c66f981e04fedf4e762f4bd4/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8dc52c23056b9ddd46818a57b78404882310fb473d63f17b07d5c40421e47f8e", size = 761089, upload-time = "2025-09-25T21:32:17.56Z" }, + { url = "https://files.pythonhosted.org/packages/be/8e/98435a21d1d4b46590d5459a22d88128103f8da4c2d4cb8f14f2a96504e1/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:41715c910c881bc081f1e8872880d3c650acf13dfa8214bad49ed4cede7c34ea", size = 790181, upload-time = "2025-09-25T21:32:18.834Z" }, + { url = "https://files.pythonhosted.org/packages/74/93/7baea19427dcfbe1e5a372d81473250b379f04b1bd3c4c5ff825e2327202/pyyaml-6.0.3-cp312-cp312-win32.whl", hash = "sha256:96b533f0e99f6579b3d4d4995707cf36df9100d67e0c8303a0c55b27b5f99bc5", size = 137658, upload-time = "2025-09-25T21:32:20.209Z" }, + { url = "https://files.pythonhosted.org/packages/86/bf/899e81e4cce32febab4fb42bb97dcdf66bc135272882d1987881a4b519e9/pyyaml-6.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:5fcd34e47f6e0b794d17de1b4ff496c00986e1c83f7ab2fb8fcfe9616ff7477b", size = 154003, upload-time = "2025-09-25T21:32:21.167Z" }, + { url = "https://files.pythonhosted.org/packages/1a/08/67bd04656199bbb51dbed1439b7f27601dfb576fb864099c7ef0c3e55531/pyyaml-6.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:64386e5e707d03a7e172c0701abfb7e10f0fb753ee1d773128192742712a98fd", size = 140344, upload-time = "2025-09-25T21:32:22.617Z" }, + { url = "https://files.pythonhosted.org/packages/d1/11/0fd08f8192109f7169db964b5707a2f1e8b745d4e239b784a5a1dd80d1db/pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8", size = 181669, upload-time = "2025-09-25T21:32:23.673Z" }, + { url = "https://files.pythonhosted.org/packages/b1/16/95309993f1d3748cd644e02e38b75d50cbc0d9561d21f390a76242ce073f/pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1", size = 173252, upload-time = "2025-09-25T21:32:25.149Z" }, + { url = "https://files.pythonhosted.org/packages/50/31/b20f376d3f810b9b2371e72ef5adb33879b25edb7a6d072cb7ca0c486398/pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c", size = 767081, upload-time = "2025-09-25T21:32:26.575Z" }, + { url = "https://files.pythonhosted.org/packages/49/1e/a55ca81e949270d5d4432fbbd19dfea5321eda7c41a849d443dc92fd1ff7/pyyaml-6.0.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5", size = 841159, upload-time = "2025-09-25T21:32:27.727Z" }, + { url = "https://files.pythonhosted.org/packages/74/27/e5b8f34d02d9995b80abcef563ea1f8b56d20134d8f4e5e81733b1feceb2/pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6", size = 801626, upload-time = "2025-09-25T21:32:28.878Z" }, + { url = "https://files.pythonhosted.org/packages/f9/11/ba845c23988798f40e52ba45f34849aa8a1f2d4af4b798588010792ebad6/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6", size = 753613, upload-time = "2025-09-25T21:32:30.178Z" }, + { url = "https://files.pythonhosted.org/packages/3d/e0/7966e1a7bfc0a45bf0a7fb6b98ea03fc9b8d84fa7f2229e9659680b69ee3/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be", size = 794115, upload-time = "2025-09-25T21:32:31.353Z" }, + { url = "https://files.pythonhosted.org/packages/de/94/980b50a6531b3019e45ddeada0626d45fa85cbe22300844a7983285bed3b/pyyaml-6.0.3-cp313-cp313-win32.whl", hash = "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26", size = 137427, upload-time = "2025-09-25T21:32:32.58Z" }, + { url = "https://files.pythonhosted.org/packages/97/c9/39d5b874e8b28845e4ec2202b5da735d0199dbe5b8fb85f91398814a9a46/pyyaml-6.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c", size = 154090, upload-time = "2025-09-25T21:32:33.659Z" }, + { url = "https://files.pythonhosted.org/packages/73/e8/2bdf3ca2090f68bb3d75b44da7bbc71843b19c9f2b9cb9b0f4ab7a5a4329/pyyaml-6.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb", size = 140246, upload-time = "2025-09-25T21:32:34.663Z" }, + { url = "https://files.pythonhosted.org/packages/9d/8c/f4bd7f6465179953d3ac9bc44ac1a8a3e6122cf8ada906b4f96c60172d43/pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac", size = 181814, upload-time = "2025-09-25T21:32:35.712Z" }, + { url = "https://files.pythonhosted.org/packages/bd/9c/4d95bb87eb2063d20db7b60faa3840c1b18025517ae857371c4dd55a6b3a/pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310", size = 173809, upload-time = "2025-09-25T21:32:36.789Z" }, + { url = "https://files.pythonhosted.org/packages/92/b5/47e807c2623074914e29dabd16cbbdd4bf5e9b2db9f8090fa64411fc5382/pyyaml-6.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7", size = 766454, upload-time = "2025-09-25T21:32:37.966Z" }, + { url = "https://files.pythonhosted.org/packages/02/9e/e5e9b168be58564121efb3de6859c452fccde0ab093d8438905899a3a483/pyyaml-6.0.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788", size = 836355, upload-time = "2025-09-25T21:32:39.178Z" }, + { url = "https://files.pythonhosted.org/packages/88/f9/16491d7ed2a919954993e48aa941b200f38040928474c9e85ea9e64222c3/pyyaml-6.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5", size = 794175, upload-time = "2025-09-25T21:32:40.865Z" }, + { url = "https://files.pythonhosted.org/packages/dd/3f/5989debef34dc6397317802b527dbbafb2b4760878a53d4166579111411e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764", size = 755228, upload-time = "2025-09-25T21:32:42.084Z" }, + { url = "https://files.pythonhosted.org/packages/d7/ce/af88a49043cd2e265be63d083fc75b27b6ed062f5f9fd6cdc223ad62f03e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35", size = 789194, upload-time = "2025-09-25T21:32:43.362Z" }, + { url = "https://files.pythonhosted.org/packages/23/20/bb6982b26a40bb43951265ba29d4c246ef0ff59c9fdcdf0ed04e0687de4d/pyyaml-6.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac", size = 156429, upload-time = "2025-09-25T21:32:57.844Z" }, + { url = "https://files.pythonhosted.org/packages/f4/f4/a4541072bb9422c8a883ab55255f918fa378ecf083f5b85e87fc2b4eda1b/pyyaml-6.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3", size = 143912, upload-time = "2025-09-25T21:32:59.247Z" }, + { url = "https://files.pythonhosted.org/packages/7c/f9/07dd09ae774e4616edf6cda684ee78f97777bdd15847253637a6f052a62f/pyyaml-6.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3", size = 189108, upload-time = "2025-09-25T21:32:44.377Z" }, + { url = "https://files.pythonhosted.org/packages/4e/78/8d08c9fb7ce09ad8c38ad533c1191cf27f7ae1effe5bb9400a46d9437fcf/pyyaml-6.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba", size = 183641, upload-time = "2025-09-25T21:32:45.407Z" }, + { url = "https://files.pythonhosted.org/packages/7b/5b/3babb19104a46945cf816d047db2788bcaf8c94527a805610b0289a01c6b/pyyaml-6.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c", size = 831901, upload-time = "2025-09-25T21:32:48.83Z" }, + { url = "https://files.pythonhosted.org/packages/8b/cc/dff0684d8dc44da4d22a13f35f073d558c268780ce3c6ba1b87055bb0b87/pyyaml-6.0.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702", size = 861132, upload-time = "2025-09-25T21:32:50.149Z" }, + { url = "https://files.pythonhosted.org/packages/b1/5e/f77dc6b9036943e285ba76b49e118d9ea929885becb0a29ba8a7c75e29fe/pyyaml-6.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c", size = 839261, upload-time = "2025-09-25T21:32:51.808Z" }, + { url = "https://files.pythonhosted.org/packages/ce/88/a9db1376aa2a228197c58b37302f284b5617f56a5d959fd1763fb1675ce6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065", size = 805272, upload-time = "2025-09-25T21:32:52.941Z" }, + { url = "https://files.pythonhosted.org/packages/da/92/1446574745d74df0c92e6aa4a7b0b3130706a4142b2d1a5869f2eaa423c6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65", size = 829923, upload-time = "2025-09-25T21:32:54.537Z" }, + { url = "https://files.pythonhosted.org/packages/f0/7a/1c7270340330e575b92f397352af856a8c06f230aa3e76f86b39d01b416a/pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9", size = 174062, upload-time = "2025-09-25T21:32:55.767Z" }, + { url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341, upload-time = "2025-09-25T21:32:56.828Z" }, +] + +[[package]] +name = "pyzmq" +version = "27.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cffi", marker = "implementation_name == 'pypy'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/04/0b/3c9baedbdf613ecaa7aa07027780b8867f57b6293b6ee50de316c9f3222b/pyzmq-27.1.0.tar.gz", hash = "sha256:ac0765e3d44455adb6ddbf4417dcce460fc40a05978c08efdf2948072f6db540", size = 281750, upload-time = "2025-09-08T23:10:18.157Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/06/5d/305323ba86b284e6fcb0d842d6adaa2999035f70f8c38a9b6d21ad28c3d4/pyzmq-27.1.0-cp311-cp311-macosx_10_15_universal2.whl", hash = "sha256:226b091818d461a3bef763805e75685e478ac17e9008f49fce2d3e52b3d58b86", size = 1333328, upload-time = "2025-09-08T23:07:45.946Z" }, + { url = "https://files.pythonhosted.org/packages/bd/a0/fc7e78a23748ad5443ac3275943457e8452da67fda347e05260261108cbc/pyzmq-27.1.0-cp311-cp311-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:0790a0161c281ca9723f804871b4027f2e8b5a528d357c8952d08cd1a9c15581", size = 908803, upload-time = "2025-09-08T23:07:47.551Z" }, + { url = "https://files.pythonhosted.org/packages/7e/22/37d15eb05f3bdfa4abea6f6d96eb3bb58585fbd3e4e0ded4e743bc650c97/pyzmq-27.1.0-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c895a6f35476b0c3a54e3eb6ccf41bf3018de937016e6e18748317f25d4e925f", size = 668836, upload-time = "2025-09-08T23:07:49.436Z" }, + { url = "https://files.pythonhosted.org/packages/b1/c4/2a6fe5111a01005fc7af3878259ce17684fabb8852815eda6225620f3c59/pyzmq-27.1.0-cp311-cp311-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5bbf8d3630bf96550b3be8e1fc0fea5cbdc8d5466c1192887bd94869da17a63e", size = 857038, upload-time = "2025-09-08T23:07:51.234Z" }, + { url = "https://files.pythonhosted.org/packages/cb/eb/bfdcb41d0db9cd233d6fb22dc131583774135505ada800ebf14dfb0a7c40/pyzmq-27.1.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:15c8bd0fe0dabf808e2d7a681398c4e5ded70a551ab47482067a572c054c8e2e", size = 1657531, upload-time = "2025-09-08T23:07:52.795Z" }, + { url = "https://files.pythonhosted.org/packages/ab/21/e3180ca269ed4a0de5c34417dfe71a8ae80421198be83ee619a8a485b0c7/pyzmq-27.1.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:bafcb3dd171b4ae9f19ee6380dfc71ce0390fefaf26b504c0e5f628d7c8c54f2", size = 2034786, upload-time = "2025-09-08T23:07:55.047Z" }, + { url = "https://files.pythonhosted.org/packages/3b/b1/5e21d0b517434b7f33588ff76c177c5a167858cc38ef740608898cd329f2/pyzmq-27.1.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e829529fcaa09937189178115c49c504e69289abd39967cd8a4c215761373394", size = 1894220, upload-time = "2025-09-08T23:07:57.172Z" }, + { url = "https://files.pythonhosted.org/packages/03/f2/44913a6ff6941905efc24a1acf3d3cb6146b636c546c7406c38c49c403d4/pyzmq-27.1.0-cp311-cp311-win32.whl", hash = "sha256:6df079c47d5902af6db298ec92151db82ecb557af663098b92f2508c398bb54f", size = 567155, upload-time = "2025-09-08T23:07:59.05Z" }, + { url = "https://files.pythonhosted.org/packages/23/6d/d8d92a0eb270a925c9b4dd039c0b4dc10abc2fcbc48331788824ef113935/pyzmq-27.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:190cbf120fbc0fc4957b56866830def56628934a9d112aec0e2507aa6a032b97", size = 633428, upload-time = "2025-09-08T23:08:00.663Z" }, + { url = "https://files.pythonhosted.org/packages/ae/14/01afebc96c5abbbd713ecfc7469cfb1bc801c819a74ed5c9fad9a48801cb/pyzmq-27.1.0-cp311-cp311-win_arm64.whl", hash = "sha256:eca6b47df11a132d1745eb3b5b5e557a7dae2c303277aa0e69c6ba91b8736e07", size = 559497, upload-time = "2025-09-08T23:08:02.15Z" }, + { url = "https://files.pythonhosted.org/packages/92/e7/038aab64a946d535901103da16b953c8c9cc9c961dadcbf3609ed6428d23/pyzmq-27.1.0-cp312-abi3-macosx_10_15_universal2.whl", hash = "sha256:452631b640340c928fa343801b0d07eb0c3789a5ffa843f6e1a9cee0ba4eb4fc", size = 1306279, upload-time = "2025-09-08T23:08:03.807Z" }, + { url = "https://files.pythonhosted.org/packages/e8/5e/c3c49fdd0f535ef45eefcc16934648e9e59dace4a37ee88fc53f6cd8e641/pyzmq-27.1.0-cp312-abi3-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:1c179799b118e554b66da67d88ed66cd37a169f1f23b5d9f0a231b4e8d44a113", size = 895645, upload-time = "2025-09-08T23:08:05.301Z" }, + { url = "https://files.pythonhosted.org/packages/f8/e5/b0b2504cb4e903a74dcf1ebae157f9e20ebb6ea76095f6cfffea28c42ecd/pyzmq-27.1.0-cp312-abi3-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3837439b7f99e60312f0c926a6ad437b067356dc2bc2ec96eb395fd0fe804233", size = 652574, upload-time = "2025-09-08T23:08:06.828Z" }, + { url = "https://files.pythonhosted.org/packages/f8/9b/c108cdb55560eaf253f0cbdb61b29971e9fb34d9c3499b0e96e4e60ed8a5/pyzmq-27.1.0-cp312-abi3-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:43ad9a73e3da1fab5b0e7e13402f0b2fb934ae1c876c51d0afff0e7c052eca31", size = 840995, upload-time = "2025-09-08T23:08:08.396Z" }, + { url = "https://files.pythonhosted.org/packages/c2/bb/b79798ca177b9eb0825b4c9998c6af8cd2a7f15a6a1a4272c1d1a21d382f/pyzmq-27.1.0-cp312-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:0de3028d69d4cdc475bfe47a6128eb38d8bc0e8f4d69646adfbcd840facbac28", size = 1642070, upload-time = "2025-09-08T23:08:09.989Z" }, + { url = "https://files.pythonhosted.org/packages/9c/80/2df2e7977c4ede24c79ae39dcef3899bfc5f34d1ca7a5b24f182c9b7a9ca/pyzmq-27.1.0-cp312-abi3-musllinux_1_2_i686.whl", hash = "sha256:cf44a7763aea9298c0aa7dbf859f87ed7012de8bda0f3977b6fb1d96745df856", size = 2021121, upload-time = "2025-09-08T23:08:11.907Z" }, + { url = "https://files.pythonhosted.org/packages/46/bd/2d45ad24f5f5ae7e8d01525eb76786fa7557136555cac7d929880519e33a/pyzmq-27.1.0-cp312-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:f30f395a9e6fbca195400ce833c731e7b64c3919aa481af4d88c3759e0cb7496", size = 1878550, upload-time = "2025-09-08T23:08:13.513Z" }, + { url = "https://files.pythonhosted.org/packages/e6/2f/104c0a3c778d7c2ab8190e9db4f62f0b6957b53c9d87db77c284b69f33ea/pyzmq-27.1.0-cp312-abi3-win32.whl", hash = "sha256:250e5436a4ba13885494412b3da5d518cd0d3a278a1ae640e113c073a5f88edd", size = 559184, upload-time = "2025-09-08T23:08:15.163Z" }, + { url = "https://files.pythonhosted.org/packages/fc/7f/a21b20d577e4100c6a41795842028235998a643b1ad406a6d4163ea8f53e/pyzmq-27.1.0-cp312-abi3-win_amd64.whl", hash = "sha256:9ce490cf1d2ca2ad84733aa1d69ce6855372cb5ce9223802450c9b2a7cba0ccf", size = 619480, upload-time = "2025-09-08T23:08:17.192Z" }, + { url = "https://files.pythonhosted.org/packages/78/c2/c012beae5f76b72f007a9e91ee9401cb88c51d0f83c6257a03e785c81cc2/pyzmq-27.1.0-cp312-abi3-win_arm64.whl", hash = "sha256:75a2f36223f0d535a0c919e23615fc85a1e23b71f40c7eb43d7b1dedb4d8f15f", size = 552993, upload-time = "2025-09-08T23:08:18.926Z" }, + { url = "https://files.pythonhosted.org/packages/60/cb/84a13459c51da6cec1b7b1dc1a47e6db6da50b77ad7fd9c145842750a011/pyzmq-27.1.0-cp313-cp313-android_24_arm64_v8a.whl", hash = "sha256:93ad4b0855a664229559e45c8d23797ceac03183c7b6f5b4428152a6b06684a5", size = 1122436, upload-time = "2025-09-08T23:08:20.801Z" }, + { url = "https://files.pythonhosted.org/packages/dc/b6/94414759a69a26c3dd674570a81813c46a078767d931a6c70ad29fc585cb/pyzmq-27.1.0-cp313-cp313-android_24_x86_64.whl", hash = "sha256:fbb4f2400bfda24f12f009cba62ad5734148569ff4949b1b6ec3b519444342e6", size = 1156301, upload-time = "2025-09-08T23:08:22.47Z" }, + { url = "https://files.pythonhosted.org/packages/a5/ad/15906493fd40c316377fd8a8f6b1f93104f97a752667763c9b9c1b71d42d/pyzmq-27.1.0-cp313-cp313t-macosx_10_15_universal2.whl", hash = "sha256:e343d067f7b151cfe4eb3bb796a7752c9d369eed007b91231e817071d2c2fec7", size = 1341197, upload-time = "2025-09-08T23:08:24.286Z" }, + { url = "https://files.pythonhosted.org/packages/14/1d/d343f3ce13db53a54cb8946594e567410b2125394dafcc0268d8dda027e0/pyzmq-27.1.0-cp313-cp313t-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:08363b2011dec81c354d694bdecaef4770e0ae96b9afea70b3f47b973655cc05", size = 897275, upload-time = "2025-09-08T23:08:26.063Z" }, + { url = "https://files.pythonhosted.org/packages/69/2d/d83dd6d7ca929a2fc67d2c3005415cdf322af7751d773524809f9e585129/pyzmq-27.1.0-cp313-cp313t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d54530c8c8b5b8ddb3318f481297441af102517602b569146185fa10b63f4fa9", size = 660469, upload-time = "2025-09-08T23:08:27.623Z" }, + { url = "https://files.pythonhosted.org/packages/3e/cd/9822a7af117f4bc0f1952dbe9ef8358eb50a24928efd5edf54210b850259/pyzmq-27.1.0-cp313-cp313t-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6f3afa12c392f0a44a2414056d730eebc33ec0926aae92b5ad5cf26ebb6cc128", size = 847961, upload-time = "2025-09-08T23:08:29.672Z" }, + { url = "https://files.pythonhosted.org/packages/9a/12/f003e824a19ed73be15542f172fd0ec4ad0b60cf37436652c93b9df7c585/pyzmq-27.1.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:c65047adafe573ff023b3187bb93faa583151627bc9c51fc4fb2c561ed689d39", size = 1650282, upload-time = "2025-09-08T23:08:31.349Z" }, + { url = "https://files.pythonhosted.org/packages/d5/4a/e82d788ed58e9a23995cee70dbc20c9aded3d13a92d30d57ec2291f1e8a3/pyzmq-27.1.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:90e6e9441c946a8b0a667356f7078d96411391a3b8f80980315455574177ec97", size = 2024468, upload-time = "2025-09-08T23:08:33.543Z" }, + { url = "https://files.pythonhosted.org/packages/d9/94/2da0a60841f757481e402b34bf4c8bf57fa54a5466b965de791b1e6f747d/pyzmq-27.1.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:add071b2d25f84e8189aaf0882d39a285b42fa3853016ebab234a5e78c7a43db", size = 1885394, upload-time = "2025-09-08T23:08:35.51Z" }, + { url = "https://files.pythonhosted.org/packages/4f/6f/55c10e2e49ad52d080dc24e37adb215e5b0d64990b57598abc2e3f01725b/pyzmq-27.1.0-cp313-cp313t-win32.whl", hash = "sha256:7ccc0700cfdf7bd487bea8d850ec38f204478681ea02a582a8da8171b7f90a1c", size = 574964, upload-time = "2025-09-08T23:08:37.178Z" }, + { url = "https://files.pythonhosted.org/packages/87/4d/2534970ba63dd7c522d8ca80fb92777f362c0f321900667c615e2067cb29/pyzmq-27.1.0-cp313-cp313t-win_amd64.whl", hash = "sha256:8085a9fba668216b9b4323be338ee5437a235fe275b9d1610e422ccc279733e2", size = 641029, upload-time = "2025-09-08T23:08:40.595Z" }, + { url = "https://files.pythonhosted.org/packages/f6/fa/f8aea7a28b0641f31d40dea42d7ef003fded31e184ef47db696bc74cd610/pyzmq-27.1.0-cp313-cp313t-win_arm64.whl", hash = "sha256:6bb54ca21bcfe361e445256c15eedf083f153811c37be87e0514934d6913061e", size = 561541, upload-time = "2025-09-08T23:08:42.668Z" }, + { url = "https://files.pythonhosted.org/packages/87/45/19efbb3000956e82d0331bafca5d9ac19ea2857722fa2caacefb6042f39d/pyzmq-27.1.0-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:ce980af330231615756acd5154f29813d553ea555485ae712c491cd483df6b7a", size = 1341197, upload-time = "2025-09-08T23:08:44.973Z" }, + { url = "https://files.pythonhosted.org/packages/48/43/d72ccdbf0d73d1343936296665826350cb1e825f92f2db9db3e61c2162a2/pyzmq-27.1.0-cp314-cp314t-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:1779be8c549e54a1c38f805e56d2a2e5c009d26de10921d7d51cfd1c8d4632ea", size = 897175, upload-time = "2025-09-08T23:08:46.601Z" }, + { url = "https://files.pythonhosted.org/packages/2f/2e/a483f73a10b65a9ef0161e817321d39a770b2acf8bcf3004a28d90d14a94/pyzmq-27.1.0-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7200bb0f03345515df50d99d3db206a0a6bee1955fbb8c453c76f5bf0e08fb96", size = 660427, upload-time = "2025-09-08T23:08:48.187Z" }, + { url = "https://files.pythonhosted.org/packages/f5/d2/5f36552c2d3e5685abe60dfa56f91169f7a2d99bbaf67c5271022ab40863/pyzmq-27.1.0-cp314-cp314t-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:01c0e07d558b06a60773744ea6251f769cd79a41a97d11b8bf4ab8f034b0424d", size = 847929, upload-time = "2025-09-08T23:08:49.76Z" }, + { url = "https://files.pythonhosted.org/packages/c4/2a/404b331f2b7bf3198e9945f75c4c521f0c6a3a23b51f7a4a401b94a13833/pyzmq-27.1.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:80d834abee71f65253c91540445d37c4c561e293ba6e741b992f20a105d69146", size = 1650193, upload-time = "2025-09-08T23:08:51.7Z" }, + { url = "https://files.pythonhosted.org/packages/1c/0b/f4107e33f62a5acf60e3ded67ed33d79b4ce18de432625ce2fc5093d6388/pyzmq-27.1.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:544b4e3b7198dde4a62b8ff6685e9802a9a1ebf47e77478a5eb88eca2a82f2fd", size = 2024388, upload-time = "2025-09-08T23:08:53.393Z" }, + { url = "https://files.pythonhosted.org/packages/0d/01/add31fe76512642fd6e40e3a3bd21f4b47e242c8ba33efb6809e37076d9b/pyzmq-27.1.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:cedc4c68178e59a4046f97eca31b148ddcf51e88677de1ef4e78cf06c5376c9a", size = 1885316, upload-time = "2025-09-08T23:08:55.702Z" }, + { url = "https://files.pythonhosted.org/packages/c4/59/a5f38970f9bf07cee96128de79590bb354917914a9be11272cfc7ff26af0/pyzmq-27.1.0-cp314-cp314t-win32.whl", hash = "sha256:1f0b2a577fd770aa6f053211a55d1c47901f4d537389a034c690291485e5fe92", size = 587472, upload-time = "2025-09-08T23:08:58.18Z" }, + { url = "https://files.pythonhosted.org/packages/70/d8/78b1bad170f93fcf5e3536e70e8fadac55030002275c9a29e8f5719185de/pyzmq-27.1.0-cp314-cp314t-win_amd64.whl", hash = "sha256:19c9468ae0437f8074af379e986c5d3d7d7bfe033506af442e8c879732bedbe0", size = 661401, upload-time = "2025-09-08T23:08:59.802Z" }, + { url = "https://files.pythonhosted.org/packages/81/d6/4bfbb40c9a0b42fc53c7cf442f6385db70b40f74a783130c5d0a5aa62228/pyzmq-27.1.0-cp314-cp314t-win_arm64.whl", hash = "sha256:dc5dbf68a7857b59473f7df42650c621d7e8923fb03fa74a526890f4d33cc4d7", size = 575170, upload-time = "2025-09-08T23:09:01.418Z" }, + { url = "https://files.pythonhosted.org/packages/4c/c6/c4dcdecdbaa70969ee1fdced6d7b8f60cfabe64d25361f27ac4665a70620/pyzmq-27.1.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:18770c8d3563715387139060d37859c02ce40718d1faf299abddcdcc6a649066", size = 836265, upload-time = "2025-09-08T23:09:49.376Z" }, + { url = "https://files.pythonhosted.org/packages/3e/79/f38c92eeaeb03a2ccc2ba9866f0439593bb08c5e3b714ac1d553e5c96e25/pyzmq-27.1.0-pp311-pypy311_pp73-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:ac25465d42f92e990f8d8b0546b01c391ad431c3bf447683fdc40565941d0604", size = 800208, upload-time = "2025-09-08T23:09:51.073Z" }, + { url = "https://files.pythonhosted.org/packages/49/0e/3f0d0d335c6b3abb9b7b723776d0b21fa7f3a6c819a0db6097059aada160/pyzmq-27.1.0-pp311-pypy311_pp73-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:53b40f8ae006f2734ee7608d59ed661419f087521edbfc2149c3932e9c14808c", size = 567747, upload-time = "2025-09-08T23:09:52.698Z" }, + { url = "https://files.pythonhosted.org/packages/a1/cf/f2b3784d536250ffd4be70e049f3b60981235d70c6e8ce7e3ef21e1adb25/pyzmq-27.1.0-pp311-pypy311_pp73-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f605d884e7c8be8fe1aa94e0a783bf3f591b84c24e4bc4f3e7564c82ac25e271", size = 747371, upload-time = "2025-09-08T23:09:54.563Z" }, + { url = "https://files.pythonhosted.org/packages/01/1b/5dbe84eefc86f48473947e2f41711aded97eecef1231f4558f1f02713c12/pyzmq-27.1.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:c9f7f6e13dff2e44a6afeaf2cf54cee5929ad64afaf4d40b50f93c58fc687355", size = 544862, upload-time = "2025-09-08T23:09:56.509Z" }, +] + +[[package]] +name = "referencing" +version = "0.37.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "attrs" }, + { name = "rpds-py" }, + { name = "typing-extensions", marker = "python_full_version < '3.13'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/22/f5/df4e9027acead3ecc63e50fe1e36aca1523e1719559c499951bb4b53188f/referencing-0.37.0.tar.gz", hash = "sha256:44aefc3142c5b842538163acb373e24cce6632bd54bdb01b21ad5863489f50d8", size = 78036, upload-time = "2025-10-13T15:30:48.871Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2c/58/ca301544e1fa93ed4f80d724bf5b194f6e4b945841c5bfd555878eea9fcb/referencing-0.37.0-py3-none-any.whl", hash = "sha256:381329a9f99628c9069361716891d34ad94af76e461dcb0335825aecc7692231", size = 26766, upload-time = "2025-10-13T15:30:47.625Z" }, +] + +[[package]] +name = "requests" +version = "2.32.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "certifi" }, + { name = "charset-normalizer" }, + { name = "idna" }, + { name = "urllib3" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c9/74/b3ff8e6c8446842c3f5c837e9c3dfcfe2018ea6ecef224c710c85ef728f4/requests-2.32.5.tar.gz", hash = "sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf", size = 134517, upload-time = "2025-08-18T20:46:02.573Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl", hash = "sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6", size = 64738, upload-time = "2025-08-18T20:46:00.542Z" }, +] + +[[package]] +name = "rich" +version = "14.3.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markdown-it-py" }, + { name = "pygments" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b3/c6/f3b320c27991c46f43ee9d856302c70dc2d0fb2dba4842ff739d5f46b393/rich-14.3.3.tar.gz", hash = "sha256:b8daa0b9e4eef54dd8cf7c86c03713f53241884e814f4e2f5fb342fe520f639b", size = 230582, upload-time = "2026-02-19T17:23:12.474Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/14/25/b208c5683343959b670dc001595f2f3737e051da617f66c31f7c4fa93abc/rich-14.3.3-py3-none-any.whl", hash = "sha256:793431c1f8619afa7d3b52b2cdec859562b950ea0d4b6b505397612db8d5362d", size = 310458, upload-time = "2026-02-19T17:23:13.732Z" }, +] + +[[package]] +name = "roman-numerals" +version = "4.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ae/f9/41dc953bbeb056c17d5f7a519f50fdf010bd0553be2d630bc69d1e022703/roman_numerals-4.1.0.tar.gz", hash = "sha256:1af8b147eb1405d5839e78aeb93131690495fe9da5c91856cb33ad55a7f1e5b2", size = 9077, upload-time = "2025-12-17T18:25:34.381Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/04/54/6f679c435d28e0a568d8e8a7c0a93a09010818634c3c3907fc98d8983770/roman_numerals-4.1.0-py3-none-any.whl", hash = "sha256:647ba99caddc2cc1e55a51e4360689115551bf4476d90e8162cf8c345fe233c7", size = 7676, upload-time = "2025-12-17T18:25:33.098Z" }, +] + +[[package]] +name = "rpds-py" +version = "0.30.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/20/af/3f2f423103f1113b36230496629986e0ef7e199d2aa8392452b484b38ced/rpds_py-0.30.0.tar.gz", hash = "sha256:dd8ff7cf90014af0c0f787eea34794ebf6415242ee1d6fa91eaba725cc441e84", size = 69469, upload-time = "2025-11-30T20:24:38.837Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4d/6e/f964e88b3d2abee2a82c1ac8366da848fce1c6d834dc2132c3fda3970290/rpds_py-0.30.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:a2bffea6a4ca9f01b3f8e548302470306689684e61602aa3d141e34da06cf425", size = 370157, upload-time = "2025-11-30T20:21:53.789Z" }, + { url = "https://files.pythonhosted.org/packages/94/ba/24e5ebb7c1c82e74c4e4f33b2112a5573ddc703915b13a073737b59b86e0/rpds_py-0.30.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dc4f992dfe1e2bc3ebc7444f6c7051b4bc13cd8e33e43511e8ffd13bf407010d", size = 359676, upload-time = "2025-11-30T20:21:55.475Z" }, + { url = "https://files.pythonhosted.org/packages/84/86/04dbba1b087227747d64d80c3b74df946b986c57af0a9f0c98726d4d7a3b/rpds_py-0.30.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:422c3cb9856d80b09d30d2eb255d0754b23e090034e1deb4083f8004bd0761e4", size = 389938, upload-time = "2025-11-30T20:21:57.079Z" }, + { url = "https://files.pythonhosted.org/packages/42/bb/1463f0b1722b7f45431bdd468301991d1328b16cffe0b1c2918eba2c4eee/rpds_py-0.30.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:07ae8a593e1c3c6b82ca3292efbe73c30b61332fd612e05abee07c79359f292f", size = 402932, upload-time = "2025-11-30T20:21:58.47Z" }, + { url = "https://files.pythonhosted.org/packages/99/ee/2520700a5c1f2d76631f948b0736cdf9b0acb25abd0ca8e889b5c62ac2e3/rpds_py-0.30.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:12f90dd7557b6bd57f40abe7747e81e0c0b119bef015ea7726e69fe550e394a4", size = 525830, upload-time = "2025-11-30T20:21:59.699Z" }, + { url = "https://files.pythonhosted.org/packages/e0/ad/bd0331f740f5705cc555a5e17fdf334671262160270962e69a2bdef3bf76/rpds_py-0.30.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:99b47d6ad9a6da00bec6aabe5a6279ecd3c06a329d4aa4771034a21e335c3a97", size = 412033, upload-time = "2025-11-30T20:22:00.991Z" }, + { url = "https://files.pythonhosted.org/packages/f8/1e/372195d326549bb51f0ba0f2ecb9874579906b97e08880e7a65c3bef1a99/rpds_py-0.30.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:33f559f3104504506a44bb666b93a33f5d33133765b0c216a5bf2f1e1503af89", size = 390828, upload-time = "2025-11-30T20:22:02.723Z" }, + { url = "https://files.pythonhosted.org/packages/ab/2b/d88bb33294e3e0c76bc8f351a3721212713629ffca1700fa94979cb3eae8/rpds_py-0.30.0-cp311-cp311-manylinux_2_31_riscv64.whl", hash = "sha256:946fe926af6e44f3697abbc305ea168c2c31d3e3ef1058cf68f379bf0335a78d", size = 404683, upload-time = "2025-11-30T20:22:04.367Z" }, + { url = "https://files.pythonhosted.org/packages/50/32/c759a8d42bcb5289c1fac697cd92f6fe01a018dd937e62ae77e0e7f15702/rpds_py-0.30.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:495aeca4b93d465efde585977365187149e75383ad2684f81519f504f5c13038", size = 421583, upload-time = "2025-11-30T20:22:05.814Z" }, + { url = "https://files.pythonhosted.org/packages/2b/81/e729761dbd55ddf5d84ec4ff1f47857f4374b0f19bdabfcf929164da3e24/rpds_py-0.30.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d9a0ca5da0386dee0655b4ccdf46119df60e0f10da268d04fe7cc87886872ba7", size = 572496, upload-time = "2025-11-30T20:22:07.713Z" }, + { url = "https://files.pythonhosted.org/packages/14/f6/69066a924c3557c9c30baa6ec3a0aa07526305684c6f86c696b08860726c/rpds_py-0.30.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8d6d1cc13664ec13c1b84241204ff3b12f9bb82464b8ad6e7a5d3486975c2eed", size = 598669, upload-time = "2025-11-30T20:22:09.312Z" }, + { url = "https://files.pythonhosted.org/packages/5f/48/905896b1eb8a05630d20333d1d8ffd162394127b74ce0b0784ae04498d32/rpds_py-0.30.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3896fa1be39912cf0757753826bc8bdc8ca331a28a7c4ae46b7a21280b06bb85", size = 561011, upload-time = "2025-11-30T20:22:11.309Z" }, + { url = "https://files.pythonhosted.org/packages/22/16/cd3027c7e279d22e5eb431dd3c0fbc677bed58797fe7581e148f3f68818b/rpds_py-0.30.0-cp311-cp311-win32.whl", hash = "sha256:55f66022632205940f1827effeff17c4fa7ae1953d2b74a8581baaefb7d16f8c", size = 221406, upload-time = "2025-11-30T20:22:13.101Z" }, + { url = "https://files.pythonhosted.org/packages/fa/5b/e7b7aa136f28462b344e652ee010d4de26ee9fd16f1bfd5811f5153ccf89/rpds_py-0.30.0-cp311-cp311-win_amd64.whl", hash = "sha256:a51033ff701fca756439d641c0ad09a41d9242fa69121c7d8769604a0a629825", size = 236024, upload-time = "2025-11-30T20:22:14.853Z" }, + { url = "https://files.pythonhosted.org/packages/14/a6/364bba985e4c13658edb156640608f2c9e1d3ea3c81b27aa9d889fff0e31/rpds_py-0.30.0-cp311-cp311-win_arm64.whl", hash = "sha256:47b0ef6231c58f506ef0b74d44e330405caa8428e770fec25329ed2cb971a229", size = 229069, upload-time = "2025-11-30T20:22:16.577Z" }, + { url = "https://files.pythonhosted.org/packages/03/e7/98a2f4ac921d82f33e03f3835f5bf3a4a40aa1bfdc57975e74a97b2b4bdd/rpds_py-0.30.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:a161f20d9a43006833cd7068375a94d035714d73a172b681d8881820600abfad", size = 375086, upload-time = "2025-11-30T20:22:17.93Z" }, + { url = "https://files.pythonhosted.org/packages/4d/a1/bca7fd3d452b272e13335db8d6b0b3ecde0f90ad6f16f3328c6fb150c889/rpds_py-0.30.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6abc8880d9d036ecaafe709079969f56e876fcf107f7a8e9920ba6d5a3878d05", size = 359053, upload-time = "2025-11-30T20:22:19.297Z" }, + { url = "https://files.pythonhosted.org/packages/65/1c/ae157e83a6357eceff62ba7e52113e3ec4834a84cfe07fa4b0757a7d105f/rpds_py-0.30.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca28829ae5f5d569bb62a79512c842a03a12576375d5ece7d2cadf8abe96ec28", size = 390763, upload-time = "2025-11-30T20:22:21.661Z" }, + { url = "https://files.pythonhosted.org/packages/d4/36/eb2eb8515e2ad24c0bd43c3ee9cd74c33f7ca6430755ccdb240fd3144c44/rpds_py-0.30.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a1010ed9524c73b94d15919ca4d41d8780980e1765babf85f9a2f90d247153dd", size = 408951, upload-time = "2025-11-30T20:22:23.408Z" }, + { url = "https://files.pythonhosted.org/packages/d6/65/ad8dc1784a331fabbd740ef6f71ce2198c7ed0890dab595adb9ea2d775a1/rpds_py-0.30.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f8d1736cfb49381ba528cd5baa46f82fdc65c06e843dab24dd70b63d09121b3f", size = 514622, upload-time = "2025-11-30T20:22:25.16Z" }, + { url = "https://files.pythonhosted.org/packages/63/8e/0cfa7ae158e15e143fe03993b5bcd743a59f541f5952e1546b1ac1b5fd45/rpds_py-0.30.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d948b135c4693daff7bc2dcfc4ec57237a29bd37e60c2fabf5aff2bbacf3e2f1", size = 414492, upload-time = "2025-11-30T20:22:26.505Z" }, + { url = "https://files.pythonhosted.org/packages/60/1b/6f8f29f3f995c7ffdde46a626ddccd7c63aefc0efae881dc13b6e5d5bb16/rpds_py-0.30.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47f236970bccb2233267d89173d3ad2703cd36a0e2a6e92d0560d333871a3d23", size = 394080, upload-time = "2025-11-30T20:22:27.934Z" }, + { url = "https://files.pythonhosted.org/packages/6d/d5/a266341051a7a3ca2f4b750a3aa4abc986378431fc2da508c5034d081b70/rpds_py-0.30.0-cp312-cp312-manylinux_2_31_riscv64.whl", hash = "sha256:2e6ecb5a5bcacf59c3f912155044479af1d0b6681280048b338b28e364aca1f6", size = 408680, upload-time = "2025-11-30T20:22:29.341Z" }, + { url = "https://files.pythonhosted.org/packages/10/3b/71b725851df9ab7a7a4e33cf36d241933da66040d195a84781f49c50490c/rpds_py-0.30.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a8fa71a2e078c527c3e9dc9fc5a98c9db40bcc8a92b4e8858e36d329f8684b51", size = 423589, upload-time = "2025-11-30T20:22:31.469Z" }, + { url = "https://files.pythonhosted.org/packages/00/2b/e59e58c544dc9bd8bd8384ecdb8ea91f6727f0e37a7131baeff8d6f51661/rpds_py-0.30.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:73c67f2db7bc334e518d097c6d1e6fed021bbc9b7d678d6cc433478365d1d5f5", size = 573289, upload-time = "2025-11-30T20:22:32.997Z" }, + { url = "https://files.pythonhosted.org/packages/da/3e/a18e6f5b460893172a7d6a680e86d3b6bc87a54c1f0b03446a3c8c7b588f/rpds_py-0.30.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:5ba103fb455be00f3b1c2076c9d4264bfcb037c976167a6047ed82f23153f02e", size = 599737, upload-time = "2025-11-30T20:22:34.419Z" }, + { url = "https://files.pythonhosted.org/packages/5c/e2/714694e4b87b85a18e2c243614974413c60aa107fd815b8cbc42b873d1d7/rpds_py-0.30.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:7cee9c752c0364588353e627da8a7e808a66873672bcb5f52890c33fd965b394", size = 563120, upload-time = "2025-11-30T20:22:35.903Z" }, + { url = "https://files.pythonhosted.org/packages/6f/ab/d5d5e3bcedb0a77f4f613706b750e50a5a3ba1c15ccd3665ecc636c968fd/rpds_py-0.30.0-cp312-cp312-win32.whl", hash = "sha256:1ab5b83dbcf55acc8b08fc62b796ef672c457b17dbd7820a11d6c52c06839bdf", size = 223782, upload-time = "2025-11-30T20:22:37.271Z" }, + { url = "https://files.pythonhosted.org/packages/39/3b/f786af9957306fdc38a74cef405b7b93180f481fb48453a114bb6465744a/rpds_py-0.30.0-cp312-cp312-win_amd64.whl", hash = "sha256:a090322ca841abd453d43456ac34db46e8b05fd9b3b4ac0c78bcde8b089f959b", size = 240463, upload-time = "2025-11-30T20:22:39.021Z" }, + { url = "https://files.pythonhosted.org/packages/f3/d2/b91dc748126c1559042cfe41990deb92c4ee3e2b415f6b5234969ffaf0cc/rpds_py-0.30.0-cp312-cp312-win_arm64.whl", hash = "sha256:669b1805bd639dd2989b281be2cfd951c6121b65e729d9b843e9639ef1fd555e", size = 230868, upload-time = "2025-11-30T20:22:40.493Z" }, + { url = "https://files.pythonhosted.org/packages/ed/dc/d61221eb88ff410de3c49143407f6f3147acf2538c86f2ab7ce65ae7d5f9/rpds_py-0.30.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:f83424d738204d9770830d35290ff3273fbb02b41f919870479fab14b9d303b2", size = 374887, upload-time = "2025-11-30T20:22:41.812Z" }, + { url = "https://files.pythonhosted.org/packages/fd/32/55fb50ae104061dbc564ef15cc43c013dc4a9f4527a1f4d99baddf56fe5f/rpds_py-0.30.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:e7536cd91353c5273434b4e003cbda89034d67e7710eab8761fd918ec6c69cf8", size = 358904, upload-time = "2025-11-30T20:22:43.479Z" }, + { url = "https://files.pythonhosted.org/packages/58/70/faed8186300e3b9bdd138d0273109784eea2396c68458ed580f885dfe7ad/rpds_py-0.30.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2771c6c15973347f50fece41fc447c054b7ac2ae0502388ce3b6738cd366e3d4", size = 389945, upload-time = "2025-11-30T20:22:44.819Z" }, + { url = "https://files.pythonhosted.org/packages/bd/a8/073cac3ed2c6387df38f71296d002ab43496a96b92c823e76f46b8af0543/rpds_py-0.30.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0a59119fc6e3f460315fe9d08149f8102aa322299deaa5cab5b40092345c2136", size = 407783, upload-time = "2025-11-30T20:22:46.103Z" }, + { url = "https://files.pythonhosted.org/packages/77/57/5999eb8c58671f1c11eba084115e77a8899d6e694d2a18f69f0ba471ec8b/rpds_py-0.30.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:76fec018282b4ead0364022e3c54b60bf368b9d926877957a8624b58419169b7", size = 515021, upload-time = "2025-11-30T20:22:47.458Z" }, + { url = "https://files.pythonhosted.org/packages/e0/af/5ab4833eadc36c0a8ed2bc5c0de0493c04f6c06de223170bd0798ff98ced/rpds_py-0.30.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:692bef75a5525db97318e8cd061542b5a79812d711ea03dbc1f6f8dbb0c5f0d2", size = 414589, upload-time = "2025-11-30T20:22:48.872Z" }, + { url = "https://files.pythonhosted.org/packages/b7/de/f7192e12b21b9e9a68a6d0f249b4af3fdcdff8418be0767a627564afa1f1/rpds_py-0.30.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9027da1ce107104c50c81383cae773ef5c24d296dd11c99e2629dbd7967a20c6", size = 394025, upload-time = "2025-11-30T20:22:50.196Z" }, + { url = "https://files.pythonhosted.org/packages/91/c4/fc70cd0249496493500e7cc2de87504f5aa6509de1e88623431fec76d4b6/rpds_py-0.30.0-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:9cf69cdda1f5968a30a359aba2f7f9aa648a9ce4b580d6826437f2b291cfc86e", size = 408895, upload-time = "2025-11-30T20:22:51.87Z" }, + { url = "https://files.pythonhosted.org/packages/58/95/d9275b05ab96556fefff73a385813eb66032e4c99f411d0795372d9abcea/rpds_py-0.30.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a4796a717bf12b9da9d3ad002519a86063dcac8988b030e405704ef7d74d2d9d", size = 422799, upload-time = "2025-11-30T20:22:53.341Z" }, + { url = "https://files.pythonhosted.org/packages/06/c1/3088fc04b6624eb12a57eb814f0d4997a44b0d208d6cace713033ff1a6ba/rpds_py-0.30.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:5d4c2aa7c50ad4728a094ebd5eb46c452e9cb7edbfdb18f9e1221f597a73e1e7", size = 572731, upload-time = "2025-11-30T20:22:54.778Z" }, + { url = "https://files.pythonhosted.org/packages/d8/42/c612a833183b39774e8ac8fecae81263a68b9583ee343db33ab571a7ce55/rpds_py-0.30.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ba81a9203d07805435eb06f536d95a266c21e5b2dfbf6517748ca40c98d19e31", size = 599027, upload-time = "2025-11-30T20:22:56.212Z" }, + { url = "https://files.pythonhosted.org/packages/5f/60/525a50f45b01d70005403ae0e25f43c0384369ad24ffe46e8d9068b50086/rpds_py-0.30.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:945dccface01af02675628334f7cf49c2af4c1c904748efc5cf7bbdf0b579f95", size = 563020, upload-time = "2025-11-30T20:22:58.2Z" }, + { url = "https://files.pythonhosted.org/packages/0b/5d/47c4655e9bcd5ca907148535c10e7d489044243cc9941c16ed7cd53be91d/rpds_py-0.30.0-cp313-cp313-win32.whl", hash = "sha256:b40fb160a2db369a194cb27943582b38f79fc4887291417685f3ad693c5a1d5d", size = 223139, upload-time = "2025-11-30T20:23:00.209Z" }, + { url = "https://files.pythonhosted.org/packages/f2/e1/485132437d20aa4d3e1d8b3fb5a5e65aa8139f1e097080c2a8443201742c/rpds_py-0.30.0-cp313-cp313-win_amd64.whl", hash = "sha256:806f36b1b605e2d6a72716f321f20036b9489d29c51c91f4dd29a3e3afb73b15", size = 240224, upload-time = "2025-11-30T20:23:02.008Z" }, + { url = "https://files.pythonhosted.org/packages/24/95/ffd128ed1146a153d928617b0ef673960130be0009c77d8fbf0abe306713/rpds_py-0.30.0-cp313-cp313-win_arm64.whl", hash = "sha256:d96c2086587c7c30d44f31f42eae4eac89b60dabbac18c7669be3700f13c3ce1", size = 230645, upload-time = "2025-11-30T20:23:03.43Z" }, + { url = "https://files.pythonhosted.org/packages/ff/1b/b10de890a0def2a319a2626334a7f0ae388215eb60914dbac8a3bae54435/rpds_py-0.30.0-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:eb0b93f2e5c2189ee831ee43f156ed34e2a89a78a66b98cadad955972548be5a", size = 364443, upload-time = "2025-11-30T20:23:04.878Z" }, + { url = "https://files.pythonhosted.org/packages/0d/bf/27e39f5971dc4f305a4fb9c672ca06f290f7c4e261c568f3dea16a410d47/rpds_py-0.30.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:922e10f31f303c7c920da8981051ff6d8c1a56207dbdf330d9047f6d30b70e5e", size = 353375, upload-time = "2025-11-30T20:23:06.342Z" }, + { url = "https://files.pythonhosted.org/packages/40/58/442ada3bba6e8e6615fc00483135c14a7538d2ffac30e2d933ccf6852232/rpds_py-0.30.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cdc62c8286ba9bf7f47befdcea13ea0e26bf294bda99758fd90535cbaf408000", size = 383850, upload-time = "2025-11-30T20:23:07.825Z" }, + { url = "https://files.pythonhosted.org/packages/14/14/f59b0127409a33c6ef6f5c1ebd5ad8e32d7861c9c7adfa9a624fc3889f6c/rpds_py-0.30.0-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:47f9a91efc418b54fb8190a6b4aa7813a23fb79c51f4bb84e418f5476c38b8db", size = 392812, upload-time = "2025-11-30T20:23:09.228Z" }, + { url = "https://files.pythonhosted.org/packages/b3/66/e0be3e162ac299b3a22527e8913767d869e6cc75c46bd844aa43fb81ab62/rpds_py-0.30.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1f3587eb9b17f3789ad50824084fa6f81921bbf9a795826570bda82cb3ed91f2", size = 517841, upload-time = "2025-11-30T20:23:11.186Z" }, + { url = "https://files.pythonhosted.org/packages/3d/55/fa3b9cf31d0c963ecf1ba777f7cf4b2a2c976795ac430d24a1f43d25a6ba/rpds_py-0.30.0-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:39c02563fc592411c2c61d26b6c5fe1e51eaa44a75aa2c8735ca88b0d9599daa", size = 408149, upload-time = "2025-11-30T20:23:12.864Z" }, + { url = "https://files.pythonhosted.org/packages/60/ca/780cf3b1a32b18c0f05c441958d3758f02544f1d613abf9488cd78876378/rpds_py-0.30.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:51a1234d8febafdfd33a42d97da7a43f5dcb120c1060e352a3fbc0c6d36e2083", size = 383843, upload-time = "2025-11-30T20:23:14.638Z" }, + { url = "https://files.pythonhosted.org/packages/82/86/d5f2e04f2aa6247c613da0c1dd87fcd08fa17107e858193566048a1e2f0a/rpds_py-0.30.0-cp313-cp313t-manylinux_2_31_riscv64.whl", hash = "sha256:eb2c4071ab598733724c08221091e8d80e89064cd472819285a9ab0f24bcedb9", size = 396507, upload-time = "2025-11-30T20:23:16.105Z" }, + { url = "https://files.pythonhosted.org/packages/4b/9a/453255d2f769fe44e07ea9785c8347edaf867f7026872e76c1ad9f7bed92/rpds_py-0.30.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6bdfdb946967d816e6adf9a3d8201bfad269c67efe6cefd7093ef959683c8de0", size = 414949, upload-time = "2025-11-30T20:23:17.539Z" }, + { url = "https://files.pythonhosted.org/packages/a3/31/622a86cdc0c45d6df0e9ccb6becdba5074735e7033c20e401a6d9d0e2ca0/rpds_py-0.30.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:c77afbd5f5250bf27bf516c7c4a016813eb2d3e116139aed0096940c5982da94", size = 565790, upload-time = "2025-11-30T20:23:19.029Z" }, + { url = "https://files.pythonhosted.org/packages/1c/5d/15bbf0fb4a3f58a3b1c67855ec1efcc4ceaef4e86644665fff03e1b66d8d/rpds_py-0.30.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:61046904275472a76c8c90c9ccee9013d70a6d0f73eecefd38c1ae7c39045a08", size = 590217, upload-time = "2025-11-30T20:23:20.885Z" }, + { url = "https://files.pythonhosted.org/packages/6d/61/21b8c41f68e60c8cc3b2e25644f0e3681926020f11d06ab0b78e3c6bbff1/rpds_py-0.30.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:4c5f36a861bc4b7da6516dbdf302c55313afa09b81931e8280361a4f6c9a2d27", size = 555806, upload-time = "2025-11-30T20:23:22.488Z" }, + { url = "https://files.pythonhosted.org/packages/f9/39/7e067bb06c31de48de3eb200f9fc7c58982a4d3db44b07e73963e10d3be9/rpds_py-0.30.0-cp313-cp313t-win32.whl", hash = "sha256:3d4a69de7a3e50ffc214ae16d79d8fbb0922972da0356dcf4d0fdca2878559c6", size = 211341, upload-time = "2025-11-30T20:23:24.449Z" }, + { url = "https://files.pythonhosted.org/packages/0a/4d/222ef0b46443cf4cf46764d9c630f3fe4abaa7245be9417e56e9f52b8f65/rpds_py-0.30.0-cp313-cp313t-win_amd64.whl", hash = "sha256:f14fc5df50a716f7ece6a80b6c78bb35ea2ca47c499e422aa4463455dd96d56d", size = 225768, upload-time = "2025-11-30T20:23:25.908Z" }, + { url = "https://files.pythonhosted.org/packages/86/81/dad16382ebbd3d0e0328776d8fd7ca94220e4fa0798d1dc5e7da48cb3201/rpds_py-0.30.0-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:68f19c879420aa08f61203801423f6cd5ac5f0ac4ac82a2368a9fcd6a9a075e0", size = 362099, upload-time = "2025-11-30T20:23:27.316Z" }, + { url = "https://files.pythonhosted.org/packages/2b/60/19f7884db5d5603edf3c6bce35408f45ad3e97e10007df0e17dd57af18f8/rpds_py-0.30.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:ec7c4490c672c1a0389d319b3a9cfcd098dcdc4783991553c332a15acf7249be", size = 353192, upload-time = "2025-11-30T20:23:29.151Z" }, + { url = "https://files.pythonhosted.org/packages/bf/c4/76eb0e1e72d1a9c4703c69607cec123c29028bff28ce41588792417098ac/rpds_py-0.30.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f251c812357a3fed308d684a5079ddfb9d933860fc6de89f2b7ab00da481e65f", size = 384080, upload-time = "2025-11-30T20:23:30.785Z" }, + { url = "https://files.pythonhosted.org/packages/72/87/87ea665e92f3298d1b26d78814721dc39ed8d2c74b86e83348d6b48a6f31/rpds_py-0.30.0-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ac98b175585ecf4c0348fd7b29c3864bda53b805c773cbf7bfdaffc8070c976f", size = 394841, upload-time = "2025-11-30T20:23:32.209Z" }, + { url = "https://files.pythonhosted.org/packages/77/ad/7783a89ca0587c15dcbf139b4a8364a872a25f861bdb88ed99f9b0dec985/rpds_py-0.30.0-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3e62880792319dbeb7eb866547f2e35973289e7d5696c6e295476448f5b63c87", size = 516670, upload-time = "2025-11-30T20:23:33.742Z" }, + { url = "https://files.pythonhosted.org/packages/5b/3c/2882bdac942bd2172f3da574eab16f309ae10a3925644e969536553cb4ee/rpds_py-0.30.0-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4e7fc54e0900ab35d041b0601431b0a0eb495f0851a0639b6ef90f7741b39a18", size = 408005, upload-time = "2025-11-30T20:23:35.253Z" }, + { url = "https://files.pythonhosted.org/packages/ce/81/9a91c0111ce1758c92516a3e44776920b579d9a7c09b2b06b642d4de3f0f/rpds_py-0.30.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47e77dc9822d3ad616c3d5759ea5631a75e5809d5a28707744ef79d7a1bcfcad", size = 382112, upload-time = "2025-11-30T20:23:36.842Z" }, + { url = "https://files.pythonhosted.org/packages/cf/8e/1da49d4a107027e5fbc64daeab96a0706361a2918da10cb41769244b805d/rpds_py-0.30.0-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:b4dc1a6ff022ff85ecafef7979a2c6eb423430e05f1165d6688234e62ba99a07", size = 399049, upload-time = "2025-11-30T20:23:38.343Z" }, + { url = "https://files.pythonhosted.org/packages/df/5a/7ee239b1aa48a127570ec03becbb29c9d5a9eb092febbd1699d567cae859/rpds_py-0.30.0-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4559c972db3a360808309e06a74628b95eaccbf961c335c8fe0d590cf587456f", size = 415661, upload-time = "2025-11-30T20:23:40.263Z" }, + { url = "https://files.pythonhosted.org/packages/70/ea/caa143cf6b772f823bc7929a45da1fa83569ee49b11d18d0ada7f5ee6fd6/rpds_py-0.30.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:0ed177ed9bded28f8deb6ab40c183cd1192aa0de40c12f38be4d59cd33cb5c65", size = 565606, upload-time = "2025-11-30T20:23:42.186Z" }, + { url = "https://files.pythonhosted.org/packages/64/91/ac20ba2d69303f961ad8cf55bf7dbdb4763f627291ba3d0d7d67333cced9/rpds_py-0.30.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:ad1fa8db769b76ea911cb4e10f049d80bf518c104f15b3edb2371cc65375c46f", size = 591126, upload-time = "2025-11-30T20:23:44.086Z" }, + { url = "https://files.pythonhosted.org/packages/21/20/7ff5f3c8b00c8a95f75985128c26ba44503fb35b8e0259d812766ea966c7/rpds_py-0.30.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:46e83c697b1f1c72b50e5ee5adb4353eef7406fb3f2043d64c33f20ad1c2fc53", size = 553371, upload-time = "2025-11-30T20:23:46.004Z" }, + { url = "https://files.pythonhosted.org/packages/72/c7/81dadd7b27c8ee391c132a6b192111ca58d866577ce2d9b0ca157552cce0/rpds_py-0.30.0-cp314-cp314-win32.whl", hash = "sha256:ee454b2a007d57363c2dfd5b6ca4a5d7e2c518938f8ed3b706e37e5d470801ed", size = 215298, upload-time = "2025-11-30T20:23:47.696Z" }, + { url = "https://files.pythonhosted.org/packages/3e/d2/1aaac33287e8cfb07aab2e6b8ac1deca62f6f65411344f1433c55e6f3eb8/rpds_py-0.30.0-cp314-cp314-win_amd64.whl", hash = "sha256:95f0802447ac2d10bcc69f6dc28fe95fdf17940367b21d34e34c737870758950", size = 228604, upload-time = "2025-11-30T20:23:49.501Z" }, + { url = "https://files.pythonhosted.org/packages/e8/95/ab005315818cc519ad074cb7784dae60d939163108bd2b394e60dc7b5461/rpds_py-0.30.0-cp314-cp314-win_arm64.whl", hash = "sha256:613aa4771c99f03346e54c3f038e4cc574ac09a3ddfb0e8878487335e96dead6", size = 222391, upload-time = "2025-11-30T20:23:50.96Z" }, + { url = "https://files.pythonhosted.org/packages/9e/68/154fe0194d83b973cdedcdcc88947a2752411165930182ae41d983dcefa6/rpds_py-0.30.0-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:7e6ecfcb62edfd632e56983964e6884851786443739dbfe3582947e87274f7cb", size = 364868, upload-time = "2025-11-30T20:23:52.494Z" }, + { url = "https://files.pythonhosted.org/packages/83/69/8bbc8b07ec854d92a8b75668c24d2abcb1719ebf890f5604c61c9369a16f/rpds_py-0.30.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:a1d0bc22a7cdc173fedebb73ef81e07faef93692b8c1ad3733b67e31e1b6e1b8", size = 353747, upload-time = "2025-11-30T20:23:54.036Z" }, + { url = "https://files.pythonhosted.org/packages/ab/00/ba2e50183dbd9abcce9497fa5149c62b4ff3e22d338a30d690f9af970561/rpds_py-0.30.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d08f00679177226c4cb8c5265012eea897c8ca3b93f429e546600c971bcbae7", size = 383795, upload-time = "2025-11-30T20:23:55.556Z" }, + { url = "https://files.pythonhosted.org/packages/05/6f/86f0272b84926bcb0e4c972262f54223e8ecc556b3224d281e6598fc9268/rpds_py-0.30.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5965af57d5848192c13534f90f9dd16464f3c37aaf166cc1da1cae1fd5a34898", size = 393330, upload-time = "2025-11-30T20:23:57.033Z" }, + { url = "https://files.pythonhosted.org/packages/cb/e9/0e02bb2e6dc63d212641da45df2b0bf29699d01715913e0d0f017ee29438/rpds_py-0.30.0-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9a4e86e34e9ab6b667c27f3211ca48f73dba7cd3d90f8d5b11be56e5dbc3fb4e", size = 518194, upload-time = "2025-11-30T20:23:58.637Z" }, + { url = "https://files.pythonhosted.org/packages/ee/ca/be7bca14cf21513bdf9c0606aba17d1f389ea2b6987035eb4f62bd923f25/rpds_py-0.30.0-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e5d3e6b26f2c785d65cc25ef1e5267ccbe1b069c5c21b8cc724efee290554419", size = 408340, upload-time = "2025-11-30T20:24:00.2Z" }, + { url = "https://files.pythonhosted.org/packages/c2/c7/736e00ebf39ed81d75544c0da6ef7b0998f8201b369acf842f9a90dc8fce/rpds_py-0.30.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:626a7433c34566535b6e56a1b39a7b17ba961e97ce3b80ec62e6f1312c025551", size = 383765, upload-time = "2025-11-30T20:24:01.759Z" }, + { url = "https://files.pythonhosted.org/packages/4a/3f/da50dfde9956aaf365c4adc9533b100008ed31aea635f2b8d7b627e25b49/rpds_py-0.30.0-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:acd7eb3f4471577b9b5a41baf02a978e8bdeb08b4b355273994f8b87032000a8", size = 396834, upload-time = "2025-11-30T20:24:03.687Z" }, + { url = "https://files.pythonhosted.org/packages/4e/00/34bcc2565b6020eab2623349efbdec810676ad571995911f1abdae62a3a0/rpds_py-0.30.0-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fe5fa731a1fa8a0a56b0977413f8cacac1768dad38d16b3a296712709476fbd5", size = 415470, upload-time = "2025-11-30T20:24:05.232Z" }, + { url = "https://files.pythonhosted.org/packages/8c/28/882e72b5b3e6f718d5453bd4d0d9cf8df36fddeb4ddbbab17869d5868616/rpds_py-0.30.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:74a3243a411126362712ee1524dfc90c650a503502f135d54d1b352bd01f2404", size = 565630, upload-time = "2025-11-30T20:24:06.878Z" }, + { url = "https://files.pythonhosted.org/packages/3b/97/04a65539c17692de5b85c6e293520fd01317fd878ea1995f0367d4532fb1/rpds_py-0.30.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:3e8eeb0544f2eb0d2581774be4c3410356eba189529a6b3e36bbbf9696175856", size = 591148, upload-time = "2025-11-30T20:24:08.445Z" }, + { url = "https://files.pythonhosted.org/packages/85/70/92482ccffb96f5441aab93e26c4d66489eb599efdcf96fad90c14bbfb976/rpds_py-0.30.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:dbd936cde57abfee19ab3213cf9c26be06d60750e60a8e4dd85d1ab12c8b1f40", size = 556030, upload-time = "2025-11-30T20:24:10.956Z" }, + { url = "https://files.pythonhosted.org/packages/20/53/7c7e784abfa500a2b6b583b147ee4bb5a2b3747a9166bab52fec4b5b5e7d/rpds_py-0.30.0-cp314-cp314t-win32.whl", hash = "sha256:dc824125c72246d924f7f796b4f63c1e9dc810c7d9e2355864b3c3a73d59ade0", size = 211570, upload-time = "2025-11-30T20:24:12.735Z" }, + { url = "https://files.pythonhosted.org/packages/d0/02/fa464cdfbe6b26e0600b62c528b72d8608f5cc49f96b8d6e38c95d60c676/rpds_py-0.30.0-cp314-cp314t-win_amd64.whl", hash = "sha256:27f4b0e92de5bfbc6f86e43959e6edd1425c33b5e69aab0984a72047f2bcf1e3", size = 226532, upload-time = "2025-11-30T20:24:14.634Z" }, + { url = "https://files.pythonhosted.org/packages/69/71/3f34339ee70521864411f8b6992e7ab13ac30d8e4e3309e07c7361767d91/rpds_py-0.30.0-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:c2262bdba0ad4fc6fb5545660673925c2d2a5d9e2e0fb603aad545427be0fc58", size = 372292, upload-time = "2025-11-30T20:24:16.537Z" }, + { url = "https://files.pythonhosted.org/packages/57/09/f183df9b8f2d66720d2ef71075c59f7e1b336bec7ee4c48f0a2b06857653/rpds_py-0.30.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:ee6af14263f25eedc3bb918a3c04245106a42dfd4f5c2285ea6f997b1fc3f89a", size = 362128, upload-time = "2025-11-30T20:24:18.086Z" }, + { url = "https://files.pythonhosted.org/packages/7a/68/5c2594e937253457342e078f0cc1ded3dd7b2ad59afdbf2d354869110a02/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3adbb8179ce342d235c31ab8ec511e66c73faa27a47e076ccc92421add53e2bb", size = 391542, upload-time = "2025-11-30T20:24:20.092Z" }, + { url = "https://files.pythonhosted.org/packages/49/5c/31ef1afd70b4b4fbdb2800249f34c57c64beb687495b10aec0365f53dfc4/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:250fa00e9543ac9b97ac258bd37367ff5256666122c2d0f2bc97577c60a1818c", size = 404004, upload-time = "2025-11-30T20:24:22.231Z" }, + { url = "https://files.pythonhosted.org/packages/e3/63/0cfbea38d05756f3440ce6534d51a491d26176ac045e2707adc99bb6e60a/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9854cf4f488b3d57b9aaeb105f06d78e5529d3145b1e4a41750167e8c213c6d3", size = 527063, upload-time = "2025-11-30T20:24:24.302Z" }, + { url = "https://files.pythonhosted.org/packages/42/e6/01e1f72a2456678b0f618fc9a1a13f882061690893c192fcad9f2926553a/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:993914b8e560023bc0a8bf742c5f303551992dcb85e247b1e5c7f4a7d145bda5", size = 413099, upload-time = "2025-11-30T20:24:25.916Z" }, + { url = "https://files.pythonhosted.org/packages/b8/25/8df56677f209003dcbb180765520c544525e3ef21ea72279c98b9aa7c7fb/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:58edca431fb9b29950807e301826586e5bbf24163677732429770a697ffe6738", size = 392177, upload-time = "2025-11-30T20:24:27.834Z" }, + { url = "https://files.pythonhosted.org/packages/4a/b4/0a771378c5f16f8115f796d1f437950158679bcd2a7c68cf251cfb00ed5b/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_31_riscv64.whl", hash = "sha256:dea5b552272a944763b34394d04577cf0f9bd013207bc32323b5a89a53cf9c2f", size = 406015, upload-time = "2025-11-30T20:24:29.457Z" }, + { url = "https://files.pythonhosted.org/packages/36/d8/456dbba0af75049dc6f63ff295a2f92766b9d521fa00de67a2bd6427d57a/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ba3af48635eb83d03f6c9735dfb21785303e73d22ad03d489e88adae6eab8877", size = 423736, upload-time = "2025-11-30T20:24:31.22Z" }, + { url = "https://files.pythonhosted.org/packages/13/64/b4d76f227d5c45a7e0b796c674fd81b0a6c4fbd48dc29271857d8219571c/rpds_py-0.30.0-pp311-pypy311_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:dff13836529b921e22f15cb099751209a60009731a68519630a24d61f0b1b30a", size = 573981, upload-time = "2025-11-30T20:24:32.934Z" }, + { url = "https://files.pythonhosted.org/packages/20/91/092bacadeda3edf92bf743cc96a7be133e13a39cdbfd7b5082e7ab638406/rpds_py-0.30.0-pp311-pypy311_pp73-musllinux_1_2_i686.whl", hash = "sha256:1b151685b23929ab7beec71080a8889d4d6d9fa9a983d213f07121205d48e2c4", size = 599782, upload-time = "2025-11-30T20:24:35.169Z" }, + { url = "https://files.pythonhosted.org/packages/d1/b7/b95708304cd49b7b6f82fdd039f1748b66ec2b21d6a45180910802f1abf1/rpds_py-0.30.0-pp311-pypy311_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:ac37f9f516c51e5753f27dfdef11a88330f04de2d564be3991384b2f3535d02e", size = 562191, upload-time = "2025-11-30T20:24:36.853Z" }, +] + +[[package]] +name = "ruff" +version = "0.15.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/06/04/eab13a954e763b0606f460443fcbf6bb5a0faf06890ea3754ff16523dce5/ruff-0.15.2.tar.gz", hash = "sha256:14b965afee0969e68bb871eba625343b8673375f457af4abe98553e8bbb98342", size = 4558148, upload-time = "2026-02-19T22:32:20.271Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2f/70/3a4dc6d09b13cb3e695f28307e5d889b2e1a66b7af9c5e257e796695b0e6/ruff-0.15.2-py3-none-linux_armv6l.whl", hash = "sha256:120691a6fdae2f16d65435648160f5b81a9625288f75544dc40637436b5d3c0d", size = 10430565, upload-time = "2026-02-19T22:32:41.824Z" }, + { url = "https://files.pythonhosted.org/packages/71/0b/bb8457b56185ece1305c666dc895832946d24055be90692381c31d57466d/ruff-0.15.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:a89056d831256099658b6bba4037ac6dd06f49d194199215befe2bb10457ea5e", size = 10820354, upload-time = "2026-02-19T22:32:07.366Z" }, + { url = "https://files.pythonhosted.org/packages/2d/c1/e0532d7f9c9e0b14c46f61b14afd563298b8b83f337b6789ddd987e46121/ruff-0.15.2-py3-none-macosx_11_0_arm64.whl", hash = "sha256:e36dee3a64be0ebd23c86ffa3aa3fd3ac9a712ff295e192243f814a830b6bd87", size = 10170767, upload-time = "2026-02-19T22:32:13.188Z" }, + { url = "https://files.pythonhosted.org/packages/47/e8/da1aa341d3af017a21c7a62fb5ec31d4e7ad0a93ab80e3a508316efbcb23/ruff-0.15.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a9fb47b6d9764677f8c0a193c0943ce9a05d6763523f132325af8a858eadc2b9", size = 10529591, upload-time = "2026-02-19T22:32:02.547Z" }, + { url = "https://files.pythonhosted.org/packages/93/74/184fbf38e9f3510231fbc5e437e808f0b48c42d1df9434b208821efcd8d6/ruff-0.15.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f376990f9d0d6442ea9014b19621d8f2aaf2b8e39fdbfc79220b7f0c596c9b80", size = 10260771, upload-time = "2026-02-19T22:32:36.938Z" }, + { url = "https://files.pythonhosted.org/packages/05/ac/605c20b8e059a0bc4b42360414baa4892ff278cec1c91fff4be0dceedefd/ruff-0.15.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2dcc987551952d73cbf5c88d9fdee815618d497e4df86cd4c4824cc59d5dd75f", size = 11045791, upload-time = "2026-02-19T22:32:31.642Z" }, + { url = "https://files.pythonhosted.org/packages/fd/52/db6e419908f45a894924d410ac77d64bdd98ff86901d833364251bd08e22/ruff-0.15.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:42a47fd785cbe8c01b9ff45031af875d101b040ad8f4de7bbb716487c74c9a77", size = 11879271, upload-time = "2026-02-19T22:32:29.305Z" }, + { url = "https://files.pythonhosted.org/packages/3e/d8/7992b18f2008bdc9231d0f10b16df7dda964dbf639e2b8b4c1b4e91b83af/ruff-0.15.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cbe9f49354866e575b4c6943856989f966421870e85cd2ac94dccb0a9dcb2fea", size = 11303707, upload-time = "2026-02-19T22:32:22.492Z" }, + { url = "https://files.pythonhosted.org/packages/d7/02/849b46184bcfdd4b64cde61752cc9a146c54759ed036edd11857e9b8443b/ruff-0.15.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b7a672c82b5f9887576087d97be5ce439f04bbaf548ee987b92d3a7dede41d3a", size = 11149151, upload-time = "2026-02-19T22:32:44.234Z" }, + { url = "https://files.pythonhosted.org/packages/70/04/f5284e388bab60d1d3b99614a5a9aeb03e0f333847e2429bebd2aaa1feec/ruff-0.15.2-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:72ecc64f46f7019e2bcc3cdc05d4a7da958b629a5ab7033195e11a438403d956", size = 11091132, upload-time = "2026-02-19T22:32:24.691Z" }, + { url = "https://files.pythonhosted.org/packages/fa/ae/88d844a21110e14d92cf73d57363fab59b727ebeabe78009b9ccb23500af/ruff-0.15.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:8dcf243b15b561c655c1ef2f2b0050e5d50db37fe90115507f6ff37d865dc8b4", size = 10504717, upload-time = "2026-02-19T22:32:26.75Z" }, + { url = "https://files.pythonhosted.org/packages/64/27/867076a6ada7f2b9c8292884ab44d08fd2ba71bd2b5364d4136f3cd537e1/ruff-0.15.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:dab6941c862c05739774677c6273166d2510d254dac0695c0e3f5efa1b5585de", size = 10263122, upload-time = "2026-02-19T22:32:10.036Z" }, + { url = "https://files.pythonhosted.org/packages/e7/ef/faf9321d550f8ebf0c6373696e70d1758e20ccdc3951ad7af00c0956be7c/ruff-0.15.2-py3-none-musllinux_1_2_i686.whl", hash = "sha256:1b9164f57fc36058e9a6806eb92af185b0697c9fe4c7c52caa431c6554521e5c", size = 10735295, upload-time = "2026-02-19T22:32:39.227Z" }, + { url = "https://files.pythonhosted.org/packages/2f/55/e8089fec62e050ba84d71b70e7834b97709ca9b7aba10c1a0b196e493f97/ruff-0.15.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:80d24fcae24d42659db7e335b9e1531697a7102c19185b8dc4a028b952865fd8", size = 11241641, upload-time = "2026-02-19T22:32:34.617Z" }, + { url = "https://files.pythonhosted.org/packages/23/01/1c30526460f4d23222d0fabd5888868262fd0e2b71a00570ca26483cd993/ruff-0.15.2-py3-none-win32.whl", hash = "sha256:fd5ff9e5f519a7e1bd99cbe8daa324010a74f5e2ebc97c6242c08f26f3714f6f", size = 10507885, upload-time = "2026-02-19T22:32:15.635Z" }, + { url = "https://files.pythonhosted.org/packages/5c/10/3d18e3bbdf8fc50bbb4ac3cc45970aa5a9753c5cb51bf9ed9a3cd8b79fa3/ruff-0.15.2-py3-none-win_amd64.whl", hash = "sha256:d20014e3dfa400f3ff84830dfb5755ece2de45ab62ecea4af6b7262d0fb4f7c5", size = 11623725, upload-time = "2026-02-19T22:32:04.947Z" }, + { url = "https://files.pythonhosted.org/packages/6d/78/097c0798b1dab9f8affe73da9642bb4500e098cb27fd8dc9724816ac747b/ruff-0.15.2-py3-none-win_arm64.whl", hash = "sha256:cabddc5822acdc8f7b5527b36ceac55cc51eec7b1946e60181de8fe83ca8876e", size = 10941649, upload-time = "2026-02-19T22:32:18.108Z" }, +] + +[[package]] +name = "scipy" +version = "1.17.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/56/3e/9cca699f3486ce6bc12ff46dc2031f1ec8eb9ccc9a320fdaf925f1417426/scipy-1.17.0.tar.gz", hash = "sha256:2591060c8e648d8b96439e111ac41fd8342fdeff1876be2e19dea3fe8930454e", size = 30396830, upload-time = "2026-01-10T21:34:23.009Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1e/4b/c89c131aa87cad2b77a54eb0fb94d633a842420fa7e919dc2f922037c3d8/scipy-1.17.0-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:2abd71643797bd8a106dff97894ff7869eeeb0af0f7a5ce02e4227c6a2e9d6fd", size = 31381316, upload-time = "2026-01-10T21:24:33.42Z" }, + { url = "https://files.pythonhosted.org/packages/5e/5f/a6b38f79a07d74989224d5f11b55267714707582908a5f1ae854cf9a9b84/scipy-1.17.0-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:ef28d815f4d2686503e5f4f00edc387ae58dfd7a2f42e348bb53359538f01558", size = 27966760, upload-time = "2026-01-10T21:24:38.911Z" }, + { url = "https://files.pythonhosted.org/packages/c1/20/095ad24e031ee8ed3c5975954d816b8e7e2abd731e04f8be573de8740885/scipy-1.17.0-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:272a9f16d6bb4667e8b50d25d71eddcc2158a214df1b566319298de0939d2ab7", size = 20138701, upload-time = "2026-01-10T21:24:43.249Z" }, + { url = "https://files.pythonhosted.org/packages/89/11/4aad2b3858d0337756f3323f8960755704e530b27eb2a94386c970c32cbe/scipy-1.17.0-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:7204fddcbec2fe6598f1c5fdf027e9f259106d05202a959a9f1aecf036adc9f6", size = 22480574, upload-time = "2026-01-10T21:24:47.266Z" }, + { url = "https://files.pythonhosted.org/packages/85/bd/f5af70c28c6da2227e510875cadf64879855193a687fb19951f0f44cfd6b/scipy-1.17.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fc02c37a5639ee67d8fb646ffded6d793c06c5622d36b35cfa8fe5ececb8f042", size = 32862414, upload-time = "2026-01-10T21:24:52.566Z" }, + { url = "https://files.pythonhosted.org/packages/ef/df/df1457c4df3826e908879fe3d76bc5b6e60aae45f4ee42539512438cfd5d/scipy-1.17.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:dac97a27520d66c12a34fd90a4fe65f43766c18c0d6e1c0a80f114d2260080e4", size = 35112380, upload-time = "2026-01-10T21:24:58.433Z" }, + { url = "https://files.pythonhosted.org/packages/5f/bb/88e2c16bd1dd4de19d80d7c5e238387182993c2fb13b4b8111e3927ad422/scipy-1.17.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ebb7446a39b3ae0fe8f416a9a3fdc6fba3f11c634f680f16a239c5187bc487c0", size = 34922676, upload-time = "2026-01-10T21:25:04.287Z" }, + { url = "https://files.pythonhosted.org/packages/02/ba/5120242cc735f71fc002cff0303d536af4405eb265f7c60742851e7ccfe9/scipy-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:474da16199f6af66601a01546144922ce402cb17362e07d82f5a6cf8f963e449", size = 37507599, upload-time = "2026-01-10T21:25:09.851Z" }, + { url = "https://files.pythonhosted.org/packages/52/c8/08629657ac6c0da198487ce8cd3de78e02cfde42b7f34117d56a3fe249dc/scipy-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:255c0da161bd7b32a6c898e7891509e8a9289f0b1c6c7d96142ee0d2b114c2ea", size = 36380284, upload-time = "2026-01-10T21:25:15.632Z" }, + { url = "https://files.pythonhosted.org/packages/6c/4a/465f96d42c6f33ad324a40049dfd63269891db9324aa66c4a1c108c6f994/scipy-1.17.0-cp311-cp311-win_arm64.whl", hash = "sha256:85b0ac3ad17fa3be50abd7e69d583d98792d7edc08367e01445a1e2076005379", size = 24370427, upload-time = "2026-01-10T21:25:20.514Z" }, + { url = "https://files.pythonhosted.org/packages/0b/11/7241a63e73ba5a516f1930ac8d5b44cbbfabd35ac73a2d08ca206df007c4/scipy-1.17.0-cp312-cp312-macosx_10_14_x86_64.whl", hash = "sha256:0d5018a57c24cb1dd828bcf51d7b10e65986d549f52ef5adb6b4d1ded3e32a57", size = 31364580, upload-time = "2026-01-10T21:25:25.717Z" }, + { url = "https://files.pythonhosted.org/packages/ed/1d/5057f812d4f6adc91a20a2d6f2ebcdb517fdbc87ae3acc5633c9b97c8ba5/scipy-1.17.0-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:88c22af9e5d5a4f9e027e26772cc7b5922fab8bcc839edb3ae33de404feebd9e", size = 27969012, upload-time = "2026-01-10T21:25:30.921Z" }, + { url = "https://files.pythonhosted.org/packages/e3/21/f6ec556c1e3b6ec4e088da667d9987bb77cc3ab3026511f427dc8451187d/scipy-1.17.0-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:f3cd947f20fe17013d401b64e857c6b2da83cae567adbb75b9dcba865abc66d8", size = 20140691, upload-time = "2026-01-10T21:25:34.802Z" }, + { url = "https://files.pythonhosted.org/packages/7a/fe/5e5ad04784964ba964a96f16c8d4676aa1b51357199014dce58ab7ec5670/scipy-1.17.0-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:e8c0b331c2c1f531eb51f1b4fc9ba709521a712cce58f1aa627bc007421a5306", size = 22463015, upload-time = "2026-01-10T21:25:39.277Z" }, + { url = "https://files.pythonhosted.org/packages/4a/69/7c347e857224fcaf32a34a05183b9d8a7aca25f8f2d10b8a698b8388561a/scipy-1.17.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5194c445d0a1c7a6c1a4a4681b6b7c71baad98ff66d96b949097e7513c9d6742", size = 32724197, upload-time = "2026-01-10T21:25:44.084Z" }, + { url = "https://files.pythonhosted.org/packages/d1/fe/66d73b76d378ba8cc2fe605920c0c75092e3a65ae746e1e767d9d020a75a/scipy-1.17.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9eeb9b5f5997f75507814ed9d298ab23f62cf79f5a3ef90031b1ee2506abdb5b", size = 35009148, upload-time = "2026-01-10T21:25:50.591Z" }, + { url = "https://files.pythonhosted.org/packages/af/07/07dec27d9dc41c18d8c43c69e9e413431d20c53a0339c388bcf72f353c4b/scipy-1.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:40052543f7bbe921df4408f46003d6f01c6af109b9e2c8a66dd1cf6cf57f7d5d", size = 34798766, upload-time = "2026-01-10T21:25:59.41Z" }, + { url = "https://files.pythonhosted.org/packages/81/61/0470810c8a093cdacd4ba7504b8a218fd49ca070d79eca23a615f5d9a0b0/scipy-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0cf46c8013fec9d3694dc572f0b54100c28405d55d3e2cb15e2895b25057996e", size = 37405953, upload-time = "2026-01-10T21:26:07.75Z" }, + { url = "https://files.pythonhosted.org/packages/92/ce/672ed546f96d5d41ae78c4b9b02006cedd0b3d6f2bf5bb76ea455c320c28/scipy-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:0937a0b0d8d593a198cededd4c439a0ea216a3f36653901ea1f3e4be949056f8", size = 36328121, upload-time = "2026-01-10T21:26:16.509Z" }, + { url = "https://files.pythonhosted.org/packages/9d/21/38165845392cae67b61843a52c6455d47d0cc2a40dd495c89f4362944654/scipy-1.17.0-cp312-cp312-win_arm64.whl", hash = "sha256:f603d8a5518c7426414d1d8f82e253e454471de682ce5e39c29adb0df1efb86b", size = 24314368, upload-time = "2026-01-10T21:26:23.087Z" }, + { url = "https://files.pythonhosted.org/packages/0c/51/3468fdfd49387ddefee1636f5cf6d03ce603b75205bf439bbf0e62069bfd/scipy-1.17.0-cp313-cp313-macosx_10_14_x86_64.whl", hash = "sha256:65ec32f3d32dfc48c72df4291345dae4f048749bc8d5203ee0a3f347f96c5ce6", size = 31344101, upload-time = "2026-01-10T21:26:30.25Z" }, + { url = "https://files.pythonhosted.org/packages/b2/9a/9406aec58268d437636069419e6977af953d1e246df941d42d3720b7277b/scipy-1.17.0-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:1f9586a58039d7229ce77b52f8472c972448cded5736eaf102d5658bbac4c269", size = 27950385, upload-time = "2026-01-10T21:26:36.801Z" }, + { url = "https://files.pythonhosted.org/packages/4f/98/e7342709e17afdfd1b26b56ae499ef4939b45a23a00e471dfb5375eea205/scipy-1.17.0-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:9fad7d3578c877d606b1150135c2639e9de9cecd3705caa37b66862977cc3e72", size = 20122115, upload-time = "2026-01-10T21:26:42.107Z" }, + { url = "https://files.pythonhosted.org/packages/fd/0e/9eeeb5357a64fd157cbe0302c213517c541cc16b8486d82de251f3c68ede/scipy-1.17.0-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:423ca1f6584fc03936972b5f7c06961670dbba9f234e71676a7c7ccf938a0d61", size = 22442402, upload-time = "2026-01-10T21:26:48.029Z" }, + { url = "https://files.pythonhosted.org/packages/c9/10/be13397a0e434f98e0c79552b2b584ae5bb1c8b2be95db421533bbca5369/scipy-1.17.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fe508b5690e9eaaa9467fc047f833af58f1152ae51a0d0aed67aa5801f4dd7d6", size = 32696338, upload-time = "2026-01-10T21:26:55.521Z" }, + { url = "https://files.pythonhosted.org/packages/63/1e/12fbf2a3bb240161651c94bb5cdd0eae5d4e8cc6eaeceb74ab07b12a753d/scipy-1.17.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6680f2dfd4f6182e7d6db161344537da644d1cf85cf293f015c60a17ecf08752", size = 34977201, upload-time = "2026-01-10T21:27:03.501Z" }, + { url = "https://files.pythonhosted.org/packages/19/5b/1a63923e23ccd20bd32156d7dd708af5bbde410daa993aa2500c847ab2d2/scipy-1.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:eec3842ec9ac9de5917899b277428886042a93db0b227ebbe3a333b64ec7643d", size = 34777384, upload-time = "2026-01-10T21:27:11.423Z" }, + { url = "https://files.pythonhosted.org/packages/39/22/b5da95d74edcf81e540e467202a988c50fef41bd2011f46e05f72ba07df6/scipy-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d7425fcafbc09a03731e1bc05581f5fad988e48c6a861f441b7ab729a49a55ea", size = 37379586, upload-time = "2026-01-10T21:27:20.171Z" }, + { url = "https://files.pythonhosted.org/packages/b9/b6/8ac583d6da79e7b9e520579f03007cb006f063642afd6b2eeb16b890bf93/scipy-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:87b411e42b425b84777718cc41516b8a7e0795abfa8e8e1d573bf0ef014f0812", size = 36287211, upload-time = "2026-01-10T21:28:43.122Z" }, + { url = "https://files.pythonhosted.org/packages/55/fb/7db19e0b3e52f882b420417644ec81dd57eeef1bd1705b6f689d8ff93541/scipy-1.17.0-cp313-cp313-win_arm64.whl", hash = "sha256:357ca001c6e37601066092e7c89cca2f1ce74e2a520ca78d063a6d2201101df2", size = 24312646, upload-time = "2026-01-10T21:28:49.893Z" }, + { url = "https://files.pythonhosted.org/packages/20/b6/7feaa252c21cc7aff335c6c55e1b90ab3e3306da3f048109b8b639b94648/scipy-1.17.0-cp313-cp313t-macosx_10_14_x86_64.whl", hash = "sha256:ec0827aa4d36cb79ff1b81de898e948a51ac0b9b1c43e4a372c0508c38c0f9a3", size = 31693194, upload-time = "2026-01-10T21:27:27.454Z" }, + { url = "https://files.pythonhosted.org/packages/76/bb/bbb392005abce039fb7e672cb78ac7d158700e826b0515cab6b5b60c26fb/scipy-1.17.0-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:819fc26862b4b3c73a60d486dbb919202f3d6d98c87cf20c223511429f2d1a97", size = 28365415, upload-time = "2026-01-10T21:27:34.26Z" }, + { url = "https://files.pythonhosted.org/packages/37/da/9d33196ecc99fba16a409c691ed464a3a283ac454a34a13a3a57c0d66f3a/scipy-1.17.0-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:363ad4ae2853d88ebcde3ae6ec46ccca903ea9835ee8ba543f12f575e7b07e4e", size = 20537232, upload-time = "2026-01-10T21:27:40.306Z" }, + { url = "https://files.pythonhosted.org/packages/56/9d/f4b184f6ddb28e9a5caea36a6f98e8ecd2a524f9127354087ce780885d83/scipy-1.17.0-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:979c3a0ff8e5ba254d45d59ebd38cde48fce4f10b5125c680c7a4bfe177aab07", size = 22791051, upload-time = "2026-01-10T21:27:46.539Z" }, + { url = "https://files.pythonhosted.org/packages/9b/9d/025cccdd738a72140efc582b1641d0dd4caf2e86c3fb127568dc80444e6e/scipy-1.17.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:130d12926ae34399d157de777472bf82e9061c60cc081372b3118edacafe1d00", size = 32815098, upload-time = "2026-01-10T21:27:54.389Z" }, + { url = "https://files.pythonhosted.org/packages/48/5f/09b879619f8bca15ce392bfc1894bd9c54377e01d1b3f2f3b595a1b4d945/scipy-1.17.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6e886000eb4919eae3a44f035e63f0fd8b651234117e8f6f29bad1cd26e7bc45", size = 35031342, upload-time = "2026-01-10T21:28:03.012Z" }, + { url = "https://files.pythonhosted.org/packages/f2/9a/f0f0a9f0aa079d2f106555b984ff0fbb11a837df280f04f71f056ea9c6e4/scipy-1.17.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:13c4096ac6bc31d706018f06a49abe0485f96499deb82066b94d19b02f664209", size = 34893199, upload-time = "2026-01-10T21:28:10.832Z" }, + { url = "https://files.pythonhosted.org/packages/90/b8/4f0f5cf0c5ea4d7548424e6533e6b17d164f34a6e2fb2e43ffebb6697b06/scipy-1.17.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:cacbaddd91fcffde703934897c5cd2c7cb0371fac195d383f4e1f1c5d3f3bd04", size = 37438061, upload-time = "2026-01-10T21:28:19.684Z" }, + { url = "https://files.pythonhosted.org/packages/f9/cc/2bd59140ed3b2fa2882fb15da0a9cb1b5a6443d67cfd0d98d4cec83a57ec/scipy-1.17.0-cp313-cp313t-win_amd64.whl", hash = "sha256:edce1a1cf66298cccdc48a1bdf8fb10a3bf58e8b58d6c3883dd1530e103f87c0", size = 36328593, upload-time = "2026-01-10T21:28:28.007Z" }, + { url = "https://files.pythonhosted.org/packages/13/1b/c87cc44a0d2c7aaf0f003aef2904c3d097b422a96c7e7c07f5efd9073c1b/scipy-1.17.0-cp313-cp313t-win_arm64.whl", hash = "sha256:30509da9dbec1c2ed8f168b8d8aa853bc6723fede1dbc23c7d43a56f5ab72a67", size = 24625083, upload-time = "2026-01-10T21:28:35.188Z" }, + { url = "https://files.pythonhosted.org/packages/1a/2d/51006cd369b8e7879e1c630999a19d1fbf6f8b5ed3e33374f29dc87e53b3/scipy-1.17.0-cp314-cp314-macosx_10_14_x86_64.whl", hash = "sha256:c17514d11b78be8f7e6331b983a65a7f5ca1fd037b95e27b280921fe5606286a", size = 31346803, upload-time = "2026-01-10T21:28:57.24Z" }, + { url = "https://files.pythonhosted.org/packages/d6/2e/2349458c3ce445f53a6c93d4386b1c4c5c0c540917304c01222ff95ff317/scipy-1.17.0-cp314-cp314-macosx_12_0_arm64.whl", hash = "sha256:4e00562e519c09da34c31685f6acc3aa384d4d50604db0f245c14e1b4488bfa2", size = 27967182, upload-time = "2026-01-10T21:29:04.107Z" }, + { url = "https://files.pythonhosted.org/packages/5e/7c/df525fbfa77b878d1cfe625249529514dc02f4fd5f45f0f6295676a76528/scipy-1.17.0-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:f7df7941d71314e60a481e02d5ebcb3f0185b8d799c70d03d8258f6c80f3d467", size = 20139125, upload-time = "2026-01-10T21:29:10.179Z" }, + { url = "https://files.pythonhosted.org/packages/33/11/fcf9d43a7ed1234d31765ec643b0515a85a30b58eddccc5d5a4d12b5f194/scipy-1.17.0-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:aabf057c632798832f071a8dde013c2e26284043934f53b00489f1773b33527e", size = 22443554, upload-time = "2026-01-10T21:29:15.888Z" }, + { url = "https://files.pythonhosted.org/packages/80/5c/ea5d239cda2dd3d31399424967a24d556cf409fbea7b5b21412b0fd0a44f/scipy-1.17.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a38c3337e00be6fd8a95b4ed66b5d988bac4ec888fd922c2ea9fe5fb1603dd67", size = 32757834, upload-time = "2026-01-10T21:29:23.406Z" }, + { url = "https://files.pythonhosted.org/packages/b8/7e/8c917cc573310e5dc91cbeead76f1b600d3fb17cf0969db02c9cf92e3cfa/scipy-1.17.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:00fb5f8ec8398ad90215008d8b6009c9db9fa924fd4c7d6be307c6f945f9cd73", size = 34995775, upload-time = "2026-01-10T21:29:31.915Z" }, + { url = "https://files.pythonhosted.org/packages/c5/43/176c0c3c07b3f7df324e7cdd933d3e2c4898ca202b090bd5ba122f9fe270/scipy-1.17.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:f2a4942b0f5f7c23c7cd641a0ca1955e2ae83dedcff537e3a0259096635e186b", size = 34841240, upload-time = "2026-01-10T21:29:39.995Z" }, + { url = "https://files.pythonhosted.org/packages/44/8c/d1f5f4b491160592e7f084d997de53a8e896a3ac01cd07e59f43ca222744/scipy-1.17.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:dbf133ced83889583156566d2bdf7a07ff89228fe0c0cb727f777de92092ec6b", size = 37394463, upload-time = "2026-01-10T21:29:48.723Z" }, + { url = "https://files.pythonhosted.org/packages/9f/ec/42a6657f8d2d087e750e9a5dde0b481fd135657f09eaf1cf5688bb23c338/scipy-1.17.0-cp314-cp314-win_amd64.whl", hash = "sha256:3625c631a7acd7cfd929e4e31d2582cf00f42fcf06011f59281271746d77e061", size = 37053015, upload-time = "2026-01-10T21:30:51.418Z" }, + { url = "https://files.pythonhosted.org/packages/27/58/6b89a6afd132787d89a362d443a7bddd511b8f41336a1ae47f9e4f000dc4/scipy-1.17.0-cp314-cp314-win_arm64.whl", hash = "sha256:9244608d27eafe02b20558523ba57f15c689357c85bdcfe920b1828750aa26eb", size = 24951312, upload-time = "2026-01-10T21:30:56.771Z" }, + { url = "https://files.pythonhosted.org/packages/e9/01/f58916b9d9ae0112b86d7c3b10b9e685625ce6e8248df139d0fcb17f7397/scipy-1.17.0-cp314-cp314t-macosx_10_14_x86_64.whl", hash = "sha256:2b531f57e09c946f56ad0b4a3b2abee778789097871fc541e267d2eca081cff1", size = 31706502, upload-time = "2026-01-10T21:29:56.326Z" }, + { url = "https://files.pythonhosted.org/packages/59/8e/2912a87f94a7d1f8b38aabc0faf74b82d3b6c9e22be991c49979f0eceed8/scipy-1.17.0-cp314-cp314t-macosx_12_0_arm64.whl", hash = "sha256:13e861634a2c480bd237deb69333ac79ea1941b94568d4b0efa5db5e263d4fd1", size = 28380854, upload-time = "2026-01-10T21:30:01.554Z" }, + { url = "https://files.pythonhosted.org/packages/bd/1c/874137a52dddab7d5d595c1887089a2125d27d0601fce8c0026a24a92a0b/scipy-1.17.0-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:eb2651271135154aa24f6481cbae5cc8af1f0dd46e6533fb7b56aa9727b6a232", size = 20552752, upload-time = "2026-01-10T21:30:05.93Z" }, + { url = "https://files.pythonhosted.org/packages/3f/f0/7518d171cb735f6400f4576cf70f756d5b419a07fe1867da34e2c2c9c11b/scipy-1.17.0-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:c5e8647f60679790c2f5c76be17e2e9247dc6b98ad0d3b065861e082c56e078d", size = 22803972, upload-time = "2026-01-10T21:30:10.651Z" }, + { url = "https://files.pythonhosted.org/packages/7c/74/3498563a2c619e8a3ebb4d75457486c249b19b5b04a30600dfd9af06bea5/scipy-1.17.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5fb10d17e649e1446410895639f3385fd2bf4c3c7dfc9bea937bddcbc3d7b9ba", size = 32829770, upload-time = "2026-01-10T21:30:16.359Z" }, + { url = "https://files.pythonhosted.org/packages/48/d1/7b50cedd8c6c9d6f706b4b36fa8544d829c712a75e370f763b318e9638c1/scipy-1.17.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8547e7c57f932e7354a2319fab613981cde910631979f74c9b542bb167a8b9db", size = 35051093, upload-time = "2026-01-10T21:30:22.987Z" }, + { url = "https://files.pythonhosted.org/packages/e2/82/a2d684dfddb87ba1b3ea325df7c3293496ee9accb3a19abe9429bce94755/scipy-1.17.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:33af70d040e8af9d5e7a38b5ed3b772adddd281e3062ff23fec49e49681c38cf", size = 34909905, upload-time = "2026-01-10T21:30:28.704Z" }, + { url = "https://files.pythonhosted.org/packages/ef/5e/e565bd73991d42023eb82bb99e51c5b3d9e2c588ca9d4b3e2cc1d3ca62a6/scipy-1.17.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:f9eb55bb97d00f8b7ab95cb64f873eb0bf54d9446264d9f3609130381233483f", size = 37457743, upload-time = "2026-01-10T21:30:34.819Z" }, + { url = "https://files.pythonhosted.org/packages/58/a8/a66a75c3d8f1fb2b83f66007d6455a06a6f6cf5618c3dc35bc9b69dd096e/scipy-1.17.0-cp314-cp314t-win_amd64.whl", hash = "sha256:1ff269abf702f6c7e67a4b7aad981d42871a11b9dd83c58d2d2ea624efbd1088", size = 37098574, upload-time = "2026-01-10T21:30:40.782Z" }, + { url = "https://files.pythonhosted.org/packages/56/a5/df8f46ef7da168f1bc52cd86e09a9de5c6f19cc1da04454d51b7d4f43408/scipy-1.17.0-cp314-cp314t-win_arm64.whl", hash = "sha256:031121914e295d9791319a1875444d55079885bbae5bdc9c5e0f2ee5f09d34ff", size = 25246266, upload-time = "2026-01-10T21:30:45.923Z" }, +] + +[[package]] +name = "six" +version = "1.17.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031, upload-time = "2024-12-04T17:35:28.174Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" }, +] + +[[package]] +name = "snowballstemmer" +version = "3.0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/75/a7/9810d872919697c9d01295633f5d574fb416d47e535f258272ca1f01f447/snowballstemmer-3.0.1.tar.gz", hash = "sha256:6d5eeeec8e9f84d4d56b847692bacf79bc2c8e90c7f80ca4444ff8b6f2e52895", size = 105575, upload-time = "2025-05-09T16:34:51.843Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c8/78/3565d011c61f5a43488987ee32b6f3f656e7f107ac2782dd57bdd7d91d9a/snowballstemmer-3.0.1-py3-none-any.whl", hash = "sha256:6cd7b3897da8d6c9ffb968a6781fa6532dce9c3618a4b127d920dab764a19064", size = 103274, upload-time = "2025-05-09T16:34:50.371Z" }, +] + +[[package]] +name = "soupsieve" +version = "2.8.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7b/ae/2d9c981590ed9999a0d91755b47fc74f74de286b0f5cee14c9269041e6c4/soupsieve-2.8.3.tar.gz", hash = "sha256:3267f1eeea4251fb42728b6dfb746edc9acaffc4a45b27e19450b676586e8349", size = 118627, upload-time = "2026-01-20T04:27:02.457Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/46/2c/1462b1d0a634697ae9e55b3cecdcb64788e8b7d63f54d923fcd0bb140aed/soupsieve-2.8.3-py3-none-any.whl", hash = "sha256:ed64f2ba4eebeab06cc4962affce381647455978ffc1e36bb79a545b91f45a95", size = 37016, upload-time = "2026-01-20T04:27:01.012Z" }, +] + +[[package]] +name = "sphinx" +version = "9.0.4" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.12'", +] +dependencies = [ + { name = "alabaster", marker = "python_full_version < '3.12'" }, + { name = "babel", marker = "python_full_version < '3.12'" }, + { name = "colorama", marker = "python_full_version < '3.12' and sys_platform == 'win32'" }, + { name = "docutils", marker = "python_full_version < '3.12'" }, + { name = "imagesize", marker = "python_full_version < '3.12'" }, + { name = "jinja2", marker = "python_full_version < '3.12'" }, + { name = "packaging", marker = "python_full_version < '3.12'" }, + { name = "pygments", marker = "python_full_version < '3.12'" }, + { name = "requests", marker = "python_full_version < '3.12'" }, + { name = "roman-numerals", marker = "python_full_version < '3.12'" }, + { name = "snowballstemmer", marker = "python_full_version < '3.12'" }, + { name = "sphinxcontrib-applehelp", marker = "python_full_version < '3.12'" }, + { name = "sphinxcontrib-devhelp", marker = "python_full_version < '3.12'" }, + { name = "sphinxcontrib-htmlhelp", marker = "python_full_version < '3.12'" }, + { name = "sphinxcontrib-jsmath", marker = "python_full_version < '3.12'" }, + { name = "sphinxcontrib-qthelp", marker = "python_full_version < '3.12'" }, + { name = "sphinxcontrib-serializinghtml", marker = "python_full_version < '3.12'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/42/50/a8c6ccc36d5eacdfd7913ddccd15a9cee03ecafc5ee2bc40e1f168d85022/sphinx-9.0.4.tar.gz", hash = "sha256:594ef59d042972abbc581d8baa577404abe4e6c3b04ef61bd7fc2acbd51f3fa3", size = 8710502, upload-time = "2025-12-04T07:45:27.343Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c6/3f/4bbd76424c393caead2e1eb89777f575dee5c8653e2d4b6afd7a564f5974/sphinx-9.0.4-py3-none-any.whl", hash = "sha256:5bebc595a5e943ea248b99c13814c1c5e10b3ece718976824ffa7959ff95fffb", size = 3917713, upload-time = "2025-12-04T07:45:24.944Z" }, +] + +[[package]] +name = "sphinx" +version = "9.1.0" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.12'", +] +dependencies = [ + { name = "alabaster", marker = "python_full_version >= '3.12'" }, + { name = "babel", marker = "python_full_version >= '3.12'" }, + { name = "colorama", marker = "python_full_version >= '3.12' and sys_platform == 'win32'" }, + { name = "docutils", marker = "python_full_version >= '3.12'" }, + { name = "imagesize", marker = "python_full_version >= '3.12'" }, + { name = "jinja2", marker = "python_full_version >= '3.12'" }, + { name = "packaging", marker = "python_full_version >= '3.12'" }, + { name = "pygments", marker = "python_full_version >= '3.12'" }, + { name = "requests", marker = "python_full_version >= '3.12'" }, + { name = "roman-numerals", marker = "python_full_version >= '3.12'" }, + { name = "snowballstemmer", marker = "python_full_version >= '3.12'" }, + { name = "sphinxcontrib-applehelp", marker = "python_full_version >= '3.12'" }, + { name = "sphinxcontrib-devhelp", marker = "python_full_version >= '3.12'" }, + { name = "sphinxcontrib-htmlhelp", marker = "python_full_version >= '3.12'" }, + { name = "sphinxcontrib-jsmath", marker = "python_full_version >= '3.12'" }, + { name = "sphinxcontrib-qthelp", marker = "python_full_version >= '3.12'" }, + { name = "sphinxcontrib-serializinghtml", marker = "python_full_version >= '3.12'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/cd/bd/f08eb0f4eed5c83f1ba2a3bd18f7745a2b1525fad70660a1c00224ec468a/sphinx-9.1.0.tar.gz", hash = "sha256:7741722357dd75f8190766926071fed3bdc211c74dd2d7d4df5404da95930ddb", size = 8718324, upload-time = "2025-12-31T15:09:27.646Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/73/f7/b1884cb3188ab181fc81fa00c266699dab600f927a964df02ec3d5d1916a/sphinx-9.1.0-py3-none-any.whl", hash = "sha256:c84fdd4e782504495fe4f2c0b3413d6c2bf388589bb352d439b2a3bb99991978", size = 3921742, upload-time = "2025-12-31T15:09:25.561Z" }, +] + +[[package]] +name = "sphinxcontrib-applehelp" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ba/6e/b837e84a1a704953c62ef8776d45c3e8d759876b4a84fe14eba2859106fe/sphinxcontrib_applehelp-2.0.0.tar.gz", hash = "sha256:2f29ef331735ce958efa4734873f084941970894c6090408b079c61b2e1c06d1", size = 20053, upload-time = "2024-07-29T01:09:00.465Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5d/85/9ebeae2f76e9e77b952f4b274c27238156eae7979c5421fba91a28f4970d/sphinxcontrib_applehelp-2.0.0-py3-none-any.whl", hash = "sha256:4cd3f0ec4ac5dd9c17ec65e9ab272c9b867ea77425228e68ecf08d6b28ddbdb5", size = 119300, upload-time = "2024-07-29T01:08:58.99Z" }, +] + +[[package]] +name = "sphinxcontrib-devhelp" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f6/d2/5beee64d3e4e747f316bae86b55943f51e82bb86ecd325883ef65741e7da/sphinxcontrib_devhelp-2.0.0.tar.gz", hash = "sha256:411f5d96d445d1d73bb5d52133377b4248ec79db5c793ce7dbe59e074b4dd1ad", size = 12967, upload-time = "2024-07-29T01:09:23.417Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/35/7a/987e583882f985fe4d7323774889ec58049171828b58c2217e7f79cdf44e/sphinxcontrib_devhelp-2.0.0-py3-none-any.whl", hash = "sha256:aefb8b83854e4b0998877524d1029fd3e6879210422ee3780459e28a1f03a8a2", size = 82530, upload-time = "2024-07-29T01:09:21.945Z" }, +] + +[[package]] +name = "sphinxcontrib-htmlhelp" +version = "2.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/43/93/983afd9aa001e5201eab16b5a444ed5b9b0a7a010541e0ddfbbfd0b2470c/sphinxcontrib_htmlhelp-2.1.0.tar.gz", hash = "sha256:c9e2916ace8aad64cc13a0d233ee22317f2b9025b9cf3295249fa985cc7082e9", size = 22617, upload-time = "2024-07-29T01:09:37.889Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0a/7b/18a8c0bcec9182c05a0b3ec2a776bba4ead82750a55ff798e8d406dae604/sphinxcontrib_htmlhelp-2.1.0-py3-none-any.whl", hash = "sha256:166759820b47002d22914d64a075ce08f4c46818e17cfc9470a9786b759b19f8", size = 98705, upload-time = "2024-07-29T01:09:36.407Z" }, +] + +[[package]] +name = "sphinxcontrib-jsmath" +version = "1.0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b2/e8/9ed3830aeed71f17c026a07a5097edcf44b692850ef215b161b8ad875729/sphinxcontrib-jsmath-1.0.1.tar.gz", hash = "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8", size = 5787, upload-time = "2019-01-21T16:10:16.347Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c2/42/4c8646762ee83602e3fb3fbe774c2fac12f317deb0b5dbeeedd2d3ba4b77/sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl", hash = "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178", size = 5071, upload-time = "2019-01-21T16:10:14.333Z" }, +] + +[[package]] +name = "sphinxcontrib-qthelp" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/68/bc/9104308fc285eb3e0b31b67688235db556cd5b0ef31d96f30e45f2e51cae/sphinxcontrib_qthelp-2.0.0.tar.gz", hash = "sha256:4fe7d0ac8fc171045be623aba3e2a8f613f8682731f9153bb2e40ece16b9bbab", size = 17165, upload-time = "2024-07-29T01:09:56.435Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/27/83/859ecdd180cacc13b1f7e857abf8582a64552ea7a061057a6c716e790fce/sphinxcontrib_qthelp-2.0.0-py3-none-any.whl", hash = "sha256:b18a828cdba941ccd6ee8445dbe72ffa3ef8cbe7505d8cd1fa0d42d3f2d5f3eb", size = 88743, upload-time = "2024-07-29T01:09:54.885Z" }, +] + +[[package]] +name = "sphinxcontrib-serializinghtml" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/3b/44/6716b257b0aa6bfd51a1b31665d1c205fb12cb5ad56de752dfa15657de2f/sphinxcontrib_serializinghtml-2.0.0.tar.gz", hash = "sha256:e9d912827f872c029017a53f0ef2180b327c3f7fd23c87229f7a8e8b70031d4d", size = 16080, upload-time = "2024-07-29T01:10:09.332Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/52/a7/d2782e4e3f77c8450f727ba74a8f12756d5ba823d81b941f1b04da9d033a/sphinxcontrib_serializinghtml-2.0.0-py3-none-any.whl", hash = "sha256:6e2cb0eef194e10c27ec0023bfeb25badbbb5868244cf5bc5bdc04e4464bf331", size = 92072, upload-time = "2024-07-29T01:10:08.203Z" }, +] + +[[package]] +name = "sympy" +version = "1.14.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mpmath" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/83/d3/803453b36afefb7c2bb238361cd4ae6125a569b4db67cd9e79846ba2d68c/sympy-1.14.0.tar.gz", hash = "sha256:d3d3fe8df1e5a0b42f0e7bdf50541697dbe7d23746e894990c030e2b05e72517", size = 7793921, upload-time = "2025-04-27T18:05:01.611Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a2/09/77d55d46fd61b4a135c444fc97158ef34a095e5681d0a6c10b75bf356191/sympy-1.14.0-py3-none-any.whl", hash = "sha256:e091cc3e99d2141a0ba2847328f5479b05d94a6635cb96148ccb3f34671bd8f5", size = 6299353, upload-time = "2025-04-27T18:04:59.103Z" }, +] + +[[package]] +name = "tinycss2" +version = "1.4.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "webencodings" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/7a/fd/7a5ee21fd08ff70d3d33a5781c255cbe779659bd03278feb98b19ee550f4/tinycss2-1.4.0.tar.gz", hash = "sha256:10c0972f6fc0fbee87c3edb76549357415e94548c1ae10ebccdea16fb404a9b7", size = 87085, upload-time = "2024-10-24T14:58:29.895Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e6/34/ebdc18bae6aa14fbee1a08b63c015c72b64868ff7dae68808ab500c492e2/tinycss2-1.4.0-py3-none-any.whl", hash = "sha256:3a49cf47b7675da0b15d0c6e1df8df4ebd96e9394bb905a5775adb0d884c5289", size = 26610, upload-time = "2024-10-24T14:58:28.029Z" }, +] + +[[package]] +name = "toml" +version = "0.10.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/be/ba/1f744cdc819428fc6b5084ec34d9b30660f6f9daaf70eead706e3203ec3c/toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f", size = 22253, upload-time = "2020-11-01T01:40:22.204Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/44/6f/7120676b6d73228c96e17f1f794d8ab046fc910d781c8d151120c3f1569e/toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b", size = 16588, upload-time = "2020-11-01T01:40:20.672Z" }, +] + +[[package]] +name = "tomli" +version = "2.4.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/82/30/31573e9457673ab10aa432461bee537ce6cef177667deca369efb79df071/tomli-2.4.0.tar.gz", hash = "sha256:aa89c3f6c277dd275d8e243ad24f3b5e701491a860d5121f2cdd399fbb31fc9c", size = 17477, upload-time = "2026-01-11T11:22:38.165Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3c/d9/3dc2289e1f3b32eb19b9785b6a006b28ee99acb37d1d47f78d4c10e28bf8/tomli-2.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b5ef256a3fd497d4973c11bf142e9ed78b150d36f5773f1ca6088c230ffc5867", size = 153663, upload-time = "2026-01-11T11:21:45.27Z" }, + { url = "https://files.pythonhosted.org/packages/51/32/ef9f6845e6b9ca392cd3f64f9ec185cc6f09f0a2df3db08cbe8809d1d435/tomli-2.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5572e41282d5268eb09a697c89a7bee84fae66511f87533a6f88bd2f7b652da9", size = 148469, upload-time = "2026-01-11T11:21:46.873Z" }, + { url = "https://files.pythonhosted.org/packages/d6/c2/506e44cce89a8b1b1e047d64bd495c22c9f71f21e05f380f1a950dd9c217/tomli-2.4.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:551e321c6ba03b55676970b47cb1b73f14a0a4dce6a3e1a9458fd6d921d72e95", size = 236039, upload-time = "2026-01-11T11:21:48.503Z" }, + { url = "https://files.pythonhosted.org/packages/b3/40/e1b65986dbc861b7e986e8ec394598187fa8aee85b1650b01dd925ca0be8/tomli-2.4.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5e3f639a7a8f10069d0e15408c0b96a2a828cfdec6fca05296ebcdcc28ca7c76", size = 243007, upload-time = "2026-01-11T11:21:49.456Z" }, + { url = "https://files.pythonhosted.org/packages/9c/6f/6e39ce66b58a5b7ae572a0f4352ff40c71e8573633deda43f6a379d56b3e/tomli-2.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1b168f2731796b045128c45982d3a4874057626da0e2ef1fdd722848b741361d", size = 240875, upload-time = "2026-01-11T11:21:50.755Z" }, + { url = "https://files.pythonhosted.org/packages/aa/ad/cb089cb190487caa80204d503c7fd0f4d443f90b95cf4ef5cf5aa0f439b0/tomli-2.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:133e93646ec4300d651839d382d63edff11d8978be23da4cc106f5a18b7d0576", size = 246271, upload-time = "2026-01-11T11:21:51.81Z" }, + { url = "https://files.pythonhosted.org/packages/0b/63/69125220e47fd7a3a27fd0de0c6398c89432fec41bc739823bcc66506af6/tomli-2.4.0-cp311-cp311-win32.whl", hash = "sha256:b6c78bdf37764092d369722d9946cb65b8767bfa4110f902a1b2542d8d173c8a", size = 96770, upload-time = "2026-01-11T11:21:52.647Z" }, + { url = "https://files.pythonhosted.org/packages/1e/0d/a22bb6c83f83386b0008425a6cd1fa1c14b5f3dd4bad05e98cf3dbbf4a64/tomli-2.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:d3d1654e11d724760cdb37a3d7691f0be9db5fbdaef59c9f532aabf87006dbaa", size = 107626, upload-time = "2026-01-11T11:21:53.459Z" }, + { url = "https://files.pythonhosted.org/packages/2f/6d/77be674a3485e75cacbf2ddba2b146911477bd887dda9d8c9dfb2f15e871/tomli-2.4.0-cp311-cp311-win_arm64.whl", hash = "sha256:cae9c19ed12d4e8f3ebf46d1a75090e4c0dc16271c5bce1c833ac168f08fb614", size = 94842, upload-time = "2026-01-11T11:21:54.831Z" }, + { url = "https://files.pythonhosted.org/packages/3c/43/7389a1869f2f26dba52404e1ef13b4784b6b37dac93bac53457e3ff24ca3/tomli-2.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:920b1de295e72887bafa3ad9f7a792f811847d57ea6b1215154030cf131f16b1", size = 154894, upload-time = "2026-01-11T11:21:56.07Z" }, + { url = "https://files.pythonhosted.org/packages/e9/05/2f9bf110b5294132b2edf13fe6ca6ae456204f3d749f623307cbb7a946f2/tomli-2.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7d6d9a4aee98fac3eab4952ad1d73aee87359452d1c086b5ceb43ed02ddb16b8", size = 149053, upload-time = "2026-01-11T11:21:57.467Z" }, + { url = "https://files.pythonhosted.org/packages/e8/41/1eda3ca1abc6f6154a8db4d714a4d35c4ad90adc0bcf700657291593fbf3/tomli-2.4.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:36b9d05b51e65b254ea6c2585b59d2c4cb91c8a3d91d0ed0f17591a29aaea54a", size = 243481, upload-time = "2026-01-11T11:21:58.661Z" }, + { url = "https://files.pythonhosted.org/packages/d2/6d/02ff5ab6c8868b41e7d4b987ce2b5f6a51d3335a70aa144edd999e055a01/tomli-2.4.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1c8a885b370751837c029ef9bc014f27d80840e48bac415f3412e6593bbc18c1", size = 251720, upload-time = "2026-01-11T11:22:00.178Z" }, + { url = "https://files.pythonhosted.org/packages/7b/57/0405c59a909c45d5b6f146107c6d997825aa87568b042042f7a9c0afed34/tomli-2.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8768715ffc41f0008abe25d808c20c3d990f42b6e2e58305d5da280ae7d1fa3b", size = 247014, upload-time = "2026-01-11T11:22:01.238Z" }, + { url = "https://files.pythonhosted.org/packages/2c/0e/2e37568edd944b4165735687cbaf2fe3648129e440c26d02223672ee0630/tomli-2.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:7b438885858efd5be02a9a133caf5812b8776ee0c969fea02c45e8e3f296ba51", size = 251820, upload-time = "2026-01-11T11:22:02.727Z" }, + { url = "https://files.pythonhosted.org/packages/5a/1c/ee3b707fdac82aeeb92d1a113f803cf6d0f37bdca0849cb489553e1f417a/tomli-2.4.0-cp312-cp312-win32.whl", hash = "sha256:0408e3de5ec77cc7f81960c362543cbbd91ef883e3138e81b729fc3eea5b9729", size = 97712, upload-time = "2026-01-11T11:22:03.777Z" }, + { url = "https://files.pythonhosted.org/packages/69/13/c07a9177d0b3bab7913299b9278845fc6eaaca14a02667c6be0b0a2270c8/tomli-2.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:685306e2cc7da35be4ee914fd34ab801a6acacb061b6a7abca922aaf9ad368da", size = 108296, upload-time = "2026-01-11T11:22:04.86Z" }, + { url = "https://files.pythonhosted.org/packages/18/27/e267a60bbeeee343bcc279bb9e8fbed0cbe224bc7b2a3dc2975f22809a09/tomli-2.4.0-cp312-cp312-win_arm64.whl", hash = "sha256:5aa48d7c2356055feef06a43611fc401a07337d5b006be13a30f6c58f869e3c3", size = 94553, upload-time = "2026-01-11T11:22:05.854Z" }, + { url = "https://files.pythonhosted.org/packages/34/91/7f65f9809f2936e1f4ce6268ae1903074563603b2a2bd969ebbda802744f/tomli-2.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:84d081fbc252d1b6a982e1870660e7330fb8f90f676f6e78b052ad4e64714bf0", size = 154915, upload-time = "2026-01-11T11:22:06.703Z" }, + { url = "https://files.pythonhosted.org/packages/20/aa/64dd73a5a849c2e8f216b755599c511badde80e91e9bc2271baa7b2cdbb1/tomli-2.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9a08144fa4cba33db5255f9b74f0b89888622109bd2776148f2597447f92a94e", size = 149038, upload-time = "2026-01-11T11:22:07.56Z" }, + { url = "https://files.pythonhosted.org/packages/9e/8a/6d38870bd3d52c8d1505ce054469a73f73a0fe62c0eaf5dddf61447e32fa/tomli-2.4.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c73add4bb52a206fd0c0723432db123c0c75c280cbd67174dd9d2db228ebb1b4", size = 242245, upload-time = "2026-01-11T11:22:08.344Z" }, + { url = "https://files.pythonhosted.org/packages/59/bb/8002fadefb64ab2669e5b977df3f5e444febea60e717e755b38bb7c41029/tomli-2.4.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1fb2945cbe303b1419e2706e711b7113da57b7db31ee378d08712d678a34e51e", size = 250335, upload-time = "2026-01-11T11:22:09.951Z" }, + { url = "https://files.pythonhosted.org/packages/a5/3d/4cdb6f791682b2ea916af2de96121b3cb1284d7c203d97d92d6003e91c8d/tomli-2.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bbb1b10aa643d973366dc2cb1ad94f99c1726a02343d43cbc011edbfac579e7c", size = 245962, upload-time = "2026-01-11T11:22:11.27Z" }, + { url = "https://files.pythonhosted.org/packages/f2/4a/5f25789f9a460bd858ba9756ff52d0830d825b458e13f754952dd15fb7bb/tomli-2.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4cbcb367d44a1f0c2be408758b43e1ffb5308abe0ea222897d6bfc8e8281ef2f", size = 250396, upload-time = "2026-01-11T11:22:12.325Z" }, + { url = "https://files.pythonhosted.org/packages/aa/2f/b73a36fea58dfa08e8b3a268750e6853a6aac2a349241a905ebd86f3047a/tomli-2.4.0-cp313-cp313-win32.whl", hash = "sha256:7d49c66a7d5e56ac959cb6fc583aff0651094ec071ba9ad43df785abc2320d86", size = 97530, upload-time = "2026-01-11T11:22:13.865Z" }, + { url = "https://files.pythonhosted.org/packages/3b/af/ca18c134b5d75de7e8dc551c5234eaba2e8e951f6b30139599b53de9c187/tomli-2.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:3cf226acb51d8f1c394c1b310e0e0e61fecdd7adcb78d01e294ac297dd2e7f87", size = 108227, upload-time = "2026-01-11T11:22:15.224Z" }, + { url = "https://files.pythonhosted.org/packages/22/c3/b386b832f209fee8073c8138ec50f27b4460db2fdae9ffe022df89a57f9b/tomli-2.4.0-cp313-cp313-win_arm64.whl", hash = "sha256:d20b797a5c1ad80c516e41bc1fb0443ddb5006e9aaa7bda2d71978346aeb9132", size = 94748, upload-time = "2026-01-11T11:22:16.009Z" }, + { url = "https://files.pythonhosted.org/packages/f3/c4/84047a97eb1004418bc10bdbcfebda209fca6338002eba2dc27cc6d13563/tomli-2.4.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:26ab906a1eb794cd4e103691daa23d95c6919cc2fa9160000ac02370cc9dd3f6", size = 154725, upload-time = "2026-01-11T11:22:17.269Z" }, + { url = "https://files.pythonhosted.org/packages/a8/5d/d39038e646060b9d76274078cddf146ced86dc2b9e8bbf737ad5983609a0/tomli-2.4.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:20cedb4ee43278bc4f2fee6cb50daec836959aadaf948db5172e776dd3d993fc", size = 148901, upload-time = "2026-01-11T11:22:18.287Z" }, + { url = "https://files.pythonhosted.org/packages/73/e5/383be1724cb30f4ce44983d249645684a48c435e1cd4f8b5cded8a816d3c/tomli-2.4.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:39b0b5d1b6dd03684b3fb276407ebed7090bbec989fa55838c98560c01113b66", size = 243375, upload-time = "2026-01-11T11:22:19.154Z" }, + { url = "https://files.pythonhosted.org/packages/31/f0/bea80c17971c8d16d3cc109dc3585b0f2ce1036b5f4a8a183789023574f2/tomli-2.4.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a26d7ff68dfdb9f87a016ecfd1e1c2bacbe3108f4e0f8bcd2228ef9a766c787d", size = 250639, upload-time = "2026-01-11T11:22:20.168Z" }, + { url = "https://files.pythonhosted.org/packages/2c/8f/2853c36abbb7608e3f945d8a74e32ed3a74ee3a1f468f1ffc7d1cb3abba6/tomli-2.4.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:20ffd184fb1df76a66e34bd1b36b4a4641bd2b82954befa32fe8163e79f1a702", size = 246897, upload-time = "2026-01-11T11:22:21.544Z" }, + { url = "https://files.pythonhosted.org/packages/49/f0/6c05e3196ed5337b9fe7ea003e95fd3819a840b7a0f2bf5a408ef1dad8ed/tomli-2.4.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:75c2f8bbddf170e8effc98f5e9084a8751f8174ea6ccf4fca5398436e0320bc8", size = 254697, upload-time = "2026-01-11T11:22:23.058Z" }, + { url = "https://files.pythonhosted.org/packages/f3/f5/2922ef29c9f2951883525def7429967fc4d8208494e5ab524234f06b688b/tomli-2.4.0-cp314-cp314-win32.whl", hash = "sha256:31d556d079d72db7c584c0627ff3a24c5d3fb4f730221d3444f3efb1b2514776", size = 98567, upload-time = "2026-01-11T11:22:24.033Z" }, + { url = "https://files.pythonhosted.org/packages/7b/31/22b52e2e06dd2a5fdbc3ee73226d763b184ff21fc24e20316a44ccc4d96b/tomli-2.4.0-cp314-cp314-win_amd64.whl", hash = "sha256:43e685b9b2341681907759cf3a04e14d7104b3580f808cfde1dfdb60ada85475", size = 108556, upload-time = "2026-01-11T11:22:25.378Z" }, + { url = "https://files.pythonhosted.org/packages/48/3d/5058dff3255a3d01b705413f64f4306a141a8fd7a251e5a495e3f192a998/tomli-2.4.0-cp314-cp314-win_arm64.whl", hash = "sha256:3d895d56bd3f82ddd6faaff993c275efc2ff38e52322ea264122d72729dca2b2", size = 96014, upload-time = "2026-01-11T11:22:26.138Z" }, + { url = "https://files.pythonhosted.org/packages/b8/4e/75dab8586e268424202d3a1997ef6014919c941b50642a1682df43204c22/tomli-2.4.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:5b5807f3999fb66776dbce568cc9a828544244a8eb84b84b9bafc080c99597b9", size = 163339, upload-time = "2026-01-11T11:22:27.143Z" }, + { url = "https://files.pythonhosted.org/packages/06/e3/b904d9ab1016829a776d97f163f183a48be6a4deb87304d1e0116a349519/tomli-2.4.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c084ad935abe686bd9c898e62a02a19abfc9760b5a79bc29644463eaf2840cb0", size = 159490, upload-time = "2026-01-11T11:22:28.399Z" }, + { url = "https://files.pythonhosted.org/packages/e3/5a/fc3622c8b1ad823e8ea98a35e3c632ee316d48f66f80f9708ceb4f2a0322/tomli-2.4.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0f2e3955efea4d1cfbcb87bc321e00dc08d2bcb737fd1d5e398af111d86db5df", size = 269398, upload-time = "2026-01-11T11:22:29.345Z" }, + { url = "https://files.pythonhosted.org/packages/fd/33/62bd6152c8bdd4c305ad9faca48f51d3acb2df1f8791b1477d46ff86e7f8/tomli-2.4.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0e0fe8a0b8312acf3a88077a0802565cb09ee34107813bba1c7cd591fa6cfc8d", size = 276515, upload-time = "2026-01-11T11:22:30.327Z" }, + { url = "https://files.pythonhosted.org/packages/4b/ff/ae53619499f5235ee4211e62a8d7982ba9e439a0fb4f2f351a93d67c1dd2/tomli-2.4.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:413540dce94673591859c4c6f794dfeaa845e98bf35d72ed59636f869ef9f86f", size = 273806, upload-time = "2026-01-11T11:22:32.56Z" }, + { url = "https://files.pythonhosted.org/packages/47/71/cbca7787fa68d4d0a9f7072821980b39fbb1b6faeb5f5cf02f4a5559fa28/tomli-2.4.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:0dc56fef0e2c1c470aeac5b6ca8cc7b640bb93e92d9803ddaf9ea03e198f5b0b", size = 281340, upload-time = "2026-01-11T11:22:33.505Z" }, + { url = "https://files.pythonhosted.org/packages/f5/00/d595c120963ad42474cf6ee7771ad0d0e8a49d0f01e29576ee9195d9ecdf/tomli-2.4.0-cp314-cp314t-win32.whl", hash = "sha256:d878f2a6707cc9d53a1be1414bbb419e629c3d6e67f69230217bb663e76b5087", size = 108106, upload-time = "2026-01-11T11:22:34.451Z" }, + { url = "https://files.pythonhosted.org/packages/de/69/9aa0c6a505c2f80e519b43764f8b4ba93b5a0bbd2d9a9de6e2b24271b9a5/tomli-2.4.0-cp314-cp314t-win_amd64.whl", hash = "sha256:2add28aacc7425117ff6364fe9e06a183bb0251b03f986df0e78e974047571fd", size = 120504, upload-time = "2026-01-11T11:22:35.764Z" }, + { url = "https://files.pythonhosted.org/packages/b3/9f/f1668c281c58cfae01482f7114a4b88d345e4c140386241a1a24dcc9e7bc/tomli-2.4.0-cp314-cp314t-win_arm64.whl", hash = "sha256:2b1e3b80e1d5e52e40e9b924ec43d81570f0e7d09d11081b797bc4692765a3d4", size = 99561, upload-time = "2026-01-11T11:22:36.624Z" }, + { url = "https://files.pythonhosted.org/packages/23/d1/136eb2cb77520a31e1f64cbae9d33ec6df0d78bdf4160398e86eec8a8754/tomli-2.4.0-py3-none-any.whl", hash = "sha256:1f776e7d669ebceb01dee46484485f43a4048746235e683bcdffacdf1fb4785a", size = 14477, upload-time = "2026-01-11T11:22:37.446Z" }, +] + +[[package]] +name = "tornado" +version = "6.5.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/37/1d/0a336abf618272d53f62ebe274f712e213f5a03c0b2339575430b8362ef2/tornado-6.5.4.tar.gz", hash = "sha256:a22fa9047405d03260b483980635f0b041989d8bcc9a313f8fe18b411d84b1d7", size = 513632, upload-time = "2025-12-15T19:21:03.836Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ab/a9/e94a9d5224107d7ce3cc1fab8d5dc97f5ea351ccc6322ee4fb661da94e35/tornado-6.5.4-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:d6241c1a16b1c9e4cc28148b1cda97dd1c6cb4fb7068ac1bedc610768dff0ba9", size = 443909, upload-time = "2025-12-15T19:20:48.382Z" }, + { url = "https://files.pythonhosted.org/packages/db/7e/f7b8d8c4453f305a51f80dbb49014257bb7d28ccb4bbb8dd328ea995ecad/tornado-6.5.4-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:2d50f63dda1d2cac3ae1fa23d254e16b5e38153758470e9956cbc3d813d40843", size = 442163, upload-time = "2025-12-15T19:20:49.791Z" }, + { url = "https://files.pythonhosted.org/packages/ba/b5/206f82d51e1bfa940ba366a8d2f83904b15942c45a78dd978b599870ab44/tornado-6.5.4-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d1cf66105dc6acb5af613c054955b8137e34a03698aa53272dbda4afe252be17", size = 445746, upload-time = "2025-12-15T19:20:51.491Z" }, + { url = "https://files.pythonhosted.org/packages/8e/9d/1a3338e0bd30ada6ad4356c13a0a6c35fbc859063fa7eddb309183364ac1/tornado-6.5.4-cp39-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:50ff0a58b0dc97939d29da29cd624da010e7f804746621c78d14b80238669335", size = 445083, upload-time = "2025-12-15T19:20:52.778Z" }, + { url = "https://files.pythonhosted.org/packages/50/d4/e51d52047e7eb9a582da59f32125d17c0482d065afd5d3bc435ff2120dc5/tornado-6.5.4-cp39-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e5fb5e04efa54cf0baabdd10061eb4148e0be137166146fff835745f59ab9f7f", size = 445315, upload-time = "2025-12-15T19:20:53.996Z" }, + { url = "https://files.pythonhosted.org/packages/27/07/2273972f69ca63dbc139694a3fc4684edec3ea3f9efabf77ed32483b875c/tornado-6.5.4-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:9c86b1643b33a4cd415f8d0fe53045f913bf07b4a3ef646b735a6a86047dda84", size = 446003, upload-time = "2025-12-15T19:20:56.101Z" }, + { url = "https://files.pythonhosted.org/packages/d1/83/41c52e47502bf7260044413b6770d1a48dda2f0246f95ee1384a3cd9c44a/tornado-6.5.4-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:6eb82872335a53dd063a4f10917b3efd28270b56a33db69009606a0312660a6f", size = 445412, upload-time = "2025-12-15T19:20:57.398Z" }, + { url = "https://files.pythonhosted.org/packages/10/c7/bc96917f06cbee182d44735d4ecde9c432e25b84f4c2086143013e7b9e52/tornado-6.5.4-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:6076d5dda368c9328ff41ab5d9dd3608e695e8225d1cd0fd1e006f05da3635a8", size = 445392, upload-time = "2025-12-15T19:20:58.692Z" }, + { url = "https://files.pythonhosted.org/packages/0c/1a/d7592328d037d36f2d2462f4bc1fbb383eec9278bc786c1b111cbbd44cfa/tornado-6.5.4-cp39-abi3-win32.whl", hash = "sha256:1768110f2411d5cd281bac0a090f707223ce77fd110424361092859e089b38d1", size = 446481, upload-time = "2025-12-15T19:21:00.008Z" }, + { url = "https://files.pythonhosted.org/packages/d6/6d/c69be695a0a64fd37a97db12355a035a6d90f79067a3cf936ec2b1dc38cd/tornado-6.5.4-cp39-abi3-win_amd64.whl", hash = "sha256:fa07d31e0cd85c60713f2b995da613588aa03e1303d75705dca6af8babc18ddc", size = 446886, upload-time = "2025-12-15T19:21:01.287Z" }, + { url = "https://files.pythonhosted.org/packages/50/49/8dc3fd90902f70084bd2cd059d576ddb4f8bb44c2c7c0e33a11422acb17e/tornado-6.5.4-cp39-abi3-win_arm64.whl", hash = "sha256:053e6e16701eb6cbe641f308f4c1a9541f91b6261991160391bfc342e8a551a1", size = 445910, upload-time = "2025-12-15T19:21:02.571Z" }, +] + +[[package]] +name = "traitlets" +version = "5.14.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/eb/79/72064e6a701c2183016abbbfedaba506d81e30e232a68c9f0d6f6fcd1574/traitlets-5.14.3.tar.gz", hash = "sha256:9ed0579d3502c94b4b3732ac120375cda96f923114522847de4b3bb98b96b6b7", size = 161621, upload-time = "2024-04-19T11:11:49.746Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/00/c0/8f5d070730d7836adc9c9b6408dec68c6ced86b304a9b26a14df072a6e8c/traitlets-5.14.3-py3-none-any.whl", hash = "sha256:b74e89e397b1ed28cc831db7aea759ba6640cb3de13090ca145426688ff1ac4f", size = 85359, upload-time = "2024-04-19T11:11:46.763Z" }, +] + +[[package]] +name = "typing-extensions" +version = "4.15.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391, upload-time = "2025-08-25T13:49:26.313Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload-time = "2025-08-25T13:49:24.86Z" }, +] + +[[package]] +name = "urllib3" +version = "2.6.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c7/24/5f1b3bdffd70275f6661c76461e25f024d5a38a46f04aaca912426a2b1d3/urllib3-2.6.3.tar.gz", hash = "sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed", size = 435556, upload-time = "2026-01-07T16:24:43.925Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl", hash = "sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4", size = 131584, upload-time = "2026-01-07T16:24:42.685Z" }, +] + +[[package]] +name = "virtualenv" +version = "20.38.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "distlib" }, + { name = "filelock" }, + { name = "platformdirs" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/d2/03/a94d404ca09a89a7301a7008467aed525d4cdeb9186d262154dd23208709/virtualenv-20.38.0.tar.gz", hash = "sha256:94f39b1abaea5185bf7ea5a46702b56f1d0c9aa2f41a6c2b8b0af4ddc74c10a7", size = 5864558, upload-time = "2026-02-19T07:48:02.385Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/42/d7/394801755d4c8684b655d35c665aea7836ec68320304f62ab3c94395b442/virtualenv-20.38.0-py3-none-any.whl", hash = "sha256:d6e78e5889de3a4742df2d3d44e779366325a90cf356f15621fddace82431794", size = 5837778, upload-time = "2026-02-19T07:47:59.778Z" }, +] + +[[package]] +name = "webencodings" +version = "0.5.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0b/02/ae6ceac1baeda530866a85075641cec12989bd8d31af6d5ab4a3e8c92f47/webencodings-0.5.1.tar.gz", hash = "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923", size = 9721, upload-time = "2017-04-05T20:21:34.189Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f4/24/2a3e3df732393fed8b3ebf2ec078f05546de641fe1b667ee316ec1dcf3b7/webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78", size = 11774, upload-time = "2017-04-05T20:21:32.581Z" }, +] From 9c817a88754a0fd0f96c9a533a506361d4ec318c Mon Sep 17 00:00:00 2001 From: Steven Murray Date: Sun, 22 Feb 2026 14:11:00 +0200 Subject: [PATCH 02/18] style: run ruff checks --- docs/conf.py | 2 +- docs/examples/broad_overview.ipynb | 2 +- docs/examples/change_mass_definition.ipynb | 10 +-- docs/examples/fitting.ipynb | 7 +- src/hmf/_cli.py | 2 +- src/hmf/_internals/_cache.py | 10 +-- src/hmf/_internals/_framework.py | 16 ++--- src/hmf/cosmology/cosmo.py | 10 ++- src/hmf/cosmology/growth_factor.py | 8 +-- src/hmf/density_field/filters.py | 24 +++---- src/hmf/density_field/halofit.py | 4 +- src/hmf/density_field/transfer.py | 32 ++++----- src/hmf/density_field/transfer_models.py | 38 +++++------ src/hmf/halos/mass_definitions.py | 10 +-- src/hmf/helpers/__init__.py | 4 +- src/hmf/helpers/cfg_utils.py | 2 +- src/hmf/helpers/functional.py | 2 +- src/hmf/mass_function/fitting_functions.py | 43 ++++++------ src/hmf/mass_function/hmf.py | 77 ++++++++++------------ src/hmf/mass_function/integrate_hmf.py | 4 +- tests/test_cli.py | 2 +- tests/test_fcoll.py | 4 +- tests/test_filters.py | 4 +- tests/test_fits.py | 4 +- tests/test_genmf.py | 8 +-- tests/test_mdef.py | 2 +- tests/test_transfer.py | 13 ++-- 27 files changed, 148 insertions(+), 196 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 2ff6b552..53f6e361 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -63,7 +63,7 @@ # General information about the project. project = "hmf" -copyright = "%s, Steven Murray" % (time.localtime()[0]) +copyright = f"{time.localtime()[0]}, Steven Murray" # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the diff --git a/docs/examples/broad_overview.ipynb b/docs/examples/broad_overview.ipynb index 7c104b5a..16e750e3 100644 --- a/docs/examples/broad_overview.ipynb +++ b/docs/examples/broad_overview.ipynb @@ -1200,7 +1200,7 @@ } ], "source": [ - "for power, tr, label in get_hmf(\n", + "for _power, tr, _label in get_hmf(\n", " req_qauntities=[\"power\"],\n", " framework=Transfer,\n", " fast_kwargs={\"transfer_model\": \"EH\"},\n", diff --git a/docs/examples/change_mass_definition.ipynb b/docs/examples/change_mass_definition.ipynb index fe6fe1cf..b4ee8310 100644 --- a/docs/examples/change_mass_definition.ipynb +++ b/docs/examples/change_mass_definition.ipynb @@ -67,7 +67,7 @@ "import hmf\n", "from hmf.halos import mass_definitions as md\n", "\n", - "print(\"Using hmf version v%s\" % hmf.__version__)" + "print(f\"Using hmf version v{hmf.__version__}\")" ] }, { @@ -249,8 +249,8 @@ "source": [ "mnew, rnew, cnew = mdef_1.change_definition(m=1e12, mdef=mdef_2)\n", "print(\"Mass in new definition is %.2f x 10^12 Msun / h\" % (mnew / 1e12))\n", - "print(\"Radius of halo in new definition is %.2f Mpc/h\" % rnew)\n", - "print(\"Concentration of halo in new definition is %.2f\" % cnew)" + "print(f\"Radius of halo in new definition is {rnew:.2f} Mpc/h\")\n", + "print(f\"Concentration of halo in new definition is {cnew:.2f}\")" ] }, { @@ -280,8 +280,8 @@ "source": [ "mnew, rnew, cnew = mdef_1.change_definition(m=1e12, mdef=mdef_2, c=5.0)\n", "print(\"Mass in new definition is %.2f x 10^12 Msun / h\" % (mnew / 1e12))\n", - "print(\"Radius of halo in new definition is %.2f Mpc/h\" % rnew)\n", - "print(\"Concentration of halo in new definition is %.2f\" % cnew)" + "print(f\"Radius of halo in new definition is {rnew:.2f} Mpc/h\")\n", + "print(f\"Concentration of halo in new definition is {cnew:.2f}\")" ] }, { diff --git a/docs/examples/fitting.ipynb b/docs/examples/fitting.ipynb index ea17f1fc..bfd4e499 100644 --- a/docs/examples/fitting.ipynb +++ b/docs/examples/fitting.ipynb @@ -274,14 +274,11 @@ "source": [ "def log_prob(param_values, param_names, data, model, volume, derived=None):\n", " # Update the base model with all the parameters that are being constrained.\n", - " params = flat_to_nested_dict(dict(zip(param_names, param_values)))\n", + " params = flat_to_nested_dict(dict(zip(param_names, param_values, strict=True)))\n", "\n", " model.update(**params)\n", "\n", - " if derived is not None:\n", - " derived = [getattr(model, d) for d in derived]\n", - " else:\n", - " derived = []\n", + " derived = [getattr(model, d) for d in derived] if derived is not None else []\n", "\n", " return log_likelihood(model.dndlog10m, data, volume, model.dlog10m), derived" ] diff --git a/src/hmf/_cli.py b/src/hmf/_cli.py index e550098a..a159ee4b 100644 --- a/src/hmf/_cli.py +++ b/src/hmf/_cli.py @@ -185,7 +185,7 @@ def run_cli(config, pkg_name, args, outdir, label, pkgs, default_framework): t = time() # Write out quantities - for qname, q in zip(quantities, quants): + for qname, q in zip(quantities, quants, strict=True): np.savetxt(outdir / f"{lab}_{qname}.txt", q) console.print( diff --git a/src/hmf/_internals/_cache.py b/src/hmf/_internals/_cache.py index e7324365..d9c4c908 100644 --- a/src/hmf/_internals/_cache.py +++ b/src/hmf/_internals/_cache.py @@ -1,6 +1,6 @@ """ This module defines two decorators, based on the code from -http://forrst.com/posts/Yet_another_caching_property_decorator_for_Pytho-PBy +http://forrst.com/posts/Yet_another_caching_property_decorator_for_Pytho-PBy. They are both designed to cache class properties, but have the added functionality of being automatically updated when a parent property is @@ -161,12 +161,12 @@ def _del_property(self): try: del getattr(self, recalc)[name] except KeyError: - warnings.warn(f"{name} not found in recalc cache.") + warnings.warn(f"{name} not found in recalc cache.", stacklevel=2) try: del getattr(self, recalc_prpa)[name] except KeyError: - warnings.warn(f"{name} not found in recalc_prop_par cache") + warnings.warn(f"{name} not found in recalc_prop_par cache", stacklevel=2) return property(_get_property, None, _del_property) @@ -296,7 +296,7 @@ def _set_property(self, val): f"validation is performed. You can turn on extra validation " f"for directly set parameters by setting framework._validate_every_param_set=True." f"However, this can be brittle, since intermediate states may not be valid.", - category=DeprecationWarning, + stacklevel=2, category=DeprecationWarning, ) update_wrapper(_set_property, f) @@ -324,7 +324,7 @@ def _get_property(self): def subframework(f): """ - A quantity that is essentially a sub-framework + A quantity that is essentially a sub-framework. Parameters ---------- diff --git a/src/hmf/_internals/_framework.py b/src/hmf/_internals/_framework.py index e6f5e70c..8639224c 100644 --- a/src/hmf/_internals/_framework.py +++ b/src/hmf/_internals/_framework.py @@ -72,7 +72,7 @@ def get_base_component(name: [str, type[Component]]) -> type[Component]: ) if len(avail) > 1: warnings.warn( - f"More than one component called '{name}'. Returning {avail[-1]}." + f"More than one component called '{name}'. Returning {avail[-1]}.", stacklevel=2 ) return avail[-1] try: @@ -138,7 +138,7 @@ def get_mdl( if len(avail_models) > 1: warnings.warn( f"More than one model was found with name '{name}'. Returning " - f"{avail_models[-1][1]}." + f"{avail_models[-1][1]}.", stacklevel=2 ) if not avail_models: raise ValueError(f"No model found with name '{name}'.") @@ -191,7 +191,7 @@ def get_model(name, mod, **kwargs): class _Validator(type): def __call__(cls, *args, **kwargs): - """Called when you call MyNewClass()""" + """Called when you call MyNewClass().""" obj = type.__call__(cls, *args, **kwargs) obj.validate() return obj @@ -220,9 +220,7 @@ def validate(self): """Perform validation of the input parameters as they relate to each other.""" def update(self, **kwargs): - """ - Update parameters of the framework with kwargs. - """ + """Update parameters of the framework with kwargs.""" self._validate = False try: for k in list(kwargs.keys()): @@ -243,7 +241,7 @@ def update(self, **kwargs): raise if kwargs: - raise ValueError("Invalid arguments: %s" % kwargs) + raise ValueError(f"Invalid arguments: {kwargs}") def clone(self, **kwargs): """Create and return an updated clone of the current object.""" @@ -281,7 +279,7 @@ def get_all_parameter_defaults(cls, recursive=True): @property def parameter_values(self): - """Dictionary of all parameters and their current values""" + """Dictionary of all parameters and their current values.""" return { name: getattr(self, name) for name in getattr( @@ -303,7 +301,7 @@ def quantities_available(cls): @classmethod def _get_all_parameters(cls): - """Yield all parameters as tuples of (name,obj)""" + """Yield all parameters as tuples of (name,obj).""" for name in cls.get_all_parameter_names(): yield name, getattr(cls, name) diff --git a/src/hmf/cosmology/cosmo.py b/src/hmf/cosmology/cosmo.py index fabcf20e..22b6f4eb 100644 --- a/src/hmf/cosmology/cosmo.py +++ b/src/hmf/cosmology/cosmo.py @@ -36,7 +36,7 @@ details="Use the cosmology.fromAstropy function in COLOSSUS instead", ) def astropy_to_colossus(cosmo: FLRW, name: str = "custom", **kwargs): - """Convert an astropy cosmology to a COLOSSUS cosmology""" + """Convert an astropy cosmology to a COLOSSUS cosmology.""" try: from colossus.cosmology import cosmology @@ -101,7 +101,7 @@ def cosmo_params(self, val): Parameters for the cosmology that deviate from the base cosmology passed. This is useful for repeated updates of a single parameter (leaving others the same). Default is the empty dict. The parameters passed must match - the allowed parameters of `cosmo_model`. For the basic class this is + the allowed parameters of `cosmo_model`. For the basic class this is. :Tcmb0: Temperature of the CMB at z=0 :Neff: Number of massless neutrino species @@ -126,9 +126,7 @@ def cosmo(self): @_cache.cached_quantity def mean_density0(self): - """ - Mean density of universe at z=0, [Msun h^2 / Mpc**3] - """ + """Mean density of universe at z=0, [Msun h^2 / Mpc**3].""" return ( (self.cosmo.Om0 * self.cosmo.critical_density0 / self.cosmo.h**2) .to(u.Msun / u.Mpc**3) @@ -147,4 +145,4 @@ def get_cosmo(name): """ if isinstance(getattr(sys.modules[__name__], name), FLRW): return getattr(sys.modules[__name__], name) - raise ValueError("%s is not a valid cosmology" % name) + raise ValueError(f"{name} is not a valid cosmology") diff --git a/src/hmf/cosmology/growth_factor.py b/src/hmf/cosmology/growth_factor.py index 5f2dbc8c..d53687ee 100644 --- a/src/hmf/cosmology/growth_factor.py +++ b/src/hmf/cosmology/growth_factor.py @@ -27,9 +27,7 @@ @pluggable class _GrowthFactor(Cmpt): - r""" - General class for a growth factor calculation. - """ + r"""General class for a growth factor calculation.""" supported_cosmos = (cosmology.LambdaCDM,) @@ -163,7 +161,7 @@ def growth_factor_fn(self, zmin=0.0, inverse=False): def growth_rate(self, z): """ - Growth rate, dln(d)/dln(a) from Hamilton 2000 eq. 4 + Growth rate, dln(d)/dln(a) from Hamilton 2000 eq. 4. Parameters ---------- @@ -247,7 +245,7 @@ def growth_factor(self, z): @_inherit class FromArray(FromFile): r""" - Use a spline over a given array to define the transfer function + Use a spline over a given array to define the transfer function. Parameters ---------- diff --git a/src/hmf/density_field/filters.py b/src/hmf/density_field/filters.py index 2006d984..4372fbf9 100644 --- a/src/hmf/density_field/filters.py +++ b/src/hmf/density_field/filters.py @@ -114,7 +114,7 @@ def mass_to_radius(self, m, rho_mean): def radius_to_mass(self, r, rho_mean): r""" - Return mass of a region of space given its radius + Return mass of a region of space given its radius. Parameters ---------- @@ -364,7 +364,7 @@ def dw_dlnkr(self, kr): @_utils.inherit_docstrings class SharpK(Filter): r""" - Fourier-space top-hat window function + Fourier-space top-hat window function. This class is based on :class:`~Filter`, which can be consulted for details of how to instantiate it. @@ -426,7 +426,7 @@ def sigma(self, r, order=0): r = np.atleast_1d(r) if self.k.max() < 1 / r.min(): - warnings.warn("Warning: Maximum r*k less than 1!") + warnings.warn("Warning: Maximum r*k less than 1!", stacklevel=2) # # Need to re-define this because the integral needs to go exactly kr=1 # # or else the function 'jitters' @@ -450,7 +450,7 @@ def sigma(self, r, order=0): @_utils.inherit_docstrings class SharpKEllipsoid(SharpK): """ - Fourier-space top-hat window function with ellipsoidal correction + Fourier-space top-hat window function with ellipsoidal correction. See Schneider, Smith, Reed 2013. @@ -475,27 +475,19 @@ def xm(self, g, v): return g * v + top / bot def em(self, xm): - """ - The average ellipticity of a patch as a function of peak tensor - """ + """The average ellipticity of a patch as a function of peak tensor.""" return 1 / np.sqrt(5 * xm**2 + 6) def pm(self, xm): - """ - The average prolateness of a patch as a function of peak tensor - """ + """The average prolateness of a patch as a function of peak tensor.""" return 30.0 / (5 * xm**2 + 6) ** 2 def a3a1(self, e, p): - """ - The short:long axis ratio of an ellipsoid given its ellipticity and prolateness - """ + """The short:long axis ratio of an ellipsoid given its ellipticity and prolateness.""" return np.sqrt((1 - 3 * e + p) / (1 + 3 * e + p)) def a3a2(self, e, p): - """ - The short:medium axis ratio of an ellipsoid given its ellipticity/prolateness - """ + """The short:medium axis ratio of an ellipsoid given its ellipticity/prolateness.""" return np.sqrt((1 - 2 * p) / (1 + 3 * e + p)) def gamma(self, r): diff --git a/src/hmf/density_field/halofit.py b/src/hmf/density_field/halofit.py index 7249b3fc..ae5ffd2a 100644 --- a/src/hmf/density_field/halofit.py +++ b/src/hmf/density_field/halofit.py @@ -60,7 +60,7 @@ def get_sigma_abs(lnr): if not res.success: warnings.warn( f"Could not determine non-linear scale! Failed with error: {res.message}. " - f"Continuing with best-fit non-linear scale: r_nl={np.exp(res.x)}, with log_sigma^2 = {res.fun}" + f"Continuing with best-fit non-linear scale: r_nl={np.exp(res.x)}, with log_sigma^2 = {res.fun}", stacklevel=2 ) rnl = np.exp(res.x) @@ -106,7 +106,7 @@ def halofit(k, delta_k, *, sigma_8=None, z=0, cosmo=None, takahashi=True): Dimensionless power at `k`, with nonlinear corrections applied. """ if sigma_8 is not None: - warnings.warn("sigma_8 is not used any more, and will be removed in v4") + warnings.warn("sigma_8 is not used any more, and will be removed in v4", stacklevel=2) if cosmo is None: cosmo = csm() diff --git a/src/hmf/density_field/transfer.py b/src/hmf/density_field/transfer.py index faa29812..5f4970be 100644 --- a/src/hmf/density_field/transfer.py +++ b/src/hmf/density_field/transfer.py @@ -139,25 +139,25 @@ def transfer_params(self, val): @parameter("param") def sigma_8(self, val): """ - RMS linear density fluctuations in spheres of radius 8 Mpc/h + RMS linear density fluctuations in spheres of radius 8 Mpc/h. :type: float """ if val < 0.1 or val > 10: - raise ValueError("sigma_8 out of bounds, %s" % val) + raise ValueError(f"sigma_8 out of bounds, {val}") return val @parameter("param") def n(self, val): """ - Spectral index of fluctuations + Spectral index of fluctuations. Must be greater than -3 and less than 4. :type: float """ if val < -3 or val > 4: - raise ValueError("n out of bounds, %s" % val) + raise ValueError(f"n out of bounds, {val}") return val @parameter("res") @@ -181,7 +181,7 @@ def lnk_max(self, val): @parameter("res") def dlnk(self, val): """ - Step-size of log wave-numbers + Step-size of log wave-numbers. :type: float """ @@ -222,28 +222,22 @@ def z(self, val): # =========================================================================== @cached_quantity def k(self): - """Wavenumbers, [h/Mpc]""" + """Wavenumbers, [h/Mpc].""" return np.exp(np.arange(self.lnk_min, self.lnk_max, self.dlnk)) @cached_quantity def transfer(self): - """ - The instantiated transfer model - """ + """The instantiated transfer model.""" return self.transfer_model(self.cosmo, **self.transfer_params) @cached_quantity def _unnormalised_lnT(self): - """ - The un-normalised transfer function. - """ + """The un-normalised transfer function.""" return self.transfer.lnt(np.log(self.k)) @cached_quantity def _unnormalised_power(self): - """ - Un-normalised CDM power at :math:`z=0` [units :math:`Mpc^3/h^3`] - """ + """Un-normalised CDM power at :math:`z=0` [units :math:`Mpc^3/h^3`].""" return self.k**self.n * np.exp(self._unnormalised_lnT) ** 2 @cached_quantity @@ -266,9 +260,7 @@ def _normalisation(self): @cached_quantity def _power0(self): - """ - Normalised power spectrum at z=0 [units :math:`Mpc^3/h^3`] - """ + """Normalised power spectrum at z=0 [units :math:`Mpc^3/h^3`].""" return self._normalisation**2 * self._unnormalised_power @cached_quantity @@ -300,9 +292,7 @@ def power(self): @cached_quantity def delta_k(self): - r""" - Dimensionless power spectrum, :math:`\Delta_k = \frac{k^3 P(k)}{2\pi^2}`. - """ + r"""Dimensionless power spectrum, :math:`\Delta_k = \frac{k^3 P(k)}{2\pi^2}`.""" return self.k**3 * self.power / (2 * np.pi**2) @cached_quantity diff --git a/src/hmf/density_field/transfer_models.py b/src/hmf/density_field/transfer_models.py index 9f80a573..da2884df 100644 --- a/src/hmf/density_field/transfer_models.py +++ b/src/hmf/density_field/transfer_models.py @@ -49,7 +49,7 @@ def __init__(self, cosmo, **model_parameters): def lnt(self, lnk): r""" - Natural log of the transfer function + Natural log of the transfer function. Parameters ---------- @@ -112,7 +112,7 @@ def _check_low_k(self, lnk, lnT, lnkmin): def lnt(self, lnk): r""" - Natural log of the transfer function + Natural log of the transfer function. Parameters ---------- @@ -232,7 +232,7 @@ def __init__(self, *args, **kwargs): warnings.warn( "'extrapolate_with_eh' was not set. Defaulting to True, which is " "different behaviour than versions <=3.4.4. This warning may be " - "removed in v4.0. Silence it by setting extrapolate_with_eh explicitly." + "removed in v4.0. Silence it by setting extrapolate_with_eh explicitly.", stacklevel=2 ) self.params["extrapolate_with_eh"] = True @@ -242,7 +242,7 @@ def __init__(self, *args, **kwargs): def lnt(self, lnk): r""" - Natural log of the transfer function + Natural log of the transfer function. Parameters ---------- @@ -361,11 +361,11 @@ def __getstate__(self): warnings.warn( f"CAMB key '{pk}' is not an attribute. If you provided a " f"custom CAMBparams, results may be inconsistent. Available: " - f"{dir(p)}" + f"{dir(p)}", stacklevel=2 ) except Exception: - warnings.warn(f"CAMB key {pk} is not pickle-able.") + warnings.warn(f"CAMB key {pk} is not pickle-able.", stacklevel=2) # Deepcopy self this = {} @@ -385,7 +385,7 @@ def __setstate__(self, state): class FromArray(FromFile): r""" - Use a spline over a given array to define the transfer function + Use a spline over a given array to define the transfer function. Parameters ---------- @@ -407,7 +407,7 @@ class FromArray(FromFile): def lnt(self, lnk): r""" - Natural log of the transfer function + Natural log of the transfer function. Parameters ---------- @@ -439,7 +439,7 @@ def lnt(self, lnk): class EH_BAO(TransferComponent): r""" - Eisenstein & Hu (1998) fitting function with BAO wiggles + Eisenstein & Hu (1998) fitting function with BAO wiggles. From EH1998, Eqs. 26,28-31. Code adapted from CHOMP. @@ -457,9 +457,7 @@ def __init__(self, *args, **kwargs): self._set_params() def _set_params(self): - """ - Port of ``TFset_parameters`` from original EH code. - """ + """Port of ``TFset_parameters`` from original EH code.""" self.Obh2 = self.cosmo.Ob0 * self.cosmo.h**2 self.Omh2 = self.cosmo.Om0 * self.cosmo.h**2 self.f_baryon = self.cosmo.Ob0 / self.cosmo.Om0 @@ -539,9 +537,7 @@ def k_peak(self): @property def sound_horizon_fit(self): - """ - Sound horizon in Mpc/h - """ + """Sound horizon in Mpc/h.""" return ( self.cosmo.h * 44.5 @@ -551,7 +547,7 @@ def sound_horizon_fit(self): def lnt(self, lnk): r""" - Natural log of the transfer function + Natural log of the transfer function. Parameters ---------- @@ -598,7 +594,7 @@ def term(a, b): class EH_NoBAO(EH_BAO): r""" - Eisenstein & Hu (1998) fitting function without BAO wiggles + Eisenstein & Hu (1998) fitting function without BAO wiggles. From EH 1998 Eqs. 26,28-31. Code adapted from CHOMP project. @@ -621,7 +617,7 @@ def alpha_gamma(self): def lnt(self, lnk): r""" - Natural log of the transfer function + Natural log of the transfer function. Parameters ---------- @@ -704,7 +700,7 @@ class attribute. def lnt(self, lnk): """ - Natural log of the transfer function + Natural log of the transfer function. Parameters ---------- @@ -743,7 +739,7 @@ def lnt(self, lnk): class BondEfs(TransferComponent): r""" - Transfer function of Bond and Efstathiou + Transfer function of Bond and Efstathiou. Parameters ---------- @@ -771,7 +767,7 @@ class attribute. def lnt(self, lnk): """ - Natural log of the transfer function + Natural log of the transfer function. Parameters ---------- diff --git a/src/hmf/halos/mass_definitions.py b/src/hmf/halos/mass_definitions.py index 40833240..a49c0d51 100644 --- a/src/hmf/halos/mass_definitions.py +++ b/src/hmf/halos/mass_definitions.py @@ -60,7 +60,7 @@ def halo_overdensity_crit(self, z=0, cosmo=Planck15): def m_to_r(self, m, z=0, cosmo=Planck15): r""" - Return the radius corresponding to m for this mass definition + Return the radius corresponding to m for this mass definition. Parameters ---------- @@ -81,7 +81,7 @@ def m_to_r(self, m, z=0, cosmo=Planck15): def r_to_m(self, r, z=0, cosmo=Planck15): r""" - Return the mass corresponding to r for this mass definition + Return the mass corresponding to r for this mass definition. Parameters ---------- @@ -168,7 +168,7 @@ def change_definition( if profile.z != z: warnings.warn( f"Redshift of given profile ({profile.z})does not match redshift " - f"passed to change_definition(). Using the redshift directly passed." + f"passed to change_definition(). Using the redshift directly passed.", stacklevel=2 ) profile.z = z @@ -189,7 +189,7 @@ def change_definition( _find_new_concentration( rho, mdef.halo_density(z, cosmo), profile._h, cc ) - for rho, cc in zip(rhos, c) + for rho, cc in zip(rhos, c, strict=True) ] ) @@ -373,7 +373,7 @@ def fnc(x): xmax = x_guess * XDELTA_GUESS_FACTORS[i] x = sp.optimize.brentq(fnc, xmin, xmax) except Exception as e: - warnings.warn(f"raised following error: {e}") + warnings.warn(f"raised following error: {e}", stacklevel=2) i += 1 if x is None: diff --git a/src/hmf/helpers/__init__.py b/src/hmf/helpers/__init__.py index a687605d..85f95947 100644 --- a/src/hmf/helpers/__init__.py +++ b/src/hmf/helpers/__init__.py @@ -1,5 +1,3 @@ -""" -A collection of helper functions which can operate on several of the Frameworks in the rest of the code. -""" +"""A collection of helper functions which can operate on several of the Frameworks in the rest of the code.""" from .functional import get_best_param_order, get_hmf diff --git a/src/hmf/helpers/cfg_utils.py b/src/hmf/helpers/cfg_utils.py index 631afe60..202ca5fd 100644 --- a/src/hmf/helpers/cfg_utils.py +++ b/src/hmf/helpers/cfg_utils.py @@ -19,7 +19,7 @@ def framework_to_dict(obj: Framework) -> dict: out["params"][k] = v.name elif k == "cosmo_params": params = {} - for key in signature(obj.cosmo.__init__).parameters.keys(): + for key in signature(obj.cosmo.__init__).parameters: val = getattr(obj.cosmo, key) if isinstance(val, Quantity): val = {"value": val.value, "unit": str(val.unit)} diff --git a/src/hmf/helpers/functional.py b/src/hmf/helpers/functional.py index 9b4a3723..8376b422 100644 --- a/src/hmf/helpers/functional.py +++ b/src/hmf/helpers/functional.py @@ -222,7 +222,7 @@ def get_hmf( ordered_list = [ordered_kwargs[k] for k in ordered_kwargs] final_list = [ - collections.OrderedDict(list(zip(list(ordered_kwargs.keys()), v))) + collections.OrderedDict(list(zip(list(ordered_kwargs.keys()), v, strict=True))) for v in itertools.product(*ordered_list) ] diff --git a/src/hmf/mass_function/fitting_functions.py b/src/hmf/mass_function/fitting_functions.py index dfe8b0ed..c16d199b 100644 --- a/src/hmf/mass_function/fitting_functions.py +++ b/src/hmf/mass_function/fitting_functions.py @@ -113,12 +113,11 @@ def __init__( def _makedoc(pdocs, lname, sname, eq, ref): return ( - r""" - %s mass function fit. + rf""" + {lname} mass function fit. For details on attributes, see documentation for :class:`FittingFunction`. """ - % lname + pdocs + rf""" Notes @@ -281,12 +280,12 @@ def get_measured_mdef(cls): else: warnings.warn( "Unrecognized overdensity criterion format. " - "Changing mass definitions will be impossible." + "Changing mass definitions will be impossible.", stacklevel=2 ) else: warnings.warn( "Unknown halo finder type in the sim_definition. " - "Changing mass definitions will be impossible." + "Changing mass definitions will be impossible.", stacklevel=2 ) return measured @@ -1306,10 +1305,10 @@ def __init__(self, **model_parameters): delta_halo = self.mass_definition.halo_overdensity_mean(self.z, self.cosmo) if delta_halo not in self.delta_virs: - A_array = np.array([self.params["A_%s" % d] for d in self.delta_virs]) - a_array = np.array([self.params["a_%s" % d] for d in self.delta_virs]) - b_array = np.array([self.params["b_%s" % d] for d in self.delta_virs]) - c_array = np.array([self.params["c_%s" % d] for d in self.delta_virs]) + A_array = np.array([self.params[f"A_{d}"] for d in self.delta_virs]) + a_array = np.array([self.params[f"a_{d}"] for d in self.delta_virs]) + b_array = np.array([self.params[f"b_{d}"] for d in self.delta_virs]) + c_array = np.array([self.params[f"c_{d}"] for d in self.delta_virs]) A_func = _spline(self.delta_virs, A_array) a_func = _spline(self.delta_virs, a_array) @@ -1321,10 +1320,10 @@ def __init__(self, **model_parameters): b_0 = b_func(delta_halo) c_0 = c_func(delta_halo) else: - A_0 = self.params["A_%s" % (int(delta_halo))] - a_0 = self.params["a_%s" % (int(delta_halo))] - b_0 = self.params["b_%s" % (int(delta_halo))] - c_0 = self.params["c_%s" % (int(delta_halo))] + A_0 = self.params[f"A_{int(delta_halo)}"] + a_0 = self.params[f"a_{int(delta_halo)}"] + b_0 = self.params[f"b_{int(delta_halo)}"] + c_0 = self.params[f"c_{int(delta_halo)}"] self.A = A_0 * (1 + self.z) ** (-self.params["A_exp"]) self.a = a_0 * (1 + self.z) ** (-self.params["a_exp"]) @@ -1438,12 +1437,12 @@ def __init__(self, **model_parameters): self.delta_halo = delta_halo if int(delta_halo) not in self.delta_virs: - beta_array = np.array([self.params["beta_%s" % d] for d in self.delta_virs]) + beta_array = np.array([self.params[f"beta_{d}"] for d in self.delta_virs]) gamma_array = np.array( - [self.params["gamma_%s" % d] for d in self.delta_virs] + [self.params[f"gamma_{d}"] for d in self.delta_virs] ) - phi_array = np.array([self.params["phi_%s" % d] for d in self.delta_virs]) - eta_array = np.array([self.params["eta_%s" % d] for d in self.delta_virs]) + phi_array = np.array([self.params[f"phi_{d}"] for d in self.delta_virs]) + eta_array = np.array([self.params[f"eta_{d}"] for d in self.delta_virs]) beta_func = _spline(self.delta_virs, beta_array) gamma_func = _spline(self.delta_virs, gamma_array) @@ -1455,10 +1454,10 @@ def __init__(self, **model_parameters): phi_0 = phi_func(delta_halo) eta_0 = eta_func(delta_halo) else: - beta_0 = self.params["beta_%s" % (int(delta_halo))] - gamma_0 = self.params["gamma_%s" % (int(delta_halo))] - phi_0 = self.params["phi_%s" % (int(delta_halo))] - eta_0 = self.params["eta_%s" % (int(delta_halo))] + beta_0 = self.params[f"beta_{int(delta_halo)}"] + gamma_0 = self.params[f"gamma_{int(delta_halo)}"] + phi_0 = self.params[f"phi_{int(delta_halo)}"] + eta_0 = self.params[f"eta_{int(delta_halo)}"] self.beta = ( beta_0 * (1 + min(self.z, self.params["max_z"])) ** self.params["beta_exp"] @@ -1500,7 +1499,7 @@ def __init__(self, **model_parameters): @property def normalise(self): if int(self.delta_halo) in self.delta_virs and self.z == 0: - return self.params["alpha_%s" % (int(self.delta_halo))] + return self.params[f"alpha_{int(self.delta_halo)}"] return 1 / ( 2 ** (self.eta - self.phi - 0.5) * self.beta ** (-2 * self.phi) diff --git a/src/hmf/mass_function/hmf.py b/src/hmf/mass_function/hmf.py index 97e129e7..65a74c5f 100644 --- a/src/hmf/mass_function/hmf.py +++ b/src/hmf/mass_function/hmf.py @@ -158,7 +158,7 @@ def Mmax(self, val): @parameter("res") def dlog10m(self, val) -> float: """ - log10 interval between mass bins + log10 interval between mass bins. :type: float """ @@ -212,7 +212,7 @@ def delta_c(self, val): @parameter("model") def hmf_model(self, val): r""" - A model to use as the fitting function :math:`f(\sigma)` + A model to use as the fitting function :math:`f(\sigma)`. :type: str or `hmf.fitting_functions.FittingFunction` subclass """ @@ -244,7 +244,7 @@ def mdef_model(self, val): def mdef_params(self, val): """ Model parameters for `mdef_model`. - :type: dict + :type: dict. """ return val @@ -300,7 +300,7 @@ def mdef(self) -> md: warnings.warn( f"Your input mass definition '{mdef}' does not match the mass " f"definition in which the hmf fit {self.hmf_model.__name__} was measured:" - f"'{self.hmf_model.get_measured_mdef()}'. {extra_msg if not self.disable_mass_conversion else ''}" + f"'{self.hmf_model.get_measured_mdef()}'. {extra_msg if not self.disable_mass_conversion else ''}", stacklevel=2 ) return mdef @@ -340,7 +340,7 @@ def halo_overdensity_crit(self): @cached_quantity def normalised_filter(self): - """A normalised filter, such that filter.sigma(8) == sigma8""" + """A normalised filter, such that filter.sigma(8) == sigma8.""" return self.filter_model(self.k, self.power, **self.filter_params) @cached_quantity @@ -360,7 +360,7 @@ def _sigma_0(self): @cached_quantity def sigma8_z(self): - """sigma(8) at redshif z""" + """sigma(8) at redshif z.""" return self.normalised_filter.sigma(8.0) @cached_quantity @@ -375,7 +375,7 @@ def radii(self): @cached_quantity def _dlnsdlnm(self): r""" - The value of :math:`\left|\frac{\d \ln \sigma}{\d \ln m}\right|`, ``len=len(m)`` + The value of :math:`\left|\frac{\d \ln \sigma}{\d \ln m}\right|`, ``len=len(m)``. Notes ----- @@ -390,16 +390,14 @@ def sigma(self): @cached_quantity def nu(self): - r""" - The parameter :math:`\nu = \left(\frac{\delta_c}{\sigma}\right)^2`, ``len=len(m)`` - """ + r"""The parameter :math:`\nu = \left(\frac{\delta_c}{\sigma}\right)^2`, ``len=len(m)``.""" return (self.delta_c / self.sigma) ** 2 @cached_quantity def nu_fn(self): r""" The parameter :math:`\nu = \left(\frac{\delta_c}{\sigma}\right)^2`, ``len=len(m)`` - as a callable function + as a callable function. """ return spline(self.m, self.nu, k=5) @@ -407,21 +405,22 @@ def nu_fn(self): def mass_nonlinear(self): """The nonlinear mass, nu(Mstar) = 1.""" if self.nu.min() > 1 or self.nu.max() < 1: - warnings.warn("Nonlinear mass outside mass range") + warnings.warn("Nonlinear mass outside mass range", stacklevel=2) if self.nu.min() > 1: startr = np.log(self.radii.min()) else: startr = np.log(self.radii.max()) - model = lambda lnr: ( - ( - self.filter.sigma(np.exp(lnr)) - * self._normalisation - * self.growth_factor - - self.delta_c - ) - ** 2 - ) + def model(lnr): + return ( + ( + self.filter.sigma(np.exp(lnr)) + * self._normalisation + * self.growth_factor + - self.delta_c + ) + ** 2 + ) res = minimize( model, @@ -433,7 +432,7 @@ def mass_nonlinear(self): if res.success: r = np.exp(res.x[0]) return self.filter.radius_to_mass(r, self.mean_density0) - warnings.warn("Minimization failed :(") + warnings.warn("Minimization failed :(", stacklevel=2) return 0 nu = spline(self.nu, self.m, k=5) return nu(1) @@ -446,7 +445,7 @@ def lnsigma(self): @cached_quantity def n_eff(self): """ - Effective spectral index at scale of halo radius, ``len=len(m)`` + Effective spectral index at scale of halo radius, ``len=len(m)``. Notes ----- @@ -461,24 +460,18 @@ def n_eff(self): @cached_quantity def n_eff_at_collapse(self): - """ - Effective spectral index at scale of halo radius at halo collapse. - """ + """Effective spectral index at scale of halo radius at halo collapse.""" fnc = spline(self.nu, self.n_eff) return fnc(1) @cached_quantity def fsigma(self): - r""" - The multiplicity function, :math:`f(\sigma)`, for `hmf_model`. ``len=len(m)`` - """ + r"""The multiplicity function, :math:`f(\sigma)`, for `hmf_model`. ``len=len(m)``.""" return self.hmf.fsigma @cached_quantity def dndm(self): - r""" - The number density of haloes, ``len=len(m)`` [units :math:`h^4 M_\odot^{-1} Mpc^{-3}`] - """ + r"""The number density of haloes, ``len=len(m)`` [units :math:`h^4 M_\odot^{-1} Mpc^{-3}`].""" # if self.z2 is None: # #This is normally the case dndm = self.fsigma * self.mean_density0 * np.abs(self._dlnsdlnm) / self.m**2 if isinstance(self.hmf, ff.Behroozi): @@ -507,21 +500,17 @@ def dndm(self): @cached_quantity def dndlnm(self): - r""" - The differential mass function in terms of natural log of `m`, ``len=len(m)`` [units :math:`h^3 Mpc^{-3}`] - """ + r"""The differential mass function in terms of natural log of `m`, ``len=len(m)`` [units :math:`h^3 Mpc^{-3}`].""" return self.m * self.dndm @cached_quantity def dndlog10m(self): - r""" - The differential mass function in terms of log of `m`, ``len=len(m)`` [units :math:`h^3 Mpc^{-3}`] - """ + r"""The differential mass function in terms of log of `m`, ``len=len(m)`` [units :math:`h^3 Mpc^{-3}`].""" return self.m * self.dndm * np.log(10) def _gtm(self, dndm, mass_density=False): """ - Calculate number or mass density above mass thresholds in `m` + Calculate number or mass density above mass thresholds in `m`. This function is here, separate from the properties, due to its need of being passed ``dndm`` in the case of the :class:`~fitting_functions.Behroozi` @@ -541,7 +530,7 @@ def _gtm(self, dndm, mass_density=False): # If the highest mass is very low, we try calculating it to higher masses # The dlog10m is NOT CHANGED, so the input needs to be finely spaced. # If the top value of dndm is NaN, don't try calculating higher masses. - if m[-1] < 10**16.5 and not np.isnan(dndm[-1]) and not dndm[-1] == 0: + if m[-1] < 10**16.5 and not np.isnan(dndm[-1]) and dndm[-1] != 0: # ff.Behroozi function won't work here. if not isinstance(self.hmf, ff.Behroozi): new_mf = copy.deepcopy(self) @@ -566,7 +555,7 @@ def _gtm(self, dndm, mass_density=False): @cached_quantity def ngtm(self): r""" - The cumulative mass function above `m`, ``len=len(m)`` [units :math:`h^3 Mpc^{-3}`] + The cumulative mass function above `m`, ``len=len(m)`` [units :math:`h^3 Mpc^{-3}`]. In the case that `m` does not extend to sufficiently high masses, this routine will auto-generate ``dndm`` for an extended mass range. @@ -580,7 +569,7 @@ def ngtm(self): @cached_quantity def rho_gtm(self): r""" - Mass density in haloes `>m`, ``len=len(m)`` [units :math:`M_\odot h^2 Mpc^{-3}`] + Mass density in haloes `>m`, ``len=len(m)`` [units :math:`M_\odot h^2 Mpc^{-3}`]. In the case that `m` does not extend to sufficiently high masses, this routine will auto-generate ``dndm`` for an extended mass range. @@ -594,7 +583,7 @@ def rho_gtm(self): @cached_quantity def rho_ltm(self): r""" - Mass density in haloes ` Path: return tmp_path_factory.mktemp("cli-tests") diff --git a/tests/test_fcoll.py b/tests/test_fcoll.py index 95ca4b06..fcfeb9ca 100644 --- a/tests/test_fcoll.py +++ b/tests/test_fcoll.py @@ -11,7 +11,7 @@ from hmf import MassFunction -@pytest.fixture(scope="function") +@pytest.fixture def getmf(request): # Note: if Mmax>15, starts going wrong because of numerics at high M return MassFunction(Mmin=10, Mmax=15, dlog10m=0.01, transfer_model="EH") @@ -55,7 +55,7 @@ def peacock(self): return MassFunction(hmf_model="Peacock", dlog10m=0.01, transfer_model="EH") @pytest.mark.parametrize( - ["Mmin", "Mmax"], + ("Mmin", "Mmax"), [ (9, 14), (9, 15), diff --git a/tests/test_filters.py b/tests/test_filters.py index 3331e798..7770adfd 100644 --- a/tests/test_filters.py +++ b/tests/test_filters.py @@ -1,6 +1,4 @@ -""" -Analytic functions for this test are defined in "analytic_filter.ipynb" in the development/ directory. -""" +"""Analytic functions for this test are defined in "analytic_filter.ipynb" in the development/ directory.""" import warnings diff --git a/tests/test_fits.py b/tests/test_fits.py index 37985c92..5b1c858d 100644 --- a/tests/test_fits.py +++ b/tests/test_fits.py @@ -46,13 +46,13 @@ def ps_max(hmf): return hmf.fsigma.max() -@pytest.mark.parametrize("redshift, fit", itertools.product([0.0, 2.0], allfits)) +@pytest.mark.parametrize(("redshift", "fit"), itertools.product([0.0, 2.0], allfits)) def test_allfits(hmf, ps_max, redshift, fit): """ This basically tests all implemented fits to check the form for three things: 1) whether the maximum fsigma is less than in the PS formula (which is known to overestimate) 2) whether the slope is positive below this maximum - 3) whether the slope is negative above this maximum + 3) whether the slope is negative above this maximum. Since it calls each class, any blatant errors should also pop up. """ diff --git a/tests/test_genmf.py b/tests/test_genmf.py index 5bde3a5d..1039fcee 100644 --- a/tests/test_genmf.py +++ b/tests/test_genmf.py @@ -1,5 +1,5 @@ """ -This module contains a number of tests that check hmf's results against those of genmf +This module contains a number of tests that check hmf's results against those of genmf. We check results for sigma, lnsigma, and the differential and cumulative mass functions against genmf for two different redshifts (0 and 2). We use precisely the same transfer function here @@ -109,7 +109,7 @@ def hmf(self): @staticmethod def check_col(pert, fit, redshift, col): - """Able to check all columns""" + """Able to check all columns.""" data = np.genfromtxt("tests/data/" + fit + "_" + str(int(redshift)))[::-1][ 400:1201 ] @@ -132,7 +132,7 @@ def check_col(pert, fit, redshift, col): assert rms_diff(pert.ngtm, 10 ** data[:, 2], 0.047) @pytest.mark.parametrize( - ["redshift", "col"], + ("redshift", "col"), [ (0.0, "sigma"), (0.0, "lnsigma"), @@ -148,7 +148,7 @@ def test_sigmas(self, hmf, redshift, col): self.check_col(hmf, "ST", redshift, col) @pytest.mark.parametrize( - ["redshift", "fit", "col"], + ("redshift", "fit", "col"), product( [0.0, 2.0], ["ST", "PS", "Reed03", "Warren", "Jenkins", "Reed07"], diff --git a/tests/test_mdef.py b/tests/test_mdef.py index f127a979..698489fb 100644 --- a/tests/test_mdef.py +++ b/tests/test_mdef.py @@ -11,7 +11,7 @@ # Set COLOSSUS cosmology -@pytest.fixture(scope="function") +@pytest.fixture def colossus_cosmo(): setCosmology("planck15") diff --git a/tests/test_transfer.py b/tests/test_transfer.py index 316994a4..5fa2e068 100644 --- a/tests/test_transfer.py +++ b/tests/test_transfer.py @@ -12,10 +12,7 @@ def transfers(): @pytest.mark.parametrize( - [ - "name", - "val", - ], + ("name", "val"), [("z", 0.1), ("sigma_8", 0.82), ("n", 0.95), ("cosmo_params", {"H0": 68.0})], ) def test_updates(transfers, name, val): @@ -23,7 +20,9 @@ def test_updates(transfers, name, val): t.update(**{name: val}) assert ( np.mean(np.abs((t.power - t2.power) / t.power)) < 1 - and np.mean(np.abs((t.power - t2.power) / t.power)) > 1e-6 + ) + assert ( + np.mean(np.abs((t.power - t2.power) / t.power)) > 1e-6 ) @@ -39,7 +38,9 @@ def test_updates_from_file_array(datadir): # This test for both FromArray transfer model and caching of dictionaries assert ( np.mean(np.abs((t.power - t2.power) / t.power)) < 1 - and np.mean(np.abs((t.power - t2.power) / t.power)) > 1e-6 + ) + assert ( + np.mean(np.abs((t.power - t2.power) / t.power)) > 1e-6 ) From 0677808fc86b68ddca4149b63312e84d97783ddf Mon Sep 17 00:00:00 2001 From: Steven Murray Date: Sun, 22 Feb 2026 14:17:21 +0200 Subject: [PATCH 03/18] style: fix transfer test --- tests/test_transfer.py | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/tests/test_transfer.py b/tests/test_transfer.py index 5fa2e068..e28ce3c3 100644 --- a/tests/test_transfer.py +++ b/tests/test_transfer.py @@ -178,7 +178,7 @@ def test_camb_w0wa(): assert t.transfer_function.shape == t.k.shape -def test_camb_wCDM(): +def test_camb_wcdm(): """Essentially just test that CAMB doesn't fall over with a w0wa model.""" t = Transfer( transfer_model="CAMB", @@ -195,17 +195,19 @@ def test_camb_wCDM(): def test_camb_unset_params(): - with pytest.raises(ValueError): - Transfer( - transfer_model="CAMB", - cosmo_model=w0waCDM(Om0=0.3, Ode0=0.7, w0=-1, wa=0.03, Ob0=0.05, H0=70.0), - ).transfer - - with pytest.raises(ValueError): - Transfer( - transfer_model="CAMB", - cosmo_model=w0waCDM(Om0=0.3, Ode0=0.7, w0=-1, wa=0.03, H0=70.0, Tcmb0=2.7), - ).transfer + t = Transfer( + transfer_model="CAMB", + cosmo_model=w0waCDM(Om0=0.3, Ode0=0.7, w0=-1, wa=0.03, Ob0=0.05, H0=70.0), + ) + with pytest.raises(ValueError, match="the CMB temperature must be set explicitly"): + t.transfer + + t = Transfer( + transfer_model="CAMB", + cosmo_model=w0waCDM(Om0=0.3, Ode0=0.7, w0=-1, wa=0.03, H0=70.0, Tcmb0=2.7), + ) + with pytest.raises(ValueError, match="you must set the baryon density"): + t.transfer def test_bbks_sugiyama(): From c21d50773f7afcfccb1ae6fb3ec6d749d1d4b098 Mon Sep 17 00:00:00 2001 From: Steven Murray Date: Sun, 22 Feb 2026 14:49:58 +0200 Subject: [PATCH 04/18] style: docstrings --- changethelog.py | 9 +- docs/conf.py | 3 +- ruff_failures.txt | 6924 ++++++++++++++++++++ src/hmf/__init__.py | 30 + src/hmf/_cli.py | 4 +- src/hmf/_internals/__init__.py | 12 + src/hmf/_internals/_cache.py | 7 +- src/hmf/_internals/_framework.py | 15 +- src/hmf/alternatives/__init__.py | 7 +- src/hmf/alternatives/wdm.py | 14 +- src/hmf/cosmology/__init__.py | 7 + src/hmf/cosmology/cosmo.py | 28 +- src/hmf/cosmology/growth_factor.py | 36 +- src/hmf/density_field/__init__.py | 17 +- src/hmf/density_field/filters.py | 5 +- src/hmf/density_field/halofit.py | 9 +- src/hmf/density_field/transfer.py | 4 +- src/hmf/density_field/transfer_models.py | 13 +- src/hmf/halos/__init__.py | 10 +- src/hmf/halos/mass_definitions.py | 19 +- src/hmf/helpers/__init__.py | 7 + src/hmf/helpers/cfg_utils.py | 4 +- src/hmf/mass_function/__init__.py | 11 + src/hmf/mass_function/fitting_functions.py | 58 +- src/hmf/mass_function/hmf.py | 19 +- tests/test_cli.py | 6 +- tests/test_fits.py | 11 +- 27 files changed, 7172 insertions(+), 117 deletions(-) create mode 100644 ruff_failures.txt diff --git a/changethelog.py b/changethelog.py index c3335c8a..02b7aac4 100644 --- a/changethelog.py +++ b/changethelog.py @@ -2,12 +2,13 @@ """Automatically update changelog.""" import sys -from datetime import datetime +from datetime import datetime, timezone +from pathlib import Path if __name__ == "__main__": newversion = sys.argv[1] - with open("CHANGELOG.rst") as fl: + with Path("CHANGELOG.rst").open() as fl: lines = fl.readlines() for _i, line in enumerate(lines): @@ -17,8 +18,8 @@ raise OSError("Couldn't Find 'dev-version' tag") lines.insert(_i + 2, "----------------------\n") - lines.insert(_i + 2, f"v{newversion} [{datetime.now().strftime('%d %b %Y')}]\n") + lines.insert(_i + 2, f"v{newversion} [{datetime.now(tz=timezone.utc).strftime('%d %b %Y')}]\n") lines.insert(_i + 2, "\n") - with open("CHANGELOG.rst", "w") as fl: + with Path("CHANGELOG.rst").open("w") as fl: fl.writelines(lines) diff --git a/docs/conf.py b/docs/conf.py index 53f6e361..136379fd 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -13,13 +13,14 @@ import os import sys import time +from pathlib import Path from importlib_metadata import version as _version # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. -sys.path.insert(0, os.path.abspath("../")) +sys.path.insert(0, str(Path("../").resolve())) # -- General configuration ----------------------------------------------------- diff --git a/ruff_failures.txt b/ruff_failures.txt new file mode 100644 index 00000000..092879d2 --- /dev/null +++ b/ruff_failures.txt @@ -0,0 +1,6924 @@ +PTH123 `open()` should be replaced by `Path.open()` + --> changethelog.py:10:10 + | + 8 | newversion = sys.argv[1] + 9 | +10 | with open("CHANGELOG.rst") as fl: + | ^^^^ +11 | lines = fl.readlines() + | +help: Replace with `Path.open()` + +DTZ005 `datetime.datetime.now()` called without a `tz` argument + --> changethelog.py:20:44 + | +19 | lines.insert(_i + 2, "----------------------\n") +20 | lines.insert(_i + 2, f"v{newversion} [{datetime.now().strftime('%d %b %Y')}]\n") + | ^^^^^^^^^^^^^^ +21 | lines.insert(_i + 2, "\n") + | +help: Pass a `datetime.timezone` object to the `tz` parameter + +PTH123 `open()` should be replaced by `Path.open()` + --> changethelog.py:23:10 + | +21 | lines.insert(_i + 2, "\n") +22 | +23 | with open("CHANGELOG.rst", "w") as fl: + | ^^^^ +24 | fl.writelines(lines) + | +help: Replace with `Path.open()` + +invalid-syntax: Simple statements must be separated by newlines or semicolons + --> development/analytic_filter.ipynb:cell 4:7:11 + | +5 | integ = integ.subs(x,k*R) +6 | res = integrate(integ,(k,kmin,kmax)) +7 | print res + | ^^^ +8 | return res + | + +invalid-syntax: Simple statements must be separated by newlines or semicolons + --> development/analytic_filter.ipynb:cell 4:19:11 + | +17 | s = sigma(W,0,p,kmin,kmax) +18 | res = integrate(integ,(k,kmin,kmax))/(pi**2*s) +19 | print res + | ^^^ +20 | return res + | + +E501 Line too long (150 > 88) + --> development/halofit_testing.ipynb:cell 9:95:89 + | +93 | …kahashi=True +94 | … +95 | …, sigma_8, zbin, cosmo=my_cosmo, takahashi=True) #Generate (?) non-linear no-wiggles with halofit + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + +D100 Missing docstring in public module +--> docs/conf.py:1:1 + +PTH100 `os.path.abspath()` should be replaced by `Path.resolve()` + --> docs/conf.py:22:20 + | +20 | # add these directories to sys.path here. If the directory is relative to the +21 | # documentation root, use os.path.abspath to make it absolute, like shown here. +22 | sys.path.insert(0, os.path.abspath("../")) + | ^^^^^^^^^^^^^^^ +23 | +24 | # -- General configuration ----------------------------------------------------- + | +help: Replace with `Path(...).resolve()` + +E501 Line too long (112 > 88) + --> docs/examples/broad_overview.ipynb:cell 5:2:89 + | +1 | from hmf import ( +2 | density_field, # Defines power spectra and transfer functions, as well as window functions/filters on those + | ^^^^^^^^^^^^^^^^^^^^^^^^ +3 | ) + | + +NPY002 Replace legacy `np.random.uniform` call with `np.random.Generator` + --> docs/examples/broad_overview.ipynb:cell 28:1:13 + | +1 | redshifts = np.random.uniform(0, 3, size=20) + | ^^^^^^^^^^^^^^^^^ + | + +invalid-syntax: Simple statements must be separated by newlines or semicolons + --> docs/examples/deal_with_cosmology.ipynb:cell 8:1:7 + | +1 | print "Matter density: ", my_cosmo.cosmo.Om0 + | ^^^^^^^^^^^^^^^^^^ +2 | print "Hubble constant: ", my_cosmo.cosmo.H0 +3 | print "Dark Energy density: ", my_cosmo.cosmo.Ode0 + | + +invalid-syntax: Simple statements must be separated by newlines or semicolons + --> docs/examples/deal_with_cosmology.ipynb:cell 8:2:7 + | +1 | print "Matter density: ", my_cosmo.cosmo.Om0 +2 | print "Hubble constant: ", my_cosmo.cosmo.H0 + | ^^^^^^^^^^^^^^^^^^^ +3 | print "Dark Energy density: ", my_cosmo.cosmo.Ode0 +4 | print "Baryon density: ", my_cosmo.cosmo.Ob0 + | + +invalid-syntax: Simple statements must be separated by newlines or semicolons + --> docs/examples/deal_with_cosmology.ipynb:cell 8:3:7 + | +1 | print "Matter density: ", my_cosmo.cosmo.Om0 +2 | print "Hubble constant: ", my_cosmo.cosmo.H0 +3 | print "Dark Energy density: ", my_cosmo.cosmo.Ode0 + | ^^^^^^^^^^^^^^^^^^^^^^^ +4 | print "Baryon density: ", my_cosmo.cosmo.Ob0 +5 | print "Curvature density: ", my_cosmo.cosmo.Ok0 + | + +invalid-syntax: Simple statements must be separated by newlines or semicolons + --> docs/examples/deal_with_cosmology.ipynb:cell 8:4:7 + | +2 | print "Hubble constant: ", my_cosmo.cosmo.H0 +3 | print "Dark Energy density: ", my_cosmo.cosmo.Ode0 +4 | print "Baryon density: ", my_cosmo.cosmo.Ob0 + | ^^^^^^^^^^^^^^^^^^ +5 | print "Curvature density: ", my_cosmo.cosmo.Ok0 + | + +invalid-syntax: Simple statements must be separated by newlines or semicolons + --> docs/examples/deal_with_cosmology.ipynb:cell 8:5:7 + | +3 | print "Dark Energy density: ", my_cosmo.cosmo.Ode0 +4 | print "Baryon density: ", my_cosmo.cosmo.Ob0 +5 | print "Curvature density: ", my_cosmo.cosmo.Ok0 + | ^^^^^^^^^^^^^^^^^^^^^ + | + +invalid-syntax: Simple statements must be separated by newlines or semicolons + --> docs/examples/deal_with_cosmology.ipynb:cell 13:3:7 + | +1 | my_cosmo = cosmo.Cosmology(cosmo_model=cosmo.WMAP5) +2 | +3 | print "WMAP5 baryon density: ", my_cosmo.cosmo.Ob0 + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + +invalid-syntax: Simple statements must be separated by newlines or semicolons + --> docs/examples/deal_with_cosmology.ipynb:cell 17:2:7 + | +1 | my_cosmo = cosmo.Cosmology(cosmo_model = new_model) +2 | print "Crazy cosmology baryon density: ", my_cosmo.cosmo.Ob0 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + +invalid-syntax: Simple statements must be separated by newlines or semicolons + --> docs/examples/deal_with_cosmology.ipynb:cell 19:5:7 + | +4 | my_cosmo = cosmo.Cosmology(cosmo_model = new_model) +5 | print "Crazy cosmology curvature density: ", my_cosmo.cosmo.Ok0 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + +invalid-syntax: Simple statements must be separated by newlines or semicolons + --> docs/examples/deal_with_cosmology.ipynb:cell 22:2:7 + | +1 | my_cosmo = cosmo.Cosmology(cosmo_params={"Om0":0.2}) +2 | print "Custom cosmology matter density: ", my_cosmo.cosmo.Om0 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + +invalid-syntax: Simple statements must be separated by newlines or semicolons + --> docs/examples/deal_with_cosmology.ipynb:cell 24:2:7 + | +1 | my_cosmo = cosmo.Cosmology(new_model,{"Om0":0.2,"Ode0":0.0,"Ob0":0.2}) +2 | print "Custom cosmology curvature density: ", my_cosmo.cosmo.Ok0 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + +invalid-syntax: Simple statements must be separated by newlines or semicolons + --> docs/examples/deal_with_cosmology.ipynb:cell 27:3:7 + | +1 | my_cosmo = cosmo.Cosmology(new_model) +2 | my_cosmo.update(cosmo_params={"Om0":0.2,"Ode0":0.0,"Ob0":0.2}) +3 | print "Custom cosmology curvature density: ", my_cosmo.cosmo.Ok0 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + +invalid-syntax: Simple statements must be separated by newlines or semicolons + --> docs/examples/deal_with_cosmology.ipynb:cell 29:2:7 + | +1 | my_cosmo.update(cosmo_params={"H0":10.0}) +2 | print "Custom cosmology curvature density: ", my_cosmo.cosmo.Ok0 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +3 | print "Custom parameters: ", my_cosmo.cosmo_params + | + +invalid-syntax: Simple statements must be separated by newlines or semicolons + --> docs/examples/deal_with_cosmology.ipynb:cell 29:3:7 + | +1 | my_cosmo.update(cosmo_params={"H0":10.0}) +2 | print "Custom cosmology curvature density: ", my_cosmo.cosmo.Ok0 +3 | print "Custom parameters: ", my_cosmo.cosmo_params + | ^^^^^^^^^^^^^^^^^^^^^ + | + +invalid-syntax: Simple statements must be separated by newlines or semicolons + --> docs/examples/deal_with_cosmology.ipynb:cell 31:2:7 + | +1 | my_cosmo.update(cosmo_model=cosmo.Planck13,cosmo_params={}) +2 | print "Flat cosmology curvature density: ", my_cosmo.cosmo.Ok0 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + +A004 Import `display` is shadowing a Python builtin + --> docs/examples/fitting.ipynb:cell 3:6:39 + | +4 | import matplotlib.pyplot as plt +5 | import numpy as np +6 | from IPython.display import Markdown, display + | ^^^^^^^ +7 | from scipy.stats import poisson + | + +NPY002 Replace legacy `np.random.poisson` call with `np.random.Generator` + --> docs/examples/fitting.ipynb:cell 11:1:18 + | +1 | counts_per_bin = np.random.poisson(model.dndlog10m * volume * model.dlog10m) + | ^^^^^^^^^^^^^^^^^ + | + +NPY002 Replace legacy `np.random.normal` call with `np.random.Generator` + --> docs/examples/fitting.ipynb:cell 32:3:12 + | +1 | initialpos = np.array( +2 | [fiducial_model.sigma_8, fiducial_model.n] +3 | ) + 1e-4 * np.random.normal(size=(sampler.nwalkers, sampler.ndim)) + | ^^^^^^^^^^^^^^^^ + | + +NPY002 Replace legacy `np.random.poisson` call with `np.random.Generator` + --> docs/examples/fitting.ipynb:cell 45:3:18 + | +1 | volume = 500**3 # Mpc^3 / h^3 +2 | +3 | counts_per_bin = np.random.poisson( + | ^^^^^^^^^^^^^^^^^ +4 | fiducial_model.dndlog10m * volume * fiducial_model.dlog10m +5 | ) + | + +NPY002 Replace legacy `np.random.normal` call with `np.random.Generator` + --> docs/examples/fitting.ipynb:cell 49:3:12 + | +1 | init_pos = np.array( +2 | [smt_model.hmf.params["a"], smt_model.hmf.params["p"], smt_model.hmf.params["A"]] +3 | ) + 1e-4 * np.random.normal(size=(sampler_hmf.nwalkers, sampler_hmf.ndim)) + | ^^^^^^^^^^^^^^^^ + | + +RUF012 Mutable default value for class attribute + --> docs/examples/plugins_and_extending.ipynb:cell 25:2:17 + | +1 | class MyNewFitParameterized(FittingFunction): +2 | _defaults = {"a": 0.5} + | ^^^^^^^^^^ +3 | +4 | @property + | +help: Consider initializing in `__init__` or annotating with `typing.ClassVar` + +W291 Trailing whitespace + --> docs/examples/your_first_plot.ipynb:cell 3:6:19 + | +5 | # This just serves to render plots inline in the notebook. Do not use in a script. +6 | %matplotlib inline + | ^^^^^^^^^^^^^^^ + | +help: Remove trailing whitespace + +E501 Line too long (154 > 88) + --> docs/examples/your_first_plot.ipynb:cell 7:1:89 + | +1 | … #The parameter names passed filter the output. Call with no parameters to get info on all of them. + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + +invalid-syntax: Simple statements must be separated by newlines or semicolons + --> docs/examples/your_first_plot.ipynb:cell 11:1:7 + | +1 | print mf.quantities_available() + | ^^ + | + +E501 Line too long (135 > 88) + --> docs/examples/your_first_plot.ipynb:cell 19:1:89 + | +1 | mf = MassFunction(cosmo_model="WMAP5") # Note how to set all cosmological parameters (except sigma_8 and n) to a given common cosmology + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +2 | +3 | for z in np.linspace(0,1,100): + | + +W293 Blank line contains whitespace + --> docs/examples/your_first_plot.ipynb:cell 19:6:1 + | +4 | mf.update(z=z) +5 | plt.plot(mf.m,mf.dndm,color="darkblue",alpha=1-z) +6 | + | ^^^^ +7 | plt.xscale('log') +8 | plt.yscale('log') + | +help: Remove whitespace from blank line + +SIM105 Use `contextlib.suppress(PackageNotFoundError)` instead of `try`-`except`-`pass` + --> src/hmf/__init__.py:8:1 + | + 6 | from importlib_metadata import PackageNotFoundError, version + 7 | + 8 | / try: + 9 | | __version__ = version(__name__) +10 | | except PackageNotFoundError: +11 | | # package is not installed +12 | | pass + | |________^ +13 | +14 | from ._internals import ( + | +help: Replace `try`-`except`-`pass` with `with contextlib.suppress(PackageNotFoundError): ...` + +F401 `._internals.Component` imported but unused; consider removing, adding to `__all__`, or using a redundant alias + --> src/hmf/__init__.py:15:5 + | +14 | from ._internals import ( +15 | Component, + | ^^^^^^^^^ +16 | Framework, +17 | cached_quantity, + | +help: Use an explicit re-export: `Component as Component` + +F401 `._internals.Framework` imported but unused; consider removing, adding to `__all__`, or using a redundant alias + --> src/hmf/__init__.py:16:5 + | +14 | from ._internals import ( +15 | Component, +16 | Framework, + | ^^^^^^^^^ +17 | cached_quantity, +18 | get_base_component, + | +help: Use an explicit re-export: `Framework as Framework` + +F401 `._internals.cached_quantity` imported but unused; consider removing, adding to `__all__`, or using a redundant alias + --> src/hmf/__init__.py:17:5 + | +15 | Component, +16 | Framework, +17 | cached_quantity, + | ^^^^^^^^^^^^^^^ +18 | get_base_component, +19 | get_base_components, + | +help: Use an explicit re-export: `cached_quantity as cached_quantity` + +F401 `._internals.get_base_component` imported but unused; consider removing, adding to `__all__`, or using a redundant alias + --> src/hmf/__init__.py:18:5 + | +16 | Framework, +17 | cached_quantity, +18 | get_base_component, + | ^^^^^^^^^^^^^^^^^^ +19 | get_base_components, +20 | get_mdl, + | +help: Use an explicit re-export: `get_base_component as get_base_component` + +F401 `._internals.get_base_components` imported but unused; consider removing, adding to `__all__`, or using a redundant alias + --> src/hmf/__init__.py:19:5 + | +17 | cached_quantity, +18 | get_base_component, +19 | get_base_components, + | ^^^^^^^^^^^^^^^^^^^ +20 | get_mdl, +21 | parameter, + | +help: Use an explicit re-export: `get_base_components as get_base_components` + +F401 `._internals.get_mdl` imported but unused; consider removing, adding to `__all__`, or using a redundant alias + --> src/hmf/__init__.py:20:5 + | +18 | get_base_component, +19 | get_base_components, +20 | get_mdl, + | ^^^^^^^ +21 | parameter, +22 | ) + | +help: Use an explicit re-export: `get_mdl as get_mdl` + +F401 `._internals.parameter` imported but unused; consider removing, adding to `__all__`, or using a redundant alias + --> src/hmf/__init__.py:21:5 + | +19 | get_base_components, +20 | get_mdl, +21 | parameter, + | ^^^^^^^^^ +22 | ) +23 | from .alternatives import wdm + | +help: Use an explicit re-export: `parameter as parameter` + +F401 `.alternatives.wdm` imported but unused; consider removing, adding to `__all__`, or using a redundant alias + --> src/hmf/__init__.py:23:27 + | +21 | parameter, +22 | ) +23 | from .alternatives import wdm + | ^^^ +24 | from .cosmology import Cosmology, GrowthFactor, cosmo, growth_factor +25 | from .density_field import CAMB, Transfer, filters, halofit, transfer, transfer_models + | +help: Use an explicit re-export: `wdm as wdm` + +F401 `.cosmology.Cosmology` imported but unused; consider removing, adding to `__all__`, or using a redundant alias + --> src/hmf/__init__.py:24:24 + | +22 | ) +23 | from .alternatives import wdm +24 | from .cosmology import Cosmology, GrowthFactor, cosmo, growth_factor + | ^^^^^^^^^ +25 | from .density_field import CAMB, Transfer, filters, halofit, transfer, transfer_models +26 | from .halos import mass_definitions + | +help: Use an explicit re-export: `Cosmology as Cosmology` + +F401 `.cosmology.GrowthFactor` imported but unused; consider removing, adding to `__all__`, or using a redundant alias + --> src/hmf/__init__.py:24:35 + | +22 | ) +23 | from .alternatives import wdm +24 | from .cosmology import Cosmology, GrowthFactor, cosmo, growth_factor + | ^^^^^^^^^^^^ +25 | from .density_field import CAMB, Transfer, filters, halofit, transfer, transfer_models +26 | from .halos import mass_definitions + | +help: Use an explicit re-export: `GrowthFactor as GrowthFactor` + +F401 `.cosmology.cosmo` imported but unused; consider removing, adding to `__all__`, or using a redundant alias + --> src/hmf/__init__.py:24:49 + | +22 | ) +23 | from .alternatives import wdm +24 | from .cosmology import Cosmology, GrowthFactor, cosmo, growth_factor + | ^^^^^ +25 | from .density_field import CAMB, Transfer, filters, halofit, transfer, transfer_models +26 | from .halos import mass_definitions + | +help: Use an explicit re-export: `cosmo as cosmo` + +F401 `.cosmology.growth_factor` imported but unused; consider removing, adding to `__all__`, or using a redundant alias + --> src/hmf/__init__.py:24:56 + | +22 | ) +23 | from .alternatives import wdm +24 | from .cosmology import Cosmology, GrowthFactor, cosmo, growth_factor + | ^^^^^^^^^^^^^ +25 | from .density_field import CAMB, Transfer, filters, halofit, transfer, transfer_models +26 | from .halos import mass_definitions + | +help: Use an explicit re-export: `growth_factor as growth_factor` + +F401 `.density_field.CAMB` imported but unused; consider removing, adding to `__all__`, or using a redundant alias + --> src/hmf/__init__.py:25:28 + | +23 | from .alternatives import wdm +24 | from .cosmology import Cosmology, GrowthFactor, cosmo, growth_factor +25 | from .density_field import CAMB, Transfer, filters, halofit, transfer, transfer_models + | ^^^^ +26 | from .halos import mass_definitions +27 | from .helpers import functional, get_best_param_order, get_hmf, sample + | +help: Use an explicit re-export: `CAMB as CAMB` + +F401 `.density_field.Transfer` imported but unused; consider removing, adding to `__all__`, or using a redundant alias + --> src/hmf/__init__.py:25:34 + | +23 | from .alternatives import wdm +24 | from .cosmology import Cosmology, GrowthFactor, cosmo, growth_factor +25 | from .density_field import CAMB, Transfer, filters, halofit, transfer, transfer_models + | ^^^^^^^^ +26 | from .halos import mass_definitions +27 | from .helpers import functional, get_best_param_order, get_hmf, sample + | +help: Use an explicit re-export: `Transfer as Transfer` + +F401 `.density_field.filters` imported but unused; consider removing, adding to `__all__`, or using a redundant alias + --> src/hmf/__init__.py:25:44 + | +23 | from .alternatives import wdm +24 | from .cosmology import Cosmology, GrowthFactor, cosmo, growth_factor +25 | from .density_field import CAMB, Transfer, filters, halofit, transfer, transfer_models + | ^^^^^^^ +26 | from .halos import mass_definitions +27 | from .helpers import functional, get_best_param_order, get_hmf, sample + | +help: Use an explicit re-export: `filters as filters` + +F401 `.density_field.halofit` imported but unused; consider removing, adding to `__all__`, or using a redundant alias + --> src/hmf/__init__.py:25:53 + | +23 | from .alternatives import wdm +24 | from .cosmology import Cosmology, GrowthFactor, cosmo, growth_factor +25 | from .density_field import CAMB, Transfer, filters, halofit, transfer, transfer_models + | ^^^^^^^ +26 | from .halos import mass_definitions +27 | from .helpers import functional, get_best_param_order, get_hmf, sample + | +help: Use an explicit re-export: `halofit as halofit` + +F401 `.density_field.transfer` imported but unused; consider removing, adding to `__all__`, or using a redundant alias + --> src/hmf/__init__.py:25:62 + | +23 | from .alternatives import wdm +24 | from .cosmology import Cosmology, GrowthFactor, cosmo, growth_factor +25 | from .density_field import CAMB, Transfer, filters, halofit, transfer, transfer_models + | ^^^^^^^^ +26 | from .halos import mass_definitions +27 | from .helpers import functional, get_best_param_order, get_hmf, sample + | +help: Use an explicit re-export: `transfer as transfer` + +F401 `.density_field.transfer_models` imported but unused; consider removing, adding to `__all__`, or using a redundant alias + --> src/hmf/__init__.py:25:72 + | +23 | from .alternatives import wdm +24 | from .cosmology import Cosmology, GrowthFactor, cosmo, growth_factor +25 | from .density_field import CAMB, Transfer, filters, halofit, transfer, transfer_models + | ^^^^^^^^^^^^^^^ +26 | from .halos import mass_definitions +27 | from .helpers import functional, get_best_param_order, get_hmf, sample + | +help: Use an explicit re-export: `transfer_models as transfer_models` + +F401 `.halos.mass_definitions` imported but unused; consider removing, adding to `__all__`, or using a redundant alias + --> src/hmf/__init__.py:26:20 + | +24 | from .cosmology import Cosmology, GrowthFactor, cosmo, growth_factor +25 | from .density_field import CAMB, Transfer, filters, halofit, transfer, transfer_models +26 | from .halos import mass_definitions + | ^^^^^^^^^^^^^^^^ +27 | from .helpers import functional, get_best_param_order, get_hmf, sample +28 | from .mass_function import MassFunction, fitting_functions, hmf, integrate_hmf + | +help: Use an explicit re-export: `mass_definitions as mass_definitions` + +F401 `.helpers.functional` imported but unused; consider removing, adding to `__all__`, or using a redundant alias + --> src/hmf/__init__.py:27:22 + | +25 | from .density_field import CAMB, Transfer, filters, halofit, transfer, transfer_models +26 | from .halos import mass_definitions +27 | from .helpers import functional, get_best_param_order, get_hmf, sample + | ^^^^^^^^^^ +28 | from .mass_function import MassFunction, fitting_functions, hmf, integrate_hmf + | +help: Use an explicit re-export: `functional as functional` + +F401 `.helpers.get_best_param_order` imported but unused; consider removing, adding to `__all__`, or using a redundant alias + --> src/hmf/__init__.py:27:34 + | +25 | from .density_field import CAMB, Transfer, filters, halofit, transfer, transfer_models +26 | from .halos import mass_definitions +27 | from .helpers import functional, get_best_param_order, get_hmf, sample + | ^^^^^^^^^^^^^^^^^^^^ +28 | from .mass_function import MassFunction, fitting_functions, hmf, integrate_hmf + | +help: Use an explicit re-export: `get_best_param_order as get_best_param_order` + +F401 `.helpers.get_hmf` imported but unused; consider removing, adding to `__all__`, or using a redundant alias + --> src/hmf/__init__.py:27:56 + | +25 | from .density_field import CAMB, Transfer, filters, halofit, transfer, transfer_models +26 | from .halos import mass_definitions +27 | from .helpers import functional, get_best_param_order, get_hmf, sample + | ^^^^^^^ +28 | from .mass_function import MassFunction, fitting_functions, hmf, integrate_hmf + | +help: Use an explicit re-export: `get_hmf as get_hmf` + +F401 `.helpers.sample` imported but unused; consider removing, adding to `__all__`, or using a redundant alias + --> src/hmf/__init__.py:27:65 + | +25 | from .density_field import CAMB, Transfer, filters, halofit, transfer, transfer_models +26 | from .halos import mass_definitions +27 | from .helpers import functional, get_best_param_order, get_hmf, sample + | ^^^^^^ +28 | from .mass_function import MassFunction, fitting_functions, hmf, integrate_hmf + | +help: Use an explicit re-export: `sample as sample` + +F401 `.mass_function.MassFunction` imported but unused; consider removing, adding to `__all__`, or using a redundant alias + --> src/hmf/__init__.py:28:28 + | +26 | from .halos import mass_definitions +27 | from .helpers import functional, get_best_param_order, get_hmf, sample +28 | from .mass_function import MassFunction, fitting_functions, hmf, integrate_hmf + | ^^^^^^^^^^^^ + | +help: Use an explicit re-export: `MassFunction as MassFunction` + +F401 `.mass_function.fitting_functions` imported but unused; consider removing, adding to `__all__`, or using a redundant alias + --> src/hmf/__init__.py:28:42 + | +26 | from .halos import mass_definitions +27 | from .helpers import functional, get_best_param_order, get_hmf, sample +28 | from .mass_function import MassFunction, fitting_functions, hmf, integrate_hmf + | ^^^^^^^^^^^^^^^^^ + | +help: Use an explicit re-export: `fitting_functions as fitting_functions` + +F401 `.mass_function.hmf` imported but unused; consider removing, adding to `__all__`, or using a redundant alias + --> src/hmf/__init__.py:28:61 + | +26 | from .halos import mass_definitions +27 | from .helpers import functional, get_best_param_order, get_hmf, sample +28 | from .mass_function import MassFunction, fitting_functions, hmf, integrate_hmf + | ^^^ + | +help: Use an explicit re-export: `hmf as hmf` + +F401 `.mass_function.integrate_hmf` imported but unused; consider removing, adding to `__all__`, or using a redundant alias + --> src/hmf/__init__.py:28:66 + | +26 | from .halos import mass_definitions +27 | from .helpers import functional, get_best_param_order, get_hmf, sample +28 | from .mass_function import MassFunction, fitting_functions, hmf, integrate_hmf + | ^^^^^^^^^^^^^ + | +help: Use an explicit re-export: `integrate_hmf as integrate_hmf` + +PTH123 `open()` should be replaced by `Path.open()` + --> src/hmf/_cli.py:29:10 + | +27 | return {} +28 | +29 | with open(config) as fl: + | ^^^^ +30 | cfg = toml.load(fl) + | +help: Replace with `Path.open()` + +PTH123 `open()` should be replaced by `Path.open()` + --> src/hmf/_cli.py:198:14 + | +196 | dct = framework_to_dict(obj) +197 | dct["quantities"] = quantities +198 | with open(outdir / f"{lab}_cfg.toml", "w") as fl: + | ^^^^ +199 | toml.dump(dct, fl, encoder=toml.TomlNumpyEncoder()) + | +help: Replace with `Path.open()` + +F401 `._cache.cached_quantity` imported but unused; consider removing, adding to `__all__`, or using a redundant alias + --> src/hmf/_internals/__init__.py:6:21 + | +4 | """ +5 | +6 | from ._cache import cached_quantity, parameter + | ^^^^^^^^^^^^^^^ +7 | from ._framework import ( +8 | Component, + | +help: Use an explicit re-export: `cached_quantity as cached_quantity` + +F401 `._cache.parameter` imported but unused; consider removing, adding to `__all__`, or using a redundant alias + --> src/hmf/_internals/__init__.py:6:38 + | +4 | """ +5 | +6 | from ._cache import cached_quantity, parameter + | ^^^^^^^^^ +7 | from ._framework import ( +8 | Component, + | +help: Use an explicit re-export: `parameter as parameter` + +F401 `._framework.Component` imported but unused; consider removing, adding to `__all__`, or using a redundant alias + --> src/hmf/_internals/__init__.py:8:5 + | + 6 | from ._cache import cached_quantity, parameter + 7 | from ._framework import ( + 8 | Component, + | ^^^^^^^^^ + 9 | Framework, +10 | get_base_component, + | +help: Use an explicit re-export: `Component as Component` + +F401 `._framework.Framework` imported but unused; consider removing, adding to `__all__`, or using a redundant alias + --> src/hmf/_internals/__init__.py:9:5 + | + 7 | from ._framework import ( + 8 | Component, + 9 | Framework, + | ^^^^^^^^^ +10 | get_base_component, +11 | get_base_components, + | +help: Use an explicit re-export: `Framework as Framework` + +F401 `._framework.get_base_component` imported but unused; consider removing, adding to `__all__`, or using a redundant alias + --> src/hmf/_internals/__init__.py:10:5 + | + 8 | Component, + 9 | Framework, +10 | get_base_component, + | ^^^^^^^^^^^^^^^^^^ +11 | get_base_components, +12 | get_mdl, + | +help: Use an explicit re-export: `get_base_component as get_base_component` + +F401 `._framework.get_base_components` imported but unused; consider removing, adding to `__all__`, or using a redundant alias + --> src/hmf/_internals/__init__.py:11:5 + | + 9 | Framework, +10 | get_base_component, +11 | get_base_components, + | ^^^^^^^^^^^^^^^^^^^ +12 | get_mdl, +13 | pluggable, + | +help: Use an explicit re-export: `get_base_components as get_base_components` + +F401 `._framework.get_mdl` imported but unused; consider removing, adding to `__all__`, or using a redundant alias + --> src/hmf/_internals/__init__.py:12:5 + | +10 | get_base_component, +11 | get_base_components, +12 | get_mdl, + | ^^^^^^^ +13 | pluggable, +14 | ) + | +help: Use an explicit re-export: `get_mdl as get_mdl` + +F401 `._framework.pluggable` imported but unused; consider removing, adding to `__all__`, or using a redundant alias + --> src/hmf/_internals/__init__.py:13:5 + | +11 | get_base_components, +12 | get_mdl, +13 | pluggable, + | ^^^^^^^^^ +14 | ) +15 | from ._utils import inherit_docstrings + | +help: Use an explicit re-export: `pluggable as pluggable` + +F401 `._utils.inherit_docstrings` imported but unused; consider removing, adding to `__all__`, or using a redundant alias + --> src/hmf/_internals/__init__.py:15:21 + | +13 | pluggable, +14 | ) +15 | from ._utils import inherit_docstrings + | ^^^^^^^^^^^^^^^^^^ + | +help: Use an explicit re-export: `inherit_docstrings as inherit_docstrings` + +D205 1 blank line required between summary line and description + --> src/hmf/_internals/_cache.py:1:1 + | + 1 | / """ + 2 | | This module defines two decorators, based on the code from + 3 | | http://forrst.com/posts/Yet_another_caching_property_decorator_for_Pytho-PBy. + 4 | | + 5 | | They are both designed to cache class properties, but have the added + 6 | | functionality of being automatically updated when a parent property is + 7 | | updated. + 8 | | """ + | |___^ + 9 | +10 | import warnings + | +help: Insert single blank line + +D404 First word of the docstring should not be "This" + --> src/hmf/_internals/_cache.py:1:1 + | + 1 | / """ + 2 | | This module defines two decorators, based on the code from + 3 | | http://forrst.com/posts/Yet_another_caching_property_decorator_for_Pytho-PBy. + 4 | | + 5 | | They are both designed to cache class properties, but have the added + 6 | | functionality of being automatically updated when a parent property is + 7 | | updated. + 8 | | """ + | |___^ + 9 | +10 | import warnings + | + +D401 First line of docstring should be in imperative mood: "A robust property caching decorator." + --> src/hmf/_internals/_cache.py:27:5 + | +26 | def cached_quantity(f): +27 | / """ +28 | | A robust property caching decorator. +29 | | +30 | | This decorator is intended for use with the complementary `parameter` decorator. +31 | | It caches the decorated quantity, contingent on the parameters it depends on. +32 | | When those parameters are modified, a further call to the quantity will result +33 | | in a recalculation. +34 | | +35 | | Examples +36 | | -------- +37 | | >>> class CachedClass: +38 | | >>> @parameter +39 | | >>> def a_param(self,val): +40 | | >>> return val +41 | | >>> +42 | | >>> @cached_quantity +43 | | >>> def a_quantity(self): +44 | | >>> return 2*self.a_param +45 | | >>> +46 | | >>> @cached_quantity +47 | | >>> def a_child_quantity(self): +48 | | >>> return self.a_quantity**3 +49 | | +50 | | This code will calculate ``a_child_quantity`` on the first call, but return the cached +51 | | value on all subsequent calls. If `a_param` is modified, the +52 | | calculation of either `a_quantity` and `a_child_quantity` will be re-performed when requested. +53 | | """ + | |_______^ +54 | name = f.__name__ + | + +E501 Line too long (90 > 88) + --> src/hmf/_internals/_cache.py:50:89 + | +48 | >>> return self.a_quantity**3 +49 | +50 | This code will calculate ``a_child_quantity`` on the first call, but return the cached + | ^^ +51 | value on all subsequent calls. If `a_param` is modified, the +52 | calculation of either `a_quantity` and `a_child_quantity` will be re-performed when requested. + | + +E501 Line too long (98 > 88) + --> src/hmf/_internals/_cache.py:52:89 + | +50 | This code will calculate ``a_child_quantity`` on the first call, but return the cached +51 | value on all subsequent calls. If `a_param` is modified, the +52 | calculation of either `a_quantity` and `a_child_quantity` will be re-performed when requested. + | ^^^^^^^^^^ +53 | """ +54 | name = f.__name__ + | + +B904 Within an `except` clause, raise exceptions with `raise ... from err` or `raise ... from None` to distinguish them from errors in exception handling + --> src/hmf/_internals/_cache.py:82:21 + | +80 | recalc_prpa[pr].update(recalc_prpa[name]) +81 | except KeyError: +82 | / raise KeyError( +83 | | f"When getting {name}, couldn't find {pr} in recalc_prpa. Had {list(recalc_prpa.keys())}." +84 | | ) + | |_____________________^ +85 | +86 | # check all quantities for dependence on subframeworks and update their entries + | + +E501 Line too long (114 > 88) + --> src/hmf/_internals/_cache.py:83:89 + | +81 | except KeyError: +82 | raise KeyError( +83 | f"When getting {name}, couldn't find {pr} in recalc_prpa. Had {list(recalc_prpa.keys())}." + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +84 | ) + | + +E501 Line too long (91 > 88) + --> src/hmf/_internals/_cache.py:86:89 + | +84 | ) +85 | +86 | # check all quantities for dependence on subframeworks and update their entries + | ^^^ +87 | for s in subframeworks: +88 | if getattr(s, hidden_loc(s, "recalc")).get(":" + name, False): + | + +E501 Line too long (99 > 88) + --> src/hmf/_internals/_cache.py:115:89 + | +113 | activeq.add(name) +114 | +115 | # Go ahead and calculate the value -- each parameter accessed will add itself to the index. + | ^^^^^^^^^^^ +116 | value = f(self) +117 | setattr(self, prop, value) + | + +D401 First line of docstring should be in imperative mood: "A decorator which indicates a parameter of a calculation." + --> src/hmf/_internals/_cache.py:189:5 + | +188 | def parameter(kind): +189 | / """ +190 | | A decorator which indicates a parameter of a calculation. +191 | | +192 | | This decorator is intended for use with the complementary `cached_quantity` decorator. +193 | | It provides the mechanisms by which the quantities are re-calculated intelligently. +194 | | Parameters should be set by the `__init__` call in any class, so that they are set before any +195 | | dependent quantity is accessed. +196 | | +197 | | Parameters +198 | | ---------- +199 | | kind : str +200 | | Either "param", "option", "model", "switch" or "res". Changes the behaviour of the parameter. +201 | | "param", "option", "model" and "res" all behave the same currently, while when a "switch" is modified, +202 | | all dependent quantities have their dependencies re-indexed. +203 | | +204 | | Examples +205 | | -------- +206 | | >>> class CachedClass(object): +207 | | >>> @parameter +208 | | >>> def a_param(self,val): +209 | | >>> return val +210 | | >>> +211 | | >>> @cached_quantity +212 | | >>> def a_quantity(self): +213 | | >>> return 2*self.a_param +214 | | >>> +215 | | >>> @cached_quantity +216 | | >>> def a_child_quantity(self): +217 | | >>> return self.a_quantity**3 +218 | | +219 | | This code will calculate ``a_child_quantity`` on the first call, but return the cached +220 | | value on all subsequent calls. If `a_param` is modified, the +221 | | calculation of either `a_quantity` and `a_child_quantity` will be re-performed when requested. +222 | | """ + | |_______^ +223 | +224 | def param(f): + | + +E501 Line too long (90 > 88) + --> src/hmf/_internals/_cache.py:192:89 + | +190 | A decorator which indicates a parameter of a calculation. +191 | +192 | This decorator is intended for use with the complementary `cached_quantity` decorator. + | ^^ +193 | It provides the mechanisms by which the quantities are re-calculated intelligently. +194 | Parameters should be set by the `__init__` call in any class, so that they are set before any + | + +E501 Line too long (97 > 88) + --> src/hmf/_internals/_cache.py:194:89 + | +192 | This decorator is intended for use with the complementary `cached_quantity` decorator. +193 | It provides the mechanisms by which the quantities are re-calculated intelligently. +194 | Parameters should be set by the `__init__` call in any class, so that they are set before any + | ^^^^^^^^^ +195 | dependent quantity is accessed. + | + +E501 Line too long (101 > 88) + --> src/hmf/_internals/_cache.py:200:89 + | +198 | ---------- +199 | kind : str +200 | Either "param", "option", "model", "switch" or "res". Changes the behaviour of the parameter. + | ^^^^^^^^^^^^^ +201 | "param", "option", "model" and "res" all behave the same currently, while when a "switch" is modified, +202 | all dependent quantities have their dependencies re-indexed. + | + +E501 Line too long (110 > 88) + --> src/hmf/_internals/_cache.py:201:89 + | +199 | kind : str +200 | Either "param", "option", "model", "switch" or "res". Changes the behaviour of the parameter. +201 | "param", "option", "model" and "res" all behave the same currently, while when a "switch" is modified, + | ^^^^^^^^^^^^^^^^^^^^^^ +202 | all dependent quantities have their dependencies re-indexed. + | + +E501 Line too long (90 > 88) + --> src/hmf/_internals/_cache.py:219:89 + | +217 | >>> return self.a_quantity**3 +218 | +219 | This code will calculate ``a_child_quantity`` on the first call, but return the cached + | ^^ +220 | value on all subsequent calls. If `a_param` is modified, the +221 | calculation of either `a_quantity` and `a_child_quantity` will be re-performed when requested. + | + +E501 Line too long (98 > 88) + --> src/hmf/_internals/_cache.py:221:89 + | +219 | This code will calculate ``a_child_quantity`` on the first call, but return the cached +220 | value on all subsequent calls. If `a_param` is modified, the +221 | calculation of either `a_quantity` and `a_child_quantity` will be re-performed when requested. + | ^^^^^^^^^^ +222 | """ + | + +E501 Line too long (93 > 88) + --> src/hmf/_internals/_cache.py:233:89 + | +231 | val = f(self, val) +232 | +233 | # Here put any custom code that should be run, dependent on the type of parameter + | ^^^^^ +234 | if ( +235 | name.endswith("_params") + | + +E501 Line too long (90 > 88) + --> src/hmf/_internals/_cache.py:269:89 + | +267 | setattr(self, recalc_papr, {name: set()}) +268 | +269 | # If either the new value is different from the old, or we never set it before + | ^^ +270 | if not obj_eq(val, old_val) or doset: +271 | # Then if its a dict, we update it + | + +E501 Line too long (90 > 88) + --> src/hmf/_internals/_cache.py:295:89 + | +293 | else: +294 | warnings.warn( +295 | f"You are setting {name} directly. This is unstable, as less " + | ^^ +296 | f"validation is performed. You can turn on extra validation " +297 | f"for directly set parameters by setting framework._validate_every_param_set=True." + | + +E501 Line too long (89 > 88) + --> src/hmf/_internals/_cache.py:296:89 + | +294 | warnings.warn( +295 | f"You are setting {name} directly. This is unstable, as less " +296 | f"validation is performed. You can turn on extra validation " + | ^ +297 | f"for directly set parameters by setting framework._validate_every_param_set=True." +298 | f"However, this can be brittle, since intermediate states may not be valid.", + | + +E501 Line too long (111 > 88) + --> src/hmf/_internals/_cache.py:297:89 + | +295 | … f"You are setting {name} directly. This is unstable, as less " +296 | … f"validation is performed. You can turn on extra validation " +297 | … f"for directly set parameters by setting framework._validate_every_param_set=True." + | ^^^^^^^^^^^^^^^^^^^^^^^ +298 | … f"However, this can be brittle, since intermediate states may not be valid.", +299 | … stacklevel=2, category=DeprecationWarning, + | + +E501 Line too long (105 > 88) + --> src/hmf/_internals/_cache.py:298:89 + | +296 | f"validation is performed. You can turn on extra validation " +297 | f"for directly set parameters by setting framework._validate_every_param_set=True." +298 | f"However, this can be brittle, since intermediate states may not be valid.", + | ^^^^^^^^^^^^^^^^^ +299 | stacklevel=2, category=DeprecationWarning, +300 | ) + | + +D401 First line of docstring should be in imperative mood: "A quantity that is essentially a sub-framework." + --> src/hmf/_internals/_cache.py:326:5 + | +325 | def subframework(f): +326 | / """ +327 | | A quantity that is essentially a sub-framework. +328 | | +329 | | Parameters +330 | | ---------- +331 | | f +332 | | +333 | | Returns +334 | | ------- +335 | | """ + | |_______^ +336 | name = f.__name__ + | + +D414 Section has no content ("Returns") + --> src/hmf/_internals/_cache.py:333:5 + | +331 | f +332 | +333 | Returns + | ^^^^^^^ +334 | ------- +335 | """ + | + +RUF012 Mutable default value for class attribute + --> src/hmf/_internals/_framework.py:27:17 + | +25 | """ +26 | +27 | _defaults = {} + | ^^ +28 | +29 | def __init__(self, **model_params): + | +help: Consider initializing in `__init__` or annotating with `typing.ClassVar` + +E501 Line too long (96 > 88) + --> src/hmf/_internals/_framework.py:75:89 + | +73 | if len(avail) > 1: +74 | warnings.warn( +75 | f"More than one component called '{name}'. Returning {avail[-1]}.", stacklevel=2 + | ^^^^^^^^ +76 | ) +77 | return avail[-1] + | + +B904 Within an `except` clause, raise exceptions with `raise ... from err` or `raise ... from None` to distinguish them from errors in exception handling + --> src/hmf/_internals/_framework.py:82:9 + | +80 | return name +81 | except TypeError: +82 | raise ValueError(f"{name} must be str or a Component subclass") + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + +D401 First line of docstring should be in imperative mood: "A decorator that adds pluggable capabilities." + --> src/hmf/_internals/_framework.py:86:5 + | +85 | def pluggable(cls): +86 | """A decorator that adds pluggable capabilities.""" + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +87 | cls._plugins = {} + | + +B904 Within an `except` clause, raise exceptions with `raise ... from err` or `raise ... from None` to distinguish them from errors in exception handling + --> src/hmf/_internals/_framework.py:126:17 + | +124 | return kind._plugins[name] +125 | except KeyError: +126 | / raise ValueError( +127 | | f"The model {name} is not a defined {kind} model. Available: " +128 | | f"{tuple(kind._plugins.keys())}" +129 | | ) + | |_________________^ +130 | else: +131 | # Try to get *any* model called by this name. + | + +B904 Within an `except` clause, raise exceptions with `raise ... from err` or `raise ... from None` to distinguish them from errors in exception handling + --> src/hmf/_internals/_framework.py:151:13 + | +149 | return name +150 | except TypeError: +151 | raise ValueError(f"{name} must be str or Component subclass") + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + +D401 First line of docstring should be in imperative mood: "Returns a class ``name`` from the module ``mod``." + --> src/hmf/_internals/_framework.py:158:5 + | +156 | ) +157 | def get_model_(name, mod): +158 | / """ +159 | | Returns a class ``name`` from the module ``mod``. +160 | | +161 | | Parameters +162 | | ---------- +163 | | name : str +164 | | The class name of the appropriate model +165 | | +166 | | mod : str +167 | | The module name of the appropriate module +168 | | """ + | |_______^ +169 | return getattr(sys.modules[mod], name) + | + +D401 First line of docstring should be in imperative mood: "Returns an instance of ``name`` from the module ``mod``, with given params." + --> src/hmf/_internals/_framework.py:176:5 + | +174 | ) +175 | def get_model(name, mod, **kwargs): +176 | / r""" +177 | | Returns an instance of ``name`` from the module ``mod``, with given params. +178 | | +179 | | Parameters +180 | | ---------- +181 | | name : str +182 | | The class name of the appropriate model +183 | | mod : str +184 | | The module name of the appropriate module +185 | | +186 | | \*\*kwargs : +187 | | Any parameters for the instantiated model (including model parameters) +188 | | """ + | |_______^ +189 | return get_model_(name, mod)(**kwargs) + | + +D401 First line of docstring should be in imperative mood: "Called when you call MyNewClass()." + --> src/hmf/_internals/_framework.py:194:9 + | +192 | class _Validator(type): +193 | def __call__(cls, *args, **kwargs): +194 | """Called when you call MyNewClass().""" + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +195 | obj = type.__call__(cls, *args, **kwargs) +196 | obj.validate() + | + +N806 Variable `K` in function should be lowercase + --> src/hmf/_internals/_framework.py:255:9 + | +253 | def get_all_parameter_names(cls): +254 | """Yield all parameter names in the class.""" +255 | K = cls() + | ^ +256 | return getattr(K, "_" + K.__class__.__name__ + "__recalc_par_prop") + | + +D401 First line of docstring should be in imperative mood: "Dictionary of all parameters and defaults." + --> src/hmf/_internals/_framework.py:260:9 + | +258 | @classmethod +259 | def get_all_parameter_defaults(cls, recursive=True): +260 | """Dictionary of all parameters and defaults.""" + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +261 | K = cls() +262 | out = {name: getattr(K, name) for name in cls.get_all_parameter_names()} + | + +N806 Variable `K` in function should be lowercase + --> src/hmf/_internals/_framework.py:261:9 + | +259 | def get_all_parameter_defaults(cls, recursive=True): +260 | """Dictionary of all parameters and defaults.""" +261 | K = cls() + | ^ +262 | out = {name: getattr(K, name) for name in cls.get_all_parameter_names()} + | + +D401 First line of docstring should be in imperative mood: "Prints information about each parameter in the class." + --> src/hmf/_internals/_framework.py:336:9 + | +334 | @classmethod +335 | def parameter_info(cls, names=None): +336 | / """ +337 | | Prints information about each parameter in the class. +338 | | +339 | | Optionally, restrict printed parameters to those found in the list of names +340 | | provided. +341 | | """ + | |___________^ +342 | docs = "" +343 | for name, obj in cls._get_all_parameters(): + | + +D205 1 blank line required between summary line and description + --> src/hmf/alternatives/__init__.py:1:1 + | +1 | / """ +2 | | A subpackage dedicated to providing "plugin"-style alternatives to the standard halo mass function, for example +3 | | Warm Dark Matter cosmologies. +4 | | """ + | |___^ +5 | +6 | from . import wdm + | +help: Insert single blank line + +E501 Line too long (111 > 88) + --> src/hmf/alternatives/__init__.py:2:89 + | +1 | """ +2 | A subpackage dedicated to providing "plugin"-style alternatives to the standard halo mass function, for example + | ^^^^^^^^^^^^^^^^^^^^^^^ +3 | Warm Dark Matter cosmologies. +4 | """ + | + +F401 `.wdm` imported but unused; consider removing, adding to `__all__`, or using a redundant alias + --> src/hmf/alternatives/__init__.py:6:15 + | +4 | """ +5 | +6 | from . import wdm + | ^^^ + | +help: Use an explicit re-export: `wdm as wdm` + +N814 Camelcase `MassFunction` imported as constant `_MF` + --> src/hmf/alternatives/wdm.py:17:33 + | +15 | from ..cosmology.cosmo import Planck15 +16 | from ..density_field.transfer import Transfer as _Tr +17 | from ..mass_function.hmf import MassFunction as _MF + | ^^^^^^^^^^^^^^^^^^^ + | + +RUF012 Mutable default value for class attribute + --> src/hmf/alternatives/wdm.py:103:17 + | +101 | """ +102 | +103 | _defaults = {"mu": 1.12, "g_x": 1.5} + | ^^^^^^^^^^^^^^^^^^^^^^^^ +104 | +105 | def transfer(self, k): + | +help: Consider initializing in `__init__` or annotating with `typing.ClassVar` + +N801 Class name `Schneider12_vCDM` should use CapWords convention + --> src/hmf/alternatives/wdm.py:197:7 + | +197 | class Schneider12_vCDM(WDMRecalibrateMF): + | ^^^^^^^^^^^^^^^^ +198 | r""" +199 | Schneider+2012 recalibration of the CDM HMF. + | + +RUF012 Mutable default value for class attribute + --> src/hmf/alternatives/wdm.py:215:17 + | +213 | """ +214 | +215 | _defaults = {"beta": 1.16} + | ^^^^^^^^^^^^^^ +216 | +217 | def dndm_alter(self): + | +help: Consider initializing in `__init__` or annotating with `typing.ClassVar` + +D102 Missing docstring in public method + --> src/hmf/alternatives/wdm.py:217:9 + | +215 | _defaults = {"beta": 1.16} +216 | +217 | def dndm_alter(self): + | ^^^^^^^^^^ +218 | return self.dndm0 * (1 + self.wdm.m_hm / self.m) ** (-self.params["beta"]) + | + +RUF012 Mutable default value for class attribute + --> src/hmf/alternatives/wdm.py:239:17 + | +237 | """ +238 | +239 | _defaults = {"alpha": 0.6} + | ^^^^^^^^^^^^^^ +240 | +241 | def dndm_alter(self): + | +help: Consider initializing in `__init__` or annotating with `typing.ClassVar` + +D102 Missing docstring in public method + --> src/hmf/alternatives/wdm.py:241:9 + | +239 | _defaults = {"alpha": 0.6} +240 | +241 | def dndm_alter(self): + | ^^^^^^^^^^ +242 | return self.dndm0 * (1 + self.wdm.m_hm / self.m) ** (-self.params["alpha"]) + | + +RUF012 Mutable default value for class attribute + --> src/hmf/alternatives/wdm.py:263:17 + | +261 | """ +262 | +263 | _defaults = {"beta": 0.99, "gamma": 2.7} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +264 | +265 | def dndm_alter(self): + | +help: Consider initializing in `__init__` or annotating with `typing.ClassVar` + +D102 Missing docstring in public method + --> src/hmf/alternatives/wdm.py:265:9 + | +263 | _defaults = {"beta": 0.99, "gamma": 2.7} +264 | +265 | def dndm_alter(self): + | ^^^^^^^^^^ +266 | return self.dndm0 * (1 + self.params["gamma"] * self.wdm.m_hm / self.m) ** ( +267 | -self.params["beta"] + | + +D401 First line of docstring should be in imperative mood: "A model for the WDM effect on the transfer function." + --> src/hmf/alternatives/wdm.py:302:9 + | +300 | @parameter("model") +301 | def wdm_model(self, val): +302 | / """ +303 | | A model for the WDM effect on the transfer function. +304 | | +305 | | :type: str or :class:`WDM` subclass +306 | | """ + | |___________^ +307 | return get_mdl(val, WDM) + | + +B904 Within an `except` clause, raise exceptions with `raise ... from err` or `raise ... from None` to distinguish them from errors in exception handling + --> src/hmf/alternatives/wdm.py:328:13 + | +326 | val = float(val) +327 | except ValueError: +328 | raise ValueError("wdm_mass must be a number (", val, ")") + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +329 | +330 | if val <= 0: + | + +D401 First line of docstring should be in imperative mood: "The instantiated WDM model." + --> src/hmf/alternatives/wdm.py:336:9 + | +334 | @cached_quantity +335 | def wdm(self): +336 | / """ +337 | | The instantiated WDM model. +338 | | +339 | | Contains quantities relevant to WDM. +340 | | """ + | |___________^ +341 | return self.wdm_model( +342 | mx=self.wdm_mass, cosmo=self.cosmo, z=self.z, **self.wdm_params + | + +N802 Function name `_unnormalised_lnT` should be lowercase + --> src/hmf/alternatives/wdm.py:346:9 + | +345 | @cached_quantity +346 | def _unnormalised_lnT(self): + | ^^^^^^^^^^^^^^^^^ +347 | return super()._unnormalised_lnT + np.log(self.wdm.transfer(self.k)) + | +help: Consider adding `@typing.override` if this method overrides a method from a superclass + +D401 First line of docstring should be in imperative mood: "A model for empirical recalibration of the HMF." + --> src/hmf/alternatives/wdm.py:371:9 + | +369 | @parameter("switch") +370 | def alter_model(self, val): +371 | / """ +372 | | A model for empirical recalibration of the HMF. +373 | | +374 | | :type: None, str, or :class`WDMRecalibrateMF` subclass. +375 | | """ + | |___________^ +376 | if val is None: +377 | return None + | + +D401 First line of docstring should be in imperative mood: "The number density of haloes in WDM, ``len=len(m)``." + --> src/hmf/alternatives/wdm.py:387:9 + | +385 | @cached_quantity +386 | def dndm(self): +387 | / r""" +388 | | The number density of haloes in WDM, ``len=len(m)``. +389 | | +390 | | Units of :math:`h^4 M_\odot^{-1} Mpc^{-3}` +391 | | """ + | |___________^ +392 | dndm = super().dndm + | + +E501 Line too long (97 > 88) + --> src/hmf/cosmology/__init__.py:1:89 + | +1 | """Cosmographic calculations, and other purely cosmological quantities, such as growth factor.""" + | ^^^^^^^^^ +2 | +3 | from . import cosmo + | + +F401 `.cosmo` imported but unused; consider removing, adding to `__all__`, or using a redundant alias + --> src/hmf/cosmology/__init__.py:3:15 + | +1 | """Cosmographic calculations, and other purely cosmological quantities, such as growth factor.""" +2 | +3 | from . import cosmo + | ^^^^^ +4 | from .cosmo import Cosmology, astropy_to_colossus +5 | from .growth_factor import GrowthFactor + | +help: Use an explicit re-export: `cosmo as cosmo` + +F401 `.cosmo.Cosmology` imported but unused; consider removing, adding to `__all__`, or using a redundant alias + --> src/hmf/cosmology/__init__.py:4:20 + | +3 | from . import cosmo +4 | from .cosmo import Cosmology, astropy_to_colossus + | ^^^^^^^^^ +5 | from .growth_factor import GrowthFactor + | +help: Use an explicit re-export: `Cosmology as Cosmology` + +F401 `.cosmo.astropy_to_colossus` imported but unused; consider removing, adding to `__all__`, or using a redundant alias + --> src/hmf/cosmology/__init__.py:4:31 + | +3 | from . import cosmo +4 | from .cosmo import Cosmology, astropy_to_colossus + | ^^^^^^^^^^^^^^^^^^^ +5 | from .growth_factor import GrowthFactor + | +help: Use an explicit re-export: `astropy_to_colossus as astropy_to_colossus` + +F401 `.growth_factor.GrowthFactor` imported but unused; consider removing, adding to `__all__`, or using a redundant alias + --> src/hmf/cosmology/__init__.py:5:28 + | +3 | from . import cosmo +4 | from .cosmo import Cosmology, astropy_to_colossus +5 | from .growth_factor import GrowthFactor + | ^^^^^^^^^^^^ + | +help: Use an explicit re-export: `GrowthFactor as GrowthFactor` + +E501 Line too long (103 > 88) + --> src/hmf/cosmology/cosmo.py:9:89 + | + 8 | Also provided in the namespace are the pre-defined cosmologies from `astropy`: + 9 | `WMAP5`, `WMAP7`, `WMAP9`, `Planck13`, `Planck15` and `Planck18`, which may be used as arguments to the + | ^^^^^^^^^^^^^^^ +10 | Cosmology framework. All custom subclasses of :class:`astropy.cosmology.FLRW` +11 | may be used as inputs. + | + +B904 Within an `except` clause, raise exceptions with `raise ... from err` or `raise ... from None` to distinguish them from errors in exception handling + --> src/hmf/cosmology/cosmo.py:45:9 + | +43 | return cosmology.fromAstropy(astropy_cosmo=cosmo, cosmo_name=name, **kwargs) +44 | except ImportError: # pragma: nocover +45 | / raise ImportError( +46 | | "Cannot convert to COLOSSUS cosmology without installing COLOSSUS!" +47 | | ) + | |_________^ + | + +E501 Line too long (89 > 88) + --> src/hmf/cosmology/cosmo.py:68:89 + | +66 | update will *update* the dictionary, rather than replacing it. +67 | +68 | To read a standard documented list of parameters, use ``Cosmology.parameter_info()``. + | ^ +69 | If you want to just see the plain list of available parameters, use ``Cosmology.get_all_parameters()``. +70 | To see the actual defaults for each parameter, use ``Cosmology.get_all_parameter_defaults()``. + | + +E501 Line too long (107 > 88) + --> src/hmf/cosmology/cosmo.py:69:89 + | +68 | To read a standard documented list of parameters, use ``Cosmology.parameter_info()``. +69 | If you want to just see the plain list of available parameters, use ``Cosmology.get_all_parameters()``. + | ^^^^^^^^^^^^^^^^^^^ +70 | To see the actual defaults for each parameter, use ``Cosmology.get_all_parameter_defaults()``. +71 | """ + | + +E501 Line too long (98 > 88) + --> src/hmf/cosmology/cosmo.py:70:89 + | +68 | To read a standard documented list of parameters, use ``Cosmology.parameter_info()``. +69 | If you want to just see the plain list of available parameters, use ``Cosmology.get_all_parameters()``. +70 | To see the actual defaults for each parameter, use ``Cosmology.get_all_parameter_defaults()``. + | ^^^^^^^^^^ +71 | """ + | + +D205 1 blank line required between summary line and description + --> src/hmf/cosmology/cosmo.py:83:9 + | +81 | @_cache.parameter("model") +82 | def cosmo_model(self, val): +83 | / """ +84 | | The basis for the cosmology -- see astropy documentation. Can be a custom +85 | | subclass. Defaults to Planck18. +86 | | +87 | | :type: instance of `astropy.cosmology.FLRW` subclass +88 | | """ + | |___________^ +89 | if isinstance(val, str): +90 | return get_cosmo(val) + | +help: Insert single blank line + +D401 First line of docstring should be in imperative mood: "The basis for the cosmology -- see astropy documentation. Can be a custom" + --> src/hmf/cosmology/cosmo.py:83:9 + | +81 | @_cache.parameter("model") +82 | def cosmo_model(self, val): +83 | / """ +84 | | The basis for the cosmology -- see astropy documentation. Can be a custom +85 | | subclass. Defaults to Planck18. +86 | | +87 | | :type: instance of `astropy.cosmology.FLRW` subclass +88 | | """ + | |___________^ +89 | if isinstance(val, str): +90 | return get_cosmo(val) + | + +D205 1 blank line required between summary line and description + --> src/hmf/cosmology/cosmo.py:100:9 + | + 98 | @_cache.parameter("param") + 99 | def cosmo_params(self, val): +100 | / """ +101 | | Parameters for the cosmology that deviate from the base cosmology passed. +102 | | This is useful for repeated updates of a single parameter (leaving others +103 | | the same). Default is the empty dict. The parameters passed must match +104 | | the allowed parameters of `cosmo_model`. For the basic class this is. +105 | | +106 | | :Tcmb0: Temperature of the CMB at z=0 +107 | | :Neff: Number of massless neutrino species +108 | | :m_nu: Mass of neutrino species (list) +109 | | :H0: The hubble constant at z=0 +110 | | :Om0: The normalised matter density at z=0 +111 | | +112 | | :type: dict +113 | | """ + | |___________^ +114 | return val + | +help: Insert single blank line + +D205 1 blank line required between summary line and description + --> src/hmf/cosmology/cosmo.py:121:9 + | +119 | @_cache.cached_quantity +120 | def cosmo(self): +121 | / """ +122 | | Cosmographic object (:class:`astropy.cosmology.FLRW` object), with custom +123 | | cosmology from :attr:`~.cosmo_params` applied. +124 | | """ + | |___________^ +125 | return self.cosmo_model.clone(**self.cosmo_params) + | +help: Insert single blank line + +D401 First line of docstring should be in imperative mood: "Returns a FLRW cosmology given a string (must be one defined in this module)." + --> src/hmf/cosmology/cosmo.py:138:5 + | +137 | def get_cosmo(name): +138 | / """ +139 | | Returns a FLRW cosmology given a string (must be one defined in this module). +140 | | +141 | | Parameters +142 | | ---------- +143 | | name : str +144 | | The class name of the appropriate model +145 | | """ + | |_______^ +146 | if isinstance(getattr(sys.modules[__name__], name), FLRW): +147 | return getattr(sys.modules[__name__], name) + | + +N813 Camelcase `InterpolatedUnivariateSpline` imported as lowercase `_spline` + --> src/hmf/cosmology/growth_factor.py:14:31 + | +12 | import numpy as np +13 | from astropy import cosmology +14 | from scipy.interpolate import InterpolatedUnivariateSpline as _spline + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +15 | +16 | from .._internals._framework import Component as Cmpt + | + +RUF012 Mutable default value for class attribute + --> src/hmf/cosmology/growth_factor.py:67:17 + | +65 | """ +66 | +67 | _defaults = {"dlna": 0.01, "amin": 1e-8} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +68 | +69 | def __init__(self, *args, **kwargs): + | +help: Consider initializing in `__init__` or annotating with `typing.ClassVar` + +D102 Missing docstring in public method + --> src/hmf/cosmology/growth_factor.py:84:9 + | +83 | @cached_property +84 | def integral(self): + | ^^^^^^^^ +85 | a = np.exp(self._lna) +86 | return _spline( + | + +D401 First line of docstring should be in imperative mood: "Finds the factor :math:`D^+(a)`, from Lukic et. al. 2007, eq. 8." + --> src/hmf/cosmology/growth_factor.py:91:9 + | + 90 | def _d_plus(self, z: float | np.ndarray) -> float | np.ndarray: + 91 | / r""" + 92 | | Finds the factor :math:`D^+(a)`, from Lukic et. al. 2007, eq. 8. + 93 | | + 94 | | Parameters + 95 | | ---------- + 96 | | z + 97 | | The redshift + 98 | | + 99 | | Returns +100 | | ------- +101 | | dplus +102 | | The un-normalised growth factor -- same type as ``z``. +103 | | """ + | |___________^ +104 | a_min = np.exp(self._lna).min() +105 | a = 1 / (1 + z) + | + +RUF012 Mutable default value for class attribute + --> src/hmf/cosmology/growth_factor.py:222:17 + | +221 | supported_cosmos = (cosmology.LambdaCDM, cosmology.w0waCDM, cosmology.wCDM) +222 | _defaults = {"dlna": 0.01, "amin": 1e-8, "fname": ""} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +223 | +224 | def growth_factor(self, z): + | +help: Consider initializing in `__init__` or annotating with `typing.ClassVar` + +D401 First line of docstring should be in imperative mood: "The growth factor, :math:`d(a) = D^+(a)/D^+(a=1)`." + --> src/hmf/cosmology/growth_factor.py:225:9 + | +224 | def growth_factor(self, z): +225 | / r""" +226 | | The growth factor, :math:`d(a) = D^+(a)/D^+(a=1)`. +227 | | +228 | | Parameters +229 | | ---------- +230 | | z : array_like +231 | | Redshift. +232 | | +233 | | Returns +234 | | ------- +235 | | gf : array_like +236 | | The growth factor at `z`. +237 | | """ + | |___________^ +238 | G = np.genfromtxt(self.params["fname"])[:, [0, 1]].T + | + +N806 Variable `G` in function should be lowercase + --> src/hmf/cosmology/growth_factor.py:238:9 + | +236 | The growth factor at `z`. +237 | """ +238 | G = np.genfromtxt(self.params["fname"])[:, [0, 1]].T + | ^ +239 | +240 | z_out = G[0, :] + | + +RUF012 Mutable default value for class attribute + --> src/hmf/cosmology/growth_factor.py:265:17 + | +264 | supported_cosmos = (cosmology.LambdaCDM, cosmology.w0waCDM, cosmology.wCDM) +265 | _defaults = {"dlna": 0.01, "amin": 1e-8, "z": None, "d": None} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +266 | +267 | def growth_factor(self, z): + | +help: Consider initializing in `__init__` or annotating with `typing.ClassVar` + +D401 First line of docstring should be in imperative mood: "The growth factor, :math:`d(a) = D^+(a)/D^+(a=1)`." + --> src/hmf/cosmology/growth_factor.py:268:9 + | +267 | def growth_factor(self, z): +268 | / r""" +269 | | The growth factor, :math:`d(a) = D^+(a)/D^+(a=1)`. +270 | | +271 | | Parameters +272 | | ---------- +273 | | z : array_like +274 | | Redshift. +275 | | +276 | | Returns +277 | | ------- +278 | | gf : array_like +279 | | The growth factor at `z`. +280 | | """ + | |___________^ +281 | z_out = self.params["z"] +282 | d_out = self.params["d"] + | + +RUF012 Mutable default value for class attribute + --> src/hmf/cosmology/growth_factor.py:312:17 + | +310 | """ +311 | +312 | _defaults = {"dz": 0.01, "zmax": 1000.0} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +313 | +314 | @cached_property + | +help: Consider initializing in `__init__` or annotating with `typing.ClassVar` + +D205 1 blank line required between summary line and description + --> src/hmf/cosmology/growth_factor.py:323:9 + | +322 | def _d_plus(self, z): +323 | / """ +324 | | This is not implemented in this class. It is not +325 | | required to calculate :meth:`growth_factor`. +326 | | """ + | |___________^ +327 | raise NotImplementedError # pragma: nocover + | +help: Insert single blank line + +D401 First line of docstring should be in imperative mood: "This is not implemented in this class. It is not" + --> src/hmf/cosmology/growth_factor.py:323:9 + | +322 | def _d_plus(self, z): +323 | / """ +324 | | This is not implemented in this class. It is not +325 | | required to calculate :meth:`growth_factor`. +326 | | """ + | |___________^ +327 | raise NotImplementedError # pragma: nocover + | + +D404 First word of the docstring should not be "This" + --> src/hmf/cosmology/growth_factor.py:323:9 + | +322 | def _d_plus(self, z): +323 | / """ +324 | | This is not implemented in this class. It is not +325 | | required to calculate :meth:`growth_factor`. +326 | | """ + | |___________^ +327 | raise NotImplementedError # pragma: nocover + | + +D401 First line of docstring should be in imperative mood: "The growth factor, :math:`d(a) = D^+(a)/D^+(a=1)`." + --> src/hmf/cosmology/growth_factor.py:339:9 + | +338 | def growth_factor(self, z): +339 | / """ +340 | | The growth factor, :math:`d(a) = D^+(a)/D^+(a=1)`. +341 | | +342 | | This uses an approximation only valid in closed or +343 | | flat cosmologies, ported from ``genmf``. +344 | | +345 | | Parameters +346 | | ---------- +347 | | z : array_like +348 | | Redshift. +349 | | +350 | | Returns +351 | | ------- +352 | | gf : array_like +353 | | The growth factor at `z`. +354 | | """ + | |___________^ +355 | a = 1 / (1 + z) +356 | w = 1 / self.cosmo.Om0 - 1.0 + | + +E501 Line too long (103 > 88) + --> src/hmf/cosmology/growth_factor.py:401:89 + | +400 | :dz: Step-size for redshift spline +401 | :zmax: Maximum redshift of spline. Only used for :meth:`growth_factor_fn`, when `inverse=True`. + | ^^^^^^^^^^^^^^^ +402 | """ + | + +RUF012 Mutable default value for class attribute + --> src/hmf/cosmology/growth_factor.py:404:17 + | +402 | """ +403 | +404 | _defaults = {"dz": 0.01, "zmax": 1000.0} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +405 | +406 | @cached_property + | +help: Consider initializing in `__init__` or annotating with `typing.ClassVar` + +D205 1 blank line required between summary line and description + --> src/hmf/cosmology/growth_factor.py:415:9 + | +414 | def _d_plus(self, z): +415 | / """ +416 | | Calculate un-normalised growth factor as a function +417 | | of redshift. Note that the `getvec` argument is not +418 | | used in this function. +419 | | """ + | |___________^ +420 | a = 1 / (1 + z) + | +help: Insert single blank line + +N806 Variable `Omega_m` in function should be lowercase + --> src/hmf/cosmology/growth_factor.py:424:9 + | +422 | om = self.cosmo.Om0 / a**3 +423 | denom = self.cosmo.Ode0 + om +424 | Omega_m = om / denom + | ^^^^^^^ +425 | Omega_L = self.cosmo.Ode0 / denom +426 | coeff = 5.0 * Omega_m / (2.0 / a) + | + +N806 Variable `Omega_L` in function should be lowercase + --> src/hmf/cosmology/growth_factor.py:425:9 + | +423 | denom = self.cosmo.Ode0 + om +424 | Omega_m = om / denom +425 | Omega_L = self.cosmo.Ode0 / denom + | ^^^^^^^ +426 | coeff = 5.0 * Omega_m / (2.0 / a) +427 | term1 = Omega_m ** (4.0 / 7.0) + | + +D205 1 blank line required between summary line and description + --> src/hmf/cosmology/growth_factor.py:436:9 + | +434 | @_inherit +435 | class CambGrowth(GrowthFactor): +436 | / """ +437 | | Uses CAMB to generate the growth factor, at k/h = 1.0. This class is recommended +438 | | if the cosmology is not LambdaCDM (but instead wCDM), as it correctly deals with +439 | | the growth in this case. However, it standard LCDM is used, other classes are +440 | | preferred, as this class needs to re-calculate the transfer function. +441 | | """ + | |___________^ +442 | +443 | supported_cosmos = (cosmology.LambdaCDM, cosmology.w0waCDM, cosmology.wCDM) + | +help: Insert single blank line + +E501 Line too long (96 > 88) + --> src/hmf/cosmology/growth_factor.py:458:89 + | +456 | if cosmo.Ob0 is None: +457 | raise ValueError( +458 | "If using CAMB, the baryon density must be set explicitly in the cosmology." + | ^^^^^^^^ +459 | ) + | + +E501 Line too long (97 > 88) + --> src/hmf/cosmology/growth_factor.py:463:89 + | +461 | if cosmo.Tcmb0.value == 0: +462 | raise ValueError( +463 | "If using CAMB, the CMB temperature must be set explicitly in the cosmology." + | ^^^^^^^^^ +464 | ) + | + +D105 Missing docstring in magic method + --> src/hmf/cosmology/growth_factor.py:521:13 + | +519 | return growth +520 | +521 | def __getstate__(self): + | ^^^^^^^^^^^^ +522 | dct = self.__dict__.copy() + | + +D105 Missing docstring in magic method + --> src/hmf/cosmology/growth_factor.py:531:13 + | +529 | return dct +530 | +531 | def __setstate__(self, state): + | ^^^^^^^^^^^^ +532 | self.__dict__ = state + | + +D205 1 blank line required between summary line and description + --> src/hmf/density_field/__init__.py:1:1 + | +1 | / """ +2 | | A subpackage dedicated to basic measures of the matter density field -- its 2-point structure, cosmological transfer +3 | | functions, and filter functions which can be applied to it. +4 | | """ + | |___^ +5 | +6 | from . import filters, transfer, transfer_models + | +help: Insert single blank line + +E501 Line too long (116 > 88) + --> src/hmf/density_field/__init__.py:2:89 + | +1 | """ +2 | A subpackage dedicated to basic measures of the matter density field -- its 2-point structure, cosmological transfer + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +3 | functions, and filter functions which can be applied to it. +4 | """ + | + +F401 `.filters` imported but unused; consider removing, adding to `__all__`, or using a redundant alias + --> src/hmf/density_field/__init__.py:6:15 + | +4 | """ +5 | +6 | from . import filters, transfer, transfer_models + | ^^^^^^^ +7 | from .filters import Filter +8 | from .halofit import halofit + | +help: Use an explicit re-export: `filters as filters` + +F401 `.transfer` imported but unused; consider removing, adding to `__all__`, or using a redundant alias + --> src/hmf/density_field/__init__.py:6:24 + | +4 | """ +5 | +6 | from . import filters, transfer, transfer_models + | ^^^^^^^^ +7 | from .filters import Filter +8 | from .halofit import halofit + | +help: Use an explicit re-export: `transfer as transfer` + +F401 `.transfer_models` imported but unused; consider removing, adding to `__all__`, or using a redundant alias + --> src/hmf/density_field/__init__.py:6:34 + | +4 | """ +5 | +6 | from . import filters, transfer, transfer_models + | ^^^^^^^^^^^^^^^ +7 | from .filters import Filter +8 | from .halofit import halofit + | +help: Use an explicit re-export: `transfer_models as transfer_models` + +F401 `.filters.Filter` imported but unused; consider removing, adding to `__all__`, or using a redundant alias + --> src/hmf/density_field/__init__.py:7:22 + | +6 | from . import filters, transfer, transfer_models +7 | from .filters import Filter + | ^^^^^^ +8 | from .halofit import halofit +9 | from .transfer import Transfer + | +help: Use an explicit re-export: `Filter as Filter` + +F401 `.halofit.halofit` imported but unused; consider removing, adding to `__all__`, or using a redundant alias + --> src/hmf/density_field/__init__.py:8:22 + | + 6 | from . import filters, transfer, transfer_models + 7 | from .filters import Filter + 8 | from .halofit import halofit + | ^^^^^^^ + 9 | from .transfer import Transfer +10 | from .transfer_models import CAMB, EH + | +help: Use an explicit re-export: `halofit as halofit` + +F401 `.transfer.Transfer` imported but unused; consider removing, adding to `__all__`, or using a redundant alias + --> src/hmf/density_field/__init__.py:9:23 + | + 7 | from .filters import Filter + 8 | from .halofit import halofit + 9 | from .transfer import Transfer + | ^^^^^^^^ +10 | from .transfer_models import CAMB, EH + | +help: Use an explicit re-export: `Transfer as Transfer` + +F401 `.transfer_models.CAMB` imported but unused; consider removing, adding to `__all__`, or using a redundant alias + --> src/hmf/density_field/__init__.py:10:30 + | + 8 | from .halofit import halofit + 9 | from .transfer import Transfer +10 | from .transfer_models import CAMB, EH + | ^^^^ + | +help: Use an explicit re-export: `CAMB as CAMB` + +F401 `.transfer_models.EH` imported but unused; consider removing, adding to `__all__`, or using a redundant alias + --> src/hmf/density_field/__init__.py:10:36 + | + 8 | from .halofit import halofit + 9 | from .transfer import Transfer +10 | from .transfer_models import CAMB, EH + | ^^ + | +help: Use an explicit re-export: `EH as EH` + +N813 Camelcase `InterpolatedUnivariateSpline` imported as lowercase `_spline` + --> src/hmf/density_field/filters.py:8:31 + | + 6 | import numpy as np + 7 | import scipy.integrate as intg + 8 | from scipy.interpolate import InterpolatedUnivariateSpline as _spline + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + 9 | +10 | from .._internals import _framework, _utils + | + +N803 Argument name `R` should be lowercase + --> src/hmf/density_field/filters.py:66:26 + | +64 | super().__init__(**model_parameters) +65 | +66 | def real_space(self, R, r): + | ^ +67 | r""" +68 | Filter definition in real space. + | + +D401 First line of docstring should be in imperative mood: "The derivative of the (fourier-transformed) filter with :math:`\ln(kr)`." + --> src/hmf/density_field/filters.py:137:9 + | +136 | def dw_dlnkr(self, kr): +137 | / r""" +138 | | The derivative of the (fourier-transformed) filter with :math:`\ln(kr)`. +139 | | +140 | | Parameters +141 | | ---------- +142 | | kr : array_like +143 | | Scale(s) at which the derivative is evaluated. +144 | | +145 | | Notes +146 | | ----- +147 | | In terms of :math:`\frac{dw^2}{dm}`, which is a commonly used +148 | | quantity, this has the relationship +149 | | +150 | | .. math:: w\frac{dw}{d\ln r} = \frac{2}{r}\frac{dw^2}{dm}\frac{dm}{dr}. +151 | | """ + | |___________^ +152 | +153 | def dlnss_dlnr(self, r): + | + +D401 First line of docstring should be in imperative mood: "The derivative of the mass variance with radius." + --> src/hmf/density_field/filters.py:154:9 + | +153 | def dlnss_dlnr(self, r): +154 | / r""" +155 | | The derivative of the mass variance with radius. +156 | | +157 | | Parameters +158 | | ---------- +159 | | r : array_like +160 | | Radii +161 | | +162 | | Returns +163 | | ------- +164 | | dlnss_dlnr : array_like +165 | | The derivative of the the mass variance with radius. +166 | | +167 | | Notes +168 | | ----- +169 | | Given a prescription for how radius grows with mass (typically with +170 | | a log-slope of 1/3, and set in :meth:`dlnr_dlnm`), this specifies +171 | | the quantity :math:`\frac{d \ln \sigma^2}{d\ln m}`. +172 | | +173 | | The general formula is +174 | | +175 | | .. math:: \frac{d\ln \sigma^2}{d\ln R} = \frac{1}{\pi^2\sigma^2} \int_0^\infty +176 | | W(kR) \frac{dW(kR)}{d\ln(kR)} P(k)k^2 dk +177 | | """ + | |___________^ +178 | dlnk = np.log(self.k[1] / self.k[0]) +179 | s = self.sigma(r) + | + +D401 First line of docstring should be in imperative mood: "The derivative of log radius with log mass." + --> src/hmf/density_field/filters.py:189:9 + | +188 | def dlnr_dlnm(self, r): +189 | / r""" +190 | | The derivative of log radius with log mass. +191 | | +192 | | For the usual :math:`m\propto r^3` mass assignment, this is just 1/3. +193 | | +194 | | Parameters +195 | | ---------- +196 | | r : array_like +197 | | Radii. +198 | | """ + | |___________^ +199 | return 1.0 / 3.0 + | + +D401 First line of docstring should be in imperative mood: "The logarithmic slope of mass variance with mass." + --> src/hmf/density_field/filters.py:202:9 + | +201 | def dlnss_dlnm(self, r): +202 | / r""" +203 | | The logarithmic slope of mass variance with mass. +204 | | +205 | | This is an important quantity, and is used directly to calculate +206 | | :math:`\frac{dn}{dm}`. +207 | | +208 | | Parameters +209 | | ---------- +210 | | r : array_like +211 | | Radii. +212 | | """ + | |___________^ +213 | return self.dlnss_dlnr(r) * self.dlnr_dlnm(r) + | + +D102 Missing docstring in public method + --> src/hmf/density_field/filters.py:298:9 + | +296 | """ +297 | +298 | def real_space(self, R, r): + | ^^^^^^^^^^ +299 | a = np.where(r < R, 1, 0) +300 | return np.where(r == R, 0.5, a) + | + +N803 Argument name `R` should be lowercase + --> src/hmf/density_field/filters.py:298:26 + | +296 | """ +297 | +298 | def real_space(self, R, r): + | ^ +299 | a = np.where(r < R, 1, 0) +300 | return np.where(r == R, 0.5, a) + | + +D102 Missing docstring in public method + --> src/hmf/density_field/filters.py:302:9 + | +300 | return np.where(r == R, 0.5, a) +301 | +302 | def k_space(self, kr): + | ^^^^^^^ +303 | return np.where(kr > 1.4e-6, (3 / kr**3) * (np.sin(kr) - kr * np.cos(kr)), 1) + | + +D102 Missing docstring in public method + --> src/hmf/density_field/filters.py:305:9 + | +303 | return np.where(kr > 1.4e-6, (3 / kr**3) * (np.sin(kr) - kr * np.cos(kr)), 1) +304 | +305 | def mass_to_radius(self, m, rho_mean): + | ^^^^^^^^^^^^^^ +306 | return (3.0 * m / (4.0 * np.pi * rho_mean)) ** (1.0 / 3.0) + | + +D102 Missing docstring in public method + --> src/hmf/density_field/filters.py:308:9 + | +306 | return (3.0 * m / (4.0 * np.pi * rho_mean)) ** (1.0 / 3.0) +307 | +308 | def radius_to_mass(self, r, rho_mean): + | ^^^^^^^^^^^^^^ +309 | return 4 * np.pi * r**3 * rho_mean / 3 + | + +D102 Missing docstring in public method + --> src/hmf/density_field/filters.py:311:9 + | +309 | return 4 * np.pi * r**3 * rho_mean / 3 +310 | +311 | def dw_dlnkr(self, kr): + | ^^^^^^^^ +312 | return np.where( +313 | kr > 1e-3, + | + +D102 Missing docstring in public method + --> src/hmf/density_field/filters.py:348:9 + | +346 | """ +347 | +348 | def real_space(self, R, r): + | ^^^^^^^^^^ +349 | return np.exp(-(r**2) / 2 / R**2) / (2 * np.pi) ** 1.5 / R**3 + | + +N803 Argument name `R` should be lowercase + --> src/hmf/density_field/filters.py:348:26 + | +346 | """ +347 | +348 | def real_space(self, R, r): + | ^ +349 | return np.exp(-(r**2) / 2 / R**2) / (2 * np.pi) ** 1.5 / R**3 + | + +D102 Missing docstring in public method + --> src/hmf/density_field/filters.py:351:9 + | +349 | return np.exp(-(r**2) / 2 / R**2) / (2 * np.pi) ** 1.5 / R**3 +350 | +351 | def k_space(self, kr): + | ^^^^^^^ +352 | return np.exp(-(kr**2) / 2.0) + | + +D102 Missing docstring in public method + --> src/hmf/density_field/filters.py:354:9 + | +352 | return np.exp(-(kr**2) / 2.0) +353 | +354 | def mass_to_radius(self, m, rho_mean): + | ^^^^^^^^^^^^^^ +355 | return (m / rho_mean) ** (1.0 / 3.0) / np.sqrt(2 * np.pi) + | + +D102 Missing docstring in public method + --> src/hmf/density_field/filters.py:357:9 + | +355 | return (m / rho_mean) ** (1.0 / 3.0) / np.sqrt(2 * np.pi) +356 | +357 | def radius_to_mass(self, r, rho_mean): + | ^^^^^^^^^^^^^^ +358 | return (2 * np.pi) ** 1.5 * r**3 * rho_mean + | + +D102 Missing docstring in public method + --> src/hmf/density_field/filters.py:360:9 + | +358 | return (2 * np.pi) ** 1.5 * r**3 * rho_mean +359 | +360 | def dw_dlnkr(self, kr): + | ^^^^^^^^ +361 | return -(kr**2) * self.k_space(kr) + | + +RUF012 Mutable default value for class attribute + --> src/hmf/density_field/filters.py:399:17 + | +397 | """ +398 | +399 | _defaults = {"c": 2.5} + | ^^^^^^^^^^ +400 | +401 | def k_space(self, kr): + | +help: Consider initializing in `__init__` or annotating with `typing.ClassVar` + +D102 Missing docstring in public method + --> src/hmf/density_field/filters.py:401:9 + | +399 | _defaults = {"c": 2.5} +400 | +401 | def k_space(self, kr): + | ^^^^^^^ +402 | a = np.where(kr > 1, 0, 1) +403 | return np.where(kr == 1, 0.5, a) + | + +D102 Missing docstring in public method + --> src/hmf/density_field/filters.py:405:9 + | +403 | return np.where(kr == 1, 0.5, a) +404 | +405 | def real_space(self, R, r): + | ^^^^^^^^^^ +406 | return (np.sin(r / R) - (r / R) * np.cos(r / R)) / (2 * np.pi**2 * r**3) + | + +N803 Argument name `R` should be lowercase + --> src/hmf/density_field/filters.py:405:26 + | +403 | return np.where(kr == 1, 0.5, a) +404 | +405 | def real_space(self, R, r): + | ^ +406 | return (np.sin(r / R) - (r / R) * np.cos(r / R)) / (2 * np.pi**2 * r**3) + | + +D102 Missing docstring in public method + --> src/hmf/density_field/filters.py:408:9 + | +406 | return (np.sin(r / R) - (r / R) * np.cos(r / R)) / (2 * np.pi**2 * r**3) +407 | +408 | def dw_dlnkr(self, kr): + | ^^^^^^^^ +409 | return np.where(kr == 1, 1.0, 0.0) + | + +D102 Missing docstring in public method + --> src/hmf/density_field/filters.py:411:9 + | +409 | return np.where(kr == 1, 1.0, 0.0) +410 | +411 | def dlnss_dlnr(self, r): + | ^^^^^^^^^^ +412 | sigma = self.sigma(r) +413 | power = _spline(self.k, self.power)(1 / r) + | + +D102 Missing docstring in public method + --> src/hmf/density_field/filters.py:416:9 + | +414 | return -power / (2 * np.pi**2 * sigma**2 * r**3) +415 | +416 | def mass_to_radius(self, m, rho_mean): + | ^^^^^^^^^^^^^^ +417 | return (1.0 / self.params["c"]) * (3.0 * m / (4.0 * np.pi * rho_mean)) ** ( +418 | 1.0 / 3.0 + | + +D102 Missing docstring in public method + --> src/hmf/density_field/filters.py:421:9 + | +419 | ) +420 | +421 | def radius_to_mass(self, r, rho_mean): + | ^^^^^^^^^^^^^^ +422 | return 4 * np.pi * (self.params["c"] * r) ** 3 * rho_mean / 3 + | + +D102 Missing docstring in public method + --> src/hmf/density_field/filters.py:424:9 + | +422 | return 4 * np.pi * (self.params["c"] * r) ** 3 * rho_mean / 3 +423 | +424 | def sigma(self, r, order=0): + | ^^^^^ +425 | if not isinstance(r, collections.abc.Iterable): +426 | r = np.atleast_1d(r) + | + +RUF012 Mutable default value for class attribute + --> src/hmf/density_field/filters.py:460:17 + | +458 | """ +459 | +460 | _defaults = {"c": 2.0} + | ^^^^^^^^^^ +461 | +462 | def xm(self, g, v): + | +help: Consider initializing in `__init__` or annotating with `typing.ClassVar` + +D401 First line of docstring should be in imperative mood: "The average ellipticity of a patch as a function of peak tensor." + --> src/hmf/density_field/filters.py:478:9 + | +477 | def em(self, xm): +478 | """The average ellipticity of a patch as a function of peak tensor.""" + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +479 | return 1 / np.sqrt(5 * xm**2 + 6) + | + +D401 First line of docstring should be in imperative mood: "The average prolateness of a patch as a function of peak tensor." + --> src/hmf/density_field/filters.py:482:9 + | +481 | def pm(self, xm): +482 | """The average prolateness of a patch as a function of peak tensor.""" + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +483 | return 30.0 / (5 * xm**2 + 6) ** 2 + | + +D401 First line of docstring should be in imperative mood: "The short:long axis ratio of an ellipsoid given its ellipticity and prolateness." + --> src/hmf/density_field/filters.py:486:9 + | +485 | def a3a1(self, e, p): +486 | """The short:long axis ratio of an ellipsoid given its ellipticity and prolateness.""" + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +487 | return np.sqrt((1 - 3 * e + p) / (1 + 3 * e + p)) + | + +E501 Line too long (94 > 88) + --> src/hmf/density_field/filters.py:486:89 + | +485 | def a3a1(self, e, p): +486 | """The short:long axis ratio of an ellipsoid given its ellipticity and prolateness.""" + | ^^^^^^ +487 | return np.sqrt((1 - 3 * e + p) / (1 + 3 * e + p)) + | + +D401 First line of docstring should be in imperative mood: "The short:medium axis ratio of an ellipsoid given its ellipticity/prolateness." + --> src/hmf/density_field/filters.py:490:9 + | +489 | def a3a2(self, e, p): +490 | """The short:medium axis ratio of an ellipsoid given its ellipticity/prolateness.""" + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +491 | return np.sqrt((1 - 2 * p) / (1 + 3 * e + p)) + | + +E501 Line too long (92 > 88) + --> src/hmf/density_field/filters.py:490:89 + | +489 | def a3a2(self, e, p): +490 | """The short:medium axis ratio of an ellipsoid given its ellipticity/prolateness.""" + | ^^^^ +491 | return np.sqrt((1 - 2 * p) / (1 + 3 * e + p)) + | + +D102 Missing docstring in public method + --> src/hmf/density_field/filters.py:500:9 + | +498 | return sig_1**2 / (sig_0 * sig_2) +499 | +500 | def xi(self, pm, em): + | ^^ +501 | return ((1 + 4 * pm) ** 2 / (1 - 3 * em + pm) / (1 - 2 * pm)) ** (1.0 / 6.0) + | + +D102 Missing docstring in public method + --> src/hmf/density_field/filters.py:503:9 + | +501 | return ((1 + 4 * pm) ** 2 / (1 - 3 * em + pm) / (1 - 2 * pm)) ** (1.0 / 6.0) +502 | +503 | def a3(self, r): + | ^^ +504 | g = self.gamma(r) +505 | xm = self.xm(g, self.nu(r)) + | + +D102 Missing docstring in public method + --> src/hmf/density_field/filters.py:510:9 + | +508 | return r / self.xi(pm, em) +509 | +510 | def r_a3(self, rmin, rmax): + | ^^^^ +511 | r = np.logspace(np.log(rmin), np.log(rmax), 200, base=np.e) +512 | a3 = self.a3(r) + | + +D102 Missing docstring in public method + --> src/hmf/density_field/filters.py:515:9 + | +513 | return _spline(a3, r) +514 | +515 | def dlnss_dlnr(self, r): + | ^^^^^^^^^^ +516 | a3 = self.a3(r) +517 | sigma = self.sigma(a3) + | + +D102 Missing docstring in public method + --> src/hmf/density_field/filters.py:521:9 + | +519 | return -power / (2 * np.pi**2 * sigma**2 * a3**3) +520 | +521 | def dlnr_dlnm(self, r): + | ^^^^^^^^^ +522 | a3 = self.a3(r) +523 | xi = r / a3 + | + +N813 Camelcase `InterpolatedUnivariateSpline` imported as lowercase `_spline` + --> src/hmf/density_field/halofit.py:14:31 + | +12 | import numpy as np +13 | from scipy.integrate import simpson as _simps +14 | from scipy.interpolate import InterpolatedUnivariateSpline as _spline + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +15 | from scipy.optimize import minimize + | + +N813 Camelcase `Cosmology` imported as lowercase `csm` + --> src/hmf/density_field/halofit.py:17:31 + | +15 | from scipy.optimize import minimize +16 | +17 | from ..cosmology.cosmo import Cosmology as csm + | ^^^^^^^^^^^^^^^^ + | + +D205 1 blank line required between summary line and description + --> src/hmf/density_field/halofit.py:23:5 + | +21 | k: np.ndarray, delta_k: np.ndarray, sigma_8=None +22 | ) -> tuple[float, float, float]: +23 | / """ +24 | | Calculate nonlinear wavenumber, effective spectral index and curvature +25 | | of the power spectrum. +26 | | +27 | | Parameters +28 | | ---------- +29 | | k : array_like +30 | | Wavenumbers +31 | | delta_k : array_like +32 | | Dimensionless power spectrum at `k` +33 | | sigma_8 : scalar +34 | | RMS linear density fluctuations in spheres of radius 8 Mpc/h at z=0. Not +35 | | used any more at all! +36 | | +37 | | Returns +38 | | ------- +39 | | knl : float +40 | | Non-linear wavenumber +41 | | n_eff : float +42 | | Effective spectral index +43 | | n_curv : float +44 | | Curvature of the spectrum +45 | | """ + | |_______^ +46 | +47 | # Initialize sigma spline + | +help: Insert single blank line + +N806 Variable `R` in function should be lowercase + --> src/hmf/density_field/halofit.py:49:9 + | +47 | # Initialize sigma spline +48 | def get_log_sigma2(lnr): +49 | R = np.exp(lnr) + | ^ +50 | integrand = delta_k * np.exp(-((k * R) ** 2)) +51 | return np.log(_simps(integrand, x=np.log(k))) + | + +E501 Line too long (122 > 88) + --> src/hmf/density_field/halofit.py:63:89 + | +61 | warnings.warn( +62 | f"Could not determine non-linear scale! Failed with error: {res.message}. " +63 | f"Continuing with best-fit non-linear scale: r_nl={np.exp(res.x)}, with log_sigma^2 = {res.fun}", stacklevel=2 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +64 | ) + | + +D401 First line of docstring should be in imperative mood: "Implementation of HALOFIT (Smith+2003)." + --> src/hmf/density_field/halofit.py:81:5 + | + 80 | def halofit(k, delta_k, *, sigma_8=None, z=0, cosmo=None, takahashi=True): + 81 | / """ + 82 | | Implementation of HALOFIT (Smith+2003). + 83 | | + 84 | | Parameters + 85 | | ---------- + 86 | | k : array_like + 87 | | Wavenumbers [h/Mpc]. + 88 | | delta_k : array_like + 89 | | Dimensionless power (linear) at `k`. + 90 | | sigma_8 : float + 91 | | RMS linear density fluctuations in spheres of radius 8 Mpc/h at z=0. Not used + 92 | | at all. + 93 | | z : float + 94 | | Redshift + 95 | | cosmo : :class:`hmf.cosmo.Cosmology` instance, optional + 96 | | An instance of either the `Cosmology` class provided in the `hmf` package, or + 97 | | any subclass of `FLRW` from `astropy`. Defualt is the default cosmology from + 98 | | the :mod:`hmf.cosmo` module. + 99 | | takahashi : bool, optional +100 | | Whether to use updated parameters from Takahashi+2012. Otherwise use +101 | | original from Smith+2003. +102 | | +103 | | Returns +104 | | ------- +105 | | nonlinear_delta_k : array_like +106 | | Dimensionless power at `k`, with nonlinear corrections applied. +107 | | """ + | |_______^ +108 | if sigma_8 is not None: +109 | warnings.warn("sigma_8 is not used any more, and will be removed in v4", stacklevel=2) + | + +E501 Line too long (94 > 88) + --> src/hmf/density_field/halofit.py:109:89 + | +107 | """ +108 | if sigma_8 is not None: +109 | warnings.warn("sigma_8 is not used any more, and will be removed in v4", stacklevel=2) + | ^^^^^^ +110 | +111 | if cosmo is None: + | + +E501 Line too long (89 > 88) + --> src/hmf/density_field/halofit.py:215:89 + | +213 | pnl = pq + ph +214 | +215 | # We have to copy so the original data is not overwritten, giving unexpected results. + | ^ +216 | nonlinear_delta_k = delta_k.copy() +217 | nonlinear_delta_k[mask] = pnl + | + +D102 Missing docstring in public method + --> src/hmf/density_field/transfer.py:89:9 + | +87 | # Parameters +88 | # =========================================================================== +89 | def validate(self): + | ^^^^^^^^ +90 | super().validate() +91 | assert self.lnk_min < self.lnk_max, ( + | + +D401 First line of docstring should be in imperative mood: "The model to use to calculate the growth function/growth rate." + --> src/hmf/density_field/transfer.py:98:9 + | + 96 | @parameter("model") + 97 | def growth_model(self, val): + 98 | / """ + 99 | | The model to use to calculate the growth function/growth rate. +100 | | +101 | | :type: `hmf.growth_factor._GrowthFactor` subclass +102 | | """ + | |___________^ +103 | return get_mdl(val, "_GrowthFactor") + | + +D401 First line of docstring should be in imperative mood: "Defines which transfer function model to use." + --> src/hmf/density_field/transfer.py:116:9 + | +114 | @parameter("model") +115 | def transfer_model(self, val): +116 | / """ +117 | | Defines which transfer function model to use. +118 | | +119 | | Built-in available models are found in the :mod:`hmf.transfer_models` module. +120 | | Default is CAMB if installed, otherwise EH. +121 | | +122 | | :type: str or :class:`hmf.transfer_models.TransferComponent` subclass, optional +123 | | """ + | |___________^ +124 | if not HAVE_CAMB and val in ["CAMB", tm.CAMB]: +125 | raise ValueError( + | + +B904 Within an `except` clause, raise exceptions with `raise ... from err` or `raise ... from None` to distinguish them from errors in exception handling + --> src/hmf/density_field/transfer.py:213:13 + | +211 | val = float(val) +212 | except ValueError: +213 | raise ValueError("z must be a number (", val, ")") + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +214 | +215 | if val < 0: + | + +D401 First line of docstring should be in imperative mood: "The instantiated transfer model." + --> src/hmf/density_field/transfer.py:230:9 + | +228 | @cached_quantity +229 | def transfer(self): +230 | """The instantiated transfer model.""" + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +231 | return self.transfer_model(self.cosmo, **self.transfer_params) + | + +N802 Function name `_unnormalised_lnT` should be lowercase + --> src/hmf/density_field/transfer.py:234:9 + | +233 | @cached_quantity +234 | def _unnormalised_lnT(self): + | ^^^^^^^^^^^^^^^^^ +235 | """The un-normalised transfer function.""" +236 | return self.transfer.lnt(np.log(self.k)) + | +help: Consider adding `@typing.override` if this method overrides a method from a superclass + +D401 First line of docstring should be in imperative mood: "The un-normalised transfer function." + --> src/hmf/density_field/transfer.py:235:9 + | +233 | @cached_quantity +234 | def _unnormalised_lnT(self): +235 | """The un-normalised transfer function.""" + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +236 | return self.transfer.lnt(np.log(self.k)) + | + +D401 First line of docstring should be in imperative mood: "The instantiated growth model." + --> src/hmf/density_field/transfer.py:273:9 + | +271 | @cached_quantity +272 | def growth(self): +273 | """The instantiated growth model.""" + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +274 | return self.growth_model(self.cosmo, **self.growth_params) + | + +D401 First line of docstring should be in imperative mood: "Function that efficiently returns the growth factor." + --> src/hmf/density_field/transfer.py:278:9 + | +276 | @cached_quantity +277 | def _growth_factor_fn(self): +278 | """Function that efficiently returns the growth factor.""" + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +279 | return self.growth.growth_factor_fn() + | + +D401 First line of docstring should be in imperative mood: "The growth factor." + --> src/hmf/density_field/transfer.py:283:9 + | +281 | @cached_quantity +282 | def growth_factor(self): +283 | r"""The growth factor.""" + | ^^^^^^^^^^^^^^^^^^^^^^^^^ +284 | if self.use_splined_growth: +285 | return self._growth_factor_fn(self.z) + | + +N813 Camelcase `InterpolatedUnivariateSpline` imported as lowercase `spline` + --> src/hmf/density_field/transfer_models.py:14:31 + | +12 | import numpy as np +13 | from astropy import cosmology +14 | from scipy.interpolate import InterpolatedUnivariateSpline as spline + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +15 | +16 | from .._internals._framework import Component, pluggable + | + +RUF012 Mutable default value for class attribute + --> src/hmf/density_field/transfer_models.py:44:17 + | +42 | """ +43 | +44 | _defaults = {} + | ^^ +45 | +46 | def __init__(self, cosmo, **model_parameters): + | +help: Consider initializing in `__init__` or annotating with `typing.ClassVar` + +RUF012 Mutable default value for class attribute + --> src/hmf/density_field/transfer_models.py:86:17 + | +84 | """ +85 | +86 | _defaults = {"fname": ""} + | ^^^^^^^^^^^^^ +87 | +88 | def _check_low_k(self, lnk, lnT, lnkmin): + | +help: Consider initializing in `__init__` or annotating with `typing.ClassVar` + +N803 Argument name `lnT` should be lowercase + --> src/hmf/density_field/transfer_models.py:88:33 + | +86 | _defaults = {"fname": ""} +87 | +88 | def _check_low_k(self, lnk, lnT, lnkmin): + | ^^^ +89 | """ +90 | Check convergence of transfer function at low k. + | + +N806 Variable `lnT` in function should be lowercase + --> src/hmf/density_field/transfer_models.py:107:9 + | +105 | start = i +106 | break +107 | lnT = lnT[start:-1] + | ^^^ +108 | lnk = lnk[start:-1] + | + +N806 Variable `T` in function should be lowercase + --> src/hmf/density_field/transfer_models.py:128:13 + | +126 | """ +127 | try: +128 | T = np.log(np.genfromtxt(self.params["fname"])[:, [0, 6]].T) + | ^ +129 | except IndexError: +130 | T = np.log(np.genfromtxt(self.params["fname"])[:, [0, 1]].T) + | + +N806 Variable `T` in function should be lowercase + --> src/hmf/density_field/transfer_models.py:130:13 + | +128 | T = np.log(np.genfromtxt(self.params["fname"])[:, [0, 6]].T) +129 | except IndexError: +130 | T = np.log(np.genfromtxt(self.params["fname"])[:, [0, 1]].T) + | ^ +131 | +132 | if lnk[0] < T[0, 0]: + | + +N806 Variable `lnT` in function should be lowercase + --> src/hmf/density_field/transfer_models.py:133:21 + | +132 | if lnk[0] < T[0, 0]: +133 | lnkout, lnT = self._check_low_k(T[0, :], T[1, :], lnk[0]) + | ^^^ +134 | else: +135 | lnkout = T[0, :] + | + +N806 Variable `lnT` in function should be lowercase + --> src/hmf/density_field/transfer_models.py:136:13 + | +134 | else: +135 | lnkout = T[0, :] +136 | lnT = T[1, :] + | ^^^ +137 | return spline(lnkout, lnT, k=1)(lnk) + | + +RUF012 Mutable default value for class attribute + --> src/hmf/density_field/transfer_models.py:164:21 + | +162 | """ +163 | +164 | _defaults = { + | _____________________^ +165 | | "camb_params": None, +166 | | "dark_energy_params": {}, +167 | | "extrapolate_with_eh": None, +168 | | "kmax": None, +169 | | } + | |_________^ +170 | +171 | def __init__(self, *args, **kwargs): + | +help: Consider initializing in `__init__` or annotating with `typing.ClassVar` + +E501 Line too long (106 > 88) + --> src/hmf/density_field/transfer_models.py:235:89 + | +233 | "'extrapolate_with_eh' was not set. Defaulting to True, which is " +234 | "different behaviour than versions <=3.4.4. This warning may be " +235 | "removed in v4.0. Silence it by setting extrapolate_with_eh explicitly.", stacklevel=2 + | ^^^^^^^^^^^^^^^^^^ +236 | ) +237 | self.params["extrapolate_with_eh"] = True + | + +N806 Variable `T` in function should be lowercase + --> src/hmf/density_field/transfer_models.py:258:13 + | +256 | """ +257 | camb_transfers = camb.get_transfer_functions(self.params["camb_params"]) +258 | T = camb_transfers.get_matter_transfer_data().transfer_data + | ^ +259 | T = np.log(T[[0, 6], :, 0]) + | + +N806 Variable `T` in function should be lowercase + --> src/hmf/density_field/transfer_models.py:259:13 + | +257 | camb_transfers = camb.get_transfer_functions(self.params["camb_params"]) +258 | T = camb_transfers.get_matter_transfer_data().transfer_data +259 | T = np.log(T[[0, 6], :, 0]) + | ^ +260 | +261 | if lnk[0] < T[0, 0]: + | + +N806 Variable `lnT` in function should be lowercase + --> src/hmf/density_field/transfer_models.py:262:25 + | +261 | if lnk[0] < T[0, 0]: +262 | lnkout, lnT = self._check_low_k(T[0, :], T[1, :], lnk[0]) + | ^^^ +263 | else: +264 | lnkout = T[0, :] + | + +N806 Variable `lnT` in function should be lowercase + --> src/hmf/density_field/transfer_models.py:265:17 + | +263 | else: +264 | lnkout = T[0, :] +265 | lnT = T[1, :] + | ^^^ +266 | +267 | lnT -= lnT[0] + | + +N806 Variable `lnT` in function should be lowercase + --> src/hmf/density_field/transfer_models.py:267:13 + | +265 | lnT = T[1, :] +266 | +267 | lnT -= lnT[0] + | ^^^ +268 | +269 | if not self.params["extrapolate_with_eh"]: + | + +N806 Variable `lnT` in function should be lowercase + --> src/hmf/density_field/transfer_models.py:276:13 + | +274 | # normalise EH at the final CAMB point. +275 | norm = self._eh.lnt(lnkout[-2]) - lnT[-1] +276 | lnT = np.concatenate((lnT, [self._eh.lnt(lnkout[-1]) - norm])) + | ^^^ +277 | +278 | lnkmin = lnkout.min() + | + +D105 Missing docstring in magic method + --> src/hmf/density_field/transfer_models.py:292:13 + | +290 | return out +291 | +292 | def __getstate__(self): + | ^^^^^^^^^^^^ +293 | # We need to get rid of the CAMBparams() object, as it cannot be pickled. +294 | p = self.params["camb_params"] + | + +E501 Line too long (93 > 88) + --> src/hmf/density_field/transfer_models.py:352:89 + | +351 | # Unsaveable parameters: +352 | # "nu_mass_degeneracies", "nu_mass_fractions", "nu_mass_numbers", "CustomSources" + | ^^^^^ +353 | +354 | dct = {} + | + +D105 Missing docstring in magic method + --> src/hmf/density_field/transfer_models.py:380:13 + | +378 | return this +379 | +380 | def __setstate__(self, state): + | ^^^^^^^^^^^^ +381 | self.__dict__ = state + | + +RUF012 Mutable default value for class attribute + --> src/hmf/density_field/transfer_models.py:406:17 + | +404 | """ +405 | +406 | _defaults = {"k": None, "T": None} + | ^^^^^^^^^^^^^^^^^^^^^^ +407 | +408 | def lnt(self, lnk): + | +help: Consider initializing in `__init__` or annotating with `typing.ClassVar` + +N806 Variable `T` in function should be lowercase + --> src/hmf/density_field/transfer_models.py:423:9 + | +421 | """ +422 | k = self.params["k"] +423 | T = self.params["T"] + | ^ +424 | +425 | if k is None or T is None: + | + +N806 Variable `lnT` in function should be lowercase + --> src/hmf/density_field/transfer_models.py:433:21 + | +432 | if lnk[0] < np.log(k.min()): +433 | lnkout, lnT = self._check_low_k(np.log(k), np.log(T), lnk[0]) + | ^^^ +434 | else: +435 | lnkout = np.log(k) + | + +N806 Variable `lnT` in function should be lowercase + --> src/hmf/density_field/transfer_models.py:436:13 + | +434 | else: +435 | lnkout = np.log(k) +436 | lnT = np.log(T) + | ^^^ +437 | return spline(lnkout, lnT, k=1)(lnk) + | + +N801 Class name `EH_BAO` should use CapWords convention + --> src/hmf/density_field/transfer_models.py:440:7 + | +440 | class EH_BAO(TransferComponent): + | ^^^^^^ +441 | r""" +442 | Eisenstein & Hu (1998) fitting function with BAO wiggles. + | + +N806 Variable `alpha_b_G` in function should be lowercase + --> src/hmf/density_field/transfer_models.py:515:9 + | +514 | y = self.z_eq / (1 + self.z_drag) +515 | alpha_b_G = y * ( + | ^^^^^^^^^ +516 | -6 * np.sqrt(1 + y) +517 | + (2 + 3 * y) * np.log((np.sqrt(1 + y) + 1) / (np.sqrt(1 + y) - 1)) + | + +D102 Missing docstring in public method + --> src/hmf/density_field/transfer_models.py:535:9 + | +534 | @property +535 | def k_peak(self): + | ^^^^^^ +536 | return 2.5 * np.pi * (1 + 0.217 * self.Omh2) / self.sound_horizon + | + +N806 Variable `T_c_ln_beta` in function should be lowercase + --> src/hmf/density_field/transfer_models.py:568:9 + | +566 | ks = k * self.sound_horizon +567 | +568 | T_c_ln_beta = np.log(np.e + 1.8 * self.beta_c * q) + | ^^^^^^^^^^^ +569 | T_c_ln_nobeta = np.log(np.e + 1.8 * q) +570 | T_c_C_alpha = (14.2 / self.alpha_c) + 386.0 / (1.0 + 69.9 * q**1.08) + | + +N806 Variable `T_c_ln_nobeta` in function should be lowercase + --> src/hmf/density_field/transfer_models.py:569:9 + | +568 | T_c_ln_beta = np.log(np.e + 1.8 * self.beta_c * q) +569 | T_c_ln_nobeta = np.log(np.e + 1.8 * q) + | ^^^^^^^^^^^^^ +570 | T_c_C_alpha = (14.2 / self.alpha_c) + 386.0 / (1.0 + 69.9 * q**1.08) +571 | T_c_C_noalpha = 14.2 + 386.0 / (1.0 + 69.9 * q**1.08) + | + +N806 Variable `T_c_C_alpha` in function should be lowercase + --> src/hmf/density_field/transfer_models.py:570:9 + | +568 | T_c_ln_beta = np.log(np.e + 1.8 * self.beta_c * q) +569 | T_c_ln_nobeta = np.log(np.e + 1.8 * q) +570 | T_c_C_alpha = (14.2 / self.alpha_c) + 386.0 / (1.0 + 69.9 * q**1.08) + | ^^^^^^^^^^^ +571 | T_c_C_noalpha = 14.2 + 386.0 / (1.0 + 69.9 * q**1.08) + | + +N806 Variable `T_c_C_noalpha` in function should be lowercase + --> src/hmf/density_field/transfer_models.py:571:9 + | +569 | T_c_ln_nobeta = np.log(np.e + 1.8 * q) +570 | T_c_C_alpha = (14.2 / self.alpha_c) + 386.0 / (1.0 + 69.9 * q**1.08) +571 | T_c_C_noalpha = 14.2 + 386.0 / (1.0 + 69.9 * q**1.08) + | ^^^^^^^^^^^^^ +572 | +573 | T_c_f = 1.0 / (1.0 + (ks / 5.4) ** 4) + | + +N806 Variable `T_c_f` in function should be lowercase + --> src/hmf/density_field/transfer_models.py:573:9 + | +571 | T_c_C_noalpha = 14.2 + 386.0 / (1.0 + 69.9 * q**1.08) +572 | +573 | T_c_f = 1.0 / (1.0 + (ks / 5.4) ** 4) + | ^^^^^ +574 | +575 | def term(a, b): + | + +N806 Variable `T_c` in function should be lowercase + --> src/hmf/density_field/transfer_models.py:578:9 + | +576 | return a / (a + b * q**2) +577 | +578 | T_c = T_c_f * term(T_c_ln_beta, T_c_C_noalpha) + (1 - T_c_f) * term( + | ^^^ +579 | T_c_ln_beta, T_c_C_alpha +580 | ) + | + +N806 Variable `T_b_T0` in function should be lowercase + --> src/hmf/density_field/transfer_models.py:585:9 + | +583 | ks_tilde = k * s_tilde +584 | +585 | T_b_T0 = term(T_c_ln_nobeta, T_c_C_noalpha) + | ^^^^^^ +586 | Tb1 = T_b_T0 / (1.0 + (ks / 5.2) ** 2) +587 | Tb2 = (self.alpha_b / (1.0 + (self.beta_b / ks) ** 3)) * np.exp( + | + +N806 Variable `Tb1` in function should be lowercase + --> src/hmf/density_field/transfer_models.py:586:9 + | +585 | T_b_T0 = term(T_c_ln_nobeta, T_c_C_noalpha) +586 | Tb1 = T_b_T0 / (1.0 + (ks / 5.2) ** 2) + | ^^^ +587 | Tb2 = (self.alpha_b / (1.0 + (self.beta_b / ks) ** 3)) * np.exp( +588 | -((k / self.k_silk) ** 1.4) + | + +N806 Variable `Tb2` in function should be lowercase + --> src/hmf/density_field/transfer_models.py:587:9 + | +585 | T_b_T0 = term(T_c_ln_nobeta, T_c_C_noalpha) +586 | Tb1 = T_b_T0 / (1.0 + (ks / 5.2) ** 2) +587 | Tb2 = (self.alpha_b / (1.0 + (self.beta_b / ks) ** 3)) * np.exp( + | ^^^ +588 | -((k / self.k_silk) ** 1.4) +589 | ) + | + +N806 Variable `T_b` in function should be lowercase + --> src/hmf/density_field/transfer_models.py:590:9 + | +588 | -((k / self.k_silk) ** 1.4) +589 | ) +590 | T_b = np.sin(ks_tilde) / ks_tilde * (Tb1 + Tb2) + | ^^^ +591 | +592 | return np.log(self.f_baryon * T_b + (1 - self.f_baryon) * T_c) + | + +N801 Class name `EH_NoBAO` should use CapWords convention + --> src/hmf/density_field/transfer_models.py:595:7 + | +595 | class EH_NoBAO(EH_BAO): + | ^^^^^^^^ +596 | r""" +597 | Eisenstein & Hu (1998) fitting function without BAO wiggles. + | + +D102 Missing docstring in public method + --> src/hmf/density_field/transfer_models.py:611:9 + | +610 | @property +611 | def alpha_gamma(self): + | ^^^^^^^^^^^ +612 | return ( +613 | 1 + | + +N806 Variable `L0` in function should be lowercase + --> src/hmf/density_field/transfer_models.py:643:9 + | +641 | q_eff = q * self.Omh2 / gamma_eff +642 | +643 | L0 = np.log(2 * np.e + 1.8 * q_eff) + | ^^ +644 | C0 = 14.2 + 731.0 / (1 + 62.5 * q_eff) +645 | return np.log(L0 / (L0 + C0 * q_eff * q_eff)) + | + +N806 Variable `C0` in function should be lowercase + --> src/hmf/density_field/transfer_models.py:644:9 + | +643 | L0 = np.log(2 * np.e + 1.8 * q_eff) +644 | C0 = 14.2 + 731.0 / (1 + 62.5 * q_eff) + | ^^ +645 | return np.log(L0 / (L0 + C0 * q_eff * q_eff)) + | + +RUF012 Mutable default value for class attribute + --> src/hmf/density_field/transfer_models.py:691:17 + | +689 | """ +690 | +691 | _defaults = { + | _________________^ +692 | | "a": 2.34, +693 | | "b": 3.89, +694 | | "c": 16.1, +695 | | "d": 5.46, +696 | | "e": 6.71, +697 | | "use_sugiyama_baryons": False, +698 | | "use_liddle_baryons": True, +699 | | } + | |_____^ +700 | +701 | def lnt(self, lnk): + | +help: Consider initializing in `__init__` or annotating with `typing.ClassVar` + +N806 Variable `Gamma` in function should be lowercase + --> src/hmf/density_field/transfer_models.py:721:9 + | +719 | e = self.params["e"] +720 | +721 | Gamma = self.cosmo.Om0 * self.cosmo.h + | ^^^^^ +722 | +723 | if self.params["use_sugiyama_baryons"]: + | + +N806 Variable `Gamma` in function should be lowercase + --> src/hmf/density_field/transfer_models.py:724:13 + | +723 | if self.params["use_sugiyama_baryons"]: +724 | Gamma *= np.exp(-self.cosmo.Ob0 * (1 + 1 / self.cosmo.Om0)) + | ^^^^^ +725 | elif self.params["use_liddle_baryons"]: +726 | Gamma *= np.exp( + | + +N806 Variable `Gamma` in function should be lowercase + --> src/hmf/density_field/transfer_models.py:726:13 + | +724 | Gamma *= np.exp(-self.cosmo.Ob0 * (1 + 1 / self.cosmo.Om0)) +725 | elif self.params["use_liddle_baryons"]: +726 | Gamma *= np.exp( + | ^^^^^ +727 | -self.cosmo.Ob0 +728 | * (1 + np.sqrt(self.cosmo.Ob0 * self.cosmo.h) / self.cosmo.Om0) + | + +RUF012 Mutable default value for class attribute + --> src/hmf/density_field/transfer_models.py:766:17 + | +764 | """ +765 | +766 | _defaults = {"a": 37.1, "b": 21.1, "c": 10.8, "nu": 1.12} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +767 | +768 | def lnt(self, lnk): + | +help: Consider initializing in `__init__` or annotating with `typing.ClassVar` + +D205 1 blank line required between summary line and description + --> src/hmf/halos/__init__.py:1:1 + | +1 | / """ +2 | | A subpackage dedicated to descriptions of internal halo properties, such as their mass. See ``halomod`` for more +3 | | extended quantities in this regard. +4 | | """ + | |___^ +5 | +6 | from . import mass_definitions + | +help: Insert single blank line + +E501 Line too long (112 > 88) + --> src/hmf/halos/__init__.py:2:89 + | +1 | """ +2 | A subpackage dedicated to descriptions of internal halo properties, such as their mass. See ``halomod`` for more + | ^^^^^^^^^^^^^^^^^^^^^^^^ +3 | extended quantities in this regard. +4 | """ + | + +F401 `.mass_definitions` imported but unused; consider removing, adding to `__all__`, or using a redundant alias + --> src/hmf/halos/__init__.py:6:15 + | +4 | """ +5 | +6 | from . import mass_definitions + | ^^^^^^^^^^^^^^^^ +7 | from .mass_definitions import MassDefinition + | +help: Use an explicit re-export: `mass_definitions as mass_definitions` + +F401 `.mass_definitions.MassDefinition` imported but unused; consider removing, adding to `__all__`, or using a redundant alias + --> src/hmf/halos/__init__.py:7:31 + | +6 | from . import mass_definitions +7 | from .mass_definitions import MassDefinition + | ^^^^^^^^^^^^^^ + | +help: Use an explicit re-export: `MassDefinition as MassDefinition` + +D401 First line of docstring should be in imperative mood: "The density of haloes under this definition." + --> src/hmf/halos/mass_definitions.py:43:9 + | +42 | def halo_density(self, z=0, cosmo=Planck15): +43 | / r""" +44 | | The density of haloes under this definition. +45 | | +46 | | May not exist in some definitions. Units are :math:`M_\odot h^2/{\rm Mpc}^3`. +47 | | """ + | |___________^ +48 | raise AttributeError("halo_density does not exist for this Mass Definition") + | + +D102 Missing docstring in public method + --> src/hmf/halos/mass_definitions.py:55:9 + | +53 | return None +54 | +55 | def halo_overdensity_mean(self, z=0, cosmo=Planck15): + | ^^^^^^^^^^^^^^^^^^^^^ +56 | return self.halo_density(z, cosmo) / self.mean_density(z, cosmo) + | + +D102 Missing docstring in public method + --> src/hmf/halos/mass_definitions.py:58:9 + | +56 | return self.halo_density(z, cosmo) / self.mean_density(z, cosmo) +57 | +58 | def halo_overdensity_crit(self, z=0, cosmo=Planck15): + | ^^^^^^^^^^^^^^^^^^^^^ +59 | return self.halo_density(z, cosmo) / self.critical_density(z, cosmo) + | + +B904 Within an `except` clause, raise exceptions with `raise ... from err` or `raise ... from None` to distinguish them from errors in exception handling + --> src/hmf/halos/mass_definitions.py:78:13 + | +76 | return (3 * m / (4 * np.pi * self.halo_density(z, cosmo))) ** (1.0 / 3.0) +77 | except AttributeError: +78 | / raise AttributeError( +79 | | f"{self.__class__.__name__} cannot convert mass to radius." +80 | | ) + | |_____________^ +81 | +82 | def r_to_m(self, r, z=0, cosmo=Planck15): + | + +B904 Within an `except` clause, raise exceptions with `raise ... from err` or `raise ... from None` to distinguish them from errors in exception handling + --> src/hmf/halos/mass_definitions.py:99:13 + | + 97 | return 4 * np.pi * r**3 * self.halo_density(z, cosmo) / 3 + 98 | except AttributeError: + 99 | / raise AttributeError( +100 | | f"{self.__class__.__name__} cannot convert radius to mass." +101 | | ) + | |_____________^ +102 | +103 | def _duffy_concentration(self, m, z=0): + | + +B904 Within an `except` clause, raise exceptions with `raise ... from err` or `raise ... from None` to distinguish them from errors in exception handling + --> src/hmf/halos/mass_definitions.py:164:17 + | +162 | ) +163 | except ImportError: +164 | / raise ImportError( +165 | | "Cannot change mass definitions without halomod installed!" +166 | | ) + | |_________________^ +167 | +168 | if profile.z != z: + | + +E501 Line too long (99 > 88) + --> src/hmf/halos/mass_definitions.py:171:89 + | +169 | warnings.warn( +170 | f"Redshift of given profile ({profile.z})does not match redshift " +171 | f"passed to change_definition(). Using the redshift directly passed.", stacklevel=2 + | ^^^^^^^^^^^ +172 | ) +173 | profile.z = z + | + +RUF012 Mutable default value for class attribute + --> src/hmf/halos/mass_definitions.py:240:17 + | +238 | """A mass definition based on spherical overdensity wrt mean background density.""" +239 | +240 | _defaults = {"overdensity": 200} + | ^^^^^^^^^^^^^^^^^^^^ +241 | +242 | def halo_density(self, z=0, cosmo=Planck15): + | +help: Consider initializing in `__init__` or annotating with `typing.ClassVar` + +D401 First line of docstring should be in imperative mood: "The density of haloes under this definition." + --> src/hmf/halos/mass_definitions.py:243:9 + | +242 | def halo_density(self, z=0, cosmo=Planck15): +243 | """The density of haloes under this definition.""" + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +244 | return self.params["overdensity"] * self.mean_density(z, cosmo) + | + +D102 Missing docstring in public method + --> src/hmf/halos/mass_definitions.py:247:9 + | +246 | @property +247 | def colossus_name(self): + | ^^^^^^^^^^^^^ +248 | return f"{int(self.params['overdensity'])}m" + | + +RUF012 Mutable default value for class attribute + --> src/hmf/halos/mass_definitions.py:254:17 + | +252 | """A mass definition based on spherical overdensity wrt critical density.""" +253 | +254 | _defaults = {"overdensity": 200} + | ^^^^^^^^^^^^^^^^^^^^ +255 | +256 | def halo_density(self, z=0, cosmo=Planck15): + | +help: Consider initializing in `__init__` or annotating with `typing.ClassVar` + +D401 First line of docstring should be in imperative mood: "The density of haloes under this definition." + --> src/hmf/halos/mass_definitions.py:257:9 + | +256 | def halo_density(self, z=0, cosmo=Planck15): +257 | """The density of haloes under this definition.""" + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +258 | return self.params["overdensity"] * self.critical_density(z, cosmo) + | + +D102 Missing docstring in public method + --> src/hmf/halos/mass_definitions.py:261:9 + | +260 | @property +261 | def colossus_name(self): + | ^^^^^^^^^^^^^ +262 | return f"{int(self.params['overdensity'])}c" + | + +D401 First line of docstring should be in imperative mood: "The density of haloes under this definition." + --> src/hmf/halos/mass_definitions.py:272:9 + | +271 | def halo_density(self, z=0, cosmo=Planck15): +272 | """The density of haloes under this definition.""" + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +273 | x = cosmo.Om(z) - 1 +274 | overdensity = 18 * np.pi**2 + 82 * x - 39 * x**2 + | + +D102 Missing docstring in public method + --> src/hmf/halos/mass_definitions.py:278:9 + | +277 | @property +278 | def colossus_name(self): + | ^^^^^^^^^^^^^ +279 | return "vir" + | + +RUF012 Mutable default value for class attribute + --> src/hmf/halos/mass_definitions.py:289:17 + | +287 | """A mass definition based on FroF networks with given linking length.""" +288 | +289 | _defaults = {"linking_length": 0.2} + | ^^^^^^^^^^^^^^^^^^^^^^^ +290 | +291 | def halo_density(self, z=0, cosmo=Planck15): + | +help: Consider initializing in `__init__` or annotating with `typing.ClassVar` + +D401 First line of docstring should be in imperative mood: "The density of halos under this mass definition." + --> src/hmf/halos/mass_definitions.py:292:9 + | +291 | def halo_density(self, z=0, cosmo=Planck15): +292 | / r""" +293 | | The density of halos under this mass definition. +294 | | +295 | | Note that for FoF halos, this is very approximate. We follow [1]_ and define +296 | | :math:`rho_{FOF} = 9/(2\pi b^3) \rho_m`, with *b* the linking length. This +297 | | assumes all groups are spherical and singular isothermal spheres. +298 | | +299 | | References +300 | | ---------- +301 | | .. [1] White, Martin, Lars Hernquist, and Volker Springel. “The Halo Model and +302 | | Numerical Simulations.” The Astrophysical Journal 550, no. 2 (April 2001): +303 | | L129–32. https://doi.org/10.1086/319644. +304 | | """ + | |___________^ +305 | overdensity = 9 / (2 * np.pi * self.params["linking_length"] ** 3) +306 | return overdensity * self.mean_density(z, cosmo) + | + +RUF002 Docstring contains ambiguous `–` (EN DASH). Did you mean `-` (HYPHEN-MINUS)? + --> src/hmf/halos/mass_definitions.py:303:16 + | +301 | .. [1] White, Martin, Lars Hernquist, and Volker Springel. “The Halo Model and +302 | Numerical Simulations.” The Astrophysical Journal 550, no. 2 (April 2001): +303 | L129–32. https://doi.org/10.1086/319644. + | ^ +304 | """ +305 | overdensity = 9 / (2 * np.pi * self.params["linking_length"] ** 3) + | + +D102 Missing docstring in public method + --> src/hmf/halos/mass_definitions.py:309:9 + | +308 | @property +309 | def colossus_name(self): + | ^^^^^^^^^^^^^ +310 | return "fof" + | + +N806 Variable `XDELTA_GUESS_FACTORS` in function should be lowercase + --> src/hmf/halos/mass_definitions.py:360:5 + | +358 | x = None +359 | i = 0 +360 | XDELTA_GUESS_FACTORS = [5.0, 10.0, 20.0, 100.0, 10000.0] + | ^^^^^^^^^^^^^^^^^^^^ +361 | +362 | if h is None: + | + +N818 Exception name `OptimizationException` should be named with an Error suffix + --> src/hmf/halos/mass_definitions.py:389:7 + | +389 | class OptimizationException(Exception): + | ^^^^^^^^^^^^^^^^^^^^^ +390 | """Exception class related to failed optimization.""" + | + +E501 Line too long (110 > 88) + --> src/hmf/helpers/__init__.py:1:89 + | +1 | """A collection of helper functions which can operate on several of the Frameworks in the rest of the code.""" + | ^^^^^^^^^^^^^^^^^^^^^^ +2 | +3 | from .functional import get_best_param_order, get_hmf + | + +F401 `.functional.get_best_param_order` imported but unused; consider removing, adding to `__all__`, or using a redundant alias + --> src/hmf/helpers/__init__.py:3:25 + | +1 | """A collection of helper functions which can operate on several of the Frameworks in the rest of the code.""" +2 | +3 | from .functional import get_best_param_order, get_hmf + | ^^^^^^^^^^^^^^^^^^^^ + | +help: Use an explicit re-export: `get_best_param_order as get_best_param_order` + +F401 `.functional.get_hmf` imported but unused; consider removing, adding to `__all__`, or using a redundant alias + --> src/hmf/helpers/__init__.py:3:47 + | +1 | """A collection of helper functions which can operate on several of the Frameworks in the rest of the code.""" +2 | +3 | from .functional import get_best_param_order, get_hmf + | ^^^^^^^ + | +help: Use an explicit re-export: `get_hmf as get_hmf` + +DTZ005 `datetime.datetime.now()` called without a `tz` argument + --> src/hmf/helpers/cfg_utils.py:15:26 + | +13 | def framework_to_dict(obj: Framework) -> dict: +14 | """Serialize a framework instance to a simple TOML-able dictionary.""" +15 | out = {"created_on": datetime.now(), "hmf_version": __version__, "params": {}} + | ^^^^^^^^^^^^^^ +16 | +17 | for k, v in obj.parameter_values.items(): + | +help: Pass a `datetime.timezone` object to the `tz` parameter + +E501 Line too long (91 > 88) + --> src/hmf/helpers/functional.py:225:89 + | +223 | ordered_list = [ordered_kwargs[k] for k in ordered_kwargs] +224 | final_list = [ +225 | collections.OrderedDict(list(zip(list(ordered_kwargs.keys()), v, strict=True))) + | ^^^ +226 | for v in itertools.product(*ordered_list) +227 | ] + | + +N813 Camelcase `InterpolatedUnivariateSpline` imported as lowercase `_spline` + --> src/hmf/helpers/sample.py:8:31 + | + 7 | import numpy as np + 8 | from scipy.interpolate import InterpolatedUnivariateSpline as _spline + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + 9 | +10 | from ..mass_function import hmf + | + +N803 Argument name `N` should be lowercase + --> src/hmf/helpers/sample.py:22:29 + | +22 | def _choose_halo_masses_num(N, icdf, xmin=0, rng=None): + | ^ +23 | # Generate random variates from 0 to maxcum +24 | if rng is None: + | + +N803 Argument name `N` should be lowercase + --> src/hmf/helpers/sample.py:33:15 + | +33 | def sample_mf(N, log_mmin, sort=False, rng=None, **mf_kwargs): + | ^ +34 | """ +35 | Create a sample of halo masses from a theoretical mass function. + | + +N803 Argument name `V` should be lowercase + --> src/hmf/helpers/sample.py:75:25 + | +75 | def dndm_from_sample(m, V, nm=None, bins=50): + | ^ +76 | """ +77 | Generate a binned dn/dm from a sample of halo masses. + | + +N806 Variable `histN` in function should be lowercase + --> src/hmf/helpers/sample.py:119:13 + | +117 | if hist[-1] == 0: +118 | try: +119 | histN = np.where(hist != 0)[0][-1] + | ^^^^^ +120 | hist[histN] = np.nan +121 | except IndexError: + | + +F401 `.fitting_functions` imported but unused; consider removing, adding to `__all__`, or using a redundant alias + --> src/hmf/mass_function/__init__.py:3:15 + | +1 | """Subpackage for determining the halo mass function in Spherical Collapse.""" +2 | +3 | from . import fitting_functions, hmf, integrate_hmf + | ^^^^^^^^^^^^^^^^^ +4 | from .fitting_functions import PS, SMT, FittingFunction, Tinker08 +5 | from .hmf import MassFunction + | +help: Use an explicit re-export: `fitting_functions as fitting_functions` + +F401 `.hmf` imported but unused; consider removing, adding to `__all__`, or using a redundant alias + --> src/hmf/mass_function/__init__.py:3:34 + | +1 | """Subpackage for determining the halo mass function in Spherical Collapse.""" +2 | +3 | from . import fitting_functions, hmf, integrate_hmf + | ^^^ +4 | from .fitting_functions import PS, SMT, FittingFunction, Tinker08 +5 | from .hmf import MassFunction + | +help: Use an explicit re-export: `hmf as hmf` + +F401 `.integrate_hmf` imported but unused; consider removing, adding to `__all__`, or using a redundant alias + --> src/hmf/mass_function/__init__.py:3:39 + | +1 | """Subpackage for determining the halo mass function in Spherical Collapse.""" +2 | +3 | from . import fitting_functions, hmf, integrate_hmf + | ^^^^^^^^^^^^^ +4 | from .fitting_functions import PS, SMT, FittingFunction, Tinker08 +5 | from .hmf import MassFunction + | +help: Use an explicit re-export: `integrate_hmf as integrate_hmf` + +F401 `.fitting_functions.PS` imported but unused; consider removing, adding to `__all__`, or using a redundant alias + --> src/hmf/mass_function/__init__.py:4:32 + | +3 | from . import fitting_functions, hmf, integrate_hmf +4 | from .fitting_functions import PS, SMT, FittingFunction, Tinker08 + | ^^ +5 | from .hmf import MassFunction + | +help: Use an explicit re-export: `PS as PS` + +F401 `.fitting_functions.SMT` imported but unused; consider removing, adding to `__all__`, or using a redundant alias + --> src/hmf/mass_function/__init__.py:4:36 + | +3 | from . import fitting_functions, hmf, integrate_hmf +4 | from .fitting_functions import PS, SMT, FittingFunction, Tinker08 + | ^^^ +5 | from .hmf import MassFunction + | +help: Use an explicit re-export: `SMT as SMT` + +F401 `.fitting_functions.FittingFunction` imported but unused; consider removing, adding to `__all__`, or using a redundant alias + --> src/hmf/mass_function/__init__.py:4:41 + | +3 | from . import fitting_functions, hmf, integrate_hmf +4 | from .fitting_functions import PS, SMT, FittingFunction, Tinker08 + | ^^^^^^^^^^^^^^^ +5 | from .hmf import MassFunction + | +help: Use an explicit re-export: `FittingFunction as FittingFunction` + +F401 `.fitting_functions.Tinker08` imported but unused; consider removing, adding to `__all__`, or using a redundant alias + --> src/hmf/mass_function/__init__.py:4:58 + | +3 | from . import fitting_functions, hmf, integrate_hmf +4 | from .fitting_functions import PS, SMT, FittingFunction, Tinker08 + | ^^^^^^^^ +5 | from .hmf import MassFunction + | +help: Use an explicit re-export: `Tinker08 as Tinker08` + +F401 `.hmf.MassFunction` imported but unused; consider removing, adding to `__all__`, or using a redundant alias + --> src/hmf/mass_function/__init__.py:5:18 + | +3 | from . import fitting_functions, hmf, integrate_hmf +4 | from .fitting_functions import PS, SMT, FittingFunction, Tinker08 +5 | from .hmf import MassFunction + | ^^^^^^^^^^^^ + | +help: Use an explicit re-export: `MassFunction as MassFunction` + +N813 Camelcase `InterpolatedUnivariateSpline` imported as lowercase `_spline` + --> src/hmf/mass_function/fitting_functions.py:13:31 + | +11 | import numpy as np +12 | import scipy.special as sp +13 | from scipy.interpolate import InterpolatedUnivariateSpline as _spline + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +14 | +15 | from .._internals import _framework + | + +N803 Argument name `L` should be lowercase + --> src/hmf/mass_function/fitting_functions.py:69:9 + | +67 | def __init__( +68 | self, +69 | L, + | ^ +70 | N, +71 | halo_finder_type, + | + +N803 Argument name `N` should be lowercase + --> src/hmf/mass_function/fitting_functions.py:70:9 + | +68 | self, +69 | L, +70 | N, + | ^ +71 | halo_finder_type, +72 | omegam, + | + +N803 Argument name `ICS` should be lowercase + --> src/hmf/mass_function/fitting_functions.py:80:9 + | +78 | z_start=None, +79 | z_meas=None, +80 | ICS=None, + | ^^^^^^^^ +81 | nmin=None, +82 | hmf_analysis_notes="", + | + +RUF012 Mutable default value for class attribute + --> src/hmf/mass_function/fitting_functions.py:207:17 + | +205 | """ +206 | __doc__ += _pdocs +207 | _defaults = {} + | ^^ +208 | +209 | # Subclass requirements + | +help: Consider initializing in `__init__` or annotating with `typing.ClassVar` + +D102 Missing docstring in public method + --> src/hmf/mass_function/fitting_functions.py:254:9 + | +253 | @classmethod +254 | def get_measured_mdef(cls): + | ^^^^^^^^^^^^^^^^^ +255 | # Try to set the measured mass definition +256 | measured = None + | + +D205 1 blank line required between summary line and description + --> src/hmf/mass_function/fitting_functions.py:314:9 + | +312 | @property +313 | def cutmask(self): +314 | / r""" +315 | | A logical mask array specifying which elements of :attr:`fsigma` are within +316 | | the fitted range. +317 | | """ + | |___________^ +318 | return np.ones(len(self.nu2), dtype=bool) + | +help: Insert single blank line + +D101 Missing docstring in public class + --> src/hmf/mass_function/fitting_functions.py:325:7 + | +325 | class PS(FittingFunction): + | ^^ +326 | # Subclass requirements +327 | req_sigma = False #: Whether sigma is required to compute this model. + | + +D102 Missing docstring in public method + --> src/hmf/mass_function/fitting_functions.py:340:9 + | +339 | @property +340 | def fsigma(self): + | ^^^^^^ +341 | return np.sqrt(2.0 / np.pi) * self.nu * np.exp(-0.5 * self.nu2) + | + +D101 Missing docstring in public class + --> src/hmf/mass_function/fitting_functions.py:344:7 + | +344 | class SMT(FittingFunction): + | ^^^ +345 | # Subclass requirements +346 | req_sigma = False + | + +RUF012 Mutable default value for class attribute + --> src/hmf/mass_function/fitting_functions.py:356:17 + | +354 | __doc__ = _makedoc(FittingFunction._pdocs, "Sheth-Mo-Tormen", "SMT", _eq, _ref) +355 | +356 | _defaults = {"a": 0.707, "p": 0.3, "A": None} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +357 | normalized = True + | +help: Consider initializing in `__init__` or annotating with `typing.ClassVar` + +D102 Missing docstring in public method + --> src/hmf/mass_function/fitting_functions.py:387:9 + | +386 | @property +387 | def fsigma(self): + | ^^^^^^ +388 | A = self.norm() +389 | a = self.params["a"] + | + +N806 Variable `A` in function should be lowercase + --> src/hmf/mass_function/fitting_functions.py:388:9 + | +386 | @property +387 | def fsigma(self): +388 | A = self.norm() + | ^ +389 | a = self.params["a"] +390 | p = self.params["p"] + | + +D102 Missing docstring in public method + --> src/hmf/mass_function/fitting_functions.py:400:9 + | +398 | ) +399 | +400 | def norm(self): + | ^^^^ +401 | if self.params["A"] is not None: +402 | return self.params["A"] + | + +D101 Missing docstring in public class + --> src/hmf/mass_function/fitting_functions.py:413:7 + | +413 | class Jenkins(FittingFunction): + | ^^^^^^^ +414 | # Subclass requirements +415 | req_z = False + | + +RUF012 Mutable default value for class attribute + --> src/hmf/mass_function/fitting_functions.py:423:17 + | +421 | ) +422 | __doc__ = _makedoc(FittingFunction._pdocs, "Jenkins", "Jenkins", _eq, _ref) +423 | _defaults = {"A": 0.315, "b": 0.61, "c": 3.8} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +424 | normalized = False + | +help: Consider initializing in `__init__` or annotating with `typing.ClassVar` + +D102 Missing docstring in public method + --> src/hmf/mass_function/fitting_functions.py:447:9 + | +446 | @property +447 | def cutmask(self): + | ^^^^^^^ +448 | return np.logical_and(self.lnsigma > -1.2, self.lnsigma < 1.05) + | + +D102 Missing docstring in public method + --> src/hmf/mass_function/fitting_functions.py:451:9 + | +450 | @property +451 | def fsigma(self): + | ^^^^^^ +452 | A = self.params["A"] +453 | b = self.params["b"] + | + +N806 Variable `A` in function should be lowercase + --> src/hmf/mass_function/fitting_functions.py:452:9 + | +450 | @property +451 | def fsigma(self): +452 | A = self.params["A"] + | ^ +453 | b = self.params["b"] +454 | c = self.params["c"] + | + +D101 Missing docstring in public class + --> src/hmf/mass_function/fitting_functions.py:458:7 + | +458 | class Warren(FittingFunction): + | ^^^^^^ +459 | # Subclass requirements +460 | req_z = False + | + +RUF012 Mutable default value for class attribute + --> src/hmf/mass_function/fitting_functions.py:473:17 + | +471 | __doc__ = _makedoc(FittingFunction._pdocs, "Warren", "Warren", _eq, _ref) +472 | +473 | _defaults = {"A": 0.7234, "b": 1.625, "c": 0.2538, "d": 1.1982, "e": 1} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +474 | normalized = False + | +help: Consider initializing in `__init__` or annotating with `typing.ClassVar` + +RUF012 Mutable default value for class attribute + --> src/hmf/mass_function/fitting_functions.py:476:21 + | +474 | normalized = False +475 | +476 | uncertainties = { + | _____________________^ +477 | | "A": 0.0073, +478 | | "a": 0.028, +479 | | "b": 0.0051, +480 | | "c": 0.0075, +481 | | } #: Quoted uncertainties of the model parameters. + | |_____^ +482 | sim_definition = SimDetails( +483 | L=[96, 135, 192, 272, 384, 543, 768, 1086, 1536, 2172, 2583, 3072], + | +help: Consider initializing in `__init__` or annotating with `typing.ClassVar` + +D102 Missing docstring in public method + --> src/hmf/mass_function/fitting_functions.py:514:9 + | +513 | @property +514 | def fsigma(self): + | ^^^^^^ +515 | A = self.params["A"] +516 | b = self.params["b"] + | + +N806 Variable `A` in function should be lowercase + --> src/hmf/mass_function/fitting_functions.py:515:9 + | +513 | @property +514 | def fsigma(self): +515 | A = self.params["A"] + | ^ +516 | b = self.params["b"] +517 | c = self.params["c"] + | + +D102 Missing docstring in public method + --> src/hmf/mass_function/fitting_functions.py:524:9 + | +523 | @property +524 | def cutmask(self): + | ^^^^^^^ +525 | return np.logical_and(self.m > 1e10, self.m < 1e15) + | + +D101 Missing docstring in public class + --> src/hmf/mass_function/fitting_functions.py:528:7 + | +528 | class Reed03(SMT): + | ^^^^^^ +529 | # Subclass requirements +530 | req_sigma = True + | + +RUF012 Mutable default value for class attribute + --> src/hmf/mass_function/fitting_functions.py:536:17 + | +534 | __doc__ = _makedoc(FittingFunction._pdocs, "Reed03", "R03", _eq, _ref) +535 | +536 | _defaults = {"a": 0.707, "p": 0.3, "A": 0.3222, "c": 0.7} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +537 | normalized = False + | +help: Consider initializing in `__init__` or annotating with `typing.ClassVar` + +D102 Missing docstring in public method + --> src/hmf/mass_function/fitting_functions.py:558:9 + | +557 | @property +558 | def fsigma(self): + | ^^^^^^ +559 | vfv = super().fsigma +560 | return vfv * np.exp( + | + +D102 Missing docstring in public method + --> src/hmf/mass_function/fitting_functions.py:565:9 + | +564 | @property +565 | def cutmask(self): + | ^^^^^^^ +566 | return np.logical_and(self.lnsigma > -1.7, self.lnsigma < 0.9) + | + +D101 Missing docstring in public class + --> src/hmf/mass_function/fitting_functions.py:569:7 + | +569 | class Reed07(FittingFunction): + | ^^^^^^ +570 | req_neff = True +571 | req_z = False + | + +E501 Line too long (146 > 88) + --> src/hmf/mass_function/fitting_functions.py:573:89 + | +571 | … +572 | … +573 | …)^p+0.6G_1+0.4G_2\right]\nu\exp\left(-ca\nu^2/2-\frac{0.03\nu^{0.6}}{(n_{\rm eff}+3)^2}\right)" + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +574 | … 374 (1), 2-15. http://adsabs.harvard.edu/abs/2007MNRAS.374....2R""" +575 | …d07", "R07", _eq, _ref) + | + +RUF012 Mutable default value for class attribute + --> src/hmf/mass_function/fitting_functions.py:577:17 + | +575 | __doc__ = _makedoc(FittingFunction._pdocs, "Reed07", "R07", _eq, _ref) +576 | +577 | _defaults = {"A": 0.3222, "p": 0.3, "c": 1.08, "a": 0.764} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +578 | +579 | sim_definition = SimDetails( + | +help: Consider initializing in `__init__` or annotating with `typing.ClassVar` + +D102 Missing docstring in public method + --> src/hmf/mass_function/fitting_functions.py:626:9 + | +625 | @property +626 | def fsigma(self): + | ^^^^^^ +627 | G_1 = np.exp(-((self.lnsigma - 0.4) ** 2) / (2 * 0.6**2)) +628 | G_2 = np.exp(-((self.lnsigma - 0.75) ** 2) / (2 * 0.2**2)) + | + +N806 Variable `G_1` in function should be lowercase + --> src/hmf/mass_function/fitting_functions.py:627:9 + | +625 | @property +626 | def fsigma(self): +627 | G_1 = np.exp(-((self.lnsigma - 0.4) ** 2) / (2 * 0.6**2)) + | ^^^ +628 | G_2 = np.exp(-((self.lnsigma - 0.75) ** 2) / (2 * 0.2**2)) + | + +N806 Variable `G_2` in function should be lowercase + --> src/hmf/mass_function/fitting_functions.py:628:9 + | +626 | def fsigma(self): +627 | G_1 = np.exp(-((self.lnsigma - 0.4) ** 2) / (2 * 0.6**2)) +628 | G_2 = np.exp(-((self.lnsigma - 0.75) ** 2) / (2 * 0.2**2)) + | ^^^ +629 | +630 | c = self.params["c"] + | + +N806 Variable `A` in function should be lowercase + --> src/hmf/mass_function/fitting_functions.py:632:9 + | +630 | c = self.params["c"] +631 | a = self.params["a"] / self.params["c"] +632 | A = self.params["A"] + | ^ +633 | p = self.params["p"] + | + +D102 Missing docstring in public method + --> src/hmf/mass_function/fitting_functions.py:646:9 + | +645 | @property +646 | def cutmask(self): + | ^^^^^^^ +647 | return np.logical_and(self.lnsigma > -0.5, self.lnsigma < 1.2) + | + +D101 Missing docstring in public class + --> src/hmf/mass_function/fitting_functions.py:650:7 + | +650 | class Peacock(FittingFunction): + | ^^^^^^^ +651 | req_z = False +652 | req_mass = True + | + +RUF012 Mutable default value for class attribute + --> src/hmf/mass_function/fitting_functions.py:657:17 + | +655 | _ref = """Peacock, J. A., Aug. 2007. MNRAS 379 (3), 1067-1074. http://adsabs.harvard.edu/abs/2007MNRAS.379.1067P""" +656 | __doc__ = _makedoc(FittingFunction._pdocs, "Peacock", "Pck", _eq, _ref) +657 | _defaults = {"a": 1.529, "b": 0.704, "c": 0.412} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +658 | +659 | sim_definition = copy(Warren.sim_definition) + | +help: Consider initializing in `__init__` or annotating with `typing.ClassVar` + +D102 Missing docstring in public method + --> src/hmf/mass_function/fitting_functions.py:664:9 + | +663 | @property +664 | def fsigma(self): + | ^^^^^^ +665 | a = self.params["a"] +666 | b = self.params["b"] + | + +D102 Missing docstring in public method + --> src/hmf/mass_function/fitting_functions.py:678:9 + | +677 | @property +678 | def cutmask(self): + | ^^^^^^^ +679 | return np.logical_and(self.m < 1e10, self.m > 1e15) + | + +D101 Missing docstring in public class + --> src/hmf/mass_function/fitting_functions.py:682:7 + | +682 | class Angulo(FittingFunction): + | ^^^^^^ +683 | req_mass = True +684 | _ref = """Angulo, R. E., et al., 2012. arXiv:1203.3216v1""" + | + +RUF012 Mutable default value for class attribute + --> src/hmf/mass_function/fitting_functions.py:687:17 + | +685 | _eq = r"$A \left[\left(\frac{d}{\sigma}\right)^b + 1 \right] \exp(-c/\sigma^2)$" +686 | __doc__ = _makedoc(FittingFunction._pdocs, "Angulo", "Ang", _eq, _ref) +687 | _defaults = {"A": 0.201, "b": 1.7, "c": 1.172, "d": 2.08} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +688 | +689 | sim_definition = SimDetails( + | +help: Consider initializing in `__init__` or annotating with `typing.ClassVar` + +D102 Missing docstring in public method + --> src/hmf/mass_function/fitting_functions.py:708:9 + | +707 | @property +708 | def fsigma(self): + | ^^^^^^ +709 | A = self.params["A"] +710 | b = self.params["b"] + | + +N806 Variable `A` in function should be lowercase + --> src/hmf/mass_function/fitting_functions.py:709:9 + | +707 | @property +708 | def fsigma(self): +709 | A = self.params["A"] + | ^ +710 | b = self.params["b"] +711 | c = self.params["c"] + | + +D102 Missing docstring in public method + --> src/hmf/mass_function/fitting_functions.py:717:9 + | +716 | @property +717 | def cutmask(self): + | ^^^^^^^ +718 | return np.logical_and(self.m > 1e8, self.m < 1e16) + | + +D101 Missing docstring in public class + --> src/hmf/mass_function/fitting_functions.py:721:7 + | +721 | class AnguloBound(Angulo): + | ^^^^^^^^^^^ +722 | __doc__ = Angulo.__doc__ +723 | _defaults = {"A": 0.265, "b": 1.9, "c": 1.4, "d": 1.675} + | + +RUF012 Mutable default value for class attribute + --> src/hmf/mass_function/fitting_functions.py:723:17 + | +721 | class AnguloBound(Angulo): +722 | __doc__ = Angulo.__doc__ +723 | _defaults = {"A": 0.265, "b": 1.9, "c": 1.4, "d": 1.675} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: Consider initializing in `__init__` or annotating with `typing.ClassVar` + +N801 Class name `Watson_FoF` should use CapWords convention + --> src/hmf/mass_function/fitting_functions.py:726:7 + | +726 | class Watson_FoF(Warren): + | ^^^^^^^^^^ +727 | req_mass = False + | + +D101 Missing docstring in public class + --> src/hmf/mass_function/fitting_functions.py:726:7 + | +726 | class Watson_FoF(Warren): + | ^^^^^^^^^^ +727 | req_mass = False + | + +E501 Line too long (103 > 88) + --> src/hmf/mass_function/fitting_functions.py:729:89 + | +727 | req_mass = False +728 | +729 | _ref = """Watson, W. A., et al., MNRAS, 2013. http://adsabs.harvard.edu/abs/2013MNRAS.433.1230W """ + | ^^^^^^^^^^^^^^^ +730 | __doc__ = _makedoc(FittingFunction._pdocs, "Watson FoF", "WatF", Warren._eq, _ref) +731 | _defaults = {"A": 0.282, "b": 2.163, "c": 1, "d": 1.21, "e": 1.406} + | + +RUF012 Mutable default value for class attribute + --> src/hmf/mass_function/fitting_functions.py:731:17 + | +729 | _ref = """Watson, W. A., et al., MNRAS, 2013. http://adsabs.harvard.edu/abs/2013MNRAS.433.1230W """ +730 | __doc__ = _makedoc(FittingFunction._pdocs, "Watson FoF", "WatF", Warren._eq, _ref) +731 | _defaults = {"A": 0.282, "b": 2.163, "c": 1, "d": 1.21, "e": 1.406} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +732 | +733 | sim_definition = SimDetails( + | +help: Consider initializing in `__init__` or annotating with `typing.ClassVar` + +E501 Line too long (91 > 88) + --> src/hmf/mass_function/fitting_functions.py:747:89 + | +745 | ICS="1LPT", +746 | nmin=1000, +747 | hmf_analysis_notes="Warren FOF correction applied. Finite-box correction applied.", + | ^^^ +748 | other_cosmo={"omegav": 0.73, "omegab": 0.044, "h": 0.7, "n": 0.96}, +749 | ) + | + +D102 Missing docstring in public method + --> src/hmf/mass_function/fitting_functions.py:752:9 + | +751 | @property +752 | def cutmask(self): + | ^^^^^^^ +753 | return np.logical_and(self.lnsigma > -0.55, self.lnsigma < 1.31) + | + +D101 Missing docstring in public class + --> src/hmf/mass_function/fitting_functions.py:756:7 + | +756 | class Watson(FittingFunction): + | ^^^^^^ +757 | req_cosmo = True +758 | req_dhalo = True + | + +E501 Line too long (103 > 88) + --> src/hmf/mass_function/fitting_functions.py:761:89 + | +759 | req_omz = True +760 | +761 | _ref = """Watson, W. A., et al., MNRAS, 2013. http://adsabs.harvard.edu/abs/2013MNRAS.433.1230W """ + | ^^^^^^^^^^^^^^^ +762 | _eq = r"\Gamma A \left((\frac{\beta}{\sigma}^\alpha+1\right)\exp(-\gamma/\sigma^2)" +763 | __doc__ = _makedoc(FittingFunction._pdocs, "Watson", "WatS", _eq, Watson_FoF._ref) + | + +RUF012 Mutable default value for class attribute + --> src/hmf/mass_function/fitting_functions.py:770:17 + | +768 | sim_definition.halo_overdensity = "*(vir)" +769 | +770 | _defaults = { + | _________________^ +771 | | "C_a": 0.023, +772 | | "d_a": 0.456, +773 | | "d_b": 0.139, +774 | | "p": 0.072, +775 | | "q": 2.13, +776 | | "A_0": 0.194, +777 | | "alpha_0": 1.805, +778 | | "beta_0": 2.267, +779 | | "gamma_0": 1.287, +780 | | "z_hi": 6, +781 | | "A_hi": 0.563, +782 | | "alpha_hi": 3.810, +783 | | "beta_hi": 0.874, +784 | | "gamma_hi": 1.453, +785 | | "A_a": 1.097, +786 | | "A_b": 3.216, +787 | | "A_c": 0.074, +788 | | "alpha_a": 3.136, +789 | | "alpha_b": 3.058, +790 | | "alpha_c": 2.349, +791 | | "beta_a": 5.907, +792 | | "beta_b": 3.599, +793 | | "beta_c": 2.344, +794 | | "gamma_z": 1.318, +795 | | } + | |_____^ +796 | +797 | def gamma(self): + | +help: Consider initializing in `__init__` or annotating with `typing.ClassVar` + +N806 Variable `C` in function should be lowercase + --> src/hmf/mass_function/fitting_functions.py:808:9 + | +806 | else: +807 | delta_halo = self.mass_definition.halo_overdensity_mean(self.z, self.cosmo) +808 | C = np.exp(self.params["C_a"] * (delta_halo / 178 - 1)) + | ^ +809 | d = -self.params["d_a"] * self.omegam_z - self.params["d_b"] +810 | p = self.params["p"] + | + +D102 Missing docstring in public method + --> src/hmf/mass_function/fitting_functions.py:820:9 + | +819 | @property +820 | def fsigma(self): + | ^^^^^^ +821 | if self.z == 0: +822 | A = self.params["A_0"] + | + +N806 Variable `A` in function should be lowercase + --> src/hmf/mass_function/fitting_functions.py:822:13 + | +820 | def fsigma(self): +821 | if self.z == 0: +822 | A = self.params["A_0"] + | ^ +823 | alpha = self.params["alpha_0"] +824 | beta = self.params["beta_0"] + | + +N806 Variable `A` in function should be lowercase + --> src/hmf/mass_function/fitting_functions.py:827:13 + | +825 | gamma = self.params["gamma_0"] +826 | elif self.z >= self.params["z_hi"]: +827 | A = self.params["A_hi"] + | ^ +828 | alpha = self.params["alpha_hi"] +829 | beta = self.params["beta_hi"] + | + +N806 Variable `A` in function should be lowercase + --> src/hmf/mass_function/fitting_functions.py:833:13 + | +831 | else: +832 | omz = self.omegam_z +833 | A = omz * ( + | ^ +834 | self.params["A_a"] * (1 + self.z) ** (-self.params["A_b"]) +835 | + self.params["A_c"] + | + +D102 Missing docstring in public method + --> src/hmf/mass_function/fitting_functions.py:855:9 + | +854 | @property +855 | def cutmask(self): + | ^^^^^^^ +856 | return np.logical_and(self.lnsigma > -0.55, self.lnsigma < 1.05) + | + +D101 Missing docstring in public class + --> src/hmf/mass_function/fitting_functions.py:859:7 + | +859 | class Crocce(Warren): + | ^^^^^^ +860 | req_z = True + | + +RUF012 Mutable default value for class attribute + --> src/hmf/mass_function/fitting_functions.py:864:17 + | +862 | _ref = """Crocce, M., et al. MNRAS 403 (3), 1353-1367. http://doi.wiley.com/10.1111/j.1365-2966.2009.16194.x""" +863 | __doc__ = _makedoc(FittingFunction._pdocs, "Crocce", "Cro", Warren._eq, _ref) +864 | _defaults = { + | _________________^ +865 | | "A_a": 0.58, +866 | | "A_b": 0.13, +867 | | "b_a": 1.37, +868 | | "b_b": 0.15, +869 | | "c_a": 0.3, +870 | | "c_b": 0.084, +871 | | "d_a": 1.036, +872 | | "d_b": 0.024, +873 | | "e": 1, +874 | | } + | |_____^ +875 | +876 | sim_definition = SimDetails( + | +help: Consider initializing in `__init__` or annotating with `typing.ClassVar` + +D102 Missing docstring in public method + --> src/hmf/mass_function/fitting_functions.py:903:9 + | +902 | @property +903 | def cutmask(self): + | ^^^^^^^ +904 | return np.logical_and(self.m > 10**10.5, self.m < 10**15.5) + | + +D101 Missing docstring in public class + --> src/hmf/mass_function/fitting_functions.py:907:7 + | +907 | class Courtin(SMT): + | ^^^^^^^ +908 | req_sigma = True +909 | _ref = """Courtin, J., et al., Oct. 2010. MNRAS 1931. http://doi.wiley.com/10.1111/j.1365-2966.2010.17573.x""" + | + +RUF012 Mutable default value for class attribute + --> src/hmf/mass_function/fitting_functions.py:911:17 + | +909 | _ref = """Courtin, J., et al., Oct. 2010. MNRAS 1931. http://doi.wiley.com/10.1111/j.1365-2966.2010.17573.x""" +910 | __doc__ = _makedoc(FittingFunction._pdocs, "Courtin", "Ctn", SMT._eq, _ref) +911 | _defaults = {"A": 0.348, "a": 0.695, "p": 0.1} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +912 | +913 | normalized = False + | +help: Consider initializing in `__init__` or annotating with `typing.ClassVar` + +D102 Missing docstring in public method + --> src/hmf/mass_function/fitting_functions.py:934:9 + | +933 | @property +934 | def cutmask(self): + | ^^^^^^^ +935 | return np.logical_and(self.lnsigma > -0.8, self.lnsigma < 0.7) + | + +D101 Missing docstring in public class + --> src/hmf/mass_function/fitting_functions.py:938:7 + | +938 | class Bhattacharya(SMT): + | ^^^^^^^^^^^^ +939 | req_z = True +940 | req_mass = True + | + +RUF012 Mutable default value for class attribute + --> src/hmf/mass_function/fitting_functions.py:945:17 + | +943 | _ref = """Bhattacharya, S., et al., May 2011. ApJ 732 (2), 122. http://labs.adsabs.harvard.edu/ui/abs/2011ApJ...732..122B""" +944 | __doc__ = _makedoc(FittingFunction._pdocs, "Bhattacharya", "Btc", _eq, _ref) +945 | _defaults = { + | _________________^ +946 | | "A_a": 0.333, +947 | | "A_b": 0.11, +948 | | "a_a": 0.788, +949 | | "a_b": 0.01, +950 | | "p": 0.807, +951 | | "q": 1.795, +952 | | "normed": False, +953 | | } + | |_____^ +954 | +955 | normalized = False + | +help: Consider initializing in `__init__` or annotating with `typing.ClassVar` + +E501 Line too long (96 > 88) + --> src/hmf/mass_function/fitting_functions.py:971:89 + | +969 | ICS=["2LPT", "2LPT", "2LPT", "1LPT", "1LPT"], +970 | nmin=400, +971 | hmf_analysis_notes="Finite force correction. FOF Correction. Finite volume correction.", + | ^^^^^^^^ +972 | other_cosmo={ +973 | "omegav": 0.74, + | + +D102 Missing docstring in public method + --> src/hmf/mass_function/fitting_functions.py:1014:9 + | +1013 | @property +1014 | def cutmask(self): + | ^^^^^^^ +1015 | return np.logical_and(self.m > 6 * 10**11, self.m < 3 * 10**15) + | + +D102 Missing docstring in public method + --> src/hmf/mass_function/fitting_functions.py:1017:9 + | +1015 | return np.logical_and(self.m > 6 * 10**11, self.m < 3 * 10**15) +1016 | +1017 | def norm(self): + | ^^^^ +1018 | if self.params["A"] is not None: +1019 | return self.params["A"] + | + +D101 Missing docstring in public class + --> src/hmf/mass_function/fitting_functions.py:1029:7 + | +1029 | class Tinker08(FittingFunction): + | ^^^^^^^^ +1030 | req_z = True +1031 | req_dhalo = True + | + +RUF012 Mutable default value for class attribute + --> src/hmf/mass_function/fitting_functions.py:1251:17 + | +1249 | ) +1250 | +1251 | _defaults = { # -- A + | _________________^ +1252 | | "A_200": 1.858659e-01, +1253 | | "A_300": 1.995973e-01, +1254 | | "A_400": 2.115659e-01, +1255 | | "A_600": 2.184113e-01, +1256 | | "A_800": 2.480968e-01, +1257 | | "A_1200": 2.546053e-01, +1258 | | "A_1600": 2.600000e-01, +1259 | | "A_2400": 2.600000e-01, +1260 | | "A_3200": 2.600000e-01, +1261 | | # -- a +1262 | | "a_200": 1.466904, +1263 | | "a_300": 1.521782, +1264 | | "a_400": 1.559186, +1265 | | "a_600": 1.614585, +1266 | | "a_800": 1.869936, +1267 | | "a_1200": 2.128056, +1268 | | "a_1600": 2.301275, +1269 | | "a_2400": 2.529241, +1270 | | "a_3200": 2.661983, +1271 | | # --- b +1272 | | "b_200": 2.571104, +1273 | | "b_300": 2.254217, +1274 | | "b_400": 2.048674, +1275 | | "b_600": 1.869559, +1276 | | "b_800": 1.588649, +1277 | | "b_1200": 1.507134, +1278 | | "b_1600": 1.464374, +1279 | | "b_2400": 1.436827, +1280 | | "b_3200": 1.405210, +1281 | | # --- c +1282 | | "c_200": 1.193958, +1283 | | "c_300": 1.270316, +1284 | | "c_400": 1.335191, +1285 | | "c_600": 1.446266, +1286 | | "c_800": 1.581345, +1287 | | "c_1200": 1.795050, +1288 | | "c_1600": 1.965613, +1289 | | "c_2400": 2.237466, +1290 | | "c_3200": 2.439729, +1291 | | # -- others +1292 | | "A_exp": 0.14, +1293 | | "a_exp": 0.06, +1294 | | } + | |_____^ +1295 | +1296 | delta_virs = np.array([200, 300, 400, 600, 800, 1200, 1600, 2400, 3200]) + | +help: Consider initializing in `__init__` or annotating with `typing.ClassVar` + +N806 Variable `A_array` in function should be lowercase + --> src/hmf/mass_function/fitting_functions.py:1308:13 + | +1307 | if delta_halo not in self.delta_virs: +1308 | A_array = np.array([self.params[f"A_{d}"] for d in self.delta_virs]) + | ^^^^^^^ +1309 | a_array = np.array([self.params[f"a_{d}"] for d in self.delta_virs]) +1310 | b_array = np.array([self.params[f"b_{d}"] for d in self.delta_virs]) + | + +N806 Variable `A_func` in function should be lowercase + --> src/hmf/mass_function/fitting_functions.py:1313:13 + | +1311 | c_array = np.array([self.params[f"c_{d}"] for d in self.delta_virs]) +1312 | +1313 | A_func = _spline(self.delta_virs, A_array) + | ^^^^^^ +1314 | a_func = _spline(self.delta_virs, a_array) +1315 | b_func = _spline(self.delta_virs, b_array) + | + +N806 Variable `A_0` in function should be lowercase + --> src/hmf/mass_function/fitting_functions.py:1318:13 + | +1316 | c_func = _spline(self.delta_virs, c_array) +1317 | +1318 | A_0 = A_func(delta_halo) + | ^^^ +1319 | a_0 = a_func(delta_halo) +1320 | b_0 = b_func(delta_halo) + | + +N806 Variable `A_0` in function should be lowercase + --> src/hmf/mass_function/fitting_functions.py:1323:13 + | +1321 | c_0 = c_func(delta_halo) +1322 | else: +1323 | A_0 = self.params[f"A_{int(delta_halo)}"] + | ^^^ +1324 | a_0 = self.params[f"a_{int(delta_halo)}"] +1325 | b_0 = self.params[f"b_{int(delta_halo)}"] + | + +D102 Missing docstring in public method + --> src/hmf/mass_function/fitting_functions.py:1335:9 + | +1334 | @property +1335 | def fsigma(self): + | ^^^^^^ +1336 | return ( +1337 | self.A + | + +D102 Missing docstring in public method + --> src/hmf/mass_function/fitting_functions.py:1343:9 + | +1342 | @property +1343 | def cutmask(self): + | ^^^^^^^ +1344 | if self.z == 0.0: +1345 | return np.logical_and( + | + +D101 Missing docstring in public class + --> src/hmf/mass_function/fitting_functions.py:1353:7 + | +1353 | class Tinker10(FittingFunction): + | ^^^^^^^^ +1354 | req_z = True +1355 | req_dhalo = True + | + +RUF012 Mutable default value for class attribute + --> src/hmf/mass_function/fitting_functions.py:1363:17 + | +1361 | sim_definition = copy(Tinker08.sim_definition) +1362 | +1363 | _defaults = { # --- alpha + | _________________^ +1364 | | "alpha_200": 0.368, +1365 | | "alpha_300": 0.363, +1366 | | "alpha_400": 0.385, +1367 | | "alpha_600": 0.389, +1368 | | "alpha_800": 0.393, +1369 | | "alpha_1200": 0.365, +1370 | | "alpha_1600": 0.379, +1371 | | "alpha_2400": 0.355, +1372 | | "alpha_3200": 0.327, +1373 | | # --- beta +1374 | | "beta_200": 0.589, +1375 | | "beta_300": 0.585, +1376 | | "beta_400": 0.544, +1377 | | "beta_600": 0.543, +1378 | | "beta_800": 0.564, +1379 | | "beta_1200": 0.623, +1380 | | "beta_1600": 0.637, +1381 | | "beta_2400": 0.673, +1382 | | "beta_3200": 0.702, +1383 | | # --- gamma +1384 | | "gamma_200": 0.864, +1385 | | "gamma_300": 0.922, +1386 | | "gamma_400": 0.987, +1387 | | "gamma_600": 1.09, +1388 | | "gamma_800": 1.2, +1389 | | "gamma_1200": 1.34, +1390 | | "gamma_1600": 1.5, +1391 | | "gamma_2400": 1.68, +1392 | | "gamma_3200": 1.81, +1393 | | # --- phi +1394 | | "phi_200": -0.729, +1395 | | "phi_300": -0.789, +1396 | | "phi_400": -0.910, +1397 | | "phi_600": -1.05, +1398 | | "phi_800": -1.2, +1399 | | "phi_1200": -1.26, +1400 | | "phi_1600": -1.45, +1401 | | "phi_2400": -1.5, +1402 | | "phi_3200": -1.49, +1403 | | # -- eta +1404 | | "eta_200": -0.243, +1405 | | "eta_300": -0.261, +1406 | | "eta_400": -0.261, +1407 | | "eta_600": -0.273, +1408 | | "eta_800": -0.278, +1409 | | "eta_1200": -0.301, +1410 | | "eta_1600": -0.301, +1411 | | "eta_2400": -0.319, +1412 | | "eta_3200": -0.336, +1413 | | # --others +1414 | | "beta_exp": 0.2, +1415 | | "phi_exp": -0.08, +1416 | | "eta_exp": 0.27, +1417 | | "gamma_exp": -0.01, +1418 | | "max_z": 3, +1419 | | } + | |_____^ +1420 | +1421 | delta_virs = np.array([200, 300, 400, 600, 800, 1200, 1600, 2400, 3200]) + | +help: Consider initializing in `__init__` or annotating with `typing.ClassVar` + +D102 Missing docstring in public method + --> src/hmf/mass_function/fitting_functions.py:1500:9 + | +1499 | @property +1500 | def normalise(self): + | ^^^^^^^^^ +1501 | if int(self.delta_halo) in self.delta_virs and self.z == 0: +1502 | return self.params[f"alpha_{int(self.delta_halo)}"] + | + +D102 Missing docstring in public method + --> src/hmf/mass_function/fitting_functions.py:1514:9 + | +1513 | @property +1514 | def fsigma(self): + | ^^^^^^ +1515 | fv = ( +1516 | (1 + (self.beta * self.nu) ** (-2 * self.phi)) + | + +D102 Missing docstring in public method + --> src/hmf/mass_function/fitting_functions.py:1524:9 + | +1523 | @property +1524 | def cutmask(self): + | ^^^^^^^ +1525 | if self.z == 0.0: +1526 | return np.logical_and( + | + +D101 Missing docstring in public class + --> src/hmf/mass_function/fitting_functions.py:1534:7 + | +1534 | class Behroozi(Tinker08): + | ^^^^^^^^ +1535 | _ref = r"""Behroozi, P., Weschler, R. and Conroy, C., ApJ, 2013, http://arxiv.org/abs/1207.6105""" +1536 | __doc__ = rf""" + | + +N806 Variable `dthetadM` in function should be lowercase + --> src/hmf/mass_function/fitting_functions.py:1586:9 + | +1584 | ) +1585 | ngtm_behroozi = 10 ** (theta + np.log10(ngtm_tinker)) +1586 | dthetadM = ( + | ^^^^^^^^ +1587 | 0.144 +1588 | / (1 + np.exp(14.79 * (a - 0.213))) + | + +D101 Missing docstring in public class + --> src/hmf/mass_function/fitting_functions.py:1599:7 + | +1599 | class Pillepich(Warren): + | ^^^^^^^^^ +1600 | _ref = r"""Pillepich, A., et al., 2010, arxiv:0811.4176""" +1601 | __doc__ = _makedoc( + | + +RUF012 Mutable default value for class attribute + --> src/hmf/mass_function/fitting_functions.py:1604:17 + | +1602 | FittingFunction._pdocs, "Pillepich", "Pillepich", Warren._eq, _ref +1603 | ) +1604 | _defaults = {"A": 0.6853, "b": 1.868, "c": 0.3324, "d": 1.2266, "e": 1} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +1605 | normalized = False + | +help: Consider initializing in `__init__` or annotating with `typing.ClassVar` + +D101 Missing docstring in public class + --> src/hmf/mass_function/fitting_functions.py:1631:7 + | +1631 | class Manera(SMT): + | ^^^^^^ +1632 | _ref = r"""Manera, M., et al., 2010, arxiv:0906.1314""" +1633 | __doc__ = _makedoc(FittingFunction._pdocs, "Manera", "Man", SMT._eq, _ref) + | + +RUF012 Mutable default value for class attribute + --> src/hmf/mass_function/fitting_functions.py:1635:17 + | +1633 | __doc__ = _makedoc(FittingFunction._pdocs, "Manera", "Man", SMT._eq, _ref) +1634 | # These are for z=0, new ML method, l_linnk = 0.2 +1635 | _defaults = {"A": None, "a": 0.709, "p": 0.289} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +1636 | +1637 | sim_definition = SimDetails( + | +help: Consider initializing in `__init__` or annotating with `typing.ClassVar` + +D101 Missing docstring in public class + --> src/hmf/mass_function/fitting_functions.py:1661:7 + | +1661 | class Ishiyama(Warren): + | ^^^^^^^^ +1662 | _eq = r"A\left[\left(\frac{e}{\sigma}\right)^b + 1\right]\exp(\frac{d}{\sigma^2})" +1663 | _ref = r"""Ishiyama, T., et al., 2015, arxiv:1412.2860""" + | + +RUF012 Mutable default value for class attribute + --> src/hmf/mass_function/fitting_functions.py:1666:17 + | +1664 | __doc__ = _makedoc(FittingFunction._pdocs, "Ishiyama", "Ishiyama", _eq, _ref) +1665 | +1666 | _defaults = {"A": 0.193, "b": 1.550, "c": 1, "d": 1.186, "e": 2.184} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +1667 | +1668 | sim_definition = SimDetails( + | +help: Consider initializing in `__init__` or annotating with `typing.ClassVar` + +D102 Missing docstring in public method + --> src/hmf/mass_function/fitting_functions.py:1692:9 + | +1691 | @property +1692 | def cutmask(self): + | ^^^^^^^ +1693 | return np.logical_and(self.m > 1e8, self.m < 1e16) + | + +D101 Missing docstring in public class + --> src/hmf/mass_function/fitting_functions.py:1696:7 + | +1696 | class Bocquet200mDMOnly(Warren): + | ^^^^^^^^^^^^^^^^^ +1697 | _eq = r"A\left[\left(\frac{e}{\sigma}\right)^b + 1\right]\exp(-\frac{d}{\sigma^2})" +1698 | _ref = r"""Bocuet, S., et al., 2016, MNRAS 456 2361""" + | + +RUF012 Mutable default value for class attribute + --> src/hmf/mass_function/fitting_functions.py:1700:17 + | +1698 | _ref = r"""Bocuet, S., et al., 2016, MNRAS 456 2361""" +1699 | __doc__ = _makedoc(FittingFunction._pdocs, "Bocquet", "Bocquet", _eq, _ref) +1700 | _defaults = { + | _________________^ +1701 | | "A": 0.216, +1702 | | "b": 1.87, +1703 | | "c": 1, +1704 | | "d": 1.31, +1705 | | "e": 2.02, +1706 | | "A_z": 0.018, +1707 | | "b_z": -0.0748, +1708 | | "d_z": -0.0689, +1709 | | "e_z": -0.215, +1710 | | } + | |_____^ +1711 | +1712 | sim_definition = SimDetails( + | +help: Consider initializing in `__init__` or annotating with `typing.ClassVar` + +D401 First line of docstring should be in imperative mood: "Function to compute mass in this definition compared to 200m." + --> src/hmf/mass_function/fitting_functions.py:1745:9 + | +1744 | def convert_mass(self): +1745 | / """Function to compute mass in this definition compared to 200m. +1746 | | +1747 | | This is an analytic approximation, not a full mass translation, and is calibrated +1748 | | to the NFW profile with Duffy+08 concentration-mass relation. This ratio is +1749 | | applied in :meth:`fsigma`. +1750 | | """ + | |___________^ +1751 | return 1 + | + +E501 Line too long (89 > 88) + --> src/hmf/mass_function/fitting_functions.py:1747:89 + | +1745 | """Function to compute mass in this definition compared to 200m. +1746 | +1747 | This is an analytic approximation, not a full mass translation, and is calibrated + | ^ +1748 | to the NFW profile with Duffy+08 concentration-mass relation. This ratio is +1749 | applied in :meth:`fsigma`. + | + +D102 Missing docstring in public method + --> src/hmf/mass_function/fitting_functions.py:1754:9 + | +1753 | @property +1754 | def fsigma(self): + | ^^^^^^ +1755 | A, b, d, e = self.get_params() +1756 | mass_conversion = self.convert_mass() + | + +N806 Variable `A` in function should be lowercase + --> src/hmf/mass_function/fitting_functions.py:1755:9 + | +1753 | @property +1754 | def fsigma(self): +1755 | A, b, d, e = self.get_params() + | ^ +1756 | mass_conversion = self.convert_mass() +1757 | return ( + | + +D101 Missing docstring in public class + --> src/hmf/mass_function/fitting_functions.py:1765:7 + | +1765 | class Bocquet200mHydro(Bocquet200mDMOnly): + | ^^^^^^^^^^^^^^^^ +1766 | __doc__ = _makedoc( +1767 | FittingFunction._pdocs, + | + +RUF012 Mutable default value for class attribute + --> src/hmf/mass_function/fitting_functions.py:1773:17 + | +1771 | Bocquet200mDMOnly._ref, +1772 | ) +1773 | _defaults = { + | _________________^ +1774 | | "A": 0.240, +1775 | | "b": 2.43, +1776 | | "c": 1, +1777 | | "d": 1.41, +1778 | | "e": 1.65, +1779 | | "A_z": 0.365, +1780 | | "b_z": -0.129, +1781 | | "d_z": -0.138, +1782 | | "e_z": -0.453, +1783 | | } + | |_____^ + | +help: Consider initializing in `__init__` or annotating with `typing.ClassVar` + +D101 Missing docstring in public class + --> src/hmf/mass_function/fitting_functions.py:1786:7 + | +1786 | class Bocquet200cDMOnly(Bocquet200mDMOnly): + | ^^^^^^^^^^^^^^^^^ +1787 | __doc__ = _makedoc( +1788 | FittingFunction._pdocs, + | + +RUF012 Mutable default value for class attribute + --> src/hmf/mass_function/fitting_functions.py:1795:17 + | +1793 | ) +1794 | +1795 | _defaults = { + | _________________^ +1796 | | "A": 0.256, +1797 | | "b": 2.01, +1798 | | "c": 1, +1799 | | "d": 1.59, +1800 | | "e": 1.97, +1801 | | "A_z": 0.218, +1802 | | "b_z": 0.290, +1803 | | "d_z": -0.174, +1804 | | "e_z": -0.518, +1805 | | } + | |_____^ +1806 | sim_definition = copy(Bocquet200mDMOnly.sim_definition) +1807 | sim_definition.halo_overdensity = "200c" + | +help: Consider initializing in `__init__` or annotating with `typing.ClassVar` + +D102 Missing docstring in public method + --> src/hmf/mass_function/fitting_functions.py:1809:9 + | +1807 | sim_definition.halo_overdensity = "200c" +1808 | +1809 | def convert_mass(self): + | ^^^^^^^^^^^^ +1810 | g0 = 3.54e-2 + self.cosmo.Om0**0.09 +1811 | g1 = 4.56e-2 + 2.68e-2 / self.cosmo.Om0 + | + +D101 Missing docstring in public class + --> src/hmf/mass_function/fitting_functions.py:1822:7 + | +1822 | class Bocquet200cHydro(Bocquet200cDMOnly): + | ^^^^^^^^^^^^^^^^ +1823 | __doc__ = _makedoc( +1824 | FittingFunction._pdocs, + | + +RUF012 Mutable default value for class attribute + --> src/hmf/mass_function/fitting_functions.py:1831:17 + | +1829 | ) +1830 | +1831 | _defaults = { + | _________________^ +1832 | | "A": 0.290, +1833 | | "b": 2.69, +1834 | | "c": 1, +1835 | | "d": 1.70, +1836 | | "e": 1.58, +1837 | | "A_z": 0.216, +1838 | | "b_z": 0.027, +1839 | | "d_z": -0.226, +1840 | | "e_z": -0.352, +1841 | | } + | |_____^ + | +help: Consider initializing in `__init__` or annotating with `typing.ClassVar` + +D101 Missing docstring in public class + --> src/hmf/mass_function/fitting_functions.py:1844:7 + | +1844 | class Bocquet500cDMOnly(Bocquet200cDMOnly): + | ^^^^^^^^^^^^^^^^^ +1845 | __doc__ = _makedoc( +1846 | FittingFunction._pdocs, + | + +RUF012 Mutable default value for class attribute + --> src/hmf/mass_function/fitting_functions.py:1853:17 + | +1851 | ) +1852 | +1853 | _defaults = { + | _________________^ +1854 | | "A": 0.390, +1855 | | "b": 3.05, +1856 | | "c": 1, +1857 | | "d": 2.32, +1858 | | "e": 1.72, +1859 | | "A_z": -0.924, +1860 | | "b_z": -0.421, +1861 | | "d_z": -0.509, +1862 | | "e_z": 0.190, +1863 | | } + | |_____^ +1864 | sim_definition = copy(Bocquet200mDMOnly.sim_definition) +1865 | sim_definition.halo_overdensity = "500c" + | +help: Consider initializing in `__init__` or annotating with `typing.ClassVar` + +D102 Missing docstring in public method + --> src/hmf/mass_function/fitting_functions.py:1867:9 + | +1865 | sim_definition.halo_overdensity = "500c" +1866 | +1867 | def convert_mass(self): + | ^^^^^^^^^^^^ +1868 | alpha_0 = 0.880 + 0.329 * self.cosmo.Om0 +1869 | alpha_1 = 1.0 + 4.31 * 1e-2 / self.cosmo.Om0 + | + +D101 Missing docstring in public class + --> src/hmf/mass_function/fitting_functions.py:1876:7 + | +1876 | class Bocquet500cHydro(Bocquet500cDMOnly): + | ^^^^^^^^^^^^^^^^ +1877 | __doc__ = _makedoc( +1878 | FittingFunction._pdocs, + | + +RUF012 Mutable default value for class attribute + --> src/hmf/mass_function/fitting_functions.py:1885:17 + | +1883 | ) +1884 | +1885 | _defaults = { + | _________________^ +1886 | | "A": 0.322, +1887 | | "b": 3.24, +1888 | | "c": 1, +1889 | | "d": 2.29, +1890 | | "e": 1.71, +1891 | | "A_z": 0.0142, +1892 | | "b_z": -0.219, +1893 | | "d_z": -0.428, +1894 | | "e_z": -0.275, +1895 | | } + | |_____^ + | +help: Consider initializing in `__init__` or annotating with `typing.ClassVar` + +N813 Camelcase `InterpolatedUnivariateSpline` imported as lowercase `spline` + --> src/hmf/mass_function/hmf.py:13:31 + | +12 | import numpy as np +13 | from scipy.interpolate import InterpolatedUnivariateSpline as spline + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +14 | from scipy.optimize import minimize + | + +N813 Camelcase `MassDefinition` imported as lowercase `md` + --> src/hmf/mass_function/hmf.py:20:38 + | +18 | from ..density_field import transfer +19 | from ..density_field.filters import Filter, TopHat +20 | from ..halos.mass_definitions import MassDefinition as md + | ^^^^^^^^^^^^^^^^^^^^ +21 | from ..halos.mass_definitions import SOGeneric, SOMean +22 | from . import fitting_functions as ff + | + +E501 Line too long (89 > 88) + --> src/hmf/mass_function/hmf.py:63:89 + | +61 | mdef_model +62 | The mass definition model to use. By default, use the mass definition in which +63 | the chosen HMF was measured. If that does not exist, use ``SOMean(200)``. If set, + | ^ +64 | this must be compatible with the halo definition used in measuring the chosen +65 | HMF -- unless ``disable_mass_conversion`` is set to False, in which case the + | + +N803 Argument name `Mmin` should be lowercase + --> src/hmf/mass_function/hmf.py:100:9 + | + 98 | def __init__( + 99 | self, +100 | Mmin: float = 10.0, + | ^^^^^^^^^^^^^^^^^^ +101 | Mmax: float = 15.0, +102 | dlog10m: float = 0.01, + | + +N803 Argument name `Mmax` should be lowercase + --> src/hmf/mass_function/hmf.py:101:9 + | + 99 | self, +100 | Mmin: float = 10.0, +101 | Mmax: float = 15.0, + | ^^^^^^^^^^^^^^^^^^ +102 | dlog10m: float = 0.01, +103 | hmf_model: str | ff.FittingFunction = ff.Tinker08, + | + +D102 Missing docstring in public method + --> src/hmf/mass_function/hmf.py:132:9 + | +130 | # PARAMETERS +131 | # =========================================================================== +132 | def validate(self): + | ^^^^^^^^ +133 | super().validate() +134 | assert self.Mmin < self.Mmax, f"Mmin > Mmax: {self.Mmin}, {self.Mmax}" + | + +B018 Found useless expression. Either assign it to a variable or remove it. + --> src/hmf/mass_function/hmf.py:138:9 + | +137 | # Check whether the hmf component validates. +138 | self.hmf + | ^^^^^^^^ +139 | +140 | @parameter("res") + | + +N802 Function name `Mmin` should be lowercase + --> src/hmf/mass_function/hmf.py:141:9 + | +140 | @parameter("res") +141 | def Mmin(self, val): + | ^^^^ +142 | r""" +143 | Minimum mass at which to perform analysis [units :math:`\log_{10}M_\odot h^{-1}`]. + | +help: Consider adding `@typing.override` if this method overrides a method from a superclass + +E501 Line too long (90 > 88) + --> src/hmf/mass_function/hmf.py:143:89 + | +141 | def Mmin(self, val): +142 | r""" +143 | Minimum mass at which to perform analysis [units :math:`\log_{10}M_\odot h^{-1}`]. + | ^^ +144 | +145 | :type: float + | + +N802 Function name `Mmax` should be lowercase + --> src/hmf/mass_function/hmf.py:150:9 + | +149 | @parameter("res") +150 | def Mmax(self, val): + | ^^^^ +151 | r""" +152 | Maximum mass at which to perform analysis [units :math:`\log_{10}M_\odot h^{-1}`]. + | +help: Consider adding `@typing.override` if this method overrides a method from a superclass + +E501 Line too long (90 > 88) + --> src/hmf/mass_function/hmf.py:152:89 + | +150 | def Mmax(self, val): +151 | r""" +152 | Maximum mass at which to perform analysis [units :math:`\log_{10}M_\odot h^{-1}`]. + | ^^ +153 | +154 | :type: float + | + +D401 First line of docstring should be in imperative mood: "A model for the window/filter function." + --> src/hmf/mass_function/hmf.py:177:9 + | +175 | @parameter("model") +176 | def filter_model(self, val): +177 | / """ +178 | | A model for the window/filter function. +179 | | +180 | | :type: :class:`hmf.filters.Filter` subclass +181 | | """ + | |___________^ +182 | return get_mdl(val, "Filter") + | + +D401 First line of docstring should be in imperative mood: "The critical overdensity for collapse, :math:`\delta_c`." + --> src/hmf/mass_function/hmf.py:195:9 + | +193 | @parameter("param") +194 | def delta_c(self, val): +195 | / r""" +196 | | The critical overdensity for collapse, :math:`\delta_c`. +197 | | +198 | | :type: float +199 | | """ + | |___________^ +200 | try: +201 | val = float(val) + | + +B904 Within an `except` clause, raise exceptions with `raise ... from err` or `raise ... from None` to distinguish them from errors in exception handling + --> src/hmf/mass_function/hmf.py:203:13 + | +201 | val = float(val) +202 | except ValueError: +203 | raise ValueError("delta_c must be a number: ", val) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +204 | +205 | if val <= 0: + | + +D401 First line of docstring should be in imperative mood: "A model to use as the fitting function :math:`f(\sigma)`." + --> src/hmf/mass_function/hmf.py:214:9 + | +212 | @parameter("model") +213 | def hmf_model(self, val): +214 | / r""" +215 | | A model to use as the fitting function :math:`f(\sigma)`. +216 | | +217 | | :type: str or `hmf.fitting_functions.FittingFunction` subclass +218 | | """ + | |___________^ +219 | if val is None: +220 | return val + | + +D401 First line of docstring should be in imperative mood: "A model to use as the mass definition." + --> src/hmf/mass_function/hmf.py:234:9 + | +232 | @parameter("model") +233 | def mdef_model(self, val): +234 | / """ +235 | | A model to use as the mass definition. +236 | | +237 | | :type: str or :class:`hmf.halos.mass_definitions.MassDefinition` subclass +238 | | """ + | |___________^ +239 | if val is None or (isinstance(val, str) and val.lower() == "none"): +240 | return None + | + +D205 1 blank line required between summary line and description + --> src/hmf/mass_function/hmf.py:245:9 + | +243 | @parameter("param") +244 | def mdef_params(self, val): +245 | / """ +246 | | Model parameters for `mdef_model`. +247 | | :type: dict. +248 | | """ + | |___________^ +249 | return val + | +help: Insert single blank line + +D401 First line of docstring should be in imperative mood: "The halo mass-definition model instance." + --> src/hmf/mass_function/hmf.py:259:9 + | +257 | @cached_quantity +258 | def mdef(self) -> md: +259 | / """The halo mass-definition model instance. +260 | | +261 | | Default mass definition is the one the chosen hmf model was measured with. +262 | | """ + | |___________^ +263 | if self.mdef_model is None: +264 | # Get the default from the mass function definition + | + +E501 Line too long (89 > 88) + --> src/hmf/mass_function/hmf.py:288:89 + | +286 | raise ValueError( +287 | f"Your input mass definition '{mdef}' does not match the mass " +288 | f"definition in which the hmf fit {self.hmf_model.__name__} was " + | ^ +289 | f"measured: '{self.hmf_model.get_measured_mdef()}' Either allow " +290 | f"automatic mass conversion by setting `disable_mass_conversion=False, " + | + +E501 Line too long (89 > 88) + --> src/hmf/mass_function/hmf.py:289:89 + | +287 | f"Your input mass definition '{mdef}' does not match the mass " +288 | f"definition in which the hmf fit {self.hmf_model.__name__} was " +289 | f"measured: '{self.hmf_model.get_measured_mdef()}' Either allow " + | ^ +290 | f"automatic mass conversion by setting `disable_mass_conversion=False, " +291 | "or use the correct mass definition." + | + +E501 Line too long (96 > 88) + --> src/hmf/mass_function/hmf.py:290:89 + | +288 | f"definition in which the hmf fit {self.hmf_model.__name__} was " +289 | f"measured: '{self.hmf_model.get_measured_mdef()}' Either allow " +290 | f"automatic mass conversion by setting `disable_mass_conversion=False, " + | ^^^^^^^^ +291 | "or use the correct mass definition." +292 | ) + | + +E501 Line too long (94 > 88) + --> src/hmf/mass_function/hmf.py:302:89 + | +300 | warnings.warn( +301 | f"Your input mass definition '{mdef}' does not match the mass " +302 | f"definition in which the hmf fit {self.hmf_model.__name__} was measured:" + | ^^^^^^ +303 | f"'{self.hmf_model.get_measured_mdef()}'. {extra_msg if not self.disable_mass_conversion else ''}", stacklevel=2 +304 | ) + | + +E501 Line too long (132 > 88) + --> src/hmf/mass_function/hmf.py:303:89 + | +301 | f"Your input mass definition '{mdef}' does not match the mass " +302 | f"definition in which the hmf fit {self.hmf_model.__name__} was measured:" +303 | f"'{self.hmf_model.get_measured_mdef()}'. {extra_msg if not self.disable_mass_conversion else ''}", stacklevel=2 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +304 | ) + | + +D401 First line of docstring should be in imperative mood: "Instantiated model for the hmf fitting function." + --> src/hmf/mass_function/hmf.py:310:9 + | +308 | @cached_quantity +309 | def hmf(self): +310 | """Instantiated model for the hmf fitting function.""" + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +311 | return self.hmf_model( +312 | m=self.m, + | + +D401 First line of docstring should be in imperative mood: "Instantiated model for filter/window functions." + --> src/hmf/mass_function/hmf.py:324:9 + | +322 | @cached_quantity +323 | def filter(self): +324 | / """Instantiated model for filter/window functions. +325 | | +326 | | Note that this filter is *not* normalised -- i.e. the output of `filter.sigma(8)` +327 | | will not be the input `sigma_8`. +328 | | """ + | |___________^ +329 | return self.filter_model(self.k, self._unnormalised_power, **self.filter_params) + | + +E501 Line too long (89 > 88) + --> src/hmf/mass_function/hmf.py:326:89 + | +324 | """Instantiated model for filter/window functions. +325 | +326 | Note that this filter is *not* normalised -- i.e. the output of `filter.sigma(8)` + | ^ +327 | will not be the input `sigma_8`. +328 | """ + | + +D401 First line of docstring should be in imperative mood: "The halo overdensity with respect to the mean background." + --> src/hmf/mass_function/hmf.py:333:9 + | +331 | @cached_quantity +332 | def halo_overdensity_mean(self): +333 | """The halo overdensity with respect to the mean background.""" + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +334 | return self.mdef.halo_overdensity_mean(self.z, self.cosmo) + | + +D401 First line of docstring should be in imperative mood: "The halo overdensity with respect to the critical density." + --> src/hmf/mass_function/hmf.py:338:9 + | +336 | @cached_quantity +337 | def halo_overdensity_crit(self): +338 | """The halo overdensity with respect to the critical density.""" + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +339 | return self.mdef.halo_overdensity_crit(self.z, self.cosmo) + | + +D401 First line of docstring should be in imperative mood: "A normalised filter, such that filter.sigma(8) == sigma8." + --> src/hmf/mass_function/hmf.py:343:9 + | +341 | @cached_quantity +342 | def normalised_filter(self): +343 | """A normalised filter, such that filter.sigma(8) == sigma8.""" + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +344 | return self.filter_model(self.k, self.power, **self.filter_params) + | + +D401 First line of docstring should be in imperative mood: "The normalised mass variance at z=0 :math:`\sigma`." + --> src/hmf/mass_function/hmf.py:358:9 + | +356 | @cached_quantity +357 | def _sigma_0(self): +358 | r"""The normalised mass variance at z=0 :math:`\sigma`.""" + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +359 | return self._normalisation * self._unn_sigma0 + | + +D401 First line of docstring should be in imperative mood: "The radii corresponding to the masses `m`." + --> src/hmf/mass_function/hmf.py:368:9 + | +366 | @cached_quantity +367 | def radii(self): +368 | / """The radii corresponding to the masses `m`. +369 | | +370 | | Note that these are not the halo radii -- they are the radii containing mass +371 | | m given a purely background density. +372 | | """ + | |___________^ +373 | return self.filter.mass_to_radius(self.m, self.mean_density0) + | + +D401 First line of docstring should be in imperative mood: "The value of :math:`\left|\frac{\d \ln \sigma}{\d \ln m}\right|`, ``len=len(m)``." + --> src/hmf/mass_function/hmf.py:377:9 + | +375 | @cached_quantity +376 | def _dlnsdlnm(self): +377 | / r""" +378 | | The value of :math:`\left|\frac{\d \ln \sigma}{\d \ln m}\right|`, ``len=len(m)``. +379 | | +380 | | Notes +381 | | ----- +382 | | .. math:: frac{d\ln\sigma}{d\ln m} = \frac{3}{2\sigma^2\pi^2R^4}\int_0^\infty \frac{dW^2(kR)}{dM}\frac{P(k)}{k^2}dk +383 | | """ + | |___________^ +384 | return 0.5 * self.filter.dlnss_dlnm(self.radii) + | + +E501 Line too long (89 > 88) + --> src/hmf/mass_function/hmf.py:378:89 + | +376 | def _dlnsdlnm(self): +377 | r""" +378 | The value of :math:`\left|\frac{\d \ln \sigma}{\d \ln m}\right|`, ``len=len(m)``. + | ^ +379 | +380 | Notes + | + +E501 Line too long (123 > 88) + --> src/hmf/mass_function/hmf.py:382:89 + | +380 | Notes +381 | ----- +382 | .. math:: frac{d\ln\sigma}{d\ln m} = \frac{3}{2\sigma^2\pi^2R^4}\int_0^\infty \frac{dW^2(kR)}{dM}\frac{P(k)}{k^2}dk + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +383 | """ +384 | return 0.5 * self.filter.dlnss_dlnm(self.radii) + | + +D401 First line of docstring should be in imperative mood: "The sqrt of the mass variance at `z`, ``len=len(m)``." + --> src/hmf/mass_function/hmf.py:388:9 + | +386 | @cached_quantity +387 | def sigma(self): +388 | """The sqrt of the mass variance at `z`, ``len=len(m)``.""" + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +389 | return self._sigma_0 * self.growth_factor + | + +D401 First line of docstring should be in imperative mood: "The parameter :math:`\nu = \left(\frac{\delta_c}{\sigma}\right)^2`, ``len=len(m)``." + --> src/hmf/mass_function/hmf.py:393:9 + | +391 | @cached_quantity +392 | def nu(self): +393 | r"""The parameter :math:`\nu = \left(\frac{\delta_c}{\sigma}\right)^2`, ``len=len(m)``.""" + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +394 | return (self.delta_c / self.sigma) ** 2 + | + +E501 Line too long (98 > 88) + --> src/hmf/mass_function/hmf.py:393:89 + | +391 | @cached_quantity +392 | def nu(self): +393 | r"""The parameter :math:`\nu = \left(\frac{\delta_c}{\sigma}\right)^2`, ``len=len(m)``.""" + | ^^^^^^^^^^ +394 | return (self.delta_c / self.sigma) ** 2 + | + +D205 1 blank line required between summary line and description + --> src/hmf/mass_function/hmf.py:398:9 + | +396 | @cached_quantity +397 | def nu_fn(self): +398 | / r""" +399 | | The parameter :math:`\nu = \left(\frac{\delta_c}{\sigma}\right)^2`, ``len=len(m)`` +400 | | as a callable function. +401 | | """ + | |___________^ +402 | return spline(self.m, self.nu, k=5) + | +help: Insert single blank line + +D401 First line of docstring should be in imperative mood: "The parameter :math:`\nu = \left(\frac{\delta_c}{\sigma}\right)^2`, ``len=len(m)``" + --> src/hmf/mass_function/hmf.py:398:9 + | +396 | @cached_quantity +397 | def nu_fn(self): +398 | / r""" +399 | | The parameter :math:`\nu = \left(\frac{\delta_c}{\sigma}\right)^2`, ``len=len(m)`` +400 | | as a callable function. +401 | | """ + | |___________^ +402 | return spline(self.m, self.nu, k=5) + | + +E501 Line too long (90 > 88) + --> src/hmf/mass_function/hmf.py:399:89 + | +397 | def nu_fn(self): +398 | r""" +399 | The parameter :math:`\nu = \left(\frac{\delta_c}{\sigma}\right)^2`, ``len=len(m)`` + | ^^ +400 | as a callable function. +401 | """ + | + +D401 First line of docstring should be in imperative mood: "The nonlinear mass, nu(Mstar) = 1." + --> src/hmf/mass_function/hmf.py:406:9 + | +404 | @cached_quantity +405 | def mass_nonlinear(self): +406 | """The nonlinear mass, nu(Mstar) = 1.""" + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +407 | if self.nu.min() > 1 or self.nu.max() < 1: +408 | warnings.warn("Nonlinear mass outside mass range", stacklevel=2) + | + +D401 First line of docstring should be in imperative mood: "The multiplicity function, :math:`f(\sigma)`, for `hmf_model`. ``len=len(m)``." + --> src/hmf/mass_function/hmf.py:469:9 + | +467 | @cached_quantity +468 | def fsigma(self): +469 | r"""The multiplicity function, :math:`f(\sigma)`, for `hmf_model`. ``len=len(m)``.""" + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +470 | return self.hmf.fsigma + | + +E501 Line too long (93 > 88) + --> src/hmf/mass_function/hmf.py:469:89 + | +467 | @cached_quantity +468 | def fsigma(self): +469 | r"""The multiplicity function, :math:`f(\sigma)`, for `hmf_model`. ``len=len(m)``.""" + | ^^^^^ +470 | return self.hmf.fsigma + | + +D401 First line of docstring should be in imperative mood: "The number density of haloes, ``len=len(m)`` [units :math:`h^4 M_\odot^{-1} Mpc^{-3}`]." + --> src/hmf/mass_function/hmf.py:474:9 + | +472 | @cached_quantity +473 | def dndm(self): +474 | r"""The number density of haloes, ``len=len(m)`` [units :math:`h^4 M_\odot^{-1} Mpc^{-3}`].""" + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +475 | # if self.z2 is None: # #This is normally the case +476 | dndm = self.fsigma * self.mean_density0 * np.abs(self._dlnsdlnm) / self.m**2 + | + +E501 Line too long (102 > 88) + --> src/hmf/mass_function/hmf.py:474:89 + | +472 | @cached_quantity +473 | def dndm(self): +474 | r"""The number density of haloes, ``len=len(m)`` [units :math:`h^4 M_\odot^{-1} Mpc^{-3}`].""" + | ^^^^^^^^^^^^^^ +475 | # if self.z2 is None: # #This is normally the case +476 | dndm = self.fsigma * self.mean_density0 * np.abs(self._dlnsdlnm) / self.m**2 + | + +D401 First line of docstring should be in imperative mood: "The differential mass function in terms of natural log of `m`, ``len=len(m)`` [units :math:`h^3 Mpc^{-3}`]." + --> src/hmf/mass_function/hmf.py:503:9 + | +501 | @cached_quantity +502 | def dndlnm(self): +503 | r"""The differential mass function in terms of natural log of `m`, ``len=len(m)`` [units :math:`h^3 Mpc^{-3}`].""" + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +504 | return self.m * self.dndm + | + +E501 Line too long (122 > 88) + --> src/hmf/mass_function/hmf.py:503:89 + | +501 | @cached_quantity +502 | def dndlnm(self): +503 | r"""The differential mass function in terms of natural log of `m`, ``len=len(m)`` [units :math:`h^3 Mpc^{-3}`].""" + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +504 | return self.m * self.dndm + | + +D401 First line of docstring should be in imperative mood: "The differential mass function in terms of log of `m`, ``len=len(m)`` [units :math:`h^3 Mpc^{-3}`]." + --> src/hmf/mass_function/hmf.py:508:9 + | +506 | @cached_quantity +507 | def dndlog10m(self): +508 | r"""The differential mass function in terms of log of `m`, ``len=len(m)`` [units :math:`h^3 Mpc^{-3}`].""" + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +509 | return self.m * self.dndm * np.log(10) + | + +E501 Line too long (114 > 88) + --> src/hmf/mass_function/hmf.py:508:89 + | +506 | @cached_quantity +507 | def dndlog10m(self): +508 | r"""The differential mass function in terms of log of `m`, ``len=len(m)`` [units :math:`h^3 Mpc^{-3}`].""" + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +509 | return self.m * self.dndm * np.log(10) + | + +SIM102 Use a single `if` statement instead of nested `if` statements + --> src/hmf/mass_function/hmf.py:533:9 + | +531 | # The dlog10m is NOT CHANGED, so the input needs to be finely spaced. +532 | # If the top value of dndm is NaN, don't try calculating higher masses. +533 | / if m[-1] < 10**16.5 and not np.isnan(dndm[-1]) and dndm[-1] != 0: +534 | | # ff.Behroozi function won't work here. +535 | | if not isinstance(self.hmf, ff.Behroozi): + | |_____________________________________________________^ +536 | new_mf = copy.deepcopy(self) +537 | new_mf.update(Mmin=np.log10(self.m[-1]) + self.dlog10m, Mmax=18) + | +help: Combine `if` statements using `and` + +ERA001 Found commented-out code + --> src/hmf/mass_function/hmf.py:548:13 + | +546 | if len(ngtm) < len(m): # Will happen if some dndlnm are NaN +547 | ngtm_temp = np.zeros(len(dndm)) +548 | # ngtm_temp[:] = np.nan + | ^^^^^^^^^^^^^^^^^^^^^^^ +549 | ngtm_temp[dndm > 0] = ngtm +550 | ngtm = ngtm_temp + | +help: Remove commented-out code + +D401 First line of docstring should be in imperative mood: "The cumulative mass function above `m`, ``len=len(m)`` [units :math:`h^3 Mpc^{-3}`]." + --> src/hmf/mass_function/hmf.py:557:9 + | +555 | @cached_quantity +556 | def ngtm(self): +557 | / r""" +558 | | The cumulative mass function above `m`, ``len=len(m)`` [units :math:`h^3 Mpc^{-3}`]. +559 | | +560 | | In the case that `m` does not extend to sufficiently high masses, this +561 | | routine will auto-generate ``dndm`` for an extended mass range. +562 | | +563 | | In the case of the ff.Behroozi fit, it is impossible to auto-extend the mass +564 | | range except by the power-law fit, thus one should be careful to supply +565 | | appropriate mass ranges in this case. +566 | | """ + | |___________^ +567 | return self._gtm(self.dndm) + | + +E501 Line too long (92 > 88) + --> src/hmf/mass_function/hmf.py:558:89 + | +556 | def ngtm(self): +557 | r""" +558 | The cumulative mass function above `m`, ``len=len(m)`` [units :math:`h^3 Mpc^{-3}`]. + | ^^^^ +559 | +560 | In the case that `m` does not extend to sufficiently high masses, this + | + +E501 Line too long (89 > 88) + --> src/hmf/mass_function/hmf.py:572:89 + | +570 | def rho_gtm(self): +571 | r""" +572 | Mass density in haloes `>m`, ``len=len(m)`` [units :math:`M_\odot h^2 Mpc^{-3}`]. + | ^ +573 | +574 | In the case that `m` does not extend to sufficiently high masses, this + | + +E501 Line too long (89 > 88) + --> src/hmf/mass_function/hmf.py:586:89 + | +584 | def rho_ltm(self): +585 | r""" +586 | Mass density in haloes ` src/hmf/mass_function/hmf.py:606:9 + | +604 | @cached_quantity +605 | def how_big(self): +606 | / r""" +607 | | Size of simulation volume in which to expect one halo of mass m (with 95% probability), ` +608 | | `len=len(m)`` [units :math:`Mpch^{-1}`]. +609 | | """ + | |___________^ +610 | return (0.366362 / self.ngtm) ** (1.0 / 3.0) + | +help: Insert single blank line + +E501 Line too long (97 > 88) + --> src/hmf/mass_function/hmf.py:607:89 + | +605 | def how_big(self): +606 | r""" +607 | Size of simulation volume in which to expect one halo of mass m (with 95% probability), ` + | ^^^^^^^^^ +608 | `len=len(m)`` [units :math:`Mpch^{-1}`]. +609 | """ + | + +E501 Line too long (103 > 88) + --> src/hmf/mass_function/integrate_hmf.py:1:89 + | +1 | """A supporting module that provides a routine to integrate the differential hmf in a robust manner.""" + | ^^^^^^^^^^^^^^^ +2 | +3 | import numpy as np + | + +N813 Camelcase `InterpolatedUnivariateSpline` imported as lowercase `_spline` + --> src/hmf/mass_function/integrate_hmf.py:5:31 + | +3 | import numpy as np +4 | import scipy.integrate as intg +5 | from scipy.interpolate import InterpolatedUnivariateSpline as _spline + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + +N818 Exception name `NaNException` should be named with an Error suffix + --> src/hmf/mass_function/integrate_hmf.py:8:7 + | +8 | class NaNException(Exception): + | ^^^^^^^^^^^^ +9 | """Integrator hit a NaN.""" + | + +E501 Line too long (93 > 88) + --> src/hmf/mass_function/integrate_hmf.py:62:89 + | +60 | if len(m) < 4: +61 | raise NaNException( +62 | f"There are too few real numbers in dndm: len(dndm) = {n}, #NaN's = {n - len(m)}" + | ^^^^^ +63 | ) + | + +PTH123 `open()` should be replaced by `Path.open()` + --> tests/test_cli.py:37:10 + | +35 | """ +36 | +37 | with open(tmpdir / "cfg.toml", "w") as fl: + | ^^^^ +38 | fl.write(cfg) + | +help: Replace with `Path.open()` + +PTH123 `open()` should be replaced by `Path.open()` + --> tests/test_cli.py:65:10 + | +63 | """ +64 | +65 | with open(tmpdir / "cfg.toml", "w") as fl: + | ^^^^ +66 | fl.write(cfg) + | +help: Replace with `Path.open()` + +PTH123 `open()` should be replaced by `Path.open()` + --> tests/test_cli.py:109:10 + | +107 | """ +108 | +109 | with open(tmpdir / "cfg.toml", "w") as fl: + | ^^^^ +110 | fl.write(cfg) + | +help: Replace with `Path.open()` + +D404 First word of the docstring should not be "This" + --> tests/test_fcoll.py:1:1 + | +1 | / """ +2 | | This module provides some tests of mgtm/mean_density0 against analytic f_coll. +3 | | +4 | | As such, it is the best test of all calculations after sigma. +5 | | """ + | |___^ +6 | +7 | import numpy as np + | + +N802 Function name `fcoll_PS` should be lowercase + --> tests/test_fcoll.py:40:5 + | +40 | def fcoll_PS(nu): + | ^^^^^^^^ +41 | return erfc(nu / np.sqrt(2)) + | + +N802 Function name `fcoll_Peacock` should be lowercase + --> tests/test_fcoll.py:44:5 + | +44 | def fcoll_Peacock(nu): + | ^^^^^^^^^^^^^ +45 | a = 1.529 +46 | b = 0.704 + | + +N803 Argument name `Mmin` should be lowercase + --> tests/test_fcoll.py:77:40 + | +75 | ], +76 | ) +77 | def test_ranges_cut(self, peacock, Mmin, Mmax): + | ^^^^ +78 | peacock.update(Mmin=Mmin, Mmax=Mmax) + | + +N803 Argument name `Mmax` should be lowercase + --> tests/test_fcoll.py:77:46 + | +75 | ], +76 | ) +77 | def test_ranges_cut(self, peacock, Mmin, Mmax): + | ^^^^ +78 | peacock.update(Mmin=Mmin, Mmax=Mmax) + | + +N803 Argument name `Mmax` should be lowercase + --> tests/test_fcoll.py:90:29 + | +89 | @pytest.mark.parametrize("Mmax", [14, 15, 16, 18, 19]) +90 | def test_mgtm(self, ps, Mmax): + | ^^^^ +91 | ps.update(Mmax=Mmax) +92 | print("rhogtm: ", ps.rho_gtm) + | + +N803 Argument name `Mmax` should be lowercase + --> tests/test_fcoll.py:99:29 + | + 98 | @pytest.mark.parametrize("Mmax", [14, 15, 16, 18, 19]) + 99 | def test_mltm(self, ps, Mmax): + | ^^^^ +100 | ps.update(Mmax=Mmax) +101 | print(np.abs(ps.rho_ltm[-1] / ps.mean_density0 - 1)) + | + +E501 Line too long (108 > 88) + --> tests/test_filters.py:1:89 + | +1 | """Analytic functions for this test are defined in "analytic_filter.ipynb" in the development/ directory.""" + | ^^^^^^^^^^^^^^^^^^^^ +2 | +3 | import warnings + | + +N806 Variable `R` in function should be lowercase + --> tests/test_filters.py:23:9 + | +22 | def test_sigma(self, cls): +23 | R = 1.0 + | ^ +24 | true = ( +25 | 9 * R**2 * sin(R) ** 2 / 2 + | + +N806 Variable `R` in function should be lowercase + --> tests/test_filters.py:35:9 + | +34 | def test_sigma1(self, cls): +35 | R = 1.0 + | ^ +36 | true = ( +37 | 3 * R**2 * sin(R) ** 2 / 2 + | + +N806 Variable `R` in function should be lowercase + --> tests/test_filters.py:54:9 + | +53 | def test_dlnssdlnr(self, cls): +54 | R = 1.0 + | ^ +55 | true = ( +56 | 2 + | + +N806 Variable `R` in function should be lowercase + --> tests/test_filters.py:84:9 + | +83 | def test_sigma(self, cls): +84 | R = 1.0 + | ^ +85 | t = 2 + 2 + 1 +86 | true = 1.0 / (2 * pi**2 * t * R**t) + | + +N806 Variable `R` in function should be lowercase + --> tests/test_filters.py:92:9 + | +91 | def test_sigma1(self, cls): +92 | R = 1.0 + | ^ +93 | t = 4 + 2 + 1 +94 | true = 1.0 / (2 * pi**2 * t * R**t) + | + +N806 Variable `R` in function should be lowercase + --> tests/test_filters.py:100:9 + | + 99 | def test_dlnssdlnr(self, cls): +100 | R = 1.0 + | ^ +101 | t = 2 + 2 + 1 +102 | sigma2 = 1.0 / (2 * pi**2 * t * R**t) + | + +N802 Function name `test_sigma_R3` should be lowercase + --> tests/test_filters.py:108:9 + | +106 | assert np.isclose(cls.dlnss_dlnr(R), true) +107 | +108 | def test_sigma_R3(self, cls): + | ^^^^^^^^^^^^^ +109 | R = 3.0 +110 | t = 2 + 2 + 1 + | +help: Consider adding `@typing.override` if this method overrides a method from a superclass + +N806 Variable `R` in function should be lowercase + --> tests/test_filters.py:109:9 + | +108 | def test_sigma_R3(self, cls): +109 | R = 3.0 + | ^ +110 | t = 2 + 2 + 1 +111 | true = 1.0 / (2 * pi**2 * t * R**t) + | + +N802 Function name `test_sigma1_R3` should be lowercase + --> tests/test_filters.py:116:9 + | +114 | assert np.isclose(cls.sigma(R)[0] ** 2, true) +115 | +116 | def test_sigma1_R3(self, cls): + | ^^^^^^^^^^^^^^ +117 | R = 3.0 +118 | t = 4 + 2 + 1 + | +help: Consider adding `@typing.override` if this method overrides a method from a superclass + +N806 Variable `R` in function should be lowercase + --> tests/test_filters.py:117:9 + | +116 | def test_sigma1_R3(self, cls): +117 | R = 3.0 + | ^ +118 | t = 4 + 2 + 1 +119 | true = 1.0 / (2 * pi**2 * t * R**t) + | + +N802 Function name `test_dlnssdlnr_R3` should be lowercase + --> tests/test_filters.py:124:9 + | +122 | assert np.isclose(cls.sigma(R, 1)[0] ** 2, true) +123 | +124 | def test_dlnssdlnr_R3(self, cls): + | ^^^^^^^^^^^^^^^^^ +125 | R = 3.0 +126 | t = 2 + 2 + 1 + | +help: Consider adding `@typing.override` if this method overrides a method from a superclass + +N806 Variable `R` in function should be lowercase + --> tests/test_filters.py:125:9 + | +124 | def test_dlnssdlnr_R3(self, cls): +125 | R = 3.0 + | ^ +126 | t = 2 + 2 + 1 +127 | sigma2 = 1.0 / (2 * pi**2 * t * R**t) + | + +N802 Function name `test_sigma_Rhalf` should be lowercase + --> tests/test_filters.py:133:9 + | +131 | assert np.isclose(cls.dlnss_dlnr(R), true) +132 | +133 | def test_sigma_Rhalf(self, cls): + | ^^^^^^^^^^^^^^^^ +134 | thisr = 1.0 / cls.k.max() +135 | t = 2 + 2 + 1 + | +help: Consider adding `@typing.override` if this method overrides a method from a superclass + +PT031 `pytest.warns()` block should contain a single simple statement + --> tests/test_filters.py:138:9 + | +136 | true = 1.0 / (2 * pi**2 * t * thisr**t) +137 | +138 | / with pytest.warns(UserWarning): +139 | | # should also raise a warning +140 | | R = 0.5 +141 | | s2 = cls.sigma(R)[0] ** 2 + | |_____________________________________^ +142 | assert np.isclose(s2, true) + | + +PT030 `pytest.warns(UserWarning)` is too broad, set the `match` parameter or use a more specific warning + --> tests/test_filters.py:138:27 + | +136 | true = 1.0 / (2 * pi**2 * t * thisr**t) +137 | +138 | with pytest.warns(UserWarning): + | ^^^^^^^^^^^ +139 | # should also raise a warning +140 | R = 0.5 + | + +N806 Variable `R` in function should be lowercase + --> tests/test_filters.py:140:13 + | +138 | with pytest.warns(UserWarning): +139 | # should also raise a warning +140 | R = 0.5 + | ^ +141 | s2 = cls.sigma(R)[0] ** 2 +142 | assert np.isclose(s2, true) + | + +N802 Function name `test_sigma1_Rhalf` should be lowercase + --> tests/test_filters.py:144:9 + | +142 | assert np.isclose(s2, true) +143 | +144 | def test_sigma1_Rhalf(self, cls): + | ^^^^^^^^^^^^^^^^^ +145 | thisr = 1.0 / cls.k.max() + | +help: Consider adding `@typing.override` if this method overrides a method from a superclass + +PT031 `pytest.warns()` block should contain a single simple statement + --> tests/test_filters.py:150:9 + | +148 | true = 1.0 / (2 * pi**2 * t * thisr**t) +149 | +150 | / with pytest.warns(UserWarning): +151 | | # should also raise a warning +152 | | R = 0.5 +153 | | s2 = cls.sigma(R, 1)[0] ** 2 + | |________________________________________^ +154 | assert np.isclose(s2, true) + | + +PT030 `pytest.warns(UserWarning)` is too broad, set the `match` parameter or use a more specific warning + --> tests/test_filters.py:150:27 + | +148 | true = 1.0 / (2 * pi**2 * t * thisr**t) +149 | +150 | with pytest.warns(UserWarning): + | ^^^^^^^^^^^ +151 | # should also raise a warning +152 | R = 0.5 + | + +N806 Variable `R` in function should be lowercase + --> tests/test_filters.py:152:13 + | +150 | with pytest.warns(UserWarning): +151 | # should also raise a warning +152 | R = 0.5 + | ^ +153 | s2 = cls.sigma(R, 1)[0] ** 2 +154 | assert np.isclose(s2, true) + | + +N802 Function name `test_dlnssdlnr_Rhalf` should be lowercase + --> tests/test_filters.py:156:9 + | +154 | assert np.isclose(s2, true) +155 | +156 | def test_dlnssdlnr_Rhalf(self, cls): + | ^^^^^^^^^^^^^^^^^^^^ +157 | R = 3.0 +158 | t = 2 + 2 + 1 + | +help: Consider adding `@typing.override` if this method overrides a method from a superclass + +N806 Variable `R` in function should be lowercase + --> tests/test_filters.py:157:9 + | +156 | def test_dlnssdlnr_Rhalf(self, cls): +157 | R = 3.0 + | ^ +158 | t = 2 + 2 + 1 +159 | sigma2 = 1.0 / (2 * pi**2 * t * R**t) + | + +N806 Variable `R` in function should be lowercase + --> tests/test_filters.py:174:9 + | +173 | def test_sigma(self, cls): +174 | R = 10.0 + | ^ +175 | true = 3.0 / (16 * pi ** (3.0 / 2.0) * R**5) + | + +N806 Variable `R` in function should be lowercase + --> tests/test_filters.py:181:9 + | +180 | def test_sigma1(self, cls): +181 | R = 10.0 + | ^ +182 | true = 15 / (32 * pi ** (3.0 / 2.0) * R**7) + | + +N806 Variable `R` in function should be lowercase + --> tests/test_filters.py:188:9 + | +187 | def test_dlnssdlnr(self, cls): +188 | R = 10.0 + | ^ +189 | true = -5 + | + +PT013 Incorrect import of `pytest`; use `import pytest` instead + --> tests/test_fits.py:6:1 + | +4 | import numpy as np +5 | import pytest +6 | from pytest import raises + | ^^^^^^^^^^^^^^^^^^^^^^^^^ +7 | +8 | from hmf import MassFunction + | + +D205 1 blank line required between summary line and description + --> tests/test_fits.py:51:5 + | +49 | @pytest.mark.parametrize(("redshift", "fit"), itertools.product([0.0, 2.0], allfits)) +50 | def test_allfits(hmf, ps_max, redshift, fit): +51 | / """ +52 | | This basically tests all implemented fits to check the form for three things: +53 | | 1) whether the maximum fsigma is less than in the PS formula (which is known to overestimate) +54 | | 2) whether the slope is positive below this maximum +55 | | 3) whether the slope is negative above this maximum. +56 | | +57 | | Since it calls each class, any blatant errors should also pop up. +58 | | """ + | |_______^ +59 | hmf.update(z=redshift, hmf_model=fit) +60 | maxarg = np.argmax(hmf.fsigma) + | +help: Insert single blank line + +D404 First word of the docstring should not be "This" + --> tests/test_fits.py:51:5 + | +49 | @pytest.mark.parametrize(("redshift", "fit"), itertools.product([0.0, 2.0], allfits)) +50 | def test_allfits(hmf, ps_max, redshift, fit): +51 | / """ +52 | | This basically tests all implemented fits to check the form for three things: +53 | | 1) whether the maximum fsigma is less than in the PS formula (which is known to overestimate) +54 | | 2) whether the slope is positive below this maximum +55 | | 3) whether the slope is negative above this maximum. +56 | | +57 | | Since it calls each class, any blatant errors should also pop up. +58 | | """ + | |_______^ +59 | hmf.update(z=redshift, hmf_model=fit) +60 | maxarg = np.argmax(hmf.fsigma) + | + +E501 Line too long (97 > 88) + --> tests/test_fits.py:53:89 + | +51 | """ +52 | This basically tests all implemented fits to check the form for three things: +53 | 1) whether the maximum fsigma is less than in the PS formula (which is known to overestimate) + | ^^^^^^^^^ +54 | 2) whether the slope is positive below this maximum +55 | 3) whether the slope is negative above this maximum. + | + +PT012 `pytest.raises()` block should contain a single simple statement + --> tests/test_fits.py:96:5 + | + 95 | def test_tinker10_neg_gam(): + 96 | / with raises(ValueError): + 97 | | h = MassFunction( + 98 | | hmf_model="Tinker10", hmf_params={"gamma_200": -1}, transfer_model="EH" + 99 | | ) +100 | | h.fsigma + | |________________^ + | + +PT011 `pytest.raises(ValueError)` is too broad, set the `match` parameter or use a more specific exception + --> tests/test_fits.py:96:17 + | +95 | def test_tinker10_neg_gam(): +96 | with raises(ValueError): + | ^^^^^^^^^^ +97 | h = MassFunction( +98 | hmf_model="Tinker10", hmf_params={"gamma_200": -1}, transfer_model="EH" + | + +B018 Found useless expression. Either assign it to a variable or remove it. + --> tests/test_fits.py:100:9 + | + 98 | hmf_model="Tinker10", hmf_params={"gamma_200": -1}, transfer_model="EH" + 99 | ) +100 | h.fsigma + | ^^^^^^^^ + | + +PT012 `pytest.raises()` block should contain a single simple statement + --> tests/test_fits.py:104:5 + | +103 | def test_tinker10_neg_eta(): +104 | / with raises(ValueError): +105 | | h = MassFunction( +106 | | hmf_model="Tinker10", hmf_params={"eta_200": -1}, transfer_model="EH" +107 | | ) +108 | | h.fsigma + | |________________^ + | + +PT011 `pytest.raises(ValueError)` is too broad, set the `match` parameter or use a more specific exception + --> tests/test_fits.py:104:17 + | +103 | def test_tinker10_neg_eta(): +104 | with raises(ValueError): + | ^^^^^^^^^^ +105 | h = MassFunction( +106 | hmf_model="Tinker10", hmf_params={"eta_200": -1}, transfer_model="EH" + | + +B018 Found useless expression. Either assign it to a variable or remove it. + --> tests/test_fits.py:108:9 + | +106 | hmf_model="Tinker10", hmf_params={"eta_200": -1}, transfer_model="EH" +107 | ) +108 | h.fsigma + | ^^^^^^^^ + | + +PT012 `pytest.raises()` block should contain a single simple statement + --> tests/test_fits.py:112:5 + | +111 | def test_tinker10_neg_etaphi(): +112 | / with raises(ValueError): +113 | | h = MassFunction( +114 | | hmf_model="Tinker10", +115 | | hmf_params={"eta_200": -1, "phi_200": 0}, +116 | | transfer_model="EH", +117 | | ) +118 | | h.fsigma + | |________________^ + | + +PT011 `pytest.raises(ValueError)` is too broad, set the `match` parameter or use a more specific exception + --> tests/test_fits.py:112:17 + | +111 | def test_tinker10_neg_etaphi(): +112 | with raises(ValueError): + | ^^^^^^^^^^ +113 | h = MassFunction( +114 | hmf_model="Tinker10", + | + +B018 Found useless expression. Either assign it to a variable or remove it. + --> tests/test_fits.py:118:9 + | +116 | transfer_model="EH", +117 | ) +118 | h.fsigma + | ^^^^^^^^ + | + +PT012 `pytest.raises()` block should contain a single simple statement + --> tests/test_fits.py:122:5 + | +121 | def test_tinker10_neg_beta(): +122 | / with raises(ValueError): +123 | | h = MassFunction( +124 | | hmf_model="Tinker10", hmf_params={"beta_200": -1}, transfer_model="EH" +125 | | ) +126 | | h.fsigma + | |________________^ + | + +PT011 `pytest.raises(ValueError)` is too broad, set the `match` parameter or use a more specific exception + --> tests/test_fits.py:122:17 + | +121 | def test_tinker10_neg_beta(): +122 | with raises(ValueError): + | ^^^^^^^^^^ +123 | h = MassFunction( +124 | hmf_model="Tinker10", hmf_params={"beta_200": -1}, transfer_model="EH" + | + +B018 Found useless expression. Either assign it to a variable or remove it. + --> tests/test_fits.py:126:9 + | +124 | hmf_model="Tinker10", hmf_params={"beta_200": -1}, transfer_model="EH" +125 | ) +126 | h.fsigma + | ^^^^^^^^ + | + +PT013 Incorrect import of `pytest`; use `import pytest` instead + --> tests/test_framework.py:3:1 + | +1 | import pytest +2 | from deprecation import fail_if_not_removed +3 | from pytest import raises + | ^^^^^^^^^^^^^^^^^^^^^^^^^ +4 | +5 | import hmf + | + +PT012 `pytest.raises()` block should contain a single simple statement + --> tests/test_framework.py:18:5 + | +17 | def test_incorrect_update_arg(): +18 | / with raises(ValueError): +19 | | t = hmf.MassFunction(transfer_model="EH") +20 | | t.update(wrong_arg=3) + | |_____________________________^ + | + +PT011 `pytest.raises(ValueError)` is too broad, set the `match` parameter or use a more specific exception + --> tests/test_framework.py:18:17 + | +17 | def test_incorrect_update_arg(): +18 | with raises(ValueError): + | ^^^^^^^^^^ +19 | t = hmf.MassFunction(transfer_model="EH") +20 | t.update(wrong_arg=3) + | + +PT031 `pytest.warns()` block should contain a single simple statement + --> tests/test_framework.py:109:5 + | +108 | # Without checking on, we can still manually set it, but it will warn us +109 | / with pytest.warns(DeprecationWarning): +110 | | m.Mmax = 9 +111 | | m.Mmin = 8 + | |__________________^ +112 | +113 | # But with checking on, we can't + | + +PT030 `pytest.warns(DeprecationWarning)` is too broad, set the `match` parameter or use a more specific warning + --> tests/test_framework.py:109:23 + | +108 | # Without checking on, we can still manually set it, but it will warn us +109 | with pytest.warns(DeprecationWarning): + | ^^^^^^^^^^^^^^^^^^ +110 | m.Mmax = 9 +111 | m.Mmin = 8 + | + +D404 First word of the docstring should not be "This" + --> tests/test_genmf.py:1:1 + | + 1 | / """ + 2 | | This module contains a number of tests that check hmf's results against those of genmf. + 3 | | + 4 | | We check results for sigma, lnsigma, and the differential and cumulative mass functions against + 5 | | genmf for two different redshifts (0 and 2). We use precisely the same transfer function here + 6 | | as we use in genmf (tabulated). Another test tests if the power spectrum is generated + 7 | | correctly according to this tabulated version. + 8 | | + 9 | | The data files in the data/ directory are the following: +10 | | ST_0 etc :: output from genmf with given fit and redshift, produced with default cosmology here +11 | | power_for_hmf_tests.dat :: the power spectrum used in genmf +12 | | transfer_for_hmf_tests.dat :: the transfer function used in hmf (corresponds directly to the power) +13 | | +14 | | The power was generated with hmf.transfer itself, so can be used as a direct test +15 | | for later versions. +16 | | +17 | | To be more explicit, the power spectrum in all cases is produced with the following parameters: +18 | | +19 | | "w_lam" :-1, +20 | | "omegab" : 0.05, +21 | | "omegac" : 0.25, +22 | | "omegav" : 0.7, +23 | | "omegan" : 0.0, +24 | | "H0" : 70, +25 | | 'cs2_lam' : 1, +26 | | 'TCMB' : 2.725, +27 | | 'yhe' : 0.24, +28 | | 'Num_NuMassless' : 3.04, +29 | | 'reion__redshift': 10.3, +30 | | 'reion__optical_depth': 0.085 +31 | | "sigma_8":0.8, +32 | | "n":1, +33 | | "delta_c":1.686, +34 | | "crit_dens":27.755 * 10 ** 10 +35 | | 'Num_NuMassive' : 0, +36 | | 'reion__fraction' :-1, +37 | | 'reion__delta_redshift' : 1.5, +38 | | 'lAccuracyBoost' : 1, +39 | | 'lSampleBoost' : 1, +40 | | 'AccuracyBoost' : 1, +41 | | 'transfer__k_per_logint': 0, +42 | | 'transfer__kmax':100.0 +43 | | """ + | |___^ +44 | +45 | from itertools import product + | + +E501 Line too long (95 > 88) + --> tests/test_genmf.py:4:89 + | +2 | This module contains a number of tests that check hmf's results against those of genmf. +3 | +4 | We check results for sigma, lnsigma, and the differential and cumulative mass functions against + | ^^^^^^^ +5 | genmf for two different redshifts (0 and 2). We use precisely the same transfer function here +6 | as we use in genmf (tabulated). Another test tests if the power spectrum is generated + | + +E501 Line too long (93 > 88) + --> tests/test_genmf.py:5:89 + | +4 | We check results for sigma, lnsigma, and the differential and cumulative mass functions against +5 | genmf for two different redshifts (0 and 2). We use precisely the same transfer function here + | ^^^^^ +6 | as we use in genmf (tabulated). Another test tests if the power spectrum is generated +7 | correctly according to this tabulated version. + | + +E501 Line too long (95 > 88) + --> tests/test_genmf.py:10:89 + | + 9 | The data files in the data/ directory are the following: +10 | ST_0 etc :: output from genmf with given fit and redshift, produced with default cosmology here + | ^^^^^^^ +11 | power_for_hmf_tests.dat :: the power spectrum used in genmf +12 | transfer_for_hmf_tests.dat :: the transfer function used in hmf (corresponds directly to the power) + | + +E501 Line too long (99 > 88) + --> tests/test_genmf.py:12:89 + | +10 | ST_0 etc :: output from genmf with given fit and redshift, produced with default cosmology here +11 | power_for_hmf_tests.dat :: the power spectrum used in genmf +12 | transfer_for_hmf_tests.dat :: the transfer function used in hmf (corresponds directly to the power) + | ^^^^^^^^^^^ +13 | +14 | The power was generated with hmf.transfer itself, so can be used as a direct test + | + +E501 Line too long (95 > 88) + --> tests/test_genmf.py:17:89 + | +15 | for later versions. +16 | +17 | To be more explicit, the power spectrum in all cases is produced with the following parameters: + | ^^^^^^^ +18 | +19 | "w_lam" :-1, + | + +PT011 `pytest.raises(ValueError)` is too broad, set the `match` parameter or use a more specific exception + --> tests/test_growth.py:66:24 + | +64 | def test_unsupported_cosmo(): +65 | cosmo = w0waCDM(H0=70.0, Om0=0.3, Ode0=0.7, w0=-0.9, Ob0=0.05, Tcmb0=2.7) +66 | with pytest.raises(ValueError): + | ^^^^^^^^^^ +67 | growth_factor.GenMFGrowth(cosmo=cosmo) + | + +PT013 Incorrect import of `pytest`; use `import pytest` instead + --> tests/test_hmf.py:5:1 + | +3 | import numpy as np +4 | import pytest +5 | from pytest import raises + | ^^^^^^^^^^^^^^^^^^^^^^^^^ +6 | +7 | from hmf import MassFunction + | + +PT011 `pytest.raises(ValueError)` is too broad, set the `match` parameter or use a more specific exception + --> tests/test_hmf.py:11:17 + | +10 | def test_wrong_filter(): +11 | with raises(ValueError): + | ^^^^^^^^^^ +12 | MassFunction(filter_model=2) + | + +PT011 `pytest.raises(ValueError)` is too broad, set the `match` parameter or use a more specific exception + --> tests/test_hmf.py:16:17 + | +15 | def test_string_dc(): +16 | with raises(ValueError): + | ^^^^^^^^^^ +17 | MassFunction(delta_c="this") + | + +PT011 `pytest.raises(ValueError)` is too broad, set the `match` parameter or use a more specific exception + --> tests/test_hmf.py:21:17 + | +20 | def test_neg_dc(): +21 | with raises(ValueError): + | ^^^^^^^^^^ +22 | MassFunction(delta_c=-1) + | + +PT011 `pytest.raises(ValueError)` is too broad, set the `match` parameter or use a more specific exception + --> tests/test_hmf.py:26:17 + | +25 | def test_big_dc(): +26 | with raises(ValueError): + | ^^^^^^^^^^ +27 | MassFunction(delta_c=20.0) + | + +PT011 `pytest.raises(ValueError)` is too broad, set the `match` parameter or use a more specific exception + --> tests/test_hmf.py:31:17 + | +30 | def test_wrong_fit(): +31 | with raises(ValueError): + | ^^^^^^^^^^ +32 | MassFunction(hmf_model=1) + | + +PT011 `pytest.raises(ValueError)` is too broad, set the `match` parameter or use a more specific exception + --> tests/test_hmf.py:36:17 + | +35 | def test_wrong_mf_par(): +36 | with raises(ValueError): + | ^^^^^^^^^^ +37 | MassFunction(hmf_params=2) + | + +PT030 `pytest.warns(UserWarning)` is too broad, set the `match` parameter or use a more specific warning + --> tests/test_hmf.py:49:23 + | +47 | def test_mass_nonlinear_outside_range(): +48 | h = MassFunction(Mmin=8, Mmax=9, transfer_model="EH") +49 | with pytest.warns(UserWarning): + | ^^^^^^^^^^^ +50 | assert h.mass_nonlinear > 0 + | + +ERA001 Found commented-out code + --> tests/test_integrate_hmf.py:32:5 + | +31 | # def test_basic(self): +32 | # m = np.logspace(10,18,500) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +33 | # dndm = self.tggd(m,14.0,-1.9,0.8) +34 | # ngtm = self.anl_int(m,14.0,-1.9,0.8) + | +help: Remove commented-out code + +ERA001 Found commented-out code + --> tests/test_integrate_hmf.py:33:5 + | +31 | # def test_basic(self): +32 | # m = np.logspace(10,18,500) +33 | # dndm = self.tggd(m,14.0,-1.9,0.8) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +34 | # ngtm = self.anl_int(m,14.0,-1.9,0.8) +35 | # + | +help: Remove commented-out code + +ERA001 Found commented-out code + --> tests/test_integrate_hmf.py:34:5 + | +32 | # m = np.logspace(10,18,500) +33 | # dndm = self.tggd(m,14.0,-1.9,0.8) +34 | # ngtm = self.anl_int(m,14.0,-1.9,0.8) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +35 | # +36 | # print ngtm/hmf_integral_gtm(m,dndm) + | +help: Remove commented-out code + +ERA001 Found commented-out code + --> tests/test_integrate_hmf.py:37:5 + | +35 | # +36 | # print ngtm/hmf_integral_gtm(m,dndm) +37 | # assert np.allclose(ngtm,hmf_integral_gtm(m,dndm),rtol=0.03) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +38 | # +39 | # def test_basic_mgtm(self): + | +help: Remove commented-out code + +ERA001 Found commented-out code + --> tests/test_integrate_hmf.py:40:5 + | +38 | # +39 | # def test_basic_mgtm(self): +40 | # m = np.logspace(10,18,500) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +41 | # dndm = self.tggd(m,14.0,-1.9,0.8) +42 | # ngtm = self.anl_m_int(m,14.0,-1.9,0.8) + | +help: Remove commented-out code + +ERA001 Found commented-out code + --> tests/test_integrate_hmf.py:41:5 + | +39 | # def test_basic_mgtm(self): +40 | # m = np.logspace(10,18,500) +41 | # dndm = self.tggd(m,14.0,-1.9,0.8) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +42 | # ngtm = self.anl_m_int(m,14.0,-1.9,0.8) +43 | # + | +help: Remove commented-out code + +ERA001 Found commented-out code + --> tests/test_integrate_hmf.py:42:5 + | +40 | # m = np.logspace(10,18,500) +41 | # dndm = self.tggd(m,14.0,-1.9,0.8) +42 | # ngtm = self.anl_m_int(m,14.0,-1.9,0.8) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +43 | # +44 | # print ngtm/hmf_integral_gtm(m,dndm,True) + | +help: Remove commented-out code + +ERA001 Found commented-out code + --> tests/test_integrate_hmf.py:45:5 + | +43 | # +44 | # print ngtm/hmf_integral_gtm(m,dndm,True) +45 | # assert np.allclose(ngtm,hmf_integral_gtm(m,dndm,True),rtol=0.03) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +46 | +47 | def test_high_z(self): + | +help: Remove commented-out code + +ERA001 Found commented-out code + --> tests/test_integrate_hmf.py:57:5 + | +56 | # def test_low_mmax_z0(self): +57 | # m = np.logspace(10,15,500) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +58 | # dndm = self.tggd(m,14.0,-1.9,0.8) +59 | # ngtm = self.anl_int(m,14.0,-1.9,0.8) + | +help: Remove commented-out code + +ERA001 Found commented-out code + --> tests/test_integrate_hmf.py:58:5 + | +56 | # def test_low_mmax_z0(self): +57 | # m = np.logspace(10,15,500) +58 | # dndm = self.tggd(m,14.0,-1.9,0.8) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +59 | # ngtm = self.anl_int(m,14.0,-1.9,0.8) +60 | # + | +help: Remove commented-out code + +ERA001 Found commented-out code + --> tests/test_integrate_hmf.py:59:5 + | +57 | # m = np.logspace(10,15,500) +58 | # dndm = self.tggd(m,14.0,-1.9,0.8) +59 | # ngtm = self.anl_int(m,14.0,-1.9,0.8) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +60 | # +61 | # print ngtm/hmf_integral_gtm(m,dndm) + | +help: Remove commented-out code + +ERA001 Found commented-out code + --> tests/test_integrate_hmf.py:62:5 + | +60 | # +61 | # print ngtm/hmf_integral_gtm(m,dndm) +62 | # assert np.allclose(ngtm,hmf_integral_gtm(m,dndm),rtol=0.03) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +63 | +64 | def test_low_mmax_high_z(self): + | +help: Remove commented-out code + +PT011 `pytest.raises(ValueError)` is too broad, set the `match` parameter or use a more specific exception + --> tests/test_mdef.py:92:24 + | +90 | assert md.from_colossus_name("vir") == md.SOVirial() +91 | +92 | with pytest.raises(ValueError): + | ^^^^^^^^^^ +93 | md.from_colossus_name("derp") + | + +PT030 `pytest.warns(UserWarning)` is too broad, set the `match` parameter or use a more specific warning + --> tests/test_mdef.py:97:23 + | +96 | def test_change_dndm(colossus_cosmo): +97 | with pytest.warns(UserWarning): + | ^^^^^^^^^^^ +98 | h = MassFunction( +99 | mdef_model="SOVirial", hmf_model="Warren", disable_mass_conversion=False + | + +N813 Camelcase `InterpolatedUnivariateSpline` imported as lowercase `spline` + --> tests/test_sample.py:2:31 + | +1 | import numpy as np +2 | from scipy.interpolate import InterpolatedUnivariateSpline as spline + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +3 | +4 | from hmf.helpers.sample import dndm_from_sample, sample_mf + | + +ERA001 Found commented-out code + --> tests/test_sample.py:22:5 + | +21 | m, h = sample_mf(1e5, 11, transfer_model="EH", Mmax=18, rng=rng) +22 | # centres,hist = dndm_from_sample(m,1e5/h.ngtm[0]) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +23 | # print centres,hist +24 | dndm_from_sample(m, 1e5 / h.ngtm[0]) + | +help: Remove commented-out code + +N806 Variable `T` in function should be lowercase + --> tests/test_transfer.py:165:5 + | +163 | assert t.transfer.params["camb_params"].Transfer.kmax == 1.0 +164 | camb_transfers = camb.get_transfer_functions(t.transfer.params["camb_params"]) +165 | T = camb_transfers.get_matter_transfer_data().transfer_data + | ^ +166 | assert np.max(T[0]) < 2.0 + | + +B018 Found useless expression. Either assign it to a variable or remove it. + --> tests/test_transfer.py:203:9 + | +201 | ) +202 | with pytest.raises(ValueError, match="the CMB temperature must be set explicitly"): +203 | t.transfer + | ^^^^^^^^^^ +204 | +205 | t = Transfer( + | + +B018 Found useless expression. Either assign it to a variable or remove it. + --> tests/test_transfer.py:210:9 + | +208 | ) +209 | with pytest.raises(ValueError, match="you must set the baryon density"): +210 | t.transfer + | ^^^^^^^^^^ + | + +PT013 Incorrect import of `pytest`; use `import pytest` instead + --> tests/test_wdm.py:2:1 + | +1 | import numpy as np +2 | from pytest import raises + | ^^^^^^^^^^^^^^^^^^^^^^^^^ +3 | +4 | import hmf + | + +PT012 `pytest.raises()` block should contain a single simple statement + --> tests/test_wdm.py:9:5 + | + 8 | def test_null(): + 9 | / with raises(NotImplementedError): +10 | | w = wdm.WDM(mx=1.0) +11 | | w.transfer(1.0) + | |_______________________^ + | + +N801 Class name `TestSchneider12_vCDM` should use CapWords convention + --> tests/test_wdm.py:39:7 + | +39 | class TestSchneider12_vCDM: + | ^^^^^^^^^^^^^^^^^^^^ +40 | def setup_class(self): +41 | self.cdm = hmf.MassFunction(transfer_model="EH") + | + +PT011 `pytest.raises(ValueError)` is too broad, set the `match` parameter or use a more specific exception + --> tests/test_wdm.py:80:21 + | +79 | def test_wrong_model_type(self): +80 | with raises(ValueError): + | ^^^^^^^^^^ +81 | wdm.TransferWDM(wdm_mass=3.0, wdm_model=3, transfer_model="EH") + | + +Found 594 errors. diff --git a/src/hmf/__init__.py b/src/hmf/__init__.py index b907eddb..f49b8760 100644 --- a/src/hmf/__init__.py +++ b/src/hmf/__init__.py @@ -26,3 +26,33 @@ from .halos import mass_definitions from .helpers import functional, get_best_param_order, get_hmf, sample from .mass_function import MassFunction, fitting_functions, hmf, integrate_hmf + +__all__ = [ + "Component", + "Framework", + "cached_quantity", + "get_base_component", + "get_base_components", + "get_mdl", + "parameter", + "wdm", + "Cosmology", + "GrowthFactor", + "cosmo", + "growth_factor", + "CAMB", + "Transfer", + "filters", + "halofit", + "transfer", + "transfer_models", + "mass_definitions", + "functional", + "get_best_param_order", + "get_hmf", + "sample", + "MassFunction", + "fitting_functions", + "hmf", + "integrate_hmf", +] diff --git a/src/hmf/_cli.py b/src/hmf/_cli.py index a159ee4b..2070bcc2 100644 --- a/src/hmf/_cli.py +++ b/src/hmf/_cli.py @@ -26,7 +26,7 @@ def _get_config(config=None): if config is None: return {} - with open(config) as fl: + with Path(config).open() as fl: cfg = toml.load(fl) # Import an actual framework. @@ -195,7 +195,7 @@ def run_cli(config, pkg_name, args, outdir, label, pkgs, default_framework): # Write out parameters dct = framework_to_dict(obj) dct["quantities"] = quantities - with open(outdir / f"{lab}_cfg.toml", "w") as fl: + with (outdir / f"{lab}_cfg.toml").open("w") as fl: toml.dump(dct, fl, encoder=toml.TomlNumpyEncoder()) console.print( diff --git a/src/hmf/_internals/__init__.py b/src/hmf/_internals/__init__.py index eac1cae2..ba3de716 100644 --- a/src/hmf/_internals/__init__.py +++ b/src/hmf/_internals/__init__.py @@ -13,3 +13,15 @@ pluggable, ) from ._utils import inherit_docstrings + +__all__ = [ + "cached_quantity", + "parameter", + "Component", + "Framework", + "get_base_component", + "get_base_components", + "get_mdl", + "pluggable", + "inherit_docstrings", +] diff --git a/src/hmf/_internals/_cache.py b/src/hmf/_internals/_cache.py index d9c4c908..aaf1ef1f 100644 --- a/src/hmf/_internals/_cache.py +++ b/src/hmf/_internals/_cache.py @@ -1,7 +1,8 @@ """ +Defines caching and parameter decorators for property management. + This module defines two decorators, based on the code from http://forrst.com/posts/Yet_another_caching_property_decorator_for_Pytho-PBy. - They are both designed to cache class properties, but have the added functionality of being automatically updated when a parent property is updated. @@ -78,10 +79,10 @@ def _get_property(self): for pr in activeq: try: recalc_prpa[pr].update(recalc_prpa[name]) - except KeyError: + except KeyError as e: raise KeyError( f"When getting {name}, couldn't find {pr} in recalc_prpa. Had {list(recalc_prpa.keys())}." - ) + ) from e # check all quantities for dependence on subframeworks and update their entries for s in subframeworks: diff --git a/src/hmf/_internals/_framework.py b/src/hmf/_internals/_framework.py index 8639224c..05c341be 100644 --- a/src/hmf/_internals/_framework.py +++ b/src/hmf/_internals/_framework.py @@ -4,6 +4,7 @@ import logging import sys import warnings +from typing import Any, ClassVar, Final import deprecation @@ -24,7 +25,7 @@ class Component: the __init__ method. """ - _defaults = {} + _defaults: ClassVar[Final[dict[str, Any]]] = {} def __init__(self, **model_params): # Check that all parameters passed are valid @@ -78,8 +79,8 @@ def get_base_component(name: [str, type[Component]]) -> type[Component]: try: assert issubclass(name, Component) return name - except TypeError: - raise ValueError(f"{name} must be str or a Component subclass") + except TypeError as e: + raise ValueError(f"{name} must be str or a Component subclass") from e def pluggable(cls): @@ -122,11 +123,11 @@ def get_mdl( if kind is not None: try: return kind._plugins[name] - except KeyError: + except KeyError as e: raise ValueError( f"The model {name} is not a defined {kind} model. Available: " f"{tuple(kind._plugins.keys())}" - ) + ) from e else: # Try to get *any* model called by this name. avail_models = [ @@ -147,8 +148,8 @@ def get_mdl( try: assert issubclass(name, kind or Component) return name - except TypeError: - raise ValueError(f"{name} must be str or Component subclass") + except TypeError as e: + raise ValueError(f"{name} must be str or Component subclass") from e @deprecation.deprecated( diff --git a/src/hmf/alternatives/__init__.py b/src/hmf/alternatives/__init__.py index c9212a1f..e6cd6dab 100644 --- a/src/hmf/alternatives/__init__.py +++ b/src/hmf/alternatives/__init__.py @@ -1,6 +1,9 @@ """ -A subpackage dedicated to providing "plugin"-style alternatives to the standard halo mass function, for example -Warm Dark Matter cosmologies. +Provides plugin-style alternatives to the standard halo mass function. + +Examples include Warm Dark Matter cosmologies. """ from . import wdm + +__all__ = ["wdm"] diff --git a/src/hmf/alternatives/wdm.py b/src/hmf/alternatives/wdm.py index cf648218..8c586d54 100644 --- a/src/hmf/alternatives/wdm.py +++ b/src/hmf/alternatives/wdm.py @@ -7,6 +7,8 @@ for other alternative cosmologies. """ +from typing import ClassVar, Final + import astropy.units as u import numpy as np @@ -100,7 +102,7 @@ class attribute. :g_x: """ - _defaults = {"mu": 1.12, "g_x": 1.5} + _defaults: ClassVar[Final[dict[str, float]]] = {"mu": 1.12, "g_x": 1.5} def transfer(self, k): """Compute the modified WDM transfer function.""" @@ -212,7 +214,7 @@ class Schneider12_vCDM(WDMRecalibrateMF): class attribute. """ - _defaults = {"beta": 1.16} + _defaults: ClassVar[Final[dict[str, float]]] = {"beta": 1.16} def dndm_alter(self): return self.dndm0 * (1 + self.wdm.m_hm / self.m) ** (-self.params["beta"]) @@ -236,7 +238,7 @@ class Schneider12(WDMRecalibrateMF): class attribute. """ - _defaults = {"alpha": 0.6} + _defaults: ClassVar[Final[dict[str, float]]] = {"alpha": 0.6} def dndm_alter(self): return self.dndm0 * (1 + self.wdm.m_hm / self.m) ** (-self.params["alpha"]) @@ -260,7 +262,7 @@ class Lovell14(WDMRecalibrateMF): class attribute. """ - _defaults = {"beta": 0.99, "gamma": 2.7} + _defaults: ClassVar[Final[dict[str, float]]] = {"beta": 0.99, "gamma": 2.7} def dndm_alter(self): return self.dndm0 * (1 + self.params["gamma"] * self.wdm.m_hm / self.m) ** ( @@ -324,8 +326,8 @@ def wdm_mass(self, val): """ try: val = float(val) - except ValueError: - raise ValueError("wdm_mass must be a number (", val, ")") + except ValueError as e: + raise ValueError("wdm_mass must be a number (", val, ")") from e if val <= 0: raise ValueError("wdm_mass must be > 0 (", val, ")") diff --git a/src/hmf/cosmology/__init__.py b/src/hmf/cosmology/__init__.py index 6e222ecb..4baadb24 100644 --- a/src/hmf/cosmology/__init__.py +++ b/src/hmf/cosmology/__init__.py @@ -3,3 +3,10 @@ from . import cosmo from .cosmo import Cosmology, astropy_to_colossus from .growth_factor import GrowthFactor + +__all__ = [ + "cosmo", + "Cosmology", + "astropy_to_colossus", + "GrowthFactor", +] diff --git a/src/hmf/cosmology/cosmo.py b/src/hmf/cosmology/cosmo.py index 22b6f4eb..e0c6ee02 100644 --- a/src/hmf/cosmology/cosmo.py +++ b/src/hmf/cosmology/cosmo.py @@ -41,10 +41,10 @@ def astropy_to_colossus(cosmo: FLRW, name: str = "custom", **kwargs): from colossus.cosmology import cosmology return cosmology.fromAstropy(astropy_cosmo=cosmo, cosmo_name=name, **kwargs) - except ImportError: # pragma: nocover + except ImportError as e: # pragma: nocover raise ImportError( "Cannot convert to COLOSSUS cosmology without installing COLOSSUS!" - ) + ) from e class Cosmology(_framework.Framework): @@ -81,10 +81,13 @@ def __init__(self, cosmo_model=Planck18, cosmo_params=None): @_cache.parameter("model") def cosmo_model(self, val): """ - The basis for the cosmology -- see astropy documentation. Can be a custom - subclass. Defaults to Planck18. + The cosmological model instance. + + Basis for the cosmology with custom subclasses supported. + Defaults to Planck18. See astropy documentation for details. :type: instance of `astropy.cosmology.FLRW` subclass + """ if isinstance(val, str): return get_cosmo(val) @@ -98,10 +101,11 @@ def cosmo_model(self, val): @_cache.parameter("param") def cosmo_params(self, val): """ - Parameters for the cosmology that deviate from the base cosmology passed. - This is useful for repeated updates of a single parameter (leaving others - the same). Default is the empty dict. The parameters passed must match - the allowed parameters of `cosmo_model`. For the basic class this is. + Parameters deviating from the base cosmology. + + Useful for repeated updates of a single parameter, leaving others + the same. Default is the empty dict. Parameters passed must match + the allowed parameters of `cosmo_model`. For the basic class, these are: :Tcmb0: Temperature of the CMB at z=0 :Neff: Number of massless neutrino species @@ -110,6 +114,7 @@ def cosmo_params(self, val): :Om0: The normalised matter density at z=0 :type: dict + """ return val @@ -119,8 +124,11 @@ def cosmo_params(self, val): @_cache.cached_quantity def cosmo(self): """ - Cosmographic object (:class:`astropy.cosmology.FLRW` object), with custom - cosmology from :attr:`~.cosmo_params` applied. + The cosmography object with custom parameters applied. + + A :class:`astropy.cosmology.FLRW` instance with custom cosmology + from :attr:`~.cosmo_params` applied. + """ return self.cosmo_model.clone(**self.cosmo_params) diff --git a/src/hmf/cosmology/growth_factor.py b/src/hmf/cosmology/growth_factor.py index d53687ee..9e24267d 100644 --- a/src/hmf/cosmology/growth_factor.py +++ b/src/hmf/cosmology/growth_factor.py @@ -8,6 +8,7 @@ """ from functools import cached_property +from typing import Any, ClassVar, Final import numpy as np from astropy import cosmology @@ -64,7 +65,7 @@ class GrowthFactor(_GrowthFactor): .. [1] Lukic et. al., ApJ, 2007, http://adsabs.harvard.edu/abs/2007ApJ...671.1160L """ - _defaults = {"dlna": 0.01, "amin": 1e-8} + _defaults: ClassVar[Final[dict[str, float]]] = {"dlna": 0.01, "amin": 1e-8} def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) @@ -219,7 +220,7 @@ class FromFile(GrowthFactor): """ supported_cosmos = (cosmology.LambdaCDM, cosmology.w0waCDM, cosmology.wCDM) - _defaults = {"dlna": 0.01, "amin": 1e-8, "fname": ""} + _defaults: ClassVar[Final[dict[str, Any]]] = {"dlna": 0.01, "amin": 1e-8, "fname": ""} def growth_factor(self, z): r""" @@ -262,7 +263,7 @@ class FromArray(FromFile): """ supported_cosmos = (cosmology.LambdaCDM, cosmology.w0waCDM, cosmology.wCDM) - _defaults = {"dlna": 0.01, "amin": 1e-8, "z": None, "d": None} + _defaults: ClassVar[Final[dict[str, Any]]] = {"dlna": 0.01, "amin": 1e-8, "z": None, "d": None} def growth_factor(self, z): r""" @@ -309,7 +310,7 @@ class GenMFGrowth(GrowthFactor): :zmax: Maximum redshift to integrate to. Only used for :meth:`growth_factor_fn`. """ - _defaults = {"dz": 0.01, "zmax": 1000.0} + _defaults: ClassVar[Final[dict[str, float]]] = {"dz": 0.01, "zmax": 1000.0} @cached_property def _lna(self): @@ -321,8 +322,11 @@ def _zvec(self): def _d_plus(self, z): """ - This is not implemented in this class. It is not - required to calculate :meth:`growth_factor`. + Unnormalized growth factor (not implemented in this class). + + This is not required to calculate :meth:`growth_factor`. + Subclasses must implement this method. + """ raise NotImplementedError # pragma: nocover @@ -401,7 +405,7 @@ class Carroll1992(GrowthFactor): :zmax: Maximum redshift of spline. Only used for :meth:`growth_factor_fn`, when `inverse=True`. """ - _defaults = {"dz": 0.01, "zmax": 1000.0} + _defaults: ClassVar[Final[dict[str, float]]] = {"dz": 0.01, "zmax": 1000.0} @cached_property def _lna(self): @@ -413,9 +417,11 @@ def _zvec(self): def _d_plus(self, z): """ - Calculate un-normalised growth factor as a function - of redshift. Note that the `getvec` argument is not - used in this function. + Calculate the unnormalized growth factor. + + Function of redshift. The `getvec` argument is not used + in this function. + """ a = 1 / (1 + z) @@ -434,10 +440,12 @@ def _d_plus(self, z): @_inherit class CambGrowth(GrowthFactor): """ - Uses CAMB to generate the growth factor, at k/h = 1.0. This class is recommended - if the cosmology is not LambdaCDM (but instead wCDM), as it correctly deals with - the growth in this case. However, it standard LCDM is used, other classes are - preferred, as this class needs to re-calculate the transfer function. + Growth factor computed using CAMB at k/h = 1.0. + + Recommended for non-LambdaCDM cosmologies (e.g., wCDM) as it correctly + deals with their growth evolution. For standard LCDM, other classes are + preferred since this class requires re-calculating the transfer function. + """ supported_cosmos = (cosmology.LambdaCDM, cosmology.w0waCDM, cosmology.wCDM) diff --git a/src/hmf/density_field/__init__.py b/src/hmf/density_field/__init__.py index 30615f89..04f0c81e 100644 --- a/src/hmf/density_field/__init__.py +++ b/src/hmf/density_field/__init__.py @@ -1,6 +1,8 @@ """ -A subpackage dedicated to basic measures of the matter density field -- its 2-point structure, cosmological transfer -functions, and filter functions which can be applied to it. +Provides measures of the matter density field. + +Includes 2-point structure, cosmological transfer functions, and filter +functions which can be applied to the density field. """ from . import filters, transfer, transfer_models @@ -8,3 +10,14 @@ from .halofit import halofit from .transfer import Transfer from .transfer_models import CAMB, EH + +__all__ = [ + "filters", + "transfer", + "transfer_models", + "Filter", + "halofit", + "Transfer", + "CAMB", + "EH", +] diff --git a/src/hmf/density_field/filters.py b/src/hmf/density_field/filters.py index 4372fbf9..5e7cf5b0 100644 --- a/src/hmf/density_field/filters.py +++ b/src/hmf/density_field/filters.py @@ -2,6 +2,7 @@ import collections import warnings +from typing import ClassVar, Final import numpy as np import scipy.integrate as intg @@ -396,7 +397,7 @@ class SharpK(Filter): .. math:: \frac{d\ln \sigma^2}{d \ln R} = -\frac{P(1/R)}{2\pi^2\sigma^2(R)R^3}. """ - _defaults = {"c": 2.5} + _defaults: ClassVar[Final[dict[str, float]]] = {"c": 2.5} def k_space(self, kr): a = np.where(kr > 1, 0, 1) @@ -457,7 +458,7 @@ class SharpKEllipsoid(SharpK): Refer to :class:`~Filter` for more details. """ - _defaults = {"c": 2.0} + _defaults: ClassVar[Final[dict[str, float]]] = {"c": 2.0} def xm(self, g, v): """ diff --git a/src/hmf/density_field/halofit.py b/src/hmf/density_field/halofit.py index ae5ffd2a..a4713acb 100644 --- a/src/hmf/density_field/halofit.py +++ b/src/hmf/density_field/halofit.py @@ -21,7 +21,9 @@ def _get_spec( k: np.ndarray, delta_k: np.ndarray, sigma_8=None ) -> tuple[float, float, float]: """ - Calculate nonlinear wavenumber, effective spectral index and curvature + Calculate spectral parameters from power spectrum. + + Computes the nonlinear wavenumber, effective spectral index, and curvature of the power spectrum. Parameters @@ -31,8 +33,8 @@ def _get_spec( delta_k : array_like Dimensionless power spectrum at `k` sigma_8 : scalar - RMS linear density fluctuations in spheres of radius 8 Mpc/h at z=0. Not - used any more at all! + RMS linear density fluctuations in spheres of radius 8 Mpc/h at z=0. + Not used any more at all! Returns ------- @@ -42,6 +44,7 @@ def _get_spec( Effective spectral index n_curv : float Curvature of the spectrum + """ # Initialize sigma spline diff --git a/src/hmf/density_field/transfer.py b/src/hmf/density_field/transfer.py index 5f4970be..9eb09845 100644 --- a/src/hmf/density_field/transfer.py +++ b/src/hmf/density_field/transfer.py @@ -209,8 +209,8 @@ def z(self, val): """ try: val = float(val) - except ValueError: - raise ValueError("z must be a number (", val, ")") + except ValueError as e: + raise ValueError("z must be a number (", val, ")") from e if val < 0: raise ValueError("z must be > 0 (", val, ")") diff --git a/src/hmf/density_field/transfer_models.py b/src/hmf/density_field/transfer_models.py index da2884df..d902a0fe 100644 --- a/src/hmf/density_field/transfer_models.py +++ b/src/hmf/density_field/transfer_models.py @@ -8,6 +8,7 @@ import pickle import warnings from copy import deepcopy +from typing import Any, ClassVar, Final import numpy as np from astropy import cosmology @@ -41,7 +42,7 @@ class TransferComponent(Component): Any model-specific parameters. """ - _defaults = {} + _defaults: ClassVar[Final[dict[str, Any]]] = {} def __init__(self, cosmo, **model_parameters): self.cosmo = cosmo @@ -83,7 +84,7 @@ class FromFile(TransferComponent): Location of the file to import. """ - _defaults = {"fname": ""} + _defaults: ClassVar[Final[dict[str, str]]] = {"fname": ""} def _check_low_k(self, lnk, lnT, lnkmin): """ @@ -161,7 +162,7 @@ class CAMB(FromFile): approximation. """ - _defaults = { + _defaults: ClassVar[Final[dict[str, Any]]] = { "camb_params": None, "dark_energy_params": {}, "extrapolate_with_eh": None, @@ -403,7 +404,7 @@ class FromArray(FromFile): Transfer function """ - _defaults = {"k": None, "T": None} + _defaults: ClassVar[Final[dict[str, Any]]] = {"k": None, "T": None} def lnt(self, lnk): r""" @@ -688,7 +689,7 @@ class attribute. \exp\left(-\Omega_{b,0}(1 + \sqrt{2h}/\Omega_{m,0})\right). """ - _defaults = { + _defaults: ClassVar[Final[dict[str, Any]]] = { "a": 2.34, "b": 3.89, "c": 16.1, @@ -763,7 +764,7 @@ class attribute. .. math:: \alpha = \frac{0.3\times 0.75^2}{\Omega_{m,0} h^2}. """ - _defaults = {"a": 37.1, "b": 21.1, "c": 10.8, "nu": 1.12} + _defaults: ClassVar[Final[dict[str, float]]] = {"a": 37.1, "b": 21.1, "c": 10.8, "nu": 1.12} def lnt(self, lnk): """ diff --git a/src/hmf/halos/__init__.py b/src/hmf/halos/__init__.py index df384dfb..dbbd3ff8 100644 --- a/src/hmf/halos/__init__.py +++ b/src/hmf/halos/__init__.py @@ -1,7 +1,13 @@ """ -A subpackage dedicated to descriptions of internal halo properties, such as their mass. See ``halomod`` for more -extended quantities in this regard. +Provides descriptions of internal halo properties. + +See ``halomod`` for more extended quantities in this regard. """ from . import mass_definitions from .mass_definitions import MassDefinition + +__all__ = [ + "mass_definitions", + "MassDefinition", +] diff --git a/src/hmf/halos/mass_definitions.py b/src/hmf/halos/mass_definitions.py index a49c0d51..0f84452f 100644 --- a/src/hmf/halos/mass_definitions.py +++ b/src/hmf/halos/mass_definitions.py @@ -5,6 +5,7 @@ """ import warnings +from typing import ClassVar, Final import astropy.units as u import numpy as np @@ -74,10 +75,10 @@ def m_to_r(self, m, z=0, cosmo=Planck15): """ try: return (3 * m / (4 * np.pi * self.halo_density(z, cosmo))) ** (1.0 / 3.0) - except AttributeError: + except AttributeError as e: raise AttributeError( f"{self.__class__.__name__} cannot convert mass to radius." - ) + ) from e def r_to_m(self, r, z=0, cosmo=Planck15): r""" @@ -95,10 +96,10 @@ def r_to_m(self, r, z=0, cosmo=Planck15): """ try: return 4 * np.pi * r**3 * self.halo_density(z, cosmo) / 3 - except AttributeError: + except AttributeError as e: raise AttributeError( f"{self.__class__.__name__} cannot convert radius to mass." - ) + ) from e def _duffy_concentration(self, m, z=0): a, b, c, ms = 6.71, -0.091, 0.44, 2e12 @@ -160,10 +161,10 @@ def change_definition( profile = NFW( cm_relation=Duffy08(cosmo=Cosmology(cosmo)), mdef=self, z=z ) - except ImportError: + except ImportError as e: raise ImportError( "Cannot change mass definitions without halomod installed!" - ) + ) from e if profile.z != z: warnings.warn( @@ -237,7 +238,7 @@ def __str__(self): class SOMean(SphericalOverdensity): """A mass definition based on spherical overdensity wrt mean background density.""" - _defaults = {"overdensity": 200} + _defaults: ClassVar[Final[dict[str, float]]] = {"overdensity": 200} def halo_density(self, z=0, cosmo=Planck15): """The density of haloes under this definition.""" @@ -251,7 +252,7 @@ def colossus_name(self): class SOCritical(SphericalOverdensity): """A mass definition based on spherical overdensity wrt critical density.""" - _defaults = {"overdensity": 200} + _defaults: ClassVar[Final[dict[str, float]]] = {"overdensity": 200} def halo_density(self, z=0, cosmo=Planck15): """The density of haloes under this definition.""" @@ -286,7 +287,7 @@ def __str__(self): class FOF(MassDefinition): """A mass definition based on FroF networks with given linking length.""" - _defaults = {"linking_length": 0.2} + _defaults: ClassVar[Final[dict[str, float]]] = {"linking_length": 0.2} def halo_density(self, z=0, cosmo=Planck15): r""" diff --git a/src/hmf/helpers/__init__.py b/src/hmf/helpers/__init__.py index 85f95947..204e5694 100644 --- a/src/hmf/helpers/__init__.py +++ b/src/hmf/helpers/__init__.py @@ -1,3 +1,10 @@ """A collection of helper functions which can operate on several of the Frameworks in the rest of the code.""" +from . import sample from .functional import get_best_param_order, get_hmf + +__all__ = [ + "sample", + "get_best_param_order", + "get_hmf", +] diff --git a/src/hmf/helpers/cfg_utils.py b/src/hmf/helpers/cfg_utils.py index 202ca5fd..832eae68 100644 --- a/src/hmf/helpers/cfg_utils.py +++ b/src/hmf/helpers/cfg_utils.py @@ -1,6 +1,6 @@ """Utilities for interacting with hmf TOML configs.""" -from datetime import datetime +from datetime import datetime, timezone from inspect import signature from astropy.units import Quantity @@ -12,7 +12,7 @@ def framework_to_dict(obj: Framework) -> dict: """Serialize a framework instance to a simple TOML-able dictionary.""" - out = {"created_on": datetime.now(), "hmf_version": __version__, "params": {}} + out = {"created_on": datetime.now(tz=timezone.utc), "hmf_version": __version__, "params": {}} for k, v in obj.parameter_values.items(): if k == "cosmo_model": diff --git a/src/hmf/mass_function/__init__.py b/src/hmf/mass_function/__init__.py index 58a75eb4..f435f7aa 100644 --- a/src/hmf/mass_function/__init__.py +++ b/src/hmf/mass_function/__init__.py @@ -3,3 +3,14 @@ from . import fitting_functions, hmf, integrate_hmf from .fitting_functions import PS, SMT, FittingFunction, Tinker08 from .hmf import MassFunction + +__all__ = [ + "fitting_functions", + "hmf", + "integrate_hmf", + "PS", + "SMT", + "FittingFunction", + "Tinker08", + "MassFunction", +] diff --git a/src/hmf/mass_function/fitting_functions.py b/src/hmf/mass_function/fitting_functions.py index c16d199b..e475ce87 100644 --- a/src/hmf/mass_function/fitting_functions.py +++ b/src/hmf/mass_function/fitting_functions.py @@ -7,6 +7,7 @@ import warnings from copy import copy +from typing import Any, ClassVar, Final import numpy as np import scipy.special as sp @@ -204,7 +205,7 @@ class FittingFunction(_framework.Component): """ __doc__ += _pdocs - _defaults = {} + _defaults: ClassVar[Final[dict[str, Any]]] = {} # Subclass requirements req_neff = False #: Whether `n_eff` is required for this subclass @@ -312,8 +313,11 @@ def lnsigma(self): @property def cutmask(self): r""" - A logical mask array specifying which elements of :attr:`fsigma` are within + Logical mask for elements within the fitted range. + + Specifies which elements of :attr:`fsigma` are within the fitted range. + """ return np.ones(len(self.nu2), dtype=bool) @@ -353,7 +357,7 @@ class SMT(FittingFunction): ) __doc__ = _makedoc(FittingFunction._pdocs, "Sheth-Mo-Tormen", "SMT", _eq, _ref) - _defaults = {"a": 0.707, "p": 0.3, "A": None} + _defaults: ClassVar[Final[dict[str, Any]]] = {"a": 0.707, "p": 0.3, "A": None} normalized = True sim_definition = SimDetails( @@ -420,7 +424,7 @@ class Jenkins(FittingFunction): r"http://doi.wiley.com/10.1046/j.1365-8711.2001.04029.x" ) __doc__ = _makedoc(FittingFunction._pdocs, "Jenkins", "Jenkins", _eq, _ref) - _defaults = {"A": 0.315, "b": 0.61, "c": 3.8} + _defaults: ClassVar[Final[dict[str, float]]] = {"A": 0.315, "b": 0.61, "c": 3.8} normalized = False sim_definition = SimDetails( @@ -470,10 +474,10 @@ class Warren(FittingFunction): ) __doc__ = _makedoc(FittingFunction._pdocs, "Warren", "Warren", _eq, _ref) - _defaults = {"A": 0.7234, "b": 1.625, "c": 0.2538, "d": 1.1982, "e": 1} + _defaults: ClassVar[Final[dict[str, float]]] = {"A": 0.7234, "b": 1.625, "c": 0.2538, "d": 1.1982, "e": 1} normalized = False - uncertainties = { + uncertainties: ClassVar[Final[dict[str, float]]] = { "A": 0.0073, "a": 0.028, "b": 0.0051, @@ -533,7 +537,7 @@ class Reed03(SMT): _ref = r"""Reed, D., et al., Dec. 2003. MNRAS 346 (2), 565-572. http://adsabs.harvard.edu/abs/2003MNRAS.346..565R""" __doc__ = _makedoc(FittingFunction._pdocs, "Reed03", "R03", _eq, _ref) - _defaults = {"a": 0.707, "p": 0.3, "A": 0.3222, "c": 0.7} + _defaults: ClassVar[Final[dict[str, float]]] = {"a": 0.707, "p": 0.3, "A": 0.3222, "c": 0.7} normalized = False sim_definition = SimDetails( @@ -574,7 +578,7 @@ class Reed07(FittingFunction): _ref = """Reed, D. S., et al., Jan. 2007. MNRAS 374 (1), 2-15. http://adsabs.harvard.edu/abs/2007MNRAS.374....2R""" __doc__ = _makedoc(FittingFunction._pdocs, "Reed07", "R07", _eq, _ref) - _defaults = {"A": 0.3222, "p": 0.3, "c": 1.08, "a": 0.764} + _defaults: ClassVar[Final[dict[str, float]]] = {"A": 0.3222, "p": 0.3, "c": 1.08, "a": 0.764} sim_definition = SimDetails( L=[1.0, 2.5, 2.5, 2.5, 2.5, 4.64, 11.6, 20, 50, 100, 500, 1340, 3000], @@ -654,7 +658,7 @@ class Peacock(FittingFunction): _eq = r"\nu\exp(-c\nu^2)(2cd\nu+ba\nu^{b-1})/d^2" _ref = """Peacock, J. A., Aug. 2007. MNRAS 379 (3), 1067-1074. http://adsabs.harvard.edu/abs/2007MNRAS.379.1067P""" __doc__ = _makedoc(FittingFunction._pdocs, "Peacock", "Pck", _eq, _ref) - _defaults = {"a": 1.529, "b": 0.704, "c": 0.412} + _defaults: ClassVar[Final[dict[str, float]]] = {"a": 1.529, "b": 0.704, "c": 0.412} sim_definition = copy(Warren.sim_definition) sim_definition.hmf_analysis_notes = "Fit directly to Warren+2006 fit." @@ -684,7 +688,7 @@ class Angulo(FittingFunction): _ref = """Angulo, R. E., et al., 2012. arXiv:1203.3216v1""" _eq = r"$A \left[\left(\frac{d}{\sigma}\right)^b + 1 \right] \exp(-c/\sigma^2)$" __doc__ = _makedoc(FittingFunction._pdocs, "Angulo", "Ang", _eq, _ref) - _defaults = {"A": 0.201, "b": 1.7, "c": 1.172, "d": 2.08} + _defaults: ClassVar[Final[dict[str, float]]] = {"A": 0.201, "b": 1.7, "c": 1.172, "d": 2.08} sim_definition = SimDetails( L=3000.0, @@ -720,7 +724,7 @@ def cutmask(self): class AnguloBound(Angulo): __doc__ = Angulo.__doc__ - _defaults = {"A": 0.265, "b": 1.9, "c": 1.4, "d": 1.675} + _defaults: ClassVar[Final[dict[str, float]]] = {"A": 0.265, "b": 1.9, "c": 1.4, "d": 1.675} class Watson_FoF(Warren): @@ -728,7 +732,7 @@ class Watson_FoF(Warren): _ref = """Watson, W. A., et al., MNRAS, 2013. http://adsabs.harvard.edu/abs/2013MNRAS.433.1230W """ __doc__ = _makedoc(FittingFunction._pdocs, "Watson FoF", "WatF", Warren._eq, _ref) - _defaults = {"A": 0.282, "b": 2.163, "c": 1, "d": 1.21, "e": 1.406} + _defaults: ClassVar[Final[dict[str, float]]] = {"A": 0.282, "b": 2.163, "c": 1, "d": 1.21, "e": 1.406} sim_definition = SimDetails( L=[11.4, 20, 114, 425, 1000, 3200, 6000], @@ -767,7 +771,7 @@ class Watson(FittingFunction): sim_definition.halo_finder = "AHF" sim_definition.halo_overdensity = "*(vir)" - _defaults = { + _defaults: ClassVar[Final[dict[str, Any]]] = { "C_a": 0.023, "d_a": 0.456, "d_b": 0.139, @@ -861,7 +865,7 @@ class Crocce(Warren): _ref = """Crocce, M., et al. MNRAS 403 (3), 1353-1367. http://doi.wiley.com/10.1111/j.1365-2966.2009.16194.x""" __doc__ = _makedoc(FittingFunction._pdocs, "Crocce", "Cro", Warren._eq, _ref) - _defaults = { + _defaults: ClassVar[Final[dict[str, Any]]] = { "A_a": 0.58, "A_b": 0.13, "b_a": 1.37, @@ -908,7 +912,7 @@ class Courtin(SMT): req_sigma = True _ref = """Courtin, J., et al., Oct. 2010. MNRAS 1931. http://doi.wiley.com/10.1111/j.1365-2966.2010.17573.x""" __doc__ = _makedoc(FittingFunction._pdocs, "Courtin", "Ctn", SMT._eq, _ref) - _defaults = {"A": 0.348, "a": 0.695, "p": 0.1} + _defaults: ClassVar[Final[dict[str, float]]] = {"A": 0.348, "a": 0.695, "p": 0.1} normalized = False @@ -942,7 +946,7 @@ class Bhattacharya(SMT): _eq = r"f_{\rm SMT}(\sigma) (\nu\sqrt{a})^{q-1}" _ref = """Bhattacharya, S., et al., May 2011. ApJ 732 (2), 122. http://labs.adsabs.harvard.edu/ui/abs/2011ApJ...732..122B""" __doc__ = _makedoc(FittingFunction._pdocs, "Bhattacharya", "Btc", _eq, _ref) - _defaults = { + _defaults: ClassVar[Final[dict[str, Any]]] = { "A_a": 0.333, "A_b": 0.11, "a_a": 0.788, @@ -1248,7 +1252,7 @@ class Tinker08(FittingFunction): }, ) - _defaults = { # -- A + _defaults: ClassVar[Final[dict[str, Any]]] = { # -- A "A_200": 1.858659e-01, "A_300": 1.995973e-01, "A_400": 2.115659e-01, @@ -1360,7 +1364,7 @@ class Tinker10(FittingFunction): sim_definition = copy(Tinker08.sim_definition) - _defaults = { # --- alpha + _defaults: ClassVar[Final[dict[str, Any]]] = { # --- alpha "alpha_200": 0.368, "alpha_300": 0.363, "alpha_400": 0.385, @@ -1601,7 +1605,7 @@ class Pillepich(Warren): __doc__ = _makedoc( FittingFunction._pdocs, "Pillepich", "Pillepich", Warren._eq, _ref ) - _defaults = {"A": 0.6853, "b": 1.868, "c": 0.3324, "d": 1.2266, "e": 1} + _defaults: ClassVar[Final[dict[str, float]]] = {"A": 0.6853, "b": 1.868, "c": 0.3324, "d": 1.2266, "e": 1} normalized = False sim_definition = SimDetails( @@ -1632,7 +1636,7 @@ class Manera(SMT): _ref = r"""Manera, M., et al., 2010, arxiv:0906.1314""" __doc__ = _makedoc(FittingFunction._pdocs, "Manera", "Man", SMT._eq, _ref) # These are for z=0, new ML method, l_linnk = 0.2 - _defaults = {"A": None, "a": 0.709, "p": 0.289} + _defaults: ClassVar[Final[dict[str, Any]]] = {"A": None, "a": 0.709, "p": 0.289} sim_definition = SimDetails( L=1280.0, @@ -1663,7 +1667,7 @@ class Ishiyama(Warren): _ref = r"""Ishiyama, T., et al., 2015, arxiv:1412.2860""" __doc__ = _makedoc(FittingFunction._pdocs, "Ishiyama", "Ishiyama", _eq, _ref) - _defaults = {"A": 0.193, "b": 1.550, "c": 1, "d": 1.186, "e": 2.184} + _defaults: ClassVar[Final[dict[str, float]]] = {"A": 0.193, "b": 1.550, "c": 1, "d": 1.186, "e": 2.184} sim_definition = SimDetails( L=[1120, 560, 280, 140, 70], @@ -1697,7 +1701,7 @@ class Bocquet200mDMOnly(Warren): _eq = r"A\left[\left(\frac{e}{\sigma}\right)^b + 1\right]\exp(-\frac{d}{\sigma^2})" _ref = r"""Bocuet, S., et al., 2016, MNRAS 456 2361""" __doc__ = _makedoc(FittingFunction._pdocs, "Bocquet", "Bocquet", _eq, _ref) - _defaults = { + _defaults: ClassVar[Final[dict[str, Any]]] = { "A": 0.216, "b": 1.87, "c": 1, @@ -1770,7 +1774,7 @@ class Bocquet200mHydro(Bocquet200mDMOnly): Bocquet200mDMOnly._eq, Bocquet200mDMOnly._ref, ) - _defaults = { + _defaults: ClassVar[Final[dict[str, Any]]] = { "A": 0.240, "b": 2.43, "c": 1, @@ -1792,7 +1796,7 @@ class Bocquet200cDMOnly(Bocquet200mDMOnly): Bocquet200mDMOnly._ref, ) - _defaults = { + _defaults: ClassVar[Final[dict[str, Any]]] = { "A": 0.256, "b": 2.01, "c": 1, @@ -1828,7 +1832,7 @@ class Bocquet200cHydro(Bocquet200cDMOnly): Bocquet200mDMOnly._ref, ) - _defaults = { + _defaults: ClassVar[Final[dict[str, Any]]] = { "A": 0.290, "b": 2.69, "c": 1, @@ -1850,7 +1854,7 @@ class Bocquet500cDMOnly(Bocquet200cDMOnly): Bocquet200mDMOnly._ref, ) - _defaults = { + _defaults: ClassVar[Final[dict[str, Any]]] = { "A": 0.390, "b": 3.05, "c": 1, @@ -1882,7 +1886,7 @@ class Bocquet500cHydro(Bocquet500cDMOnly): Bocquet200mDMOnly._ref, ) - _defaults = { + _defaults: ClassVar[Final[dict[str, Any]]] = { "A": 0.322, "b": 3.24, "c": 1, diff --git a/src/hmf/mass_function/hmf.py b/src/hmf/mass_function/hmf.py index 65a74c5f..8d6d2522 100644 --- a/src/hmf/mass_function/hmf.py +++ b/src/hmf/mass_function/hmf.py @@ -199,8 +199,8 @@ def delta_c(self, val): """ try: val = float(val) - except ValueError: - raise ValueError("delta_c must be a number: ", val) + except ValueError as e: + raise ValueError("delta_c must be a number: ", val) from e if val <= 0: raise ValueError("delta_c must be > 0 (", val, ")") @@ -244,6 +244,7 @@ def mdef_model(self, val): def mdef_params(self, val): """ Model parameters for `mdef_model`. + :type: dict. """ return val @@ -396,8 +397,11 @@ def nu(self): @cached_quantity def nu_fn(self): r""" - The parameter :math:`\nu = \left(\frac{\delta_c}{\sigma}\right)^2`, ``len=len(m)`` - as a callable function. + The nu parameter as a callable function. + + The parameter :math:`\nu = \left(\frac{\delta_c}{\sigma}\right)^2`, + with length equal to ``len(m)``. + """ return spline(self.m, self.nu, k=5) @@ -604,7 +608,10 @@ def rho_ltm(self): @cached_quantity def how_big(self): r""" - Size of simulation volume in which to expect one halo of mass m (with 95% probability), ` - `len=len(m)`` [units :math:`Mpch^{-1}`]. + Expected simulation volume per halo. + + Size of simulation volume in which to expect one halo of mass m + (with 95% probability), in units :math:`Mpch^{-1}`, with length ``len(m)``. + """ return (0.366362 / self.ngtm) ** (1.0 / 3.0) diff --git a/tests/test_cli.py b/tests/test_cli.py index 6e940cc5..72406b15 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -34,7 +34,7 @@ def test_with_config(tmpdir: Path): transfer_model = 'EH' """ - with open(tmpdir / "cfg.toml", "w") as fl: + with (tmpdir / "cfg.toml").open("w") as fl: fl.write(cfg) result = runner.invoke( @@ -62,7 +62,7 @@ def test_config_vs_cli(tmpdir: Path): transfer_model = 'EH' """ - with open(tmpdir / "cfg.toml", "w") as fl: + with (tmpdir / "cfg.toml").open("w") as fl: fl.write(cfg) result_cfg = runner.invoke( @@ -106,7 +106,7 @@ def test_roundtrip_cfg(tmpdir): transfer_model = 'EH' """ - with open(tmpdir / "cfg.toml", "w") as fl: + with (tmpdir / "cfg.toml").open("w") as fl: fl.write(cfg) result = runner.invoke( diff --git a/tests/test_fits.py b/tests/test_fits.py index 5b1c858d..96f4e408 100644 --- a/tests/test_fits.py +++ b/tests/test_fits.py @@ -49,12 +49,15 @@ def ps_max(hmf): @pytest.mark.parametrize(("redshift", "fit"), itertools.product([0.0, 2.0], allfits)) def test_allfits(hmf, ps_max, redshift, fit): """ - This basically tests all implemented fits to check the form for three things: - 1) whether the maximum fsigma is less than in the PS formula (which is known to overestimate) - 2) whether the slope is positive below this maximum - 3) whether the slope is negative above this maximum. + Test all implemented fits for correct form and behavior. + + Tests that: + 1) the maximum fsigma is less than in the PS formula (which is known to overestimate) + 2) the slope is positive below this maximum + 3) the slope is negative above this maximum Since it calls each class, any blatant errors should also pop up. + """ hmf.update(z=redshift, hmf_model=fit) maxarg = np.argmax(hmf.fsigma) From d0e398fb57c15d767f7a4ea0ca15dcf77c493de3 Mon Sep 17 00:00:00 2001 From: Steven Murray Date: Sun, 22 Feb 2026 15:23:07 +0200 Subject: [PATCH 05/18] style: D102 fixed --- src/hmf/alternatives/wdm.py | 7 +++- src/hmf/cosmology/growth_factor.py | 9 ++++- src/hmf/density_field/filters.py | 32 ++++++++++++++- src/hmf/density_field/transfer.py | 2 + src/hmf/density_field/transfer_models.py | 4 +- src/hmf/halos/mass_definitions.py | 8 +++- src/hmf/mass_function/fitting_functions.py | 45 ++++++++++++++++++---- src/hmf/mass_function/hmf.py | 3 +- 8 files changed, 97 insertions(+), 13 deletions(-) diff --git a/src/hmf/alternatives/wdm.py b/src/hmf/alternatives/wdm.py index 8c586d54..93b8ce04 100644 --- a/src/hmf/alternatives/wdm.py +++ b/src/hmf/alternatives/wdm.py @@ -7,7 +7,7 @@ for other alternative cosmologies. """ -from typing import ClassVar, Final +from typing import ClassVar, Final, override import astropy.units as u import numpy as np @@ -216,6 +216,7 @@ class attribute. _defaults: ClassVar[Final[dict[str, float]]] = {"beta": 1.16} + @override def dndm_alter(self): return self.dndm0 * (1 + self.wdm.m_hm / self.m) ** (-self.params["beta"]) @@ -240,6 +241,7 @@ class attribute. _defaults: ClassVar[Final[dict[str, float]]] = {"alpha": 0.6} + @override def dndm_alter(self): return self.dndm0 * (1 + self.wdm.m_hm / self.m) ** (-self.params["alpha"]) @@ -264,6 +266,7 @@ class attribute. _defaults: ClassVar[Final[dict[str, float]]] = {"beta": 0.99, "gamma": 2.7} + @override def dndm_alter(self): return self.dndm0 * (1 + self.params["gamma"] * self.wdm.m_hm / self.m) ** ( -self.params["beta"] @@ -344,6 +347,7 @@ def wdm(self): mx=self.wdm_mass, cosmo=self.cosmo, z=self.z, **self.wdm_params ) + @override @cached_quantity def _unnormalised_lnT(self): return super()._unnormalised_lnT + np.log(self.wdm.transfer(self.k)) @@ -384,6 +388,7 @@ def alter_params(self, val): """Model parameters for `alter_model`.""" return val + @override @cached_quantity def dndm(self): r""" diff --git a/src/hmf/cosmology/growth_factor.py b/src/hmf/cosmology/growth_factor.py index 9e24267d..4d9630de 100644 --- a/src/hmf/cosmology/growth_factor.py +++ b/src/hmf/cosmology/growth_factor.py @@ -8,7 +8,7 @@ """ from functools import cached_property -from typing import Any, ClassVar, Final +from typing import Any, ClassVar, Final, override import numpy as np from astropy import cosmology @@ -83,6 +83,13 @@ def _zvec(self): @cached_property def integral(self): + """The integral :math:`\int_0^a da' / (a'^3 E(a')^3)`. + + Parameters + ---------- + a : array_like + Scale factor(s) at which to evaluate the integral. + """ a = np.exp(self._lna) return _spline( a, 2.5 * self.cosmo.Om0 / (a * self.cosmo.efunc(self._zvec)) ** 3 diff --git a/src/hmf/density_field/filters.py b/src/hmf/density_field/filters.py index 5e7cf5b0..2553993d 100644 --- a/src/hmf/density_field/filters.py +++ b/src/hmf/density_field/filters.py @@ -2,7 +2,7 @@ import collections import warnings -from typing import ClassVar, Final +from typing import ClassVar, Final, override import numpy as np import scipy.integrate as intg @@ -296,19 +296,24 @@ class TopHat(Filter): .. math:: \frac{dW}{d\ln x}(x=kR) = \frac{1}{x^3}[9x\cos x + 3(x^2-3)\sin x]. """ + @override def real_space(self, R, r): a = np.where(r < R, 1, 0) return np.where(r == R, 0.5, a) + @override def k_space(self, kr): return np.where(kr > 1.4e-6, (3 / kr**3) * (np.sin(kr) - kr * np.cos(kr)), 1) + @override def mass_to_radius(self, m, rho_mean): return (3.0 * m / (4.0 * np.pi * rho_mean)) ** (1.0 / 3.0) + @override def radius_to_mass(self, r, rho_mean): return 4 * np.pi * r**3 * rho_mean / 3 + @override def dw_dlnkr(self, kr): return np.where( kr > 1e-3, @@ -346,18 +351,23 @@ class Gaussian(Filter): .. math:: \frac{dW}{d\ln x}(x=kR) = -xW(x). """ + @override def real_space(self, R, r): return np.exp(-(r**2) / 2 / R**2) / (2 * np.pi) ** 1.5 / R**3 + @override def k_space(self, kr): return np.exp(-(kr**2) / 2.0) + @override def mass_to_radius(self, m, rho_mean): return (m / rho_mean) ** (1.0 / 3.0) / np.sqrt(2 * np.pi) + @override def radius_to_mass(self, r, rho_mean): return (2 * np.pi) ** 1.5 * r**3 * rho_mean + @override def dw_dlnkr(self, kr): return -(kr**2) * self.k_space(kr) @@ -399,29 +409,36 @@ class SharpK(Filter): _defaults: ClassVar[Final[dict[str, float]]] = {"c": 2.5} + @override def k_space(self, kr): a = np.where(kr > 1, 0, 1) return np.where(kr == 1, 0.5, a) + @override def real_space(self, R, r): return (np.sin(r / R) - (r / R) * np.cos(r / R)) / (2 * np.pi**2 * r**3) + @override def dw_dlnkr(self, kr): return np.where(kr == 1, 1.0, 0.0) + @override def dlnss_dlnr(self, r): sigma = self.sigma(r) power = _spline(self.k, self.power)(1 / r) return -power / (2 * np.pi**2 * sigma**2 * r**3) + @override def mass_to_radius(self, m, rho_mean): return (1.0 / self.params["c"]) * (3.0 * m / (4.0 * np.pi * rho_mean)) ** ( 1.0 / 3.0 ) + @override def radius_to_mass(self, r, rho_mean): return 4 * np.pi * (self.params["c"] * r) ** 3 * rho_mean / 3 + @override def sigma(self, r, order=0): if not isinstance(r, collections.abc.Iterable): r = np.atleast_1d(r) @@ -499,9 +516,15 @@ def gamma(self, r): return sig_1**2 / (sig_0 * sig_2) def xi(self, pm, em): + """ + Ellipsoid axis ratio correction factor. + + Computed from ellipticity and prolateness parameters. + """ return ((1 + 4 * pm) ** 2 / (1 - 3 * em + pm) / (1 - 2 * pm)) ** (1.0 / 6.0) def a3(self, r): + """Short-axis scale with ellipsoidal correction.""" g = self.gamma(r) xm = self.xm(g, self.nu(r)) em = self.em(xm) @@ -509,16 +532,23 @@ def a3(self, r): return r / self.xi(pm, em) def r_a3(self, rmin, rmax): + """ + Spline interpolant for radius-to-axis ratio relationship. + + Created from computed a3 values over the radius range. + """ r = np.logspace(np.log(rmin), np.log(rmax), 200, base=np.e) a3 = self.a3(r) return _spline(a3, r) + @override def dlnss_dlnr(self, r): a3 = self.a3(r) sigma = self.sigma(a3) power = _spline(self.k, self.power)(1 / a3) return -power / (2 * np.pi**2 * sigma**2 * a3**3) + @override def dlnr_dlnm(self, r): a3 = self.a3(r) xi = r / a3 diff --git a/src/hmf/density_field/transfer.py b/src/hmf/density_field/transfer.py index 9eb09845..d40c2f62 100644 --- a/src/hmf/density_field/transfer.py +++ b/src/hmf/density_field/transfer.py @@ -7,6 +7,7 @@ """ import numpy as np +from typing import override from .._internals._cache import cached_quantity, parameter from .._internals._framework import get_mdl @@ -86,6 +87,7 @@ def __init__( # =========================================================================== # Parameters # =========================================================================== + @override def validate(self): super().validate() assert self.lnk_min < self.lnk_max, ( diff --git a/src/hmf/density_field/transfer_models.py b/src/hmf/density_field/transfer_models.py index d902a0fe..ec7de590 100644 --- a/src/hmf/density_field/transfer_models.py +++ b/src/hmf/density_field/transfer_models.py @@ -8,7 +8,7 @@ import pickle import warnings from copy import deepcopy -from typing import Any, ClassVar, Final +from typing import Any, ClassVar, Final, override import numpy as np from astropy import cosmology @@ -534,6 +534,7 @@ def _set_params(self): @property def k_peak(self): + """The k_peak parameter from EH1998, Eq. 29, in units of Mpc^-1 (no h).""" return 2.5 * np.pi * (1 + 0.217 * self.Omh2) / self.sound_horizon @property @@ -610,6 +611,7 @@ class EH_NoBAO(EH_BAO): @property def alpha_gamma(self): + """The alpha_gamma parameter from EH1998, Eq. 31.""" return ( 1 - 0.328 * np.log(431 * self.Omh2) * self.f_baryon diff --git a/src/hmf/halos/mass_definitions.py b/src/hmf/halos/mass_definitions.py index 0f84452f..51912041 100644 --- a/src/hmf/halos/mass_definitions.py +++ b/src/hmf/halos/mass_definitions.py @@ -5,7 +5,7 @@ """ import warnings -from typing import ClassVar, Final +from typing import ClassVar, Final, override import astropy.units as u import numpy as np @@ -54,9 +54,11 @@ def colossus_name(self): return None def halo_overdensity_mean(self, z=0, cosmo=Planck15): + """Compute the halo overdensity with respect to the mean density.""" return self.halo_density(z, cosmo) / self.mean_density(z, cosmo) def halo_overdensity_crit(self, z=0, cosmo=Planck15): + """Compute the halo overdensity with respect to the critical density.""" return self.halo_density(z, cosmo) / self.critical_density(z, cosmo) def m_to_r(self, m, z=0, cosmo=Planck15): @@ -244,6 +246,7 @@ def halo_density(self, z=0, cosmo=Planck15): """The density of haloes under this definition.""" return self.params["overdensity"] * self.mean_density(z, cosmo) + @override @property def colossus_name(self): return f"{int(self.params['overdensity'])}m" @@ -258,6 +261,7 @@ def halo_density(self, z=0, cosmo=Planck15): """The density of haloes under this definition.""" return self.params["overdensity"] * self.critical_density(z, cosmo) + @override @property def colossus_name(self): return f"{int(self.params['overdensity'])}c" @@ -275,6 +279,7 @@ def halo_density(self, z=0, cosmo=Planck15): overdensity = 18 * np.pi**2 + 82 * x - 39 * x**2 return overdensity * self.mean_density(z, cosmo) / cosmo.Om(z) + @override @property def colossus_name(self): return "vir" @@ -306,6 +311,7 @@ def halo_density(self, z=0, cosmo=Planck15): overdensity = 9 / (2 * np.pi * self.params["linking_length"] ** 3) return overdensity * self.mean_density(z, cosmo) + @override @property def colossus_name(self): return "fof" diff --git a/src/hmf/mass_function/fitting_functions.py b/src/hmf/mass_function/fitting_functions.py index e475ce87..dcd97503 100644 --- a/src/hmf/mass_function/fitting_functions.py +++ b/src/hmf/mass_function/fitting_functions.py @@ -7,7 +7,7 @@ import warnings from copy import copy -from typing import Any, ClassVar, Final +from typing import Any, ClassVar, Final, override import numpy as np import scipy.special as sp @@ -253,6 +253,7 @@ def __init__( @classmethod def get_measured_mdef(cls): + """Get the mass definition used in the defining simulation.""" # Try to set the measured mass definition measured = None if cls.sim_definition is not None: @@ -340,6 +341,7 @@ class PS(FittingFunction): __doc__ = _makedoc(FittingFunction._pdocs, "Press-Schechter", "PS", _eq, _ref) normalized = True + @override @property def fsigma(self): return np.sqrt(2.0 / np.pi) * self.nu * np.exp(-0.5 * self.nu2) @@ -387,9 +389,10 @@ def __init__(self, *args, validate=True, **kwargs): if self.params["a"] <= 0: raise ValueError(f"a in SMT must be > 0. Got {self.params['a']}.") + @override @property def fsigma(self): - A = self.norm() + A = self._norm() a = self.params["a"] p = self.params["p"] @@ -401,7 +404,7 @@ def fsigma(self): * (1 + (1.0 / (a * self.nu2)) ** p) ) - def norm(self): + def _norm(self): if self.params["A"] is not None: return self.params["A"] @@ -447,10 +450,12 @@ class Jenkins(FittingFunction): other_cosmo={"omegav": 0.7, "h": 0.7, "n": 1}, ) + @override @property def cutmask(self): return np.logical_and(self.lnsigma > -1.2, self.lnsigma < 1.05) + @override @property def fsigma(self): A = self.params["A"] @@ -514,6 +519,7 @@ class Warren(FittingFunction): other_cosmo={"omegav": 0.7, "omegab": 0.04, "h": 0.7, "n": 1}, ) + @override @property def fsigma(self): A = self.params["A"] @@ -524,6 +530,7 @@ def fsigma(self): return A * ((e / self.sigma) ** b + c) * np.exp(-d / self.sigma**2) + @override @property def cutmask(self): return np.logical_and(self.m > 1e10, self.m < 1e15) @@ -558,6 +565,7 @@ class Reed03(SMT): other_cosmo={"omegav": 0.7, "omegab": 0.04, "h": None, "n": None}, ) + @override @property def fsigma(self): vfv = super().fsigma @@ -565,6 +573,7 @@ def fsigma(self): -self.params["c"] / (self.sigma * np.cosh(2.0 * self.sigma) ** 5) ) + @override @property def cutmask(self): return np.logical_and(self.lnsigma > -1.7, self.lnsigma < 0.9) @@ -626,6 +635,7 @@ class Reed07(FittingFunction): other_cosmo={"omegav": 0.7, "omegab": None, "h": 0.7, "n": 1.0}, ) + @override @property def fsigma(self): G_1 = np.exp(-((self.lnsigma - 0.4) ** 2) / (2 * 0.6**2)) @@ -646,6 +656,7 @@ def fsigma(self): ) ) + @override @property def cutmask(self): return np.logical_and(self.lnsigma > -0.5, self.lnsigma < 1.2) @@ -664,6 +675,7 @@ class Peacock(FittingFunction): sim_definition.hmf_analysis_notes = "Fit directly to Warren+2006 fit." normalized = True + @override @property def fsigma(self): a = self.params["a"] @@ -678,6 +690,7 @@ def fsigma(self): / d**2 ) + @override @property def cutmask(self): return np.logical_and(self.m < 1e10, self.m > 1e15) @@ -708,6 +721,7 @@ class Angulo(FittingFunction): other_cosmo={"omegav": 0.75, "omegab": 0.045, "h": 0.73, "n": 1.0}, ) + @override @property def fsigma(self): A = self.params["A"] @@ -717,6 +731,7 @@ def fsigma(self): return A * ((d / self.sigma) ** b + 1) * np.exp(-c / self.sigma**2) + @override @property def cutmask(self): return np.logical_and(self.m > 1e8, self.m < 1e16) @@ -752,6 +767,7 @@ class Watson_FoF(Warren): other_cosmo={"omegav": 0.73, "omegab": 0.044, "h": 0.7, "n": 0.96}, ) + @override @property def cutmask(self): return np.logical_and(self.lnsigma > -0.55, self.lnsigma < 1.31) @@ -820,6 +836,7 @@ def gamma(self): * np.exp(p * (1 - delta_halo / 178) / self.sigma**q) ) + @override @property def fsigma(self): if self.z == 0: @@ -855,6 +872,7 @@ def fsigma(self): * np.exp(-gamma / self.sigma**2) ) + @override @property def cutmask(self): return np.logical_and(self.lnsigma > -0.55, self.lnsigma < 1.05) @@ -903,6 +921,7 @@ def __init__(self, *args, **kwargs): self.params["c"] = self.params["c_a"] * (1 + self.z) ** (-self.params["c_b"]) self.params["d"] = self.params["d_a"] * (1 + self.z) ** (-self.params["d_b"]) + @override @property def cutmask(self): return np.logical_and(self.m > 10**10.5, self.m < 10**15.5) @@ -934,6 +953,7 @@ class Courtin(SMT): other_cosmo={"omegav": 0.74, "omegab": 0.044, "h": 0.72, "n": 0.963}, ) + @override @property def cutmask(self): return np.logical_and(self.lnsigma > -0.8, self.lnsigma < 0.7) @@ -986,7 +1006,7 @@ def __init__(self, **kwargs): if not self.params["normed"]: self.params["A"] = self.params["A_a"] * (1 + self.z) ** -self.params["A_b"] else: - self.params["A"] = self.norm() + self.params["A"] = self._norm() self.params["a"] = self.params["a_a"] * (1 + self.z) ** -self.params["a_b"] @@ -997,6 +1017,7 @@ def __init__(self, **kwargs): raise ValueError("2p in Bhattacharya must be < q") @property + @override def fsigma(self): r""" Calculate :math:`f(\sigma)` for Bhattacharya form. @@ -1014,11 +1035,13 @@ def fsigma(self): vfv = super().fsigma return vfv * (np.sqrt(self.params["a"]) * self.nu) ** (self.params["q"] - 1) + @override @property def cutmask(self): return np.logical_and(self.m > 6 * 10**11, self.m < 3 * 10**15) - def norm(self): + @override + def _norm(self): if self.params["A"] is not None: return self.params["A"] @@ -1335,6 +1358,7 @@ def __init__(self, **model_parameters): self.b = b_0 * (1 + self.z) ** (-alpha) self.c = c_0 + @override @property def fsigma(self): return ( @@ -1343,6 +1367,7 @@ def fsigma(self): * np.exp(-self.c / self.sigma**2) ) + @override @property def cutmask(self): if self.z == 0.0: @@ -1501,7 +1526,7 @@ def __init__(self, **model_parameters): self.beta = 1e-3 @property - def normalise(self): + def _normalise(self): if int(self.delta_halo) in self.delta_virs and self.z == 0: return self.params[f"alpha_{int(self.delta_halo)}"] return 1 / ( @@ -1514,6 +1539,7 @@ def normalise(self): ) ) + @override @property def fsigma(self): fv = ( @@ -1522,8 +1548,9 @@ def fsigma(self): * np.exp(-self.gamma * (self.nu**2) / 2) ) - return fv * self.normalise * self.nu + return fv * self._normalise * self.nu + @override @property def cutmask(self): if self.z == 0.0: @@ -1692,6 +1719,7 @@ class Ishiyama(Warren): }, ) + @override @property def cutmask(self): return np.logical_and(self.m > 1e8, self.m < 1e16) @@ -1754,6 +1782,7 @@ def convert_mass(self): """ return 1 + @override @property def fsigma(self): A, b, d, e = self.get_params() @@ -1810,6 +1839,7 @@ class Bocquet200cDMOnly(Bocquet200mDMOnly): sim_definition = copy(Bocquet200mDMOnly.sim_definition) sim_definition.halo_overdensity = "200c" + @override def convert_mass(self): g0 = 3.54e-2 + self.cosmo.Om0**0.09 g1 = 4.56e-2 + 2.68e-2 / self.cosmo.Om0 @@ -1868,6 +1898,7 @@ class Bocquet500cDMOnly(Bocquet200cDMOnly): sim_definition = copy(Bocquet200mDMOnly.sim_definition) sim_definition.halo_overdensity = "500c" + @override def convert_mass(self): alpha_0 = 0.880 + 0.329 * self.cosmo.Om0 alpha_1 = 1.0 + 4.31 * 1e-2 / self.cosmo.Om0 diff --git a/src/hmf/mass_function/hmf.py b/src/hmf/mass_function/hmf.py index 8d6d2522..9535b8b1 100644 --- a/src/hmf/mass_function/hmf.py +++ b/src/hmf/mass_function/hmf.py @@ -7,7 +7,7 @@ import copy import warnings -from typing import Any +from typing import Any, override import numpy as np from scipy.interpolate import InterpolatedUnivariateSpline as spline @@ -129,6 +129,7 @@ def __init__( # =========================================================================== # PARAMETERS # =========================================================================== + @override def validate(self): super().validate() assert self.Mmin < self.Mmax, f"Mmin > Mmax: {self.Mmin}, {self.Mmax}" From 2ce32878ca9d79553e669f8fbf6a37060e771ccc Mon Sep 17 00:00:00 2001 From: Steven Murray Date: Sun, 22 Feb 2026 15:38:36 +0200 Subject: [PATCH 06/18] style: imperative mood docs --- pyproject.toml | 46 +++++++++++++++++------------- src/hmf/cosmology/growth_factor.py | 8 +++--- src/hmf/density_field/filters.py | 16 +++++------ 3 files changed, 38 insertions(+), 32 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index de321d7b..378e6185 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -97,7 +97,7 @@ testpaths = [ # exclude = [ # "*.ipynb", # for now # ] -line-length=88 +line-length=100 target-version="py311" [tool.ruff.lint] @@ -131,24 +131,24 @@ extend-select = [ "RSE", # exception raises "TRY201", # verbose raise ] -# ignore = [ -# # "DTZ007", # use %z in strptime -# # "DTZ001", # require tzinfo in datetime -# # "B008", # do not performa function call in argument defaults -# # "PTH207", # allow glob.glob() because when we use it, it's necessary -# # "A003", # class attribute shadowing builtins -# # "RUF009", # don;e perform function call in dataclass defaults -# # "N806", # Variable name should be lower case. We have some single-letter variables that make more sense to be caps. -# # "D401", # First line should be in imperative mood -- cached_properties don't fit this bill. -# # "N815", -# # "N807", # Allow method names to start and end with __ -# # "RUF012", # mutable class attributes annotation -# # # The rest should be un-commented when possible... -# # "PTH123", -# # "PT011", -# # "A005", # module name shadows builtin -# # "RUF067", # allow defining new variables in __Init__ files -# ] +ignore = [ + # "DTZ007", # use %z in strptime + # "DTZ001", # require tzinfo in datetime + # "B008", # do not performa function call in argument defaults + # "PTH207", # allow glob.glob() because when we use it, it's necessary + # "A003", # class attribute shadowing builtins + # "RUF009", # don;e perform function call in dataclass defaults + "N806", # Variable name should be lower case. We have some single-letter variables that make more sense to be caps. + "D401", # First line should be in imperative mood -- cached_properties and parameter descriptors don't fit this. + # "N815", + # "N807", # Allow method names to start and end with __ + # "RUF012", # mutable class attributes annotation + # # The rest should be un-commented when possible... + # "PTH123", + # "PT011", + # "A005", # module name shadows builtin + # "RUF067", # allow defining new variables in __Init__ files +] [tool.ruff.lint.per-file-ignores] "tests/*.py" = [ @@ -166,7 +166,13 @@ extend-select = [ [tool.ruff.lint.pydocstyle] convention = 'numpy' -property-decorators = ["pytest.fixture"] +property-decorators = [ + "pytest.fixture", + "property", + "cached_property", + "cached_quantity", + "parameter", +] [tool.ruff.lint.mccabe] max-complexity = 21 \ No newline at end of file diff --git a/src/hmf/cosmology/growth_factor.py b/src/hmf/cosmology/growth_factor.py index 4d9630de..ea049453 100644 --- a/src/hmf/cosmology/growth_factor.py +++ b/src/hmf/cosmology/growth_factor.py @@ -97,7 +97,7 @@ def integral(self): def _d_plus(self, z: float | np.ndarray) -> float | np.ndarray: r""" - Finds the factor :math:`D^+(a)`, from Lukic et. al. 2007, eq. 8. + Find the factor :math:`D^+(a)`, from Lukic et. al. 2007, eq. 8. Parameters ---------- @@ -231,7 +231,7 @@ class FromFile(GrowthFactor): def growth_factor(self, z): r""" - The growth factor, :math:`d(a) = D^+(a)/D^+(a=1)`. + Compute the growth factor, :math:`d(a) = D^+(a)/D^+(a=1)`. Parameters ---------- @@ -274,7 +274,7 @@ class FromArray(FromFile): def growth_factor(self, z): r""" - The growth factor, :math:`d(a) = D^+(a)/D^+(a=1)`. + Compute the growth factor, :math:`d(a) = D^+(a)/D^+(a=1)`. Parameters ---------- @@ -348,7 +348,7 @@ def _general_case(self, w, x): def growth_factor(self, z): """ - The growth factor, :math:`d(a) = D^+(a)/D^+(a=1)`. + Compute the growth factor, :math:`d(a) = D^+(a)/D^+(a=1)`. This uses an approximation only valid in closed or flat cosmologies, ported from ``genmf``. diff --git a/src/hmf/density_field/filters.py b/src/hmf/density_field/filters.py index 2553993d..624e35c1 100644 --- a/src/hmf/density_field/filters.py +++ b/src/hmf/density_field/filters.py @@ -136,7 +136,7 @@ def radius_to_mass(self, r, rho_mean): def dw_dlnkr(self, kr): r""" - The derivative of the (fourier-transformed) filter with :math:`\ln(kr)`. + Compute the derivative of the (fourier-transformed) filter with :math:`\ln(kr)`. Parameters ---------- @@ -153,7 +153,7 @@ def dw_dlnkr(self, kr): def dlnss_dlnr(self, r): r""" - The derivative of the mass variance with radius. + Compute the derivative of the mass variance with radius. Parameters ---------- @@ -188,7 +188,7 @@ def dlnss_dlnr(self, r): def dlnr_dlnm(self, r): r""" - The derivative of log radius with log mass. + Compute the derivative of log radius with log mass. For the usual :math:`m\propto r^3` mass assignment, this is just 1/3. @@ -201,7 +201,7 @@ def dlnr_dlnm(self, r): def dlnss_dlnm(self, r): r""" - The logarithmic slope of mass variance with mass. + Compute the logarithmic slope of mass variance with mass. This is an important quantity, and is used directly to calculate :math:`\frac{dn}{dm}`. @@ -493,19 +493,19 @@ def xm(self, g, v): return g * v + top / bot def em(self, xm): - """The average ellipticity of a patch as a function of peak tensor.""" + """Compute the average ellipticity of a patch as a function of peak tensor.""" return 1 / np.sqrt(5 * xm**2 + 6) def pm(self, xm): - """The average prolateness of a patch as a function of peak tensor.""" + """Compute the average prolateness of a patch as a function of peak tensor.""" return 30.0 / (5 * xm**2 + 6) ** 2 def a3a1(self, e, p): - """The short:long axis ratio of an ellipsoid given its ellipticity and prolateness.""" + """Compute the short:long axis ratio of an ellipsoid given its ellipticity and prolateness.""" return np.sqrt((1 - 3 * e + p) / (1 + 3 * e + p)) def a3a2(self, e, p): - """The short:medium axis ratio of an ellipsoid given its ellipticity/prolateness.""" + """Compute the short:medium axis ratio of an ellipsoid given its ellipticity/prolateness.""" return np.sqrt((1 - 2 * p) / (1 + 3 * e + p)) def gamma(self, r): From b33e0e2fb685a78e64c0234e57c9c988c3e2a24c Mon Sep 17 00:00:00 2001 From: Steven Murray Date: Sun, 22 Feb 2026 15:53:42 +0200 Subject: [PATCH 07/18] style: follow class import style --- pyproject.toml | 2 + src/hmf/__init__.py | 34 +++++------ src/hmf/_internals/__init__.py | 6 +- src/hmf/cosmology/__init__.py | 4 +- src/hmf/cosmology/growth_factor.py | 16 ++--- src/hmf/density_field/__init__.py | 10 ++-- src/hmf/density_field/filters.py | 12 ++-- src/hmf/density_field/halofit.py | 8 +-- src/hmf/density_field/transfer.py | 3 +- src/hmf/density_field/transfer_models.py | 12 ++-- src/hmf/halos/__init__.py | 2 +- src/hmf/helpers/__init__.py | 2 +- src/hmf/helpers/cfg_utils.py | 4 +- src/hmf/helpers/sample.py | 4 +- src/hmf/mass_function/__init__.py | 8 +-- src/hmf/mass_function/fitting_functions.py | 70 +++++++++++++++++++--- src/hmf/mass_function/hmf.py | 14 ++--- src/hmf/mass_function/integrate_hmf.py | 4 +- 18 files changed, 135 insertions(+), 80 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 378e6185..3da70578 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -139,6 +139,8 @@ ignore = [ # "A003", # class attribute shadowing builtins # "RUF009", # don;e perform function call in dataclass defaults "N806", # Variable name should be lower case. We have some single-letter variables that make more sense to be caps. + "N803", # Argument name should be lowercase. Scientific notation (N, L, R, Mmin, etc.) - changing would break API. + "N801", # Class name should use CapWords. Names like Watson_FoF, EH_BAO are part of the public API. "D401", # First line should be in imperative mood -- cached_properties and parameter descriptors don't fit this. # "N815", # "N807", # Allow method names to start and end with __ diff --git a/src/hmf/__init__.py b/src/hmf/__init__.py index f49b8760..f64ddff2 100644 --- a/src/hmf/__init__.py +++ b/src/hmf/__init__.py @@ -28,31 +28,31 @@ from .mass_function import MassFunction, fitting_functions, hmf, integrate_hmf __all__ = [ + "CAMB", "Component", - "Framework", - "cached_quantity", - "get_base_component", - "get_base_components", - "get_mdl", - "parameter", - "wdm", "Cosmology", + "Framework", "GrowthFactor", - "cosmo", - "growth_factor", - "CAMB", + "MassFunction", "Transfer", + "cached_quantity", + "cosmo", "filters", - "halofit", - "transfer", - "transfer_models", - "mass_definitions", + "fitting_functions", "functional", + "get_base_component", + "get_base_components", "get_best_param_order", "get_hmf", - "sample", - "MassFunction", - "fitting_functions", + "get_mdl", + "growth_factor", + "halofit", "hmf", "integrate_hmf", + "mass_definitions", + "parameter", + "sample", + "transfer", + "transfer_models", + "wdm", ] diff --git a/src/hmf/_internals/__init__.py b/src/hmf/_internals/__init__.py index ba3de716..9319d3dd 100644 --- a/src/hmf/_internals/__init__.py +++ b/src/hmf/_internals/__init__.py @@ -15,13 +15,13 @@ from ._utils import inherit_docstrings __all__ = [ - "cached_quantity", - "parameter", "Component", "Framework", + "cached_quantity", "get_base_component", "get_base_components", "get_mdl", - "pluggable", "inherit_docstrings", + "parameter", + "pluggable", ] diff --git a/src/hmf/cosmology/__init__.py b/src/hmf/cosmology/__init__.py index 4baadb24..d86f36ed 100644 --- a/src/hmf/cosmology/__init__.py +++ b/src/hmf/cosmology/__init__.py @@ -5,8 +5,8 @@ from .growth_factor import GrowthFactor __all__ = [ - "cosmo", "Cosmology", - "astropy_to_colossus", "GrowthFactor", + "astropy_to_colossus", + "cosmo", ] diff --git a/src/hmf/cosmology/growth_factor.py b/src/hmf/cosmology/growth_factor.py index ea049453..a9589332 100644 --- a/src/hmf/cosmology/growth_factor.py +++ b/src/hmf/cosmology/growth_factor.py @@ -8,11 +8,11 @@ """ from functools import cached_property -from typing import Any, ClassVar, Final, override +from typing import Any, ClassVar, Final import numpy as np from astropy import cosmology -from scipy.interpolate import InterpolatedUnivariateSpline as _spline +from scipy.interpolate import InterpolatedUnivariateSpline as Spline from .._internals._framework import Component as Cmpt from .._internals._framework import pluggable @@ -83,7 +83,7 @@ def _zvec(self): @cached_property def integral(self): - """The integral :math:`\int_0^a da' / (a'^3 E(a')^3)`. + r"""The integral :math:`\int_0^a da' / (a'^3 E(a')^3)`. Parameters ---------- @@ -91,7 +91,7 @@ def integral(self): Scale factor(s) at which to evaluate the integral. """ a = np.exp(self._lna) - return _spline( + return Spline( a, 2.5 * self.cosmo.Om0 / (a * self.cosmo.efunc(self._zvec)) ** 3 ).antiderivative() @@ -165,7 +165,7 @@ def growth_factor_fn(self, zmin=0.0, inverse=False): gf = self.growth_factor(self._zvec) idx = np.argsort(gf) - return _spline(gf[idx], self._zvec[idx]) + return Spline(gf[idx], self._zvec[idx]) def growth_rate(self, z): """ @@ -247,7 +247,7 @@ def growth_factor(self, z): z_out = G[0, :] d_out = G[1, :] - return _spline(z_out, d_out, k=1)(z) + return Spline(z_out, d_out, k=1)(z) @_inherit @@ -296,7 +296,7 @@ def growth_factor(self, z): if len(z_out) != len(d_out): raise ValueError("z and d must have same length") - return _spline(z_out, d_out, k=1)(z) + return Spline(z_out, d_out, k=1)(z) @_inherit @@ -341,7 +341,7 @@ def _general_case(self, w, x): x = np.atleast_1d(x) xn_vec = np.linspace(0, x.max(), 1000) - func = _spline(xn_vec, (xn_vec / (xn_vec**3 + 2)) ** 1.5) + func = Spline(xn_vec, (xn_vec / (xn_vec**3 + 2)) ** 1.5) g = np.array([func.integral(0, y) for y in x]) return ((x**3.0 + 2.0) ** 0.5) * (g / x**1.5) diff --git a/src/hmf/density_field/__init__.py b/src/hmf/density_field/__init__.py index 04f0c81e..a3fa9f7e 100644 --- a/src/hmf/density_field/__init__.py +++ b/src/hmf/density_field/__init__.py @@ -12,12 +12,12 @@ from .transfer_models import CAMB, EH __all__ = [ + "CAMB", + "EH", + "Filter", + "Transfer", "filters", + "halofit", "transfer", "transfer_models", - "Filter", - "halofit", - "Transfer", - "CAMB", - "EH", ] diff --git a/src/hmf/density_field/filters.py b/src/hmf/density_field/filters.py index 624e35c1..f4b178fe 100644 --- a/src/hmf/density_field/filters.py +++ b/src/hmf/density_field/filters.py @@ -6,7 +6,7 @@ import numpy as np import scipy.integrate as intg -from scipy.interpolate import InterpolatedUnivariateSpline as _spline +from scipy.interpolate import InterpolatedUnivariateSpline as Spline from .._internals import _framework, _utils @@ -425,7 +425,7 @@ def dw_dlnkr(self, kr): @override def dlnss_dlnr(self, r): sigma = self.sigma(r) - power = _spline(self.k, self.power)(1 / r) + power = Spline(self.k, self.power)(1 / r) return -power / (2 * np.pi**2 * sigma**2 * r**3) @override @@ -449,7 +449,7 @@ def sigma(self, r, order=0): # # Need to re-define this because the integral needs to go exactly kr=1 # # or else the function 'jitters' sigma = np.zeros(len(r)) - power = _spline(self.k, self.power) + power = Spline(self.k, self.power) for i, rr in enumerate(r): k = np.logspace( np.log10(self.k[0]), @@ -539,18 +539,18 @@ def r_a3(self, rmin, rmax): """ r = np.logspace(np.log(rmin), np.log(rmax), 200, base=np.e) a3 = self.a3(r) - return _spline(a3, r) + return Spline(a3, r) @override def dlnss_dlnr(self, r): a3 = self.a3(r) sigma = self.sigma(a3) - power = _spline(self.k, self.power)(1 / a3) + power = Spline(self.k, self.power)(1 / a3) return -power / (2 * np.pi**2 * sigma**2 * a3**3) @override def dlnr_dlnm(self, r): a3 = self.a3(r) xi = r / a3 - drda = _spline(a3, r).derivative()(a3) + drda = Spline(a3, r).derivative()(a3) return xi / 3 / drda diff --git a/src/hmf/density_field/halofit.py b/src/hmf/density_field/halofit.py index a4713acb..04251426 100644 --- a/src/hmf/density_field/halofit.py +++ b/src/hmf/density_field/halofit.py @@ -11,10 +11,10 @@ import numpy as np from scipy.integrate import simpson as _simps -from scipy.interpolate import InterpolatedUnivariateSpline as _spline +from scipy.interpolate import InterpolatedUnivariateSpline as Spline from scipy.optimize import minimize -from ..cosmology.cosmo import Cosmology as csm +from ..cosmology.cosmo import Cosmology as CosmologyClass def _get_spec( @@ -71,7 +71,7 @@ def get_sigma_abs(lnr): lnr = np.linspace(np.log(0.75 * rnl), np.log(1.25 * rnl), 20) lnsig = [get_log_sigma2(r) for r in lnr] - sig_of_r = _spline(lnr, lnsig, k=5) + sig_of_r = Spline(lnr, lnsig, k=5) dev1, dev2 = sig_of_r.derivatives(np.log(rnl))[1:3] n_eff = -dev1 - 3.0 @@ -112,7 +112,7 @@ def halofit(k, delta_k, *, sigma_8=None, z=0, cosmo=None, takahashi=True): warnings.warn("sigma_8 is not used any more, and will be removed in v4", stacklevel=2) if cosmo is None: - cosmo = csm() + cosmo = CosmologyClass() # Get physical parameters rknl, neff, rncur = _get_spec(k, delta_k) diff --git a/src/hmf/density_field/transfer.py b/src/hmf/density_field/transfer.py index d40c2f62..15a771b9 100644 --- a/src/hmf/density_field/transfer.py +++ b/src/hmf/density_field/transfer.py @@ -6,9 +6,10 @@ related quantities. """ -import numpy as np from typing import override +import numpy as np + from .._internals._cache import cached_quantity, parameter from .._internals._framework import get_mdl from ..cosmology import cosmo diff --git a/src/hmf/density_field/transfer_models.py b/src/hmf/density_field/transfer_models.py index ec7de590..dd69831f 100644 --- a/src/hmf/density_field/transfer_models.py +++ b/src/hmf/density_field/transfer_models.py @@ -8,11 +8,11 @@ import pickle import warnings from copy import deepcopy -from typing import Any, ClassVar, Final, override +from typing import Any, ClassVar, Final import numpy as np from astropy import cosmology -from scipy.interpolate import InterpolatedUnivariateSpline as spline +from scipy.interpolate import InterpolatedUnivariateSpline as Spline from .._internals._framework import Component, pluggable @@ -135,7 +135,7 @@ def lnt(self, lnk): else: lnkout = T[0, :] lnT = T[1, :] - return spline(lnkout, lnT, k=1)(lnk) + return Spline(lnkout, lnT, k=1)(lnk) if HAVE_CAMB: @@ -268,7 +268,7 @@ def lnt(self, lnk): lnT -= lnT[0] if not self.params["extrapolate_with_eh"]: - return spline(lnkout, lnT, k=1)(lnk) + return Spline(lnkout, lnT, k=1)(lnk) # Now add a point one e-fold above the max, with an EH-generated transfer lnkout = np.concatenate((lnkout, [lnkout[-1] + 1])) @@ -279,7 +279,7 @@ def lnt(self, lnk): lnkmin = lnkout.min() lnkmax = lnkout.max() - inner_spline = spline(lnkout, lnT, k=3) + inner_spline = Spline(lnkout, lnT, k=3) out = np.zeros_like(lnk) out[lnk < lnkmin] = 0 @@ -435,7 +435,7 @@ def lnt(self, lnk): else: lnkout = np.log(k) lnT = np.log(T) - return spline(lnkout, lnT, k=1)(lnk) + return Spline(lnkout, lnT, k=1)(lnk) class EH_BAO(TransferComponent): diff --git a/src/hmf/halos/__init__.py b/src/hmf/halos/__init__.py index dbbd3ff8..ef06550e 100644 --- a/src/hmf/halos/__init__.py +++ b/src/hmf/halos/__init__.py @@ -8,6 +8,6 @@ from .mass_definitions import MassDefinition __all__ = [ - "mass_definitions", "MassDefinition", + "mass_definitions", ] diff --git a/src/hmf/helpers/__init__.py b/src/hmf/helpers/__init__.py index 204e5694..54a9b429 100644 --- a/src/hmf/helpers/__init__.py +++ b/src/hmf/helpers/__init__.py @@ -4,7 +4,7 @@ from .functional import get_best_param_order, get_hmf __all__ = [ - "sample", "get_best_param_order", "get_hmf", + "sample", ] diff --git a/src/hmf/helpers/cfg_utils.py b/src/hmf/helpers/cfg_utils.py index 832eae68..66f9f94e 100644 --- a/src/hmf/helpers/cfg_utils.py +++ b/src/hmf/helpers/cfg_utils.py @@ -1,6 +1,6 @@ """Utilities for interacting with hmf TOML configs.""" -from datetime import datetime, timezone +from datetime import UTC, datetime from inspect import signature from astropy.units import Quantity @@ -12,7 +12,7 @@ def framework_to_dict(obj: Framework) -> dict: """Serialize a framework instance to a simple TOML-able dictionary.""" - out = {"created_on": datetime.now(tz=timezone.utc), "hmf_version": __version__, "params": {}} + out = {"created_on": datetime.now(tz=UTC), "hmf_version": __version__, "params": {}} for k, v in obj.parameter_values.items(): if k == "cosmo_model": diff --git a/src/hmf/helpers/sample.py b/src/hmf/helpers/sample.py index ebd77001..4456720b 100644 --- a/src/hmf/helpers/sample.py +++ b/src/hmf/helpers/sample.py @@ -5,7 +5,7 @@ """ import numpy as np -from scipy.interpolate import InterpolatedUnivariateSpline as _spline +from scipy.interpolate import InterpolatedUnivariateSpline as Spline from ..mass_function import hmf @@ -14,7 +14,7 @@ def _prepare_mf(log_mmin, **mf_kwargs): h = hmf.MassFunction(Mmin=log_mmin, **mf_kwargs) mask = h.ngtm > 0 _icdf = np.log10(h.ngtm[mask] / h.ngtm[0]) - icdf = _spline(_icdf[::-1], np.log10(h.m[mask][::-1]), k=3) + icdf = Spline(_icdf[::-1], np.log10(h.m[mask][::-1]), k=3) return icdf, h diff --git a/src/hmf/mass_function/__init__.py b/src/hmf/mass_function/__init__.py index f435f7aa..2c8935d1 100644 --- a/src/hmf/mass_function/__init__.py +++ b/src/hmf/mass_function/__init__.py @@ -5,12 +5,12 @@ from .hmf import MassFunction __all__ = [ - "fitting_functions", - "hmf", - "integrate_hmf", "PS", "SMT", "FittingFunction", - "Tinker08", "MassFunction", + "Tinker08", + "fitting_functions", + "hmf", + "integrate_hmf", ] diff --git a/src/hmf/mass_function/fitting_functions.py b/src/hmf/mass_function/fitting_functions.py index dcd97503..282ed412 100644 --- a/src/hmf/mass_function/fitting_functions.py +++ b/src/hmf/mass_function/fitting_functions.py @@ -11,7 +11,7 @@ import numpy as np import scipy.special as sp -from scipy.interpolate import InterpolatedUnivariateSpline as _spline +from scipy.interpolate import InterpolatedUnivariateSpline as Spline from .._internals import _framework from ..cosmology import cosmo as csm @@ -328,6 +328,8 @@ def fsigma(self): class PS(FittingFunction): + """Press-Schechter mass function fit.""" + # Subclass requirements req_sigma = False #: Whether sigma is required to compute this model. req_z = False #: Whether redshift is required for this model. @@ -348,6 +350,8 @@ def fsigma(self): class SMT(FittingFunction): + """Sheth-Mo-Tormen mass function fit.""" + # Subclass requirements req_sigma = False req_z = False @@ -418,6 +422,8 @@ class ST(SMT): class Jenkins(FittingFunction): + """Jenkins mass function fit.""" + # Subclass requirements req_z = False @@ -465,6 +471,8 @@ def fsigma(self): class Warren(FittingFunction): + """Warren mass function fit.""" + # Subclass requirements req_z = False req_mass = True @@ -537,6 +545,8 @@ def cutmask(self): class Reed03(SMT): + """Reed 2003 mass function fit.""" + # Subclass requirements req_sigma = True @@ -580,6 +590,8 @@ def cutmask(self): class Reed07(FittingFunction): + """Reed 2007 mass function fit.""" + req_neff = True req_z = False @@ -663,6 +675,8 @@ def cutmask(self): class Peacock(FittingFunction): + """Peacock mass function fit.""" + req_z = False req_mass = True @@ -697,6 +711,8 @@ def cutmask(self): class Angulo(FittingFunction): + """Angulo mass function fit.""" + req_mass = True _ref = """Angulo, R. E., et al., 2012. arXiv:1203.3216v1""" _eq = r"$A \left[\left(\frac{d}{\sigma}\right)^b + 1 \right] \exp(-c/\sigma^2)$" @@ -738,11 +754,15 @@ def cutmask(self): class AnguloBound(Angulo): + """Bounded version of Angulo mass function fit.""" + __doc__ = Angulo.__doc__ _defaults: ClassVar[Final[dict[str, float]]] = {"A": 0.265, "b": 1.9, "c": 1.4, "d": 1.675} class Watson_FoF(Warren): + """Watson friend-of-friend mass function fit.""" + req_mass = False _ref = """Watson, W. A., et al., MNRAS, 2013. http://adsabs.harvard.edu/abs/2013MNRAS.433.1230W """ @@ -774,6 +794,8 @@ def cutmask(self): class Watson(FittingFunction): + """Watson mass function fit.""" + req_cosmo = True req_dhalo = True req_omz = True @@ -879,6 +901,8 @@ def cutmask(self): class Crocce(Warren): + """Crocce mass function fit.""" + req_z = True _ref = """Crocce, M., et al. MNRAS 403 (3), 1353-1367. http://doi.wiley.com/10.1111/j.1365-2966.2009.16194.x""" @@ -928,6 +952,8 @@ def cutmask(self): class Courtin(SMT): + """Courtin mass function fit.""" + req_sigma = True _ref = """Courtin, J., et al., Oct. 2010. MNRAS 1931. http://doi.wiley.com/10.1111/j.1365-2966.2010.17573.x""" __doc__ = _makedoc(FittingFunction._pdocs, "Courtin", "Ctn", SMT._eq, _ref) @@ -960,6 +986,8 @@ def cutmask(self): class Bhattacharya(SMT): + """Bhattacharya mass function fit.""" + req_z = True req_mass = True @@ -1054,6 +1082,8 @@ def _norm(self): class Tinker08(FittingFunction): + """Tinker 2008 mass function fit.""" + req_z = True req_dhalo = True @@ -1337,10 +1367,10 @@ def __init__(self, **model_parameters): b_array = np.array([self.params[f"b_{d}"] for d in self.delta_virs]) c_array = np.array([self.params[f"c_{d}"] for d in self.delta_virs]) - A_func = _spline(self.delta_virs, A_array) - a_func = _spline(self.delta_virs, a_array) - b_func = _spline(self.delta_virs, b_array) - c_func = _spline(self.delta_virs, c_array) + A_func = Spline(self.delta_virs, A_array) + a_func = Spline(self.delta_virs, a_array) + b_func = Spline(self.delta_virs, b_array) + c_func = Spline(self.delta_virs, c_array) A_0 = A_func(delta_halo) a_0 = a_func(delta_halo) @@ -1380,6 +1410,8 @@ def cutmask(self): class Tinker10(FittingFunction): + """Tinker 2010 mass function fit.""" + req_z = True req_dhalo = True @@ -1473,10 +1505,10 @@ def __init__(self, **model_parameters): phi_array = np.array([self.params[f"phi_{d}"] for d in self.delta_virs]) eta_array = np.array([self.params[f"eta_{d}"] for d in self.delta_virs]) - beta_func = _spline(self.delta_virs, beta_array) - gamma_func = _spline(self.delta_virs, gamma_array) - phi_func = _spline(self.delta_virs, phi_array) - eta_func = _spline(self.delta_virs, eta_array) + beta_func = Spline(self.delta_virs, beta_array) + gamma_func = Spline(self.delta_virs, gamma_array) + phi_func = Spline(self.delta_virs, phi_array) + eta_func = Spline(self.delta_virs, eta_array) beta_0 = beta_func(delta_halo) gamma_0 = gamma_func(delta_halo) @@ -1563,6 +1595,8 @@ def cutmask(self): class Behroozi(Tinker08): + """Behroozi mass function fit.""" + _ref = r"""Behroozi, P., Weschler, R. and Conroy, C., ApJ, 2013, http://arxiv.org/abs/1207.6105""" __doc__ = rf""" Behroozi mass function fit [1]_. @@ -1628,6 +1662,8 @@ def _modify_dndm(self, m, dndm, z, ngtm_tinker): class Pillepich(Warren): + """Pillepich mass function fit.""" + _ref = r"""Pillepich, A., et al., 2010, arxiv:0811.4176""" __doc__ = _makedoc( FittingFunction._pdocs, "Pillepich", "Pillepich", Warren._eq, _ref @@ -1660,6 +1696,8 @@ class Pillepich(Warren): class Manera(SMT): + """Manera mass function fit.""" + _ref = r"""Manera, M., et al., 2010, arxiv:0906.1314""" __doc__ = _makedoc(FittingFunction._pdocs, "Manera", "Man", SMT._eq, _ref) # These are for z=0, new ML method, l_linnk = 0.2 @@ -1690,6 +1728,8 @@ class Manera(SMT): class Ishiyama(Warren): + """Ishiyama mass function fit.""" + _eq = r"A\left[\left(\frac{e}{\sigma}\right)^b + 1\right]\exp(\frac{d}{\sigma^2})" _ref = r"""Ishiyama, T., et al., 2015, arxiv:1412.2860""" __doc__ = _makedoc(FittingFunction._pdocs, "Ishiyama", "Ishiyama", _eq, _ref) @@ -1726,6 +1766,8 @@ def cutmask(self): class Bocquet200mDMOnly(Warren): + """Bocquet mass function fit for 200m definition with dark matter only.""" + _eq = r"A\left[\left(\frac{e}{\sigma}\right)^b + 1\right]\exp(-\frac{d}{\sigma^2})" _ref = r"""Bocuet, S., et al., 2016, MNRAS 456 2361""" __doc__ = _makedoc(FittingFunction._pdocs, "Bocquet", "Bocquet", _eq, _ref) @@ -1796,6 +1838,8 @@ def fsigma(self): class Bocquet200mHydro(Bocquet200mDMOnly): + """Bocquet mass function fit for 200m definition with hydrodynamics.""" + __doc__ = _makedoc( FittingFunction._pdocs, "Bocquet", @@ -1817,6 +1861,8 @@ class Bocquet200mHydro(Bocquet200mDMOnly): class Bocquet200cDMOnly(Bocquet200mDMOnly): + """Bocquet mass function fit for 200c definition with dark matter only.""" + __doc__ = _makedoc( FittingFunction._pdocs, "Bocquet", @@ -1854,6 +1900,8 @@ def convert_mass(self): class Bocquet200cHydro(Bocquet200cDMOnly): + """Bocquet mass function fit for 200c definition with hydrodynamics.""" + __doc__ = _makedoc( FittingFunction._pdocs, "Bocquet", @@ -1876,6 +1924,8 @@ class Bocquet200cHydro(Bocquet200cDMOnly): class Bocquet500cDMOnly(Bocquet200cDMOnly): + """Bocquet mass function fit for 500c definition with dark matter only.""" + __doc__ = _makedoc( FittingFunction._pdocs, "Bocquet", @@ -1909,6 +1959,8 @@ def convert_mass(self): class Bocquet500cHydro(Bocquet500cDMOnly): + """Bocquet mass function fit for 500c definition with hydrodynamics.""" + __doc__ = _makedoc( FittingFunction._pdocs, "Bocquet", diff --git a/src/hmf/mass_function/hmf.py b/src/hmf/mass_function/hmf.py index 9535b8b1..de698546 100644 --- a/src/hmf/mass_function/hmf.py +++ b/src/hmf/mass_function/hmf.py @@ -10,14 +10,14 @@ from typing import Any, override import numpy as np -from scipy.interpolate import InterpolatedUnivariateSpline as spline +from scipy.interpolate import InterpolatedUnivariateSpline as Spline from scipy.optimize import minimize from .._internals._cache import cached_quantity, parameter from .._internals._framework import get_mdl from ..density_field import transfer from ..density_field.filters import Filter, TopHat -from ..halos.mass_definitions import MassDefinition as md +from ..halos.mass_definitions import MassDefinition as MassDef from ..halos.mass_definitions import SOGeneric, SOMean from . import fitting_functions as ff from .integrate_hmf import hmf_integral_gtm as int_gtm @@ -102,7 +102,7 @@ def __init__( dlog10m: float = 0.01, hmf_model: str | ff.FittingFunction = ff.Tinker08, hmf_params: dict[str, Any] | None = None, - mdef_model: None | str | md = None, + mdef_model: None | str | MassDef = None, mdef_params: dict | None = None, delta_c: float = 1.686, filter_model: str | Filter = TopHat, @@ -257,7 +257,7 @@ def mean_density(self): return self.mean_density0 * (1 + self.z) ** 3 @cached_quantity - def mdef(self) -> md: + def mdef(self) -> MassDef: """The halo mass-definition model instance. Default mass definition is the one the chosen hmf model was measured with. @@ -404,7 +404,7 @@ def nu_fn(self): with length equal to ``len(m)``. """ - return spline(self.m, self.nu, k=5) + return Spline(self.m, self.nu, k=5) @cached_quantity def mass_nonlinear(self): @@ -439,7 +439,7 @@ def model(lnr): return self.filter.radius_to_mass(r, self.mean_density0) warnings.warn("Minimization failed :(", stacklevel=2) return 0 - nu = spline(self.nu, self.m, k=5) + nu = Spline(self.nu, self.m, k=5) return nu(1) @cached_quantity @@ -466,7 +466,7 @@ def n_eff(self): @cached_quantity def n_eff_at_collapse(self): """Effective spectral index at scale of halo radius at halo collapse.""" - fnc = spline(self.nu, self.n_eff) + fnc = Spline(self.nu, self.n_eff) return fnc(1) @cached_quantity diff --git a/src/hmf/mass_function/integrate_hmf.py b/src/hmf/mass_function/integrate_hmf.py index 5f1f0ff3..8c609d1e 100644 --- a/src/hmf/mass_function/integrate_hmf.py +++ b/src/hmf/mass_function/integrate_hmf.py @@ -2,7 +2,7 @@ import numpy as np import scipy.integrate as intg -from scipy.interpolate import InterpolatedUnivariateSpline as _spline +from scipy.interpolate import InterpolatedUnivariateSpline as Spline class NaNException(Exception): @@ -65,7 +65,7 @@ def hmf_integral_gtm(m, dndm, mass_density=False): # Calculate the mass function (and its integral) from the highest M up to 10**18 if m[-1] < m[0] * 10**18 / m[3]: m_upper = np.arange(np.log(m[-1]), np.log(10**18), np.log(m[1]) - np.log(m[0])) - mf_func = _spline(np.log(m), np.log(dndlnm), k=1) + mf_func = Spline(np.log(m), np.log(dndlnm), k=1) mf = mf_func(m_upper) if not mass_density: From 184c4e0573e59b86632779ea78eff80cf10b50ce Mon Sep 17 00:00:00 2001 From: Steven Murray Date: Sun, 22 Feb 2026 15:57:21 +0200 Subject: [PATCH 08/18] style: line length --- src/hmf/_internals/_cache.py | 16 ++++++---- src/hmf/cosmology/cosmo.py | 9 +++--- src/hmf/cosmology/growth_factor.py | 3 +- src/hmf/density_field/filters.py | 3 +- src/hmf/density_field/halofit.py | 4 ++- src/hmf/density_field/transfer_models.py | 3 +- src/hmf/helpers/__init__.py | 4 ++- src/hmf/mass_function/fitting_functions.py | 36 +++++++++++++++++----- src/hmf/mass_function/hmf.py | 19 +++++++++--- src/hmf/mass_function/integrate_hmf.py | 4 ++- 10 files changed, 72 insertions(+), 29 deletions(-) diff --git a/src/hmf/_internals/_cache.py b/src/hmf/_internals/_cache.py index aaf1ef1f..1fa16da1 100644 --- a/src/hmf/_internals/_cache.py +++ b/src/hmf/_internals/_cache.py @@ -81,7 +81,8 @@ def _get_property(self): recalc_prpa[pr].update(recalc_prpa[name]) except KeyError as e: raise KeyError( - f"When getting {name}, couldn't find {pr} in recalc_prpa. Had {list(recalc_prpa.keys())}." + f"When getting {name}, couldn't find {pr} in recalc_prpa. " + f"Had {list(recalc_prpa.keys())}." ) from e # check all quantities for dependence on subframeworks and update their entries @@ -198,9 +199,10 @@ def parameter(kind): Parameters ---------- kind : str - Either "param", "option", "model", "switch" or "res". Changes the behaviour of the parameter. - "param", "option", "model" and "res" all behave the same currently, while when a "switch" is modified, - all dependent quantities have their dependencies re-indexed. + Either "param", "option", "model", "switch" or "res". Changes the behaviour of the + parameter. "param", "option", "model" and "res" all behave the same currently, + while when a "switch" is modified, all dependent quantities have their dependencies + re-indexed. Examples -------- @@ -295,8 +297,10 @@ def _set_property(self, val): warnings.warn( f"You are setting {name} directly. This is unstable, as less " f"validation is performed. You can turn on extra validation " - f"for directly set parameters by setting framework._validate_every_param_set=True." - f"However, this can be brittle, since intermediate states may not be valid.", + f"for directly set parameters by setting " + f"framework._validate_every_param_set=True. " + f"However, this can be brittle, since intermediate states " + f"may not be valid.", stacklevel=2, category=DeprecationWarning, ) diff --git a/src/hmf/cosmology/cosmo.py b/src/hmf/cosmology/cosmo.py index e0c6ee02..54ee20ed 100644 --- a/src/hmf/cosmology/cosmo.py +++ b/src/hmf/cosmology/cosmo.py @@ -6,8 +6,8 @@ for use in this package. Also provided in the namespace are the pre-defined cosmologies from `astropy`: -`WMAP5`, `WMAP7`, `WMAP9`, `Planck13`, `Planck15` and `Planck18`, which may be used as arguments to the -Cosmology framework. All custom subclasses of :class:`astropy.cosmology.FLRW` +`WMAP5`, `WMAP7`, `WMAP9`, `Planck13`, `Planck15` and `Planck18`, which may be used as +arguments to the Cosmology framework. All custom subclasses of :class:`astropy.cosmology.FLRW` may be used as inputs. """ @@ -66,8 +66,9 @@ class Cosmology(_framework.Framework): update will *update* the dictionary, rather than replacing it. To read a standard documented list of parameters, use ``Cosmology.parameter_info()``. - If you want to just see the plain list of available parameters, use ``Cosmology.get_all_parameters()``. - To see the actual defaults for each parameter, use ``Cosmology.get_all_parameter_defaults()``. + If you want to just see the plain list of available parameters, use + ``Cosmology.get_all_parameters()``. To see the actual defaults for each parameter, use + ``Cosmology.get_all_parameter_defaults()``. """ def __init__(self, cosmo_model=Planck18, cosmo_params=None): diff --git a/src/hmf/cosmology/growth_factor.py b/src/hmf/cosmology/growth_factor.py index a9589332..081cdbc8 100644 --- a/src/hmf/cosmology/growth_factor.py +++ b/src/hmf/cosmology/growth_factor.py @@ -409,7 +409,8 @@ class Carroll1992(GrowthFactor): the :attr:`_defaults` class attribute. :dz: Step-size for redshift spline - :zmax: Maximum redshift of spline. Only used for :meth:`growth_factor_fn`, when `inverse=True`. + :zmax: Maximum redshift of spline. Only used for :meth:`growth_factor_fn`, when + `inverse=True`. """ _defaults: ClassVar[Final[dict[str, float]]] = {"dz": 0.01, "zmax": 1000.0} diff --git a/src/hmf/density_field/filters.py b/src/hmf/density_field/filters.py index f4b178fe..3b99bdc1 100644 --- a/src/hmf/density_field/filters.py +++ b/src/hmf/density_field/filters.py @@ -501,7 +501,8 @@ def pm(self, xm): return 30.0 / (5 * xm**2 + 6) ** 2 def a3a1(self, e, p): - """Compute the short:long axis ratio of an ellipsoid given its ellipticity and prolateness.""" + """Compute the short:long axis ratio of an ellipsoid given its ellipticity and prolateness. + """ return np.sqrt((1 - 3 * e + p) / (1 + 3 * e + p)) def a3a2(self, e, p): diff --git a/src/hmf/density_field/halofit.py b/src/hmf/density_field/halofit.py index 04251426..ee627871 100644 --- a/src/hmf/density_field/halofit.py +++ b/src/hmf/density_field/halofit.py @@ -63,7 +63,9 @@ def get_sigma_abs(lnr): if not res.success: warnings.warn( f"Could not determine non-linear scale! Failed with error: {res.message}. " - f"Continuing with best-fit non-linear scale: r_nl={np.exp(res.x)}, with log_sigma^2 = {res.fun}", stacklevel=2 + f"Continuing with best-fit non-linear scale: r_nl={np.exp(res.x)}, with " + f"log_sigma^2 = {res.fun}", + stacklevel=2 ) rnl = np.exp(res.x) diff --git a/src/hmf/density_field/transfer_models.py b/src/hmf/density_field/transfer_models.py index dd69831f..64c0bcb0 100644 --- a/src/hmf/density_field/transfer_models.py +++ b/src/hmf/density_field/transfer_models.py @@ -233,7 +233,8 @@ def __init__(self, *args, **kwargs): warnings.warn( "'extrapolate_with_eh' was not set. Defaulting to True, which is " "different behaviour than versions <=3.4.4. This warning may be " - "removed in v4.0. Silence it by setting extrapolate_with_eh explicitly.", stacklevel=2 + "removed in v4.0. Silence it by setting extrapolate_with_eh explicitly.", + stacklevel=2 ) self.params["extrapolate_with_eh"] = True diff --git a/src/hmf/helpers/__init__.py b/src/hmf/helpers/__init__.py index 54a9b429..ba9890d3 100644 --- a/src/hmf/helpers/__init__.py +++ b/src/hmf/helpers/__init__.py @@ -1,4 +1,6 @@ -"""A collection of helper functions which can operate on several of the Frameworks in the rest of the code.""" +"""A collection of helper functions which can operate on several of the Frameworks in the +rest of the code. +""" from . import sample from .functional import get_best_param_order, get_hmf diff --git a/src/hmf/mass_function/fitting_functions.py b/src/hmf/mass_function/fitting_functions.py index 282ed412..f4b5b18b 100644 --- a/src/hmf/mass_function/fitting_functions.py +++ b/src/hmf/mass_function/fitting_functions.py @@ -487,7 +487,9 @@ class Warren(FittingFunction): ) __doc__ = _makedoc(FittingFunction._pdocs, "Warren", "Warren", _eq, _ref) - _defaults: ClassVar[Final[dict[str, float]]] = {"A": 0.7234, "b": 1.625, "c": 0.2538, "d": 1.1982, "e": 1} + _defaults: ClassVar[Final[dict[str, float]]] = { + "A": 0.7234, "b": 1.625, "c": 0.2538, "d": 1.1982, "e": 1 + } normalized = False uncertainties: ClassVar[Final[dict[str, float]]] = { @@ -595,8 +597,14 @@ class Reed07(FittingFunction): req_neff = True req_z = False - _eq = r"A\sqrt{2a/\pi}\left[1+(\frac{1}{a\nu^2})^p+0.6G_1+0.4G_2\right]\nu\exp\left(-ca\nu^2/2-\frac{0.03\nu^{0.6}}{(n_{\rm eff}+3)^2}\right)" - _ref = """Reed, D. S., et al., Jan. 2007. MNRAS 374 (1), 2-15. http://adsabs.harvard.edu/abs/2007MNRAS.374....2R""" + _eq = ( + r"A\sqrt{2a/\pi}\left[1+(\frac{1}{a\nu^2})^p+0.6G_1+0.4G_2\right]\nu" + r"\exp\left(-ca\nu^2/2-\frac{0.03\nu^{0.6}}{(n_{\rm eff}+3)^2}\right)" + ) + _ref = ( + """Reed, D. S., et al., Jan. 2007. MNRAS 374 (1), 2-15. """ + """http://adsabs.harvard.edu/abs/2007MNRAS.374....2R""" + ) __doc__ = _makedoc(FittingFunction._pdocs, "Reed07", "R07", _eq, _ref) _defaults: ClassVar[Final[dict[str, float]]] = {"A": 0.3222, "p": 0.3, "c": 1.08, "a": 0.764} @@ -765,9 +773,14 @@ class Watson_FoF(Warren): req_mass = False - _ref = """Watson, W. A., et al., MNRAS, 2013. http://adsabs.harvard.edu/abs/2013MNRAS.433.1230W """ + _ref = ( + """Watson, W. A., et al., MNRAS, 2013. """ + """http://adsabs.harvard.edu/abs/2013MNRAS.433.1230W """ + ) __doc__ = _makedoc(FittingFunction._pdocs, "Watson FoF", "WatF", Warren._eq, _ref) - _defaults: ClassVar[Final[dict[str, float]]] = {"A": 0.282, "b": 2.163, "c": 1, "d": 1.21, "e": 1.406} + _defaults: ClassVar[Final[dict[str, float]]] = { + "A": 0.282, "b": 2.163, "c": 1, "d": 1.21, "e": 1.406 + } sim_definition = SimDetails( L=[11.4, 20, 114, 425, 1000, 3200, 6000], @@ -800,7 +813,10 @@ class Watson(FittingFunction): req_dhalo = True req_omz = True - _ref = """Watson, W. A., et al., MNRAS, 2013. http://adsabs.harvard.edu/abs/2013MNRAS.433.1230W """ + _ref = ( + """Watson, W. A., et al., MNRAS, 2013. """ + """http://adsabs.harvard.edu/abs/2013MNRAS.433.1230W """ + ) _eq = r"\Gamma A \left((\frac{\beta}{\sigma}^\alpha+1\right)\exp(-\gamma/\sigma^2)" __doc__ = _makedoc(FittingFunction._pdocs, "Watson", "WatS", _eq, Watson_FoF._ref) @@ -1668,7 +1684,9 @@ class Pillepich(Warren): __doc__ = _makedoc( FittingFunction._pdocs, "Pillepich", "Pillepich", Warren._eq, _ref ) - _defaults: ClassVar[Final[dict[str, float]]] = {"A": 0.6853, "b": 1.868, "c": 0.3324, "d": 1.2266, "e": 1} + _defaults: ClassVar[Final[dict[str, float]]] = { + "A": 0.6853, "b": 1.868, "c": 0.3324, "d": 1.2266, "e": 1 + } normalized = False sim_definition = SimDetails( @@ -1734,7 +1752,9 @@ class Ishiyama(Warren): _ref = r"""Ishiyama, T., et al., 2015, arxiv:1412.2860""" __doc__ = _makedoc(FittingFunction._pdocs, "Ishiyama", "Ishiyama", _eq, _ref) - _defaults: ClassVar[Final[dict[str, float]]] = {"A": 0.193, "b": 1.550, "c": 1, "d": 1.186, "e": 2.184} + _defaults: ClassVar[Final[dict[str, float]]] = { + "A": 0.193, "b": 1.550, "c": 1, "d": 1.186, "e": 2.184 + } sim_definition = SimDetails( L=[1120, 560, 280, 140, 70], diff --git a/src/hmf/mass_function/hmf.py b/src/hmf/mass_function/hmf.py index de698546..98b40f88 100644 --- a/src/hmf/mass_function/hmf.py +++ b/src/hmf/mass_function/hmf.py @@ -302,7 +302,9 @@ def mdef(self) -> MassDef: warnings.warn( f"Your input mass definition '{mdef}' does not match the mass " f"definition in which the hmf fit {self.hmf_model.__name__} was measured:" - f"'{self.hmf_model.get_measured_mdef()}'. {extra_msg if not self.disable_mass_conversion else ''}", stacklevel=2 + f"'{self.hmf_model.get_measured_mdef()}'. " + f"{extra_msg if not self.disable_mass_conversion else ''}", + stacklevel=2 ) return mdef @@ -381,7 +383,8 @@ def _dlnsdlnm(self): Notes ----- - .. math:: frac{d\ln\sigma}{d\ln m} = \frac{3}{2\sigma^2\pi^2R^4}\int_0^\infty \frac{dW^2(kR)}{dM}\frac{P(k)}{k^2}dk + .. math:: frac{d\ln\sigma}{d\ln m} = \frac{3}{2\sigma^2\pi^2R^4}\int_0^\infty + \frac{dW^2(kR)}{dM}\frac{P(k)}{k^2}dk """ return 0.5 * self.filter.dlnss_dlnm(self.radii) @@ -476,7 +479,9 @@ def fsigma(self): @cached_quantity def dndm(self): - r"""The number density of haloes, ``len=len(m)`` [units :math:`h^4 M_\odot^{-1} Mpc^{-3}`].""" + r"""The number density of haloes, ``len=len(m)`` [units :math:`h^4 M_\odot^{-1} + Mpc^{-3}`]. + """ # if self.z2 is None: # #This is normally the case dndm = self.fsigma * self.mean_density0 * np.abs(self._dlnsdlnm) / self.m**2 if isinstance(self.hmf, ff.Behroozi): @@ -505,12 +510,16 @@ def dndm(self): @cached_quantity def dndlnm(self): - r"""The differential mass function in terms of natural log of `m`, ``len=len(m)`` [units :math:`h^3 Mpc^{-3}`].""" + r"""The differential mass function in terms of natural log of `m`, ``len=len(m)`` + [units :math:`h^3 Mpc^{-3}`]. + """ return self.m * self.dndm @cached_quantity def dndlog10m(self): - r"""The differential mass function in terms of log of `m`, ``len=len(m)`` [units :math:`h^3 Mpc^{-3}`].""" + r"""The differential mass function in terms of log of `m`, ``len=len(m)`` + [units :math:`h^3 Mpc^{-3}`]. + """ return self.m * self.dndm * np.log(10) def _gtm(self, dndm, mass_density=False): diff --git a/src/hmf/mass_function/integrate_hmf.py b/src/hmf/mass_function/integrate_hmf.py index 8c609d1e..8994ee5c 100644 --- a/src/hmf/mass_function/integrate_hmf.py +++ b/src/hmf/mass_function/integrate_hmf.py @@ -1,4 +1,6 @@ -"""A supporting module that provides a routine to integrate the differential hmf in a robust manner.""" +"""A supporting module that provides a routine to integrate the differential hmf in a robust +manner. +""" import numpy as np import scipy.integrate as intg From 407eaa64076c9e927c9f3a055261d7cdc55f3109 Mon Sep 17 00:00:00 2001 From: Steven Murray Date: Sun, 22 Feb 2026 16:00:07 +0200 Subject: [PATCH 09/18] style: small fixes --- changethelog.py | 25 ------------------------- docs/conf.py | 1 - docs/examples/your_first_plot.ipynb | 14 +++++++------- 3 files changed, 7 insertions(+), 33 deletions(-) delete mode 100644 changethelog.py diff --git a/changethelog.py b/changethelog.py deleted file mode 100644 index 02b7aac4..00000000 --- a/changethelog.py +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/python -"""Automatically update changelog.""" - -import sys -from datetime import datetime, timezone -from pathlib import Path - -if __name__ == "__main__": - newversion = sys.argv[1] - - with Path("CHANGELOG.rst").open() as fl: - lines = fl.readlines() - - for _i, line in enumerate(lines): - if line == "dev-version\n": - break - else: - raise OSError("Couldn't Find 'dev-version' tag") - - lines.insert(_i + 2, "----------------------\n") - lines.insert(_i + 2, f"v{newversion} [{datetime.now(tz=timezone.utc).strftime('%d %b %Y')}]\n") - lines.insert(_i + 2, "\n") - - with Path("CHANGELOG.rst").open("w") as fl: - fl.writelines(lines) diff --git a/docs/conf.py b/docs/conf.py index 136379fd..2904f87e 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -10,7 +10,6 @@ # All configuration values have a default; values that are commented out # serve to show the default. -import os import sys import time from pathlib import Path diff --git a/docs/examples/your_first_plot.ipynb b/docs/examples/your_first_plot.ipynb index 64df34e3..3c8f7713 100644 --- a/docs/examples/your_first_plot.ipynb +++ b/docs/examples/your_first_plot.ipynb @@ -18,7 +18,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": { "ExecuteTime": { "end_time": "2020-05-20T02:59:51.220133Z", @@ -32,7 +32,7 @@ "import numpy as np # Numerical array library\n", "\n", "# This just serves to render plots inline in the notebook. Do not use in a script.\n", - "%matplotlib inline " + "%matplotlib inline" ] }, { @@ -204,7 +204,7 @@ "outputs": [ { "data": { - "image/png": "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\n", + "image/png": "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", "text/plain": [ "
" ] @@ -268,7 +268,7 @@ "outputs": [ { "data": { - "image/png": "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\n", + "image/png": "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", "text/plain": [ "
" ] @@ -297,7 +297,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": null, "metadata": { "ExecuteTime": { "end_time": "2020-05-20T03:07:40.411067Z", @@ -307,7 +307,7 @@ "outputs": [ { "data": { - "image/png": "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\n", + "image/png": "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", "text/plain": [ "
" ] @@ -324,7 +324,7 @@ "for z in np.linspace(0,1,100):\n", " mf.update(z=z)\n", " plt.plot(mf.m,mf.dndm,color=\"darkblue\",alpha=1-z)\n", - " \n", + "\n", "plt.xscale('log')\n", "plt.yscale('log')\n", "\n", From e20d3e2419b7e0c3312df40eda2843001fa5fb44 Mon Sep 17 00:00:00 2001 From: Steven Murray Date: Sun, 22 Feb 2026 16:53:34 +0200 Subject: [PATCH 10/18] style: all ruff stuff done! --- development/growth_factor_integration.ipynb | 8 +- development/halofit_testing.ipynb | 4 +- docs/conf.py | 5 +- docs/examples/broad_overview.ipynb | 12 +- docs/examples/change_mass_definition.ipynb | 14 +- docs/examples/deal_with_cosmology.ipynb | 79 ++++++------ docs/examples/fitting.ipynb | 46 ++++--- docs/examples/plugins_and_extending.ipynb | 16 +-- docs/examples/your_first_plot.ipynb | 39 +++--- pyproject.toml | 12 +- src/hmf/__init__.py | 11 +- src/hmf/_cli.py | 8 +- src/hmf/_internals/_cache.py | 41 ++---- src/hmf/_internals/_framework.py | 35 ++--- src/hmf/alternatives/wdm.py | 28 ++-- src/hmf/cosmology/cosmo.py | 4 +- src/hmf/cosmology/growth_factor.py | 37 ++---- src/hmf/density_field/filters.py | 11 +- src/hmf/density_field/halofit.py | 23 +--- src/hmf/density_field/transfer.py | 12 +- src/hmf/density_field/transfer_models.py | 74 +++-------- src/hmf/halos/mass_definitions.py | 48 ++----- src/hmf/helpers/__init__.py | 4 +- src/hmf/helpers/cfg_utils.py | 4 +- src/hmf/mass_function/fitting_functions.py | 135 ++++++++------------ src/hmf/mass_function/hmf.py | 53 ++++---- src/hmf/mass_function/integrate_hmf.py | 15 +-- tests/test_cli.py | 16 +-- tests/test_fcoll.py | 2 +- tests/test_filters.py | 19 ++- tests/test_fits.py | 21 +-- tests/test_framework.py | 17 +-- tests/test_genmf.py | 18 +-- tests/test_growth.py | 14 +- tests/test_halofit.py | 16 +-- tests/test_hmf.py | 19 ++- tests/test_integrate_hmf.py | 24 ---- tests/test_mdef.py | 11 +- tests/test_sample.py | 6 +- tests/test_transfer.py | 40 ++---- tests/test_wdm.py | 12 +- 41 files changed, 364 insertions(+), 649 deletions(-) diff --git a/development/growth_factor_integration.ipynb b/development/growth_factor_integration.ipynb index 7fc2478f..8bb25fbf 100644 --- a/development/growth_factor_integration.ipynb +++ b/development/growth_factor_integration.ipynb @@ -97,9 +97,7 @@ " integral = intg.simpson(np.exp(lna) * integrand, x=lna)\n", " dplus = 5.0 * cosmo.Om0 * cosmo.efunc(z) * integral / 2.0\n", " else:\n", - " integral = intg.cumulative_trapezoid(\n", - " np.exp(lna) * integrand, dx=dlna, initial=0.0\n", - " )\n", + " integral = intg.cumulative_trapezoid(np.exp(lna) * integrand, dx=dlna, initial=0.0)\n", " dplus = 5.0 * cosmo.Om0 * cosmo.efunc(_zvec) * integral / 2.0\n", "\n", " return dplus" @@ -251,9 +249,7 @@ " integral = intg.simpson(integrand, x=np.exp(lna))\n", " dplus = 5.0 * cosmo.Om0 * cosmo.efunc(z) * integral / 2.0\n", " else:\n", - " integral = intg.cumulative_trapezoid(\n", - " np.exp(lna) * integrand, dx=dlna, initial=0.0\n", - " )\n", + " integral = intg.cumulative_trapezoid(np.exp(lna) * integrand, dx=dlna, initial=0.0)\n", " dplus = 5.0 * cosmo.Om0 * cosmo.efunc(_zvec) * integral / 2.0\n", "\n", " return dplus" diff --git a/development/halofit_testing.ipynb b/development/halofit_testing.ipynb index daf6adf2..b72333f2 100644 --- a/development/halofit_testing.ipynb +++ b/development/halofit_testing.ipynb @@ -82,9 +82,7 @@ } ], "source": [ - "plt.plot(\n", - " teh_nl_tk.k, np.abs(teh_nl_ntk.nonlinear_power / teh_nl_tk.nonlinear_power - 1)\n", - ")\n", + "plt.plot(teh_nl_tk.k, np.abs(teh_nl_ntk.nonlinear_power / teh_nl_tk.nonlinear_power - 1))\n", "# plt.plot(teh_nl_ntk.k, teh_nl_ntk.nonlinear_power)\n", "# plt.plot(teh_nl_ntk.k, teh_nl_ntk.power)\n", "\n", diff --git a/docs/conf.py b/docs/conf.py index 2904f87e..a32349a8 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,3 +1,4 @@ +"""Documentation config.""" # # hmf documentation build configuration file, created by # sphinx-quickstart on Mon Dec 2 10:40:08 2013. @@ -278,6 +279,4 @@ } -mathjax_path = ( - "http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML" -) +mathjax_path = "http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML" diff --git a/docs/examples/broad_overview.ipynb b/docs/examples/broad_overview.ipynb index 16e750e3..b90e45a7 100644 --- a/docs/examples/broad_overview.ipynb +++ b/docs/examples/broad_overview.ipynb @@ -31,7 +31,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": { "ExecuteTime": { "end_time": "2020-05-20T04:48:50.517186Z", @@ -40,9 +40,8 @@ }, "outputs": [], "source": [ - "from hmf import (\n", - " density_field, # Defines power spectra and transfer functions, as well as window functions/filters on those\n", - " )" + "# Defines power spectra and transfer functions, as well as window functions/filters on those\n", + "from hmf import density_field" ] }, { @@ -655,7 +654,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": null, "metadata": { "ExecuteTime": { "end_time": "2020-05-20T04:02:27.817305Z", @@ -664,7 +663,8 @@ }, "outputs": [], "source": [ - "redshifts = np.random.uniform(0, 3, size=20)" + "rng = np.random.default_rng(seed=42)\n", + "redshifts = rng.uniform(0, 3, size=20)" ] }, { diff --git a/docs/examples/change_mass_definition.ipynb b/docs/examples/change_mass_definition.ipynb index b4ee8310..be32ed19 100644 --- a/docs/examples/change_mass_definition.ipynb +++ b/docs/examples/change_mass_definition.ipynb @@ -123,11 +123,7 @@ } ], "source": [ - "[\n", - " x[1]\n", - " for x in inspect.getmembers(md, inspect.isclass)\n", - " if issubclass(x[1], md.MassDefinition)\n", - "]" + "[x[1] for x in inspect.getmembers(md, inspect.isclass) if issubclass(x[1], md.MassDefinition)]" ] }, { @@ -343,9 +339,7 @@ ], "source": [ "print(SMT.sim_definition.halo_finder_type, SMT.sim_definition.halo_overdensity)\n", - "print(\n", - " Tinker08.sim_definition.halo_finder_type, Tinker08.sim_definition.halo_overdensity\n", - ")\n", + "print(Tinker08.sim_definition.halo_finder_type, Tinker08.sim_definition.halo_overdensity)\n", "print(Jenkins.sim_definition.halo_finder_type, Jenkins.sim_definition.halo_overdensity)" ] }, @@ -583,9 +577,7 @@ " color=\"r\",\n", ")\n", "\n", - "ax[0].plot(\n", - " m, mf500c_conv.dndm / mf500c_refit.dndm - 1, ls=\"--\", color=\"k\", label=\"500c\"\n", - ")\n", + "ax[0].plot(m, mf500c_conv.dndm / mf500c_refit.dndm - 1, ls=\"--\", color=\"k\", label=\"500c\")\n", "ax[0].plot(\n", " m,\n", " mf500c_conv.fsigma / (mf500c_refit.fsigma / mf500c_refit.hmf.convert_mass()) - 1,\n", diff --git a/docs/examples/deal_with_cosmology.ipynb b/docs/examples/deal_with_cosmology.ipynb index b2323458..306736a3 100644 --- a/docs/examples/deal_with_cosmology.ipynb +++ b/docs/examples/deal_with_cosmology.ipynb @@ -25,6 +25,7 @@ "outputs": [], "source": [ "from hmf import cosmo\n", + "\n", "%matplotlib inline\n", "import matplotlib.pyplot as plt\n", "import numpy as np" @@ -65,7 +66,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "metadata": { "collapsed": false }, @@ -83,11 +84,11 @@ } ], "source": [ - "print \"Matter density: \", my_cosmo.cosmo.Om0\n", - "print \"Hubble constant: \", my_cosmo.cosmo.H0\n", - "print \"Dark Energy density: \", my_cosmo.cosmo.Ode0\n", - "print \"Baryon density: \", my_cosmo.cosmo.Ob0\n", - "print \"Curvature density: \", my_cosmo.cosmo.Ok0" + "print(\"Matter density: \", my_cosmo.cosmo.Om0)\n", + "print(\"Hubble constant: \", my_cosmo.cosmo.H0)\n", + "print(\"Dark Energy density: \", my_cosmo.cosmo.Ode0)\n", + "print(\"Baryon density: \", my_cosmo.cosmo.Ob0)\n", + "print(\"Curvature density: \", my_cosmo.cosmo.Ok0)" ] }, { @@ -126,8 +127,8 @@ } ], "source": [ - "z = np.linspace(0,8,100)\n", - "plt.plot(z,my_cosmo.cosmo.comoving_distance(z))\n", + "z = np.linspace(0, 8, 100)\n", + "plt.plot(z, my_cosmo.cosmo.comoving_distance(z))\n", "plt.ylabel(\"Comoving Distance, [Mpc]\")\n", "plt.xlabel(\"Redshift\")" ] @@ -148,7 +149,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": null, "metadata": { "collapsed": false }, @@ -164,7 +165,7 @@ "source": [ "my_cosmo = cosmo.Cosmology(cosmo_model=cosmo.WMAP5)\n", "\n", - "print \"WMAP5 baryon density: \", my_cosmo.cosmo.Ob0" + "print(\"WMAP5 baryon density: \", my_cosmo.cosmo.Ob0)" ] }, { @@ -183,7 +184,8 @@ "outputs": [], "source": [ "from astropy.cosmology import FlatLambdaCDM\n", - "new_model = FlatLambdaCDM(H0 = 75.0, Om0=0.4, Tcmb0 = 5.0, Ob0 = 0.3)" + "\n", + "new_model = FlatLambdaCDM(H0=75.0, Om0=0.4, Tcmb0=5.0, Ob0=0.3)" ] }, { @@ -195,7 +197,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": null, "metadata": { "collapsed": false }, @@ -209,8 +211,8 @@ } ], "source": [ - "my_cosmo = cosmo.Cosmology(cosmo_model = new_model)\n", - "print \"Crazy cosmology baryon density: \", my_cosmo.cosmo.Ob0" + "my_cosmo = cosmo.Cosmology(cosmo_model=new_model)\n", + "print(\"Crazy cosmology baryon density: \", my_cosmo.cosmo.Ob0)" ] }, { @@ -222,7 +224,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": null, "metadata": { "collapsed": false }, @@ -237,10 +239,11 @@ ], "source": [ "from astropy.cosmology import LambdaCDM\n", - "new_model = LambdaCDM(H0 = 75.0, Om0=0.4, Tcmb0 = 0.0, Ob0 = 0.3, Ode0=0.4)\n", "\n", - "my_cosmo = cosmo.Cosmology(cosmo_model = new_model)\n", - "print \"Crazy cosmology curvature density: \", my_cosmo.cosmo.Ok0" + "new_model = LambdaCDM(H0=75.0, Om0=0.4, Tcmb0=0.0, Ob0=0.3, Ode0=0.4)\n", + "\n", + "my_cosmo = cosmo.Cosmology(cosmo_model=new_model)\n", + "print(\"Crazy cosmology curvature density: \", my_cosmo.cosmo.Ok0)" ] }, { @@ -261,7 +264,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": null, "metadata": { "collapsed": false }, @@ -275,8 +278,8 @@ } ], "source": [ - "my_cosmo = cosmo.Cosmology(cosmo_params={\"Om0\":0.2})\n", - "print \"Custom cosmology matter density: \", my_cosmo.cosmo.Om0" + "my_cosmo = cosmo.Cosmology(cosmo_params={\"Om0\": 0.2})\n", + "print(\"Custom cosmology matter density: \", my_cosmo.cosmo.Om0)" ] }, { @@ -288,7 +291,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": null, "metadata": { "collapsed": false }, @@ -302,8 +305,8 @@ } ], "source": [ - "my_cosmo = cosmo.Cosmology(new_model,{\"Om0\":0.2,\"Ode0\":0.0,\"Ob0\":0.2})\n", - "print \"Custom cosmology curvature density: \", my_cosmo.cosmo.Ok0" + "my_cosmo = cosmo.Cosmology(new_model, {\"Om0\": 0.2, \"Ode0\": 0.0, \"Ob0\": 0.2})\n", + "print(\"Custom cosmology curvature density: \", my_cosmo.cosmo.Ok0)" ] }, { @@ -324,7 +327,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": null, "metadata": { "collapsed": false }, @@ -339,8 +342,8 @@ ], "source": [ "my_cosmo = cosmo.Cosmology(new_model)\n", - "my_cosmo.update(cosmo_params={\"Om0\":0.2,\"Ode0\":0.0,\"Ob0\":0.2})\n", - "print \"Custom cosmology curvature density: \", my_cosmo.cosmo.Ok0" + "my_cosmo.update(cosmo_params={\"Om0\": 0.2, \"Ode0\": 0.0, \"Ob0\": 0.2})\n", + "print(\"Custom cosmology curvature density: \", my_cosmo.cosmo.Ok0)" ] }, { @@ -352,7 +355,7 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": null, "metadata": { "collapsed": false }, @@ -367,9 +370,9 @@ } ], "source": [ - "my_cosmo.update(cosmo_params={\"H0\":10.0})\n", - "print \"Custom cosmology curvature density: \", my_cosmo.cosmo.Ok0\n", - "print \"Custom parameters: \", my_cosmo.cosmo_params" + "my_cosmo.update(cosmo_params={\"H0\": 10.0})\n", + "print(\"Custom cosmology curvature density: \", my_cosmo.cosmo.Ok0)\n", + "print(\"Custom parameters: \", my_cosmo.cosmo_params)" ] }, { @@ -381,7 +384,7 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": null, "metadata": { "collapsed": false }, @@ -395,8 +398,8 @@ } ], "source": [ - "my_cosmo.update(cosmo_model=cosmo.Planck13,cosmo_params={})\n", - "print \"Flat cosmology curvature density: \", my_cosmo.cosmo.Ok0" + "my_cosmo.update(cosmo_model=cosmo.Planck13, cosmo_params={})\n", + "print(\"Flat cosmology curvature density: \", my_cosmo.cosmo.Ok0)" ] }, { @@ -408,7 +411,7 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": null, "metadata": { "collapsed": false }, @@ -425,9 +428,9 @@ } ], "source": [ - "for Om0 in np.linspace(0.2,0.4,7):\n", - " my_cosmo.update(cosmo_params={\"Om0\":Om0})\n", - " plt.plot(z,my_cosmo.cosmo.comoving_distance(z),label=\"%s\"%Om0)\n", + "for Om0 in np.linspace(0.2, 0.4, 7):\n", + " my_cosmo.update(cosmo_params={\"Om0\": Om0})\n", + " plt.plot(z, my_cosmo.cosmo.comoving_distance(z), label=str(Om0))\n", "_ = plt.legend(loc=0)" ] } diff --git a/docs/examples/fitting.ipynb b/docs/examples/fitting.ipynb index bfd4e499..aaafa2de 100644 --- a/docs/examples/fitting.ipynb +++ b/docs/examples/fitting.ipynb @@ -18,7 +18,7 @@ }, { "cell_type": "code", - "execution_count": 87, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -27,7 +27,8 @@ "import emcee\n", "import matplotlib.pyplot as plt\n", "import numpy as np\n", - "from IPython.display import Markdown, display\n", + "from IPython.display import Markdown\n", + "from IPython.display import display as ipdisplay\n", "from scipy.stats import poisson\n", "\n", "import hmf\n", @@ -116,11 +117,12 @@ }, { "cell_type": "code", - "execution_count": 45, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ - "counts_per_bin = np.random.poisson(model.dndlog10m * volume * model.dlog10m)" + "rng = np.random.default_rng(seed=42)\n", + "counts_per_bin = rng.poisson(model.dndlog10m * volume * model.dlog10m)" ] }, { @@ -130,7 +132,7 @@ "outputs": [ { "data": { - "image/png": "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\n", + "image/png": "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", "text/plain": [ "
" ] @@ -374,13 +376,13 @@ }, { "cell_type": "code", - "execution_count": 61, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ - "initialpos = np.array(\n", - " [fiducial_model.sigma_8, fiducial_model.n]\n", - ") + 1e-4 * np.random.normal(size=(sampler.nwalkers, sampler.ndim))" + "initialpos = np.array([fiducial_model.sigma_8, fiducial_model.n]) + 1e-4 * rng.normal(\n", + " size=(sampler.nwalkers, sampler.ndim)\n", + ")" ] }, { @@ -698,7 +700,7 @@ }, { "data": { - "image/png": "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\n", + "image/png": "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", "text/plain": [ "
" ] @@ -755,7 +757,7 @@ }, { "cell_type": "code", - "execution_count": 91, + "execution_count": null, "metadata": {}, "outputs": [ { @@ -772,7 +774,7 @@ } ], "source": [ - "display(Markdown(f\"${fiducial_model.hmf._eq}$\"))" + "ipdisplay(Markdown(f\"${fiducial_model.hmf._eq}$\"))" ] }, { @@ -811,12 +813,12 @@ }, { "cell_type": "code", - "execution_count": 95, + "execution_count": null, "metadata": {}, "outputs": [ { "data": { - "image/png": "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\n", + "image/png": "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", "text/plain": [ "
" ] @@ -830,9 +832,7 @@ "source": [ "volume = 500**3 # Mpc^3 / h^3\n", "\n", - "counts_per_bin = np.random.poisson(\n", - " fiducial_model.dndlog10m * volume * fiducial_model.dlog10m\n", - ")\n", + "counts_per_bin = rng.poisson(fiducial_model.dndlog10m * volume * fiducial_model.dlog10m)\n", "\n", "plt.plot(fiducial_model.m, fiducial_model.dndlog10m * volume * fiducial_model.dlog10m)\n", "plt.plot(fiducial_model.m, counts_per_bin)\n", @@ -879,13 +879,13 @@ }, { "cell_type": "code", - "execution_count": 100, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ "init_pos = np.array(\n", " [smt_model.hmf.params[\"a\"], smt_model.hmf.params[\"p\"], smt_model.hmf.params[\"A\"]]\n", - ") + 1e-4 * np.random.normal(size=(sampler_hmf.nwalkers, sampler_hmf.ndim))" + ") + 1e-4 * rng.normal(size=(sampler_hmf.nwalkers, sampler_hmf.ndim))" ] }, { @@ -1147,7 +1147,7 @@ }, { "data": { - "image/png": "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\n", + "image/png": "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", "text/plain": [ "
" ] @@ -1229,7 +1229,7 @@ }, { "data": { - "image/png": "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\n", + "image/png": "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", "text/plain": [ "
" ] @@ -1241,9 +1241,7 @@ } ], "source": [ - "plt.fill_between(\n", - " fiducial_model.m, percentiles[0] / percentiles[1], percentiles[2] / percentiles[1]\n", - ")\n", + "plt.fill_between(fiducial_model.m, percentiles[0] / percentiles[1], percentiles[2] / percentiles[1])\n", "plt.xscale(\"log\")\n", "plt.ylabel(\"Fractional difference to Median\")\n", "plt.xlabel(\"Mass\")\n", diff --git a/docs/examples/plugins_and_extending.ipynb b/docs/examples/plugins_and_extending.ipynb index c5c01127..b7011ad6 100644 --- a/docs/examples/plugins_and_extending.ipynb +++ b/docs/examples/plugins_and_extending.ipynb @@ -9,11 +9,13 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%matplotlib inline\n", + "import typing\n", + "\n", "import matplotlib.pyplot as plt\n", "import numpy as np" ] @@ -274,7 +276,7 @@ }, { "data": { - "image/png": "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\n", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAZIAAAEQCAYAAACa+vIpAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDMuMC4wLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvqOYd8AAAIABJREFUeJzt3Wd4FdX+9vHvL43Qe5PeEbEBIlIUEOlIEQXEThEUOwKKiuUoiIiCIghSRARERClSVHqHUASUIlID0nsNSdbzIvH88+QQCGTvTMr9ua5cJ7Oy9+x7mQM3s9fsGXPOISIicr0CvA4gIiKpm4pERESSREUiIiJJoiIREZEkUZGIiEiSqEhERCRJVCQiIpIkKhIREUmSFF8kZlbSzEaa2eQ4Y5nN7GszG2Fm7b3MJyKS3vm1SMxslJkdMrNN8cYbmtlWM9tuZr2utA/n3A7nXId4w62Ayc65TsD9Po4tIiLXIMjP+x8DfA6M/XfAzAKBIcB9QDiw2symAYFA33jPf8o5d+gy+y0MbIz9PsrHmUVE5Br4tUicc4vMrHi84arAdufcDgAzmwg0d871BZomctfhxJTJelLB23MiImmZv49ILqcQsDfOdjhwZ0IPNrPcwPvA7Wb2WmzhTAE+N7MmwPQEntcZ6AyQOXPmyuXLl/dRfBGR9GHNmjVHnHN5r/Y4L4rELjOW4CWInXNHgS7xxs4CT17pRZxzw4HhAFWqVHFhYWHXnlREJB0zs92JeZwXbwuFA0XibBcG9nuQQ0REfMCLIlkNlDGzEmYWArQFpnmQQ0REfMDfp/9OAJYD5cws3Mw6OOcigW7AHGAzMMk594c/c4iIiP/4+6ytdgmMzwRm+vO1RUQkeejUWRERSRIViYiIJImK5Aqcc8ybN5sLEZFeRxERSbFUJFewZc186i5qwx/97mHBgl+Jjk7w4y4iIumWiuQKbry9FjvueIfSbg+1F7RmQb9WrNmw8epPFBFJR1QkVxIYTMkmL5L11Y1sLdOJGhFLuOmHOvz8SRf+Dv/H63QiIimCiiQRAjLloFz7AbhuYewuUJ8mJyeQY0RVpn31DkdOnvE6noiIp1Qk1yA0TzHKdR3PiUd+5VTWUtwfPpBTA+9gxvdfcf6iFuRFJH1SkVyHHKWrUuKV+fzTZAwZQ4Jo+scrbO53N3PnziZKC/Iiks6oSK6XGQXvaEnBXuvYWe0/lCScexe3YWG/Fqxe97vX6UREko2KJKkCgyjR8Dmy9djItnJPUyNiGbf8dC8zBnbmr937vE4nIuJ3KhIfCciYnbLt+sNzYewu2IDGpyaRa9SdTP2yD4eOn/Y6noiI36hIfCxD7mKU7fItZx77lVPZytL8n085++kdTJs4nLMXLnkdT0TE51QkfpKt5B2UeHkuh5qOJTRDCPdveZWtH9Zizi8ziYyK9jqeiIjPqEj8yYx8VZpTsOdadt/1PiXtHxosa8eifs1ZHrYW53SGl4ikfiqS5BAYRLEG3cjeYyPby3el+qUVVJp+Hz9/3InNO/d4nU5EJElUJMnIQrNRum0/Ap5fy55CjWl8ZjL5x9zFlGFvsv/oSa/jiYhcFxWJB0JyFaFM5284+8Q8TmYvT6sDg7k4uCo/jR/G6fMRXscTEbkmKhIPZS1eiRIv/caR5uMIzRBKi2092f5hLWbNmsYlLciLSCqhIvGaGXlub0bBnmsIr9mPEgEHabTyURb3vZ/Fq1ZrQV5EUjwVSUoRGEThel3J3nMjOyo8S/XIlVT9uSHTB3Rg0/bdXqcTEUmQiiSFsQxZKfnQBwS+sI69hZvR9OwUCn1TnR++6M3ewye8jici8j9UJClUcM7ClO40hvNPLeBkjpt44NDnRH9elSnjhnDynBbkRSTlUJGkcJmL3kbxl37haMsJhIRmotX219nZvybTf55KRKQW5EXEeyqSVCL3rY0p2HMN++7uT/GAwzRb/RhL+jZl/vJVWpAXEU+pSFKTgEAK1X2a7D03sLPi81SPCqPG7IZM7/8k67ft9DqdiKRTKpJUyDJkpUTr9wh+aT17i7agyfmpFP+2BpM/78Wug8e8jici6UyqKBIzK2lmI81scpyxFmY2wsymmll9L/N5JTD7DZTqMIqLHRZyItcttD4ylIAv7uT7sZ9x/MxFr+OJSDrh9yIxs1FmdsjMNsUbb2hmW81su5n1utI+nHM7nHMd4o395JzrBDwBtPF58FQkU5FbKP7CbE60+o7gjFl4cMcb7B5Qk6nTp3DhUpTX8UQkjUuOI5IxQMO4A2YWCAwBGgEVgHZmVsHMbjazGfG+8l1l/2/E7ivdy3FLQwr2CONA7QEUCzxC8zVPsqxvE35dupzoaC3Ii4h/WHKc8WNmxYEZzrmKsdt3AW875xrEbr8G4Jzre5X9THbOtY793oB+wK/Oud8u89jOQGeAokWLVt69O519OjziLHtm9CfvhmEEukvMytiUG5r34Y4bS3mdTERSCTNb45yrcrXHebVGUgjYG2c7PHbssswst5kNA27/t3SA54B6QGsz6xL/Oc654c65Ks65Knnz5vVh9FQiJDNFW71DhpfWs69YS5pemE7ZiTWZNLgHfx846nU6EUlDvCoSu8xYgodGzrmjzrkuzrlS/x61OOcGO+cqx44P81vSVC4ge0FKPDWSyE6LOJH7dh469iXBQ6vx3ehPOXL6gtfxRCQN8KpIwoEicbYLA/s9ypIuZCh0M8Wen8nJ1pMIyZiNNrv7sG9ATab89D3nI7QgLyLXz6siWQ2UMbMSZhYCtAWmeZQlXclesQEFeqziYN2BFA06Rqv1HVnRrzFzFi7VgryIXJfkOP13ArAcKGdm4WbWwTkXCXQD5gCbgUnOuT/8nUViBQSS/+4O5Oy5ib23vUy16PXUndeM6R8+yspN27xOJyKpTLKcteW1KlWquLCwMK9jpFjRpw6we8qbFN01mbMulFk523N7656ULZwOT1IQkf9K6WdtSQoSkK0AJZ4YQWTnJRzPU4k2J0aQccRdTBg1kEMnz3sdT0RSOBWJ/FeGG26i2HM/c/qhHwjKlIN2e97hwMCaTPrhO85FRHodT0RSKBWJ/I+sFepR8NVVHK43iCLBJ3hoY2dW9m3Mz/MWEaUFeRGJR0UilxcQQN6aT5Czx0b2VepONTZQf2ELpvd7hCUbtugeKCLyXyoSubKQTBS6/01CX/6d/aUeomnETG75oTYTP+3On3sOep1ORFIAFYkkimXNT7HHhhHdZRkn8lal3cmvyD6yOt+OGMA/J856HU9EPKQikWsSUuBGinabxpm2PxKQOTft973HkU9qMnHSBE5fuOR1PBHxgIpErkuW8nUp2H0FR+t/RqHgM7T9swtr+jVi6m8LiIyK9jqeiCQjFYlcv4AAcld/jFw9N/BPlR5UtT9osrglM/q1Z8HazVqQF0knVCSSdMEZKdi0Nxlf+Z1/Srel2aXZVJ5ahwkDX2LjrgNepxMRP1ORiM9YlnwUeXQo0V2XcyLfnTx8ejS5Rlfnmy8/JPzYGa/jiYifqEjE54Lzl6fIs1M51+4nArPk5dF/PuDEoJp8+904Tp7XgrxIWqMiEb/JVK4OBV5ZzvGGQ7gh5BztNz/L+g8bMOWXeUREakFeJK1QkYh/BQSQs9oj5OrxOwfu6MUdtpn7lz7AzH7tmLt6kxbkRdIAFYkkj+CMFGjyGhlf2cCBsu1pGvkrVWfUY/zHL7Buxz9epxORJFCRSLKyLHkp3P5z6LqckwXuov2Zr8n/dXW+HtqX3UdOex1PRK6DikQ8EZS/HIW7/sj59tMJyFqAxw/248xnNRn77ViOn43wOp6IXAMViXgqY5m7KfDyUk42HsoNIRd47K/n2PBRA76f9SsXI6O8jiciiaAiEe8FBJC96sPk7PE7h6r15g7bSqsVDzKrb1vmrNygBXmRFE5FIilHcCj5GvYgU/eNHCj/GE2j5lJj5n18+9FzrN4W7nU6EUmAikRSnsy5KdRuMPbsKk4UrMkj576h8Le1GD3kfXYcPOl1OhGJR0UiKVZg3tIU7vIDFx+dSUC2gjx5uD8XhtRizLgxHD1z0et4IhJLRSIpXoZSNcj/8lJONRlOwdAIntj+An981IAJM+Zw4ZIW5EW8piKR1MGMbHe0IWeP3zly15tUCdzGQ6vbMLtvG35eto7oaC3Ii3hFRSKpS1AG8jToTqbumzhU4XGaRM+n9pwGfPvRs6zYssfrdCLpkopEUqdMuSjYZhCB3VZxstA9PHr+W4pPuJtRn73HX/+c8DqdSLqS4ovEzEqa2UgzmxxvPLOZrTGzpl5lE+8F5CnFDZ2/5+JjM7HshXjq6AAih9Zi5NejOHT6gtfxRNIFvxaJmY0ys0NmtineeEMz22pm282s15X24Zzb4ZzrcJkf9QQm+TKvpF4ZStYg/0tLONNsBAVCI+mw8yW2DmjAuKmzOBcR6XU8kTTN30ckY4CGcQfMLBAYAjQCKgDtzKyCmd1sZjPifeW73E7NrB7wJ3DQv/ElVTEjS+WHyNljPUdr9KFy4HbarW3HL33bMHXxGqK0IC/iF0H+3LlzbpGZFY83XBXY7pzbAWBmE4Hmzrm+QGLfpqoDZCamiM6b2UznnO6UJDGCMpD7vpehxhMcmPEfmvz5NRG/LWb80gcofn8valUo5nVCkTTFizWSQsDeONvhsWOXZWa5zWwYcLuZvQbgnOvtnHsRGA+MuFyJmFlnMwszs7DDhw/7dgaSOmTKRYGHBhL03GpOFq7DoxfGU/a7u/lq0Nv8GX7c63QiaYYXRWKXGUvwPQfn3FHnXBfnXKnYo5a4PxvjnJuRwPOGO+eqOOeq5M2bN4mRJTWz3CW5odN3RDw+C3IUpePxTwgYXosRo0dw4KQW5EWSyosiCQeKxNkuDOz3IIekMyElqpP/xUWcbT6K/Bmj6bS7O9sH3seYH2dy5qIW5EWulxdFshooY2YlzCwEaAtM8yCHpEdmZL79AXK+uo7jtd6mUuAOHl3/MHP6tWXywrVERmmpTeRa+fv03wnAcqCcmYWbWQfnXCTQDZgDbAYmOef+8GcOkf8RlIGc975Epu4bOXbTEzR382gwrzFj+r/A/E17dA8UkWtg6eEPTJUqVVxYWJjXMSQFc4e3cfjHnuTbP49wl4cfcnWibqsu3Fwkh9fRRDxjZmucc1Wu9rgU/8l2keRgecuSr/OPRD7yE5my5eaF432JGFGPT8aMZ9+J817HE0nRVCQicQSVrkOul5ZzvtEgymU4xku7urJ2YCu++Gk+py5c8jqeSIqkt7ZEEnLxNKfnfkzo6iFERTvGWVNC63TnoRoVCAnSv8Ek7dNbWyJJlSErWRu/TfCL67hQpikd+ZEG8xoz6KM3mL1xnxbkRWKpSESuJnthcjwyBtdxLsF5S/PqxSEU+74h7w76gnV79Al5ERWJSCJZ4SrkeHYuUQ+MpkjmKPqceJ2jI1ry7pif2HP0nNfxRDyjNRKR63HpAheXfQGLBhAQeYEJ0fU4VPklOtavTI5MIV6nE/GJxK6RqEhEkuLMYc79+h9Cfx/LaRfKl9aaPHW60b5GaTIEBXqdTiRJtNgukhyy5CVTy0EEPLOMwKJV6cFY6sxtxjv9P2T6ei3IS/qgIhHxhXw3kqXDVGj/A/lyZuWDiA/JO+UBXhk0ltW7jnmdTsSvVCQivlSmHpmfX0l044HcFnqQASdeYPfIx+k5ehY7Dp/xOp2IX2iNRMRfLpzk0oIBBKwcysXoAEZENeV0pa50rX8LubNk8DqdyFVpsT0OFYl46vguLsx6i9BtUzngcjKI9hSp/ThP1SxFaLAW5CXl0mK7SEqRszihD4+Fp+aQI19R+trn3DW/Hd36D+fHdeFER6f9f8xJ2qYiEUkuRasR2nUBtBjKTZlP8tWlXrgpT/Pk4J9YueOo1+lErpuKRCQ5BQTAbQ8T8uI6XI2XaR68imEnnmbJyB48P3aZPiEvqZLWSES8dHwXUbPfIHDrdPa5vPSPepgC1dvSrW4ZsoYGe51O0jmtkYikBjmLE9huHDw+g3z58jEoaBD3rniCLv1HMX7lHqK0fiKpQKKKxMyamtk6MztmZqfM7LSZnfJ3OJF0o0QtgrsuhmaDqJTpCN9E9yRw+nM88uk0lvx1xOt0IleUqLe2zGw70ArY6FLhe2F6a0tSlQsncQv741Z8yXkXxGeXmrOz9GP0aHorpfJm8TqdpCM+/RyJmc0H7nXORfsiXHJTkUiqdPRvoma/TuBfs9nr8vNBZHsK3tmaF+qVJXsmrZ+I//m6SO4A3gMWAhf/HXfODUxKyOSiIpFU7e95RM7sRdDRrSyLrsAngU/RpF492lcrRnCgljnFf3y92P4+cA4IBbLG+RIRfytVl6BnlkHjAVTNuJ/vXA+CZr1Cm4HTmb/lkK4wLJ5L7BFJWGJaKaXSEYmkGeeO4Rb0xa0eyTkXyieXWvJ3iXa83uxWyubXv+3Et3x9RPKbmdVPYiYRSapMubDGHxHQdRmZSlbjzeBxvB3ekQ8HD+KNHzdw9MzFq+9DxMcSe0RyGshMzPrIJcAA55zL5t94vqEjEkmTnIO/fiFq1msEHv+bRdG3MCDgSZrWvYfHqxfXHRolyXx6ROKcy+qcC3DOZXTOZYvdThUlIpJmmUHZBgQ+uwIafECN0J1MoTvulzdpMXA2szcd0PqJJIsrHpGYWaUrPdk5t9bnif43Q0mgN5DdOdc6diyAmLPIsgFhzrmvr7QPHZFIunDmMMx9G9aN46jl5D8X23KgWDN6N61IxULZvU4nqZBPTv+N/fwIxJytVQX4nZi3tW4BVjrnal4lxCigKXDIOVcxznhDYBAQCHzlnOt31aBmk+MUSUugOXAM+Nk5N/dKz1WRSLoSvgY3szu2fy2/U5beEY9ToVItujcoR76soV6nk1TEJ29tOefqOOfqALuBSs65Ks65ysDtwPZE5BgDNIwXLBAYAjQCKgDtzKyCmd1sZjPifeVLYL/lgOXOuZeBronIIZJ+FK6MdZwL93/OzZmOMT3kDSr9/g6tBkzny4V/ExGZKj9XLClYYs/aKu+c2/jvhnNuE3Db1Z7knFtEzFFDXFWB7c65Hc65CGAi0Nw5t9E51zTe16EEdh0OHI/9PiqRcxBJPwICoNKjBDy3BruzC22CFjAn8CXCfxlMo0/mM2/LQa8TShqS2CLZbGZfmVltM7vHzEYAm6/zNQsBe+Nsh8eOXZaZ5TazYcDtZvZa7PAUoIGZfQYsSuB5nc0szMzCDh8+fJ1RRVK5jDmgUT+syxIyF72N94LHMPz8ywz7+hueGL2Kvw+f8TqhpAGJPf03lJi3kO6OHVoEDHXOXUjEc4sDM/5dIzGzB4EGzrmOsduPAlWdc89dzwQSQ2skIsScLvznVNyc17FT+5jpavD+pYdpVL0Sz9crQzbd/0Ti8fXpvxecc58451rGfn2SmBJJQDhQJM52YWD/de5LRBLLDG5qgXULg7t70CgojHmh3QleMYgGH/3Kd6v36P7xcl0Sez+SGmb2q5ltM7Md/35d52uuBsqYWQkzCwHaAtOuc18icq1CMkHd3tizK8lQpi49gyYyhVeY/eNYmg9Zyprd8Zc1Ra4ssW9tbQFeAtYQZ3HbOXf0Ks+bANQG8gAHgT7OuZFm1hj4lJjTf0c5596/3gkkht7aErmC7b/hZvXEjm5niVWm94X23H5rJXo1upEC2XW6cHrm68vIr3TO3emTZB5QkYhcRWQErByGW9iPqEsRDI9qygjXkg51KtCxVklCg3W5lfTI10XSj5ijhyn8//cj8fsn231BRSKSSKcPwK9vwYbvOBJUgJ7n2rMtR016N65Ag5vyY2ZeJ5Rk5I87JAL8++B/L9pY9/ojJh8Vicg12rkYZnaHw1tYHlSVV88+TLFSN9Kn2U26XH064qtLpLz877fElEjcf4443SFRJA2LugQrvsAt+JCoqEiGRbdkSERjHrqzFC/fV063+00HfHX67793QqxMzOdICgI3AE8Tc3kTEUmrAoOhxgtYt1UElW9INyayOOvr7Fw5nTofL2DS6r06XViAxL+19QvwgHPudOx2VuB751zDKz8zZdARiYgPbP8NZr4Kx3awLEMtXj75EAWKlOK95hW5ubCuLpwW+foOiUWBiDjbEUDx68glIqlV6XrQdTnU6c1dUatZkrkHtY9OpNWQBfT+cSMnzkVcfR+SJiW2SL4BVpnZ22bWB1gJXPEeICKSBgWHwj09sGdWEFTybl6MHsvS7H34O+wX6gxYwIRV+nR8epSot7bgvze5qhW7ucg5t85vqXxMb22J+IFzsHUmzOoFJ/ewMPReXjnRmkKFi/Ju84rcWiSH1wkliXx6+m9qpyIR8aOIc7B4AG7pYC4FZqR/dHtGnatBmzuK8WqD8uTKHOJ1QrlOvl4jERG5vJBMcO9bWNdlhNxwM29EDWVB7gGsDVtB3Y8XMG7FbqL0dleapiIREd/IWxYenwH3f07RyF3MDn2dtzJN4b2f1tJiyFLW7Tl+9X1IqqQiERHfib0zI93CsIqtaHVmAmty96HIydW0/GIZPSdv4NhZnd2V1qhIRMT3suSFVsPh0R/JEhLAF5FvM63QOOat/ZN7P17ApLC9pIf12fRCRSIi/lOqLjyzHGp155bjv7A8Wy86ZFlOj8m/0+bLFWw7eNrrhOIDKhIR8a/gjHDvm9BlCUF5y9Lt1EBW3vApFw9uofGgxfSfvYXzEVFX34+kWCoSEUke+W6EJ2dD00/Jf24bPwX0YEihX/lqwRbu+2Qh87cc8jqhXCcViYgkn4AAqPIkPLsau7EZDQ6PYn3+97jd/uLJMavpOm4N/5w873VKuUYqEhFJflnzQ+tR0P4HMnGRwed6MrXUdJZv2UO9jxcycslOIqOivU4piaQiERHvlKkHzyzH7ujIrfsmEJbrLR4rsIv3ZvxJ8yFLWb/3hNcJJRFUJCLirQxZockAeGImQUHB9DzUk8Xlf+T86WO0/GIpb/y0kZPnL3mdUq5ARSIiKUPxGtB1KVR/niK7f+C3DD34oEI441fu4b6BC5nzxwGvE0oCVCQiknIEZ4T670HH3wjIlJt2f/dgbYXvKJnpAk9/s4au49Zw6NQFr1NKPCoSEUl5ClWGzgug9mvk2DmTCZeeZ/jtu5i75SD3DlzIxFV79Mn4FERFIiIpU1AI1O4FTy/CchSj/ubXWVd6NNXzXaLXlI20G7GCnUfOep1SUJGISEqXvwJ0+BXue4/M4YsYdupZvq0Wzh/7T9Lw00UMXfA3l3SqsKdUJCKS8gUGQY3nocsSLHdpaqzvweqy39KkdAgfzt5C88+XsjH8pNcp060UXyRmVtLMRprZ5DhjRc1smpmNMrNeXuYTkWSUpww8NQfu7UPo9lkMPPw0P9Q9weEzF2k+ZAkfzNys63Z5wK9FEvsX/SEz2xRvvKGZbTWz7VcrAufcDudch3jDZYGfnXNPARV8HFtEUrLAIKj1csxifJYCVF72DEvLfc/jlXIwfNEOGny6iJU7jnqdMl3x9xHJGKBh3AEzCwSGAI2IKYF2ZlbBzG42sxnxvvIlsN91QFszmwfM92N+EUmpClSETvPg7lcJ+eN7+uztxMymkQC0Gb6Ct6f9wbmISI9Dpg9+LRLn3CLgWLzhqsD22CONCGAi0Nw5t9E51zTeV0KXA30S6OOcqws08d8MRCRFCwqBum/ELMaHZKbCb48xt/w0Ot+ZjzHLdtFo0GJW7Yz/V5D4mhdrJIWAvXG2w2PHLsvMcpvZMOB2M3stdng28Hzs+K4EntfZzMLMLOzw4cO+SS4iKVPhyvD0IrirG8FrR/P6nk5MbxFCtHO0Gb6cd6b/obUTPzJ/f6jHzIoDM5xzFWO3HwQaOOc6xm4/ClR1zj3nrwxVqlRxYWFh/tq9iKQku5fBj0/DyX1E1OjOB2caM2bFPorlzsRHrW+laolcXidMNcxsjXOuytUe58URSThQJM52YWC/BzlEJC0qVh26LIGbHyRkyYe8feRVfmhbkKjomKOTd6f/qaMTH/OiSFYDZcyshJmFAG2BaR7kEJG0KjQ7tPoSHhgJh7dSeeb9zL13P49ULcqopTtpPHgxYbu0duIr/j79dwKwHChnZuFm1sE5Fwl0A+YAm4FJzrk//JlDRNKpm1tD1yVQ4GYyzHiW9yIH8t2j5bkUFc1DXy7nozlbiIjUp+KTyu9rJCmB1khE0rnoKFjyCSzoC1kKcL7pEPpsyMmksHAqFsrGp21uo3S+rF6nTHFS8hqJiEjyCgiEu7tDh18gKAMZx7egf64ZDG9/K/tPXKDJ4CWMXrqT6Oi0/w9rf1CRiEj6USj2NOHbHoZF/akf1plfOpSmRuk8vDP9Tx4fvYoDJ3W/k2ulIhGR9CVDFmjxBbT8EvavJ883dRl511Heb1mRsF3HafDpImZs0Imk10JFIiLp061t4emFkO0GbEIb2p8cwc/PVqV4nsx0G7+Ol75bz6kLuld8YqhIRCT9ylMGOs6FOzrCss8oOb01P7S5gRfrlWHa7/tpMngx6/ee8DpliqciEZH0LTgUmnwMD34NR/4iaMQ9vFhoK5OerkZ0NLQeuoxhC//WQvwVqEhERABuagFdFkPuUvDdI1Te9ikzu93FfRXy02/WFh4fvYpDp7UQfzkqEhGRf+UsDk/NhiodYOkgsn/fmi+aF+KDljezaucxGg9azKJtughsfCoSEZG4gjJA04ExZ3XtW4N9eQ8PF9jHtG41yZU5hMdGraLvzM36RHwcKhIRkcu5tS10/A1CMsGYJpTbOZapz9Tg4TuL8uWiHTz45XL2HjvndcoUQUUiIpKQAhVjbulbrhHMeZ2MUzvwQeMSfNG+EjsOn6HpZ0uYt+Wg1yk9pyIREbmS0OzQZhzUewc2T4OR9Wlc6AIznqtJoRwZeWpMGB/N2UJUOj6rS0UiInI1ZlDzRXjkBzi1D0bUodjJMKY8U502VYowZP7fPDpyJYdPX/Q6qSdUJCIiiVWqLnSaB1nywzctCV37FR8+cDP9W9/Cmt3HafrZYlanw/ucqEhERK5F7lIxi/BlG8KsHjC1Gw/dlo8fn6lBxuBA2g5fwYhFO0gPt+j4l4pERORaZcjawx2sAAAMtUlEQVQas25yT09YPw7GNKFC1nNMe64m9W7Mx/szN/Ps+LWcvRjpddJkoSIREbkeAQFQ53V4aCwc/BOG1ybb8T8Z9khlXmtUntmbDvDA0GXp4hRhFYmISFJUaB5zwywLgFGNsG1zePqeUox+sir7T5yn2edLWLr9iNcp/UpFIiKSVAUqxlxFOE9pmNgOVg7nnrJ5mdatJvmyZuCxUasYuWRnml03UZGIiPhCtoLw5Cwo2whmvQqzelE8VyhTnqlBvRvz8d6MP3nl+9+5cCnK66Q+pyIREfGVkMzQ5huo9iysHAoT25OFCwxtX5mX6pVlytp9tBm+Is1dRVhFIiLiSwGB0PADaDwA/poDoxsRcOYAL9Qrw7BHKrPtwGlaDlnGlgOnvE7qMyoSERF/qNoJ2n0Hx3bAyPvgyF80rFiA77vcRWR0NK2HLmf+1kNep/QJFYmIiL+UrQ9P/AyRF2BkfQhfQ8VC2Zn6bE2K5c5EhzGr+XrZLq9TJpmKRETEn264DZ6aA6HZ4OtmsH0uBbKHMunpu6hbPj99pv1Bn6mbiIxKvfc3UZGIiPhb7lLw1C+QqySMfwg2fE/mDEF8+WhlOtUqwdfLd9P5mzWci0idn4RXkYiIJIes+eHJn6FINZjSEVYMJTDA6N2kAu+3rMiCrYdoN2Ilx85GeJ30mqX4IjGzFmY2wsymmln92LHMZvZ17Hh7rzOKiCRKaPaYS9Hf2Axm94K574JztL+zGMMeqcyWf07ROhVeVsWvRWJmo8zskJltijfe0My2mtl2M+t1pX04535yznUCngDaxA63AibHjt/vj+wiIn4RHAoPfg2VHofFH8Oc18E56t9UgG873snRsxG0GrqMP/af9Dppovn7iGQM0DDugJkFAkOARkAFoJ2ZVTCzm81sRryvfHGe+kbs8wAKA3tjv097HxMVkbQtIBCaDYI7u8CKL+DnlyE6mirFc/F9l7sICjDafLmCZankGl1+LRLn3CIg/l1eqgLbnXM7nHMRwESguXNuo3OuabyvQxbjQ2CWc25t7D7CiSkTv89BRMQvzKBhP6jxIoSNgmndIDqKsvmzMuWZ6tyQI5THR69i+u/7vU56VV78JVyI/zuagJhSKHSFxz8H1ANam1mX2LEpwANmNhSYfrknmVlnMwszs7DDhw/7ILaIiI+ZQb23ofZrsP5b+KEjRF2iYPaMfP90dW4rkoPnJ67ju9V7vE56RUEevKZdZizBS2I65wYDg+ONnQWevNKLOOeGA8MBqlSpkjYvuSkiqZ8Z1O4FQaHwWx+IioDWo8meKYSxT91Jl3Fr6PnDRs5ejOKpmiW8TntZXhyRhANF4mwXBlL+sZuIiD/VfBEafghbZsDkJyHqEhlDAhn+WGUa3JSfd2f8yZD5271OeVleFMlqoIyZlTCzEKAtMM2DHCIiKUu1LtCof0yZ/NARoiLJEBTIkIcr0fL2Qnw0Zyv9Z29Jcfc18etbW2Y2AagN5DGzcKCPc26kmXUD5gCBwCjn3B/+zCEikmrc+TREXYJfekNAELQaTlBgIB8/eCuhwYF8seBvzkVE8VbTCgQEXG6lIPn5tUicc+0SGJ8JzPTna4uIpFrVu0H0Jfjt7ZgyafEFAQGBfNCyIplDAvlqyU4uRUXznxYVMfO+TLxYbBcRkaup+RJERcL8/8SUyf2fYQEB9G5yI0GBAQxb+DcBZrzb/CbPy0RFIiKSUt3zasyRycIPIUNWaNgXM6Nnw3JEO8fwRTsIDDD6NKvgaZmoSEREUrLar8GFUzG37s2UC+7pgZnxWqPyREU7Ri7ZSYAZbza90bMyUZGIiKRkZtDgAzh/HOa/DxlzQtVOmBlvNLmRaOcYtXQngQHwemNvykRFIiKS0gUEQPPP4eIpmPkqhOaAWx7EzHiraQWiox0jFu8kY3AgL9cvl+zxVCQiIqlBYDC0Hg3jHoCfusRckr5sfcyMt++/ifOXohg8bzvZMgbTsVbJZI2mCx6KiKQWwaHQbgLkvwkmPQb71gBgZvRtdQuNKhbgPz9vZtLqvVfZkW+pSEREUpPQbNB+MmTJB+PbwPFdAAQGGJ+2vY1aZfLQa8oGZm38J9kiqUhERFKbLPliyiQqAr59MGYhHsgQFMiXj1b+71WDF21Lniufq0hERFKjvGWh7fiYI5KJj0DkRQAyhQQx+omqlMqbhae/WcP6vSf8HkVFIiKSWhWvCc2/gN1LYGo3iL2YY/ZMwYztUJU8WUP4cJb/L/Kos7ZERFKzWx6EE7tg3n8gZ3Go2xuAfFlDGd+xGtlCg/3+2RIViYhIalere8xbXIv6Q77yUPEBAIrkypQsL6+3tkREUjszaPIJFKkGPz0L//yerC+vIhERSQuCQqDNN5ApN0x4GM4kzxlboCIREUk7suSDtt/CuSMw6VGIjEiWl1WRiIikJTfcBs2HwJ7lMKtHsrykFttFRNKam1vDwU2w5BMoUBHu6OjXl1ORiIikRXXfhIN/wv71fn8pFYmISFoUEAgPjYWgDH5/KRWJiEhaFRyaLC+jxXYREUkSFYmIiCSJikRERJJERSIiIkmiIhERkSRRkYiISJKoSEREJEnM33fOSgnM7DCwG8gOnIzzoyttx/0+D3DEB1Hiv971Pjahn11uXHPWnONva86ac2IVc87lveqjnHPp5gsYntjteN+H+eP1r/exCf3scuOas+asOWvOvppzQl/p7a2t6dewHf9n/nj9631sQj+73LjmrDnH39acfSM9zvmy0sVbW0llZmHOuSpe50hOmnP6oDmnD/6ec3o7Irlew70O4AHNOX3QnNMHv85ZRyQiIpIkOiIREZEkUZGIiEiSqEhERCRJVCSJZGYlzWykmU2OM5bZzL42sxFm1t7LfP6QwJz/ZywtSWDOLWJ/x1PNrL6X+fwhgTnfaGbDzGyymXX1Mp8/JPT/49g/02vMrKlX2fwlgd9zbTNbHPu7rn29+07XRWJmo8zskJltijfe0My2mtl2M+sF4Jzb4ZzrEG8XrYDJzrlOwP3JFDtJkjrnBP47pGg+mPNPsb/jJ4A2yRY8CXww583OuS7AQ0CqOFXWB3+eAXoCk5Ijry/4YM4OOAOEAuHXmyNdFwkwBmgYd8DMAoEhQCOgAtDOzCok8PzCwN7Y76P8lNHXxpC0OadGY/DNnN+IfU5qMIYkztnM7geWAHP9F9OnxpCEOZtZPeBP4KB/Y/rUGJL2e17snGtETIG+c70h0nWROOcWAcfiDVcFtse2dwQwEWiewC7CiSkTSCX/LX0w51QnqXO2GB8Cs5xza/2b1jd88Xt2zk1zzlUHUsXbtj6Ycx2gGvAw0MnMUvyf6aTO2TkXHfvtcSDD9eZI8f+hPFCI/zvKgJiyKGRmuc1sGHC7mb0W+7MpwANmNpRkvByBHyR6zgn8d0iNruX3/BxQD2htZl2SOacvXcvvubaZDTazL4GZHmT1lUTP2TnX2zn3IjAeGBHnL9nU5lp+z61if8ffAJ9f7wsGJSVtGmWXGXPOuaNAl3iDZ4EnkyWVf13LnP9nLJW6ljkPBgYnSyr/upY5LwAWJEMmf0v0nOP8cIxfE/nftfyepxDzD+Ik0RHJ/woHisTZLgzs9yhLctGcNee0SnNOhjmrSP7XaqCMmZUwsxCgLTDN40z+pjlrzmmV5pwMc07XRWJmE4DlQDkzCzezDs65SKAbMAfYDExyzv3hZU5f0pw1ZzRnzdnXOXTRRhERSYp0fUQiIiJJpyIREZEkUZGIiEiSqEhERCRJVCQiIpIkKhIREUkSFYmIj5mZM7Nv4mwHmdlhM5vhZS4Rf1GRiPjeWaCimWWM3b4P2OdhHhG/UpGI+McsoEns9+2ACf/+wMyqmtkyM1sX+7/lYsdvMrNVZrbezDaYWRmLuWPfz2b2u5ltMrNUcWMtSV9UJCL+MRFoa2ahwC3Ayjg/2wLc7Zy7HXgL+CB2vAswyDl3GzF3JQwn5qZF+51ztzrnKgKzk2sCIomly8iL+IFzboOZFSfmaCT+/TyyA1+bWRlibnUaHDu+HOhtZoWBKc65v8xsIzAg9sZaM5xzi5NlAiLXQEckIv4zDRhAnLe1Yr0HzI89wmhGzP2ycc6NB+4HzgNzzKyuc24bUBnYCPQ1s7eSK7xIYumIRMR/RgEnnXMbzax2nPHs/N/i+xP/DppZSWCHc25w7Pe3mNkW4JhzbpyZnYn7eJGUQkUi4ifOuXBg0GV+1J+Yt7ZeBubFGW8DPGJml4ADwLvAHcBHZhYNXAK6+je1yLXTZeRFRCRJtEYiIiJJoiIREZEkUZGIiEiSqEhERCRJVCQiIpIkKhIREUkSFYmIiCSJikRERJLk/wEojvG7S13LdgAAAABJRU5ErkJggg==", "text/plain": [ "
" ] @@ -320,12 +322,12 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ "class MyNewFitParameterized(FittingFunction):\n", - " _defaults = {\"a\": 0.5}\n", + " _defaults: typing.ClassVar = {\"a\": 0.5}\n", "\n", " @property\n", " def fsigma(self):\n", @@ -352,9 +354,7 @@ "metadata": {}, "outputs": [], "source": [ - "mf = MassFunction(\n", - " hmf_model=MyNewFitParameterized, hmf_params={\"a\": 0.55}, transfer_model=\"EH\"\n", - ")" + "mf = MassFunction(hmf_model=MyNewFitParameterized, hmf_params={\"a\": 0.55}, transfer_model=\"EH\")" ] }, { @@ -374,7 +374,7 @@ }, { "data": { - "image/png": "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\n", + "image/png": "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", "text/plain": [ "
" ] diff --git a/docs/examples/your_first_plot.ipynb b/docs/examples/your_first_plot.ipynb index 3c8f7713..60486c56 100644 --- a/docs/examples/your_first_plot.ipynb +++ b/docs/examples/your_first_plot.ipynb @@ -27,9 +27,10 @@ }, "outputs": [], "source": [ - "from hmf import MassFunction # The main hmf class\n", "import matplotlib.pyplot as plt # The necessary plotting library\n", - "import numpy as np # Numerical array library\n", + "import numpy as np # Numerical array library\n", + "\n", + "from hmf import MassFunction # The main hmf class\n", "\n", "# This just serves to render plots inline in the notebook. Do not use in a script.\n", "%matplotlib inline" @@ -99,7 +100,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "metadata": { "ExecuteTime": { "end_time": "2020-05-20T03:00:27.448302Z", @@ -122,7 +123,8 @@ } ], "source": [ - "MassFunction.parameter_info([\"cosmo_model\",\"sigma_8\"]) #The parameter names passed filter the output. Call with no parameters to get info on all of them." + "# The parameter names passed filter the output. Call with no parameters to get info on all of them.\n", + "MassFunction.parameter_info([\"cosmo_model\", \"sigma_8\"])" ] }, { @@ -160,7 +162,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": null, "metadata": { "ExecuteTime": { "end_time": "2016-12-12T10:47:17.900768", @@ -177,7 +179,7 @@ } ], "source": [ - "print mf.quantities_available()" + "print(mf.quantities_available())" ] }, { @@ -216,9 +218,9 @@ } ], "source": [ - "plt.plot(mf.m,mf.dndm)\n", - "plt.xscale('log')\n", - "plt.yscale('log')\n", + "plt.plot(mf.m, mf.dndm)\n", + "plt.xscale(\"log\")\n", + "plt.yscale(\"log\")\n", "\n", "plt.xlabel(r\"Mass, $[h^{-1}M_\\odot]$\")\n", "plt.ylabel(r\"$dn/dm$, $[h^{4}{\\rm Mpc}^{-3}M_\\odot^{-1}]$\");" @@ -244,9 +246,11 @@ }, "outputs": [], "source": [ - "mf = MassFunction(z = 1.0, # Redshift of 1.0\n", - " cosmo_params={\"Om0\":0.3}, # Matter density of 0.3\n", - " hmf_model=\"PS\") # Press-Schechter fitting function" + "mf = MassFunction(\n", + " z=1.0, # Redshift of 1.0\n", + " cosmo_params={\"Om0\": 0.3}, # Matter density of 0.3\n", + " hmf_model=\"PS\",\n", + ") # Press-Schechter fitting function" ] }, { @@ -319,14 +323,15 @@ } ], "source": [ - "mf = MassFunction(cosmo_model=\"WMAP5\") # Note how to set all cosmological parameters (except sigma_8 and n) to a given common cosmology\n", + "# Note how to set all cosmological parameters (except sigma_8 and n) to a given common cosmology\n", + "mf = MassFunction(cosmo_model=\"WMAP5\")\n", "\n", - "for z in np.linspace(0,1,100):\n", + "for z in np.linspace(0, 1, 100):\n", " mf.update(z=z)\n", - " plt.plot(mf.m,mf.dndm,color=\"darkblue\",alpha=1-z)\n", + " plt.plot(mf.m, mf.dndm, color=\"darkblue\", alpha=1 - z)\n", "\n", - "plt.xscale('log')\n", - "plt.yscale('log')\n", + "plt.xscale(\"log\")\n", + "plt.yscale(\"log\")\n", "\n", "plt.xlabel(r\"Mass, $[h^{-1}M_\\odot]$\")\n", "plt.ylabel(r\"$dn/dm$, $[h^{4}{\\rm Mpc}^{-3}M_\\odot^{-1}]$\");" diff --git a/pyproject.toml b/pyproject.toml index 3da70578..fba6a78d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -94,9 +94,9 @@ testpaths = [ [tool.ruff] -# exclude = [ -# "*.ipynb", # for now -# ] +exclude = [ + "development/*.ipynb", +] line-length=100 target-version="py311" @@ -141,7 +141,9 @@ ignore = [ "N806", # Variable name should be lower case. We have some single-letter variables that make more sense to be caps. "N803", # Argument name should be lowercase. Scientific notation (N, L, R, Mmin, etc.) - changing would break API. "N801", # Class name should use CapWords. Names like Watson_FoF, EH_BAO are part of the public API. + "N802", # Function name should be lowercase. Test functions often use capitals for scientific notation. "D401", # First line should be in imperative mood -- cached_properties and parameter descriptors don't fit this. + "B018", # Picks up "useless" expressions that are properties. # "N815", # "N807", # Allow method names to start and end with __ # "RUF012", # mutable class attributes annotation @@ -156,6 +158,10 @@ ignore = [ "tests/*.py" = [ "D1", "T", # print statements + "N802", # function names - test functions often use capitals for scientific notation + "PT011", # pytest.raises too broad - acceptable in tests + "PT012", # pytest.raises with multiple statements - acceptable in tests + "PT030", # pytest.warns too broad - acceptable in tests ] "docs/conf.py" = [ "A", # conf.py can shadow builtins diff --git a/src/hmf/__init__.py b/src/hmf/__init__.py index f64ddff2..9a0d6296 100644 --- a/src/hmf/__init__.py +++ b/src/hmf/__init__.py @@ -1,15 +1,10 @@ """A package for producing halo mass functions under Spherical Collapse.""" -try: - from importlib.metadata import PackageNotFoundError, version -except ImportError: - from importlib_metadata import PackageNotFoundError, version +import contextlib +from importlib.metadata import PackageNotFoundError, version -try: +with contextlib.suppress(PackageNotFoundError): __version__ = version(__name__) -except PackageNotFoundError: - # package is not installed - pass from ._internals import ( Component, diff --git a/src/hmf/_cli.py b/src/hmf/_cli.py index 2070bcc2..94cc8e1f 100644 --- a/src/hmf/_cli.py +++ b/src/hmf/_cli.py @@ -188,9 +188,7 @@ def run_cli(config, pkg_name, args, outdir, label, pkgs, default_framework): for qname, q in zip(quantities, quants, strict=True): np.savetxt(outdir / f"{lab}_{qname}.txt", q) - console.print( - f" Writing quantities to [cyan]{outdir}/{lab}_.txt[/cyan]." - ) + console.print(f" Writing quantities to [cyan]{outdir}/{lab}_.txt[/cyan].") # Write out parameters dct = framework_to_dict(obj) @@ -198,9 +196,7 @@ def run_cli(config, pkg_name, args, outdir, label, pkgs, default_framework): with (outdir / f"{lab}_cfg.toml").open("w") as fl: toml.dump(dct, fl, encoder=toml.TomlNumpyEncoder()) - console.print( - f" Writing full config to [cyan]{outdir}/{lab}_cfg.toml[/cyan]." - ) + console.print(f" Writing full config to [cyan]{outdir}/{lab}_cfg.toml[/cyan].") console.print() console.print(Rule("Finished!", style="grey53"), style="bold green") diff --git a/src/hmf/_internals/_cache.py b/src/hmf/_internals/_cache.py index 1fa16da1..ba66673a 100644 --- a/src/hmf/_internals/_cache.py +++ b/src/hmf/_internals/_cache.py @@ -109,9 +109,7 @@ def _get_property(self): # if name is already there, can only be because the method has been supered. supered = name in activeq if not supered: - recalc_prpa[name] = ( - set() - ) # Empty set to which parameter names will be added + recalc_prpa[name] = set() # Empty set to which parameter names will be added activeq.add(name) # Go ahead and calculate the value -- each parameter accessed will add itself to the index. @@ -234,11 +232,7 @@ def _set_property(self, val): val = f(self, val) # Here put any custom code that should be run, dependent on the type of parameter - if ( - name.endswith("_params") - and not isinstance(val, dict) - and val is not None - ): + if name.endswith("_params") and not isinstance(val, dict) and val is not None: raise ValueError(f"{name} must be a dictionary") # Locations of indexes @@ -291,18 +285,14 @@ def _set_property(self, val): delattr(self, pr) if not doset and self._validate: - if self._validate_every_param_set: - self.validate() - else: - warnings.warn( - f"You are setting {name} directly. This is unstable, as less " - f"validation is performed. You can turn on extra validation " - f"for directly set parameters by setting " - f"framework._validate_every_param_set=True. " - f"However, this can be brittle, since intermediate states " - f"may not be valid.", - stacklevel=2, category=DeprecationWarning, - ) + warnings.warn( + f"You are setting {name} directly. This is not recommended, " + f"as validation is required on every change. Please use the update " + f"method instead.Setting directly will become an error in v4.", + stacklevel=2, + ) + + self.validate() update_wrapper(_set_property, f) @@ -328,16 +318,7 @@ def _get_property(self): def subframework(f): - """ - A quantity that is essentially a sub-framework. - - Parameters - ---------- - f - - Returns - ------- - """ + """Define a decorator that creates quantities that are essentially a sub-framework.""" name = f.__name__ def _get_property(self): diff --git a/src/hmf/_internals/_framework.py b/src/hmf/_internals/_framework.py index 05c341be..d62f2e51 100644 --- a/src/hmf/_internals/_framework.py +++ b/src/hmf/_internals/_framework.py @@ -31,9 +31,7 @@ def __init__(self, **model_params): # Check that all parameters passed are valid for k in model_params: if k not in self._defaults: - raise ValueError( - f"{k} is not a valid argument for {self.__class__.__name__}." - ) + raise ValueError(f"{k} is not a valid argument for {self.__class__.__name__}.") # Gather model parameters self.params = copy.copy(self._defaults) @@ -68,8 +66,7 @@ def get_base_component(name: [str, type[Component]]) -> type[Component]: avail = [cmp for cmp in get_base_components() if cmp.__name__ == name] if not avail: raise ValueError( - f"There are no components called '{name}'. Available: " - f"{get_base_components()}" + f"There are no components called '{name}'. Available: {get_base_components()}" ) if len(avail) > 1: warnings.warn( @@ -139,7 +136,8 @@ def get_mdl( if len(avail_models) > 1: warnings.warn( f"More than one model was found with name '{name}'. Returning " - f"{avail_models[-1][1]}.", stacklevel=2 + f"{avail_models[-1][1]}.", + stacklevel=2, ) if not avail_models: raise ValueError(f"No model found with name '{name}'.") @@ -152,9 +150,7 @@ def get_mdl( raise ValueError(f"{name} must be str or Component subclass") from e -@deprecation.deprecated( - "3.3.0", removed_in="4.0.0", details="Use get_mdl instead of get_model_" -) +@deprecation.deprecated("3.3.0", removed_in="4.0.0", details="Use get_mdl instead of get_model_") def get_model_(name, mod): """ Returns a class ``name`` from the module ``mod``. @@ -215,7 +211,6 @@ class Framework(metaclass=_Validator): """ _validate = True - _validate_every_param_set = False def validate(self): """Perform validation of the input parameters as they relate to each other.""" @@ -231,9 +226,7 @@ def update(self, **kwargs): # If key is a dictionary of parameters to a sub-framework, # update the sub-framework - elif k.endswith("_params") and isinstance( - getattr(self, k[:-7]), Framework - ): + elif k.endswith("_params") and isinstance(getattr(self, k[:-7]), Framework): getattr(self, k[:-7]).update(**kwargs.pop(k)) self._validate = True self.validate() @@ -266,9 +259,7 @@ def get_all_parameter_defaults(cls, recursive=True): for name, default in out.items(): if default == {} and name.endswith("_params"): try: - out[name] = getattr( - K, name.replace("_params", "_model") - )._defaults + out[name] = getattr(K, name.replace("_params", "_model"))._defaults except Exception: logger.info( @@ -283,9 +274,7 @@ def parameter_values(self): """Dictionary of all parameters and their current values.""" return { name: getattr(self, name) - for name in getattr( - self, "_" + self.__class__.__name__ + "__recalc_par_prop" - ) + for name in getattr(self, "_" + self.__class__.__name__ + "__recalc_par_prop") } @classmethod @@ -295,9 +284,7 @@ def quantities_available(cls): return [ name for name in dir(cls) - if name not in all_names - and not name.startswith("__") - and name not in dir(Framework) + if name not in all_names and not name.startswith("__") and name not in dir(Framework) ] @classmethod @@ -325,9 +312,7 @@ def get_dependencies(self, *q): getattr(self, quant) deps.update( - getattr( - self, "_" + self.__class__.__name__ + "__recalc_prop_par_static" - )[quant] + getattr(self, "_" + self.__class__.__name__ + "__recalc_prop_par_static")[quant] ) return deps diff --git a/src/hmf/alternatives/wdm.py b/src/hmf/alternatives/wdm.py index 93b8ce04..67754b0c 100644 --- a/src/hmf/alternatives/wdm.py +++ b/src/hmf/alternatives/wdm.py @@ -15,8 +15,8 @@ from .._internals._cache import cached_quantity, parameter from .._internals._framework import Component, get_mdl, pluggable from ..cosmology.cosmo import Planck15 -from ..density_field.transfer import Transfer as _Tr -from ..mass_function.hmf import MassFunction as _MF +from ..density_field.transfer import Transfer +from ..mass_function.hmf import MassFunction # =============================================================================== @@ -74,8 +74,7 @@ def transfer(self, lnk): """ raise NotImplementedError( - "You shouldn't call the WDM class, and any subclass should define the " - "transfer method." + "You shouldn't call the WDM class, and any subclass should define the transfer method." ) @@ -106,9 +105,7 @@ class attribute. def transfer(self, k): """Compute the modified WDM transfer function.""" - return (1 + (self.lam_eff_fs * k) ** (2 * self.params["mu"])) ** ( - -5.0 / self.params["mu"] - ) + return (1 + (self.lam_eff_fs * k) ** (2 * self.params["mu"])) ** (-5.0 / self.params["mu"]) @property def lam_eff_fs(self): @@ -161,7 +158,6 @@ class Bode01(Viel05): """The WDM model of Bode et al. (2001).""" - viel_model = Viel05(mx=1.0) @@ -276,7 +272,7 @@ def dndm_alter(self): # =============================================================================== # Frameworks # =============================================================================== -class TransferWDM(_Tr): +class TransferWDM(Transfer): """ A subclass of :class:`hmf.transfer.Transfer` that mixes in WDM capabilities. @@ -289,9 +285,7 @@ class TransferWDM(_Tr): actual defaults for each parameter, use :meth:`get_all_parameter_defaults`. """ - def __init__( - self, wdm_mass=3.0, wdm_model=Viel05, wdm_params=None, **transfer_kwargs - ): + def __init__(self, wdm_mass=3.0, wdm_model=Viel05, wdm_params=None, **transfer_kwargs): wdm_params = wdm_params or {} # Call standard transfer @@ -343,9 +337,7 @@ def wdm(self): Contains quantities relevant to WDM. """ - return self.wdm_model( - mx=self.wdm_mass, cosmo=self.cosmo, z=self.z, **self.wdm_params - ) + return self.wdm_model(mx=self.wdm_mass, cosmo=self.cosmo, z=self.z, **self.wdm_params) @override @cached_quantity @@ -353,7 +345,7 @@ def _unnormalised_lnT(self): return super()._unnormalised_lnT + np.log(self.wdm.transfer(self.k)) -class MassFunctionWDM(_MF, TransferWDM): +class MassFunctionWDM(MassFunction, TransferWDM): """ A subclass of :class:`hmf.MassFunction` that mixes in WDM capabilities. @@ -399,9 +391,7 @@ def dndm(self): dndm = super().dndm if self.alter_model is not None: - alter = self.alter_model( - m=self.m, dndm0=dndm, wdm=self.wdm, **self.alter_params - ) + alter = self.alter_model(m=self.m, dndm0=dndm, wdm=self.wdm, **self.alter_params) dndm = alter.dndm_alter() return dndm diff --git a/src/hmf/cosmology/cosmo.py b/src/hmf/cosmology/cosmo.py index 54ee20ed..f3fe5a55 100644 --- a/src/hmf/cosmology/cosmo.py +++ b/src/hmf/cosmology/cosmo.py @@ -94,9 +94,7 @@ def cosmo_model(self, val): return get_cosmo(val) if not isinstance(val, FLRW): - raise ValueError( - "cosmo_model must be an instance of astropy.cosmology.FLRW" - ) + raise ValueError("cosmo_model must be an instance of astropy.cosmology.FLRW") return val @_cache.parameter("param") diff --git a/src/hmf/cosmology/growth_factor.py b/src/hmf/cosmology/growth_factor.py index 081cdbc8..6849aefe 100644 --- a/src/hmf/cosmology/growth_factor.py +++ b/src/hmf/cosmology/growth_factor.py @@ -84,7 +84,7 @@ def _zvec(self): @cached_property def integral(self): r"""The integral :math:`\int_0^a da' / (a'^3 E(a')^3)`. - + Parameters ---------- a : array_like @@ -115,9 +115,7 @@ def _d_plus(self, z: float | np.ndarray) -> float | np.ndarray: if np.any(z < 0): raise ValueError("Redshifts <0 not supported") if np.any(a < a_min): - raise ValueError( - f"Cannot compute integral for z > {1 / a_min - 1}. Set amin lower." - ) + raise ValueError(f"Cannot compute integral for z > {1 / a_min - 1}. Set amin lower.") return (self.integral(a) - self.integral(a_min)) * self.cosmo.efunc(z) @@ -200,10 +198,7 @@ def growth_rate_fn(self, zmin=0): gfn = self.growth_factor_fn(zmin) return lambda z: ( - -1 - - self.cosmo.Om(z) / 2 - + self.cosmo.Ode(z) - + 5 * self.cosmo.Om(z) / (2 * gfn(z)) + -1 - self.cosmo.Om(z) / 2 + self.cosmo.Ode(z) + 5 * self.cosmo.Om(z) / (2 * gfn(z)) ) @@ -290,9 +285,7 @@ def growth_factor(self, z): d_out = self.params["d"] if z_out is None or d_out is None: - raise ValueError( - "You must supply an array for both z and d for this Growth model" - ) + raise ValueError("You must supply an array for both z and d for this Growth model") if len(z_out) != len(d_out): raise ValueError("z and d must have same length") @@ -379,17 +372,9 @@ def growth_factor(self, z): x = a * xn aofx = self._general_case(w, x) return aofx / aofxn - dn = ( - 1 - + 3 / w - + (3 * ((1 + w) ** 0.5) / w**1.5) * np.log((1 + w) ** 0.5 - w**0.5) - ) + dn = 1 + 3 / w + (3 * ((1 + w) ** 0.5) / w**1.5) * np.log((1 + w) ** 0.5 - w**0.5) x = w * a - return ( - 1 - + 3 / x - + (3 * ((1 + x) ** 0.5) / x**1.5) * np.log((1 + x) ** 0.5 - x**0.5) - ) / dn + return (1 + 3 / x + (3 * ((1 + x) ** 0.5) / x**1.5) * np.log((1 + x) ** 0.5 - x**0.5)) / dn @_inherit @@ -506,9 +491,7 @@ def _camb_transfers(self): @cached_property def _t0(self): """The Transfer function at z=0.""" - return self._camb_transfers.get_redshift_evolution(1.0, 0.0, ["delta_tot"])[ - 0 - ][0] + return self._camb_transfers.get_redshift_evolution(1.0, 0.0, ["delta_tot"])[0][0] def growth_factor(self, z): """ @@ -525,9 +508,7 @@ def growth_factor(self, z): The normalised growth factor. """ growth = ( - self._camb_transfers.get_redshift_evolution( - 1.0, z, ["delta_tot"] - ).flatten() + self._camb_transfers.get_redshift_evolution(1.0, z, ["delta_tot"]).flatten() / self._t0 ) if len(growth) == 1: @@ -535,6 +516,7 @@ def growth_factor(self, z): return growth def __getstate__(self): + """Get the state of the object, including converting the CAMBparams object to a dict.""" dct = self.__dict__.copy() # Can't pickle/copy CAMBparams or CAMBResults @@ -545,6 +527,7 @@ def __getstate__(self): return dct def __setstate__(self, state): + """Set the state of the object, including reconstructing the CAMBparams object.""" self.__dict__ = state self.p = self._get_camb_params(self.cosmo) diff --git a/src/hmf/density_field/filters.py b/src/hmf/density_field/filters.py index 3b99bdc1..7ba49863 100644 --- a/src/hmf/density_field/filters.py +++ b/src/hmf/density_field/filters.py @@ -430,9 +430,7 @@ def dlnss_dlnr(self, r): @override def mass_to_radius(self, m, rho_mean): - return (1.0 / self.params["c"]) * (3.0 * m / (4.0 * np.pi * rho_mean)) ** ( - 1.0 / 3.0 - ) + return (1.0 / self.params["c"]) * (3.0 * m / (4.0 * np.pi * rho_mean)) ** (1.0 / 3.0) @override def radius_to_mass(self, r, rho_mean): @@ -486,9 +484,7 @@ def xm(self, g, v): Equation A6. in Schneider et al. 2013 """ - top = 3 * (1 - g**2) + (1.1 - 0.9 * g**4) * np.exp( - -g * (1 - g**2) * (g * v / 2) ** 2 - ) + top = 3 * (1 - g**2) + (1.1 - 0.9 * g**4) * np.exp(-g * (1 - g**2) * (g * v / 2) ** 2) bot = (3 * (1 - g**2) + 0.45 + (g * v / 2) ** 2) ** 0.5 + g * v / 2 return g * v + top / bot @@ -501,8 +497,7 @@ def pm(self, xm): return 30.0 / (5 * xm**2 + 6) ** 2 def a3a1(self, e, p): - """Compute the short:long axis ratio of an ellipsoid given its ellipticity and prolateness. - """ + """Compute the short:long axis ratio of an ellipsoid.""" return np.sqrt((1 - 3 * e + p) / (1 + 3 * e + p)) def a3a2(self, e, p): diff --git a/src/hmf/density_field/halofit.py b/src/hmf/density_field/halofit.py index ee627871..e25b88a5 100644 --- a/src/hmf/density_field/halofit.py +++ b/src/hmf/density_field/halofit.py @@ -17,9 +17,7 @@ from ..cosmology.cosmo import Cosmology as CosmologyClass -def _get_spec( - k: np.ndarray, delta_k: np.ndarray, sigma_8=None -) -> tuple[float, float, float]: +def _get_spec(k: np.ndarray, delta_k: np.ndarray, sigma_8=None) -> tuple[float, float, float]: """ Calculate spectral parameters from power spectrum. @@ -56,16 +54,14 @@ def get_log_sigma2(lnr): def get_sigma_abs(lnr): return np.abs(get_log_sigma2(lnr)) - res = minimize( - get_sigma_abs, x0=[1.0], options={"xatol": np.log(1.1)}, method="Nelder-Mead" - ) + res = minimize(get_sigma_abs, x0=[1.0], options={"xatol": np.log(1.1)}, method="Nelder-Mead") if not res.success: warnings.warn( f"Could not determine non-linear scale! Failed with error: {res.message}. " f"Continuing with best-fit non-linear scale: r_nl={np.exp(res.x)}, with " f"log_sigma^2 = {res.fun}", - stacklevel=2 + stacklevel=2, ) rnl = np.exp(res.x) @@ -202,19 +198,10 @@ def halofit(k, delta_k, *, sigma_8=None, z=0, cosmo=None, takahashi=True): y = k / rknl ph = a * y ** (f1 * 3) / (1 + b * y**f2 + (f3 * c * y) ** (3 - gam)) - ph = ( - ph - / (1 + xmu / y + xnu * y**-2) - * (1 + fnu * (0.977 - 18.015 * (cosmo.Om0 - 0.3))) - ) + ph = ph / (1 + xmu / y + xnu * y**-2) * (1 + fnu * (0.977 - 18.015 * (cosmo.Om0 - 0.3))) plinaa = plin * (1 + fnu * 47.48 * k**2 / (1 + 1.5 * k**2)) - pq = ( - plin - * (1 + plinaa) ** beta - / (1 + plinaa * alpha) - * np.exp(-y / 4.0 - y**2 / 8.0) - ) + pq = plin * (1 + plinaa) ** beta / (1 + plinaa * alpha) * np.exp(-y / 4.0 - y**2 / 8.0) pnl = pq + ph # We have to copy so the original data is not overwritten, giving unexpected results. diff --git a/src/hmf/density_field/transfer.py b/src/hmf/density_field/transfer.py index 15a771b9..703124f8 100644 --- a/src/hmf/density_field/transfer.py +++ b/src/hmf/density_field/transfer.py @@ -91,9 +91,7 @@ def __init__( @override def validate(self): super().validate() - assert self.lnk_min < self.lnk_max, ( - f"lnk_min >= lnk_max: {self.lnk_min}, {self.lnk_max}" - ) + assert self.lnk_min < self.lnk_max, f"lnk_min >= lnk_max: {self.lnk_min}, {self.lnk_max}" assert len(self.k) > 1, f"len(k) < 2: {len(self.k)}" @parameter("model") @@ -125,9 +123,7 @@ def transfer_model(self, val): :type: str or :class:`hmf.transfer_models.TransferComponent` subclass, optional """ if not HAVE_CAMB and val in ["CAMB", tm.CAMB]: - raise ValueError( - "You cannot use the CAMB transfer since pycamb isn't installed" - ) + raise ValueError("You cannot use the CAMB transfer since pycamb isn't installed") return get_mdl(val, "TransferComponent") @parameter("param") @@ -314,6 +310,4 @@ def nonlinear_delta_k(self): .. math:: \Delta_k = \frac{k^3 P_{\rm nl}(k)}{2\pi^2} """ - return _hfit( - self.k, self.delta_k, z=self.z, cosmo=self.cosmo, takahashi=self.takahashi - ) + return _hfit(self.k, self.delta_k, z=self.z, cosmo=self.cosmo, takahashi=self.takahashi) diff --git a/src/hmf/density_field/transfer_models.py b/src/hmf/density_field/transfer_models.py index 64c0bcb0..0063bc0d 100644 --- a/src/hmf/density_field/transfer_models.py +++ b/src/hmf/density_field/transfer_models.py @@ -172,9 +172,7 @@ class CAMB(FromFile): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - if not isinstance( - self.cosmo, (cosmology.LambdaCDM, cosmology.wCDM, cosmology.w0waCDM) - ): + if not isinstance(self.cosmo, (cosmology.LambdaCDM, cosmology.wCDM, cosmology.w0waCDM)): raise ValueError("CAMB will only work with LCDM or wCDM cosmologies") # Save the CAMB object properly for use @@ -198,14 +196,12 @@ def __init__(self, *args, **kwargs): if self.cosmo.Ob0 is None or self.cosmo.Ob0 == 0.0: raise ValueError( - "To use CAMB, you must set the baryon density in the cosmology " - "explicitly." + "To use CAMB, you must set the baryon density in the cosmology explicitly." ) if self.cosmo.Tcmb0.value == 0: raise ValueError( - "If using CAMB, the CMB temperature must be set explicitly in the " - "cosmology." + "If using CAMB, the CMB temperature must be set explicitly in the cosmology." ) self.params["camb_params"].set_cosmology( @@ -225,16 +221,14 @@ def __init__(self, *args, **kwargs): if isinstance(self.cosmo, cosmology.wCDM): self.params["camb_params"].set_dark_energy(w=self.cosmo.w0) elif isinstance(self.cosmo, cosmology.w0waCDM): - self.params["camb_params"].set_dark_energy( - w=self.cosmo.w0, wa=self.cosmo.wa - ) + self.params["camb_params"].set_dark_energy(w=self.cosmo.w0, wa=self.cosmo.wa) if self.params["extrapolate_with_eh"] is None: warnings.warn( "'extrapolate_with_eh' was not set. Defaulting to True, which is " "different behaviour than versions <=3.4.4. This warning may be " "removed in v4.0. Silence it by setting extrapolate_with_eh explicitly.", - stacklevel=2 + stacklevel=2, ) self.params["extrapolate_with_eh"] = True @@ -292,6 +286,7 @@ def lnt(self, lnk): return out def __getstate__(self): + """Get the state of the object, including converting the CAMBparams object to a dict.""" # We need to get rid of the CAMBparams() object, as it cannot be pickled. p = self.params["camb_params"] @@ -363,7 +358,8 @@ def __getstate__(self): warnings.warn( f"CAMB key '{pk}' is not an attribute. If you provided a " f"custom CAMBparams, results may be inconsistent. Available: " - f"{dir(p)}", stacklevel=2 + f"{dir(p)}", + stacklevel=2, ) except Exception: @@ -380,6 +376,7 @@ def __getstate__(self): return this def __setstate__(self, state): + """Set the state of the object, including reconstructing the CAMBparams object.""" self.__dict__ = state self.params["camb_params"] = camb.CAMBparams(**self.params["camb_params"]) @@ -425,9 +422,7 @@ def lnt(self, lnk): T = self.params["T"] if k is None or T is None: - raise ValueError( - "You must supply an array for both k and T for this Transfer Model" - ) + raise ValueError("You must supply an array for both k and T for this Transfer Model") if len(k) != len(T): raise ValueError("k and T must have same length") @@ -478,9 +473,7 @@ def _set_params(self): * (1.0 + self.z_drag_b1 * self.Obh2**self.z_drag_b2) ) - self.r_drag = ( - 31.5 * self.Obh2 * self.theta_cmb**-4 * (1000.0 / (1 + self.z_drag)) - ) + self.r_drag = 31.5 * self.Obh2 * self.theta_cmb**-4 * (1000.0 / (1 + self.z_drag)) self.r_eq = 31.5 * self.Obh2 * self.theta_cmb**-4 * (1000.0 / self.z_eq) self.sound_horizon = ( @@ -493,21 +486,12 @@ def _set_params(self): ) self.k_silk = ( - 1.6 - * self.Obh2**0.52 - * self.Omh2**0.73 - * (1.0 + (10.4 * self.Omh2) ** (-0.95)) + 1.6 * self.Obh2**0.52 * self.Omh2**0.73 * (1.0 + (10.4 * self.Omh2) ** (-0.95)) ) - alpha_c_a1 = (46.9 * self.Omh2) ** 0.670 * ( - 1.0 + (32.1 * self.Omh2) ** (-0.532) - ) - alpha_c_a2 = (12.0 * self.Omh2) ** 0.424 * ( - 1.0 + (45.0 * self.Omh2) ** (-0.582) - ) - self.alpha_c = alpha_c_a1 ** (-self.f_baryon) * alpha_c_a2 ** ( - -(self.f_baryon**3) - ) + alpha_c_a1 = (46.9 * self.Omh2) ** 0.670 * (1.0 + (32.1 * self.Omh2) ** (-0.532)) + alpha_c_a2 = (12.0 * self.Omh2) ** 0.424 * (1.0 + (45.0 * self.Omh2) ** (-0.582)) + self.alpha_c = alpha_c_a1 ** (-self.f_baryon) * alpha_c_a2 ** (-(self.f_baryon**3)) beta_c_b1 = 0.944 / (1.0 + (458.0 * self.Omh2) ** -0.708) beta_c_b2 = (0.395 * self.Omh2) ** -0.0266 @@ -515,15 +499,10 @@ def _set_params(self): y = self.z_eq / (1 + self.z_drag) alpha_b_G = y * ( - -6 * np.sqrt(1 + y) - + (2 + 3 * y) * np.log((np.sqrt(1 + y) + 1) / (np.sqrt(1 + y) - 1)) + -6 * np.sqrt(1 + y) + (2 + 3 * y) * np.log((np.sqrt(1 + y) + 1) / (np.sqrt(1 + y) - 1)) ) self.alpha_b = ( - 2.07 - * self.k_eq - * self.sound_horizon - * (1.0 + self.r_drag) ** -0.75 - * alpha_b_G + 2.07 * self.k_eq * self.sound_horizon * (1.0 + self.r_drag) ** -0.75 * alpha_b_G ) self.beta_node = 8.41 * self.Omh2**0.435 @@ -541,12 +520,7 @@ def k_peak(self): @property def sound_horizon_fit(self): """Sound horizon in Mpc/h.""" - return ( - self.cosmo.h - * 44.5 - * np.log(9.83 / self.Omh2) - / np.sqrt(1 + 10 * (self.Obh2**0.75)) - ) + return self.cosmo.h * 44.5 * np.log(9.83 / self.Omh2) / np.sqrt(1 + 10 * (self.Obh2**0.75)) def lnt(self, lnk): r""" @@ -587,9 +561,7 @@ def term(a, b): T_b_T0 = term(T_c_ln_nobeta, T_c_C_noalpha) Tb1 = T_b_T0 / (1.0 + (ks / 5.2) ** 2) - Tb2 = (self.alpha_b / (1.0 + (self.beta_b / ks) ** 3)) * np.exp( - -((k / self.k_silk) ** 1.4) - ) + Tb2 = (self.alpha_b / (1.0 + (self.beta_b / ks) ** 3)) * np.exp(-((k / self.k_silk) ** 1.4)) T_b = np.sin(ks_tilde) / ks_tilde * (Tb1 + Tb2) return np.log(self.f_baryon * T_b + (1 - self.f_baryon) * T_c) @@ -637,9 +609,7 @@ def lnt(self, lnk): ks = k * self.sound_horizon_fit / self.cosmo.h # need sound horizon in Mpc here - gamma_eff = self.Omh2 * ( - self.alpha_gamma + (1 - self.alpha_gamma) / (1 + (0.43 * ks) ** 4) - ) + gamma_eff = self.Omh2 * (self.alpha_gamma + (1 - self.alpha_gamma) / (1 + (0.43 * ks) ** 4)) q = k / (13.4 * self.k_eq) q_eff = q * self.Omh2 / gamma_eff @@ -728,8 +698,7 @@ def lnt(self, lnk): Gamma *= np.exp(-self.cosmo.Ob0 * (1 + 1 / self.cosmo.Om0)) elif self.params["use_liddle_baryons"]: Gamma *= np.exp( - -self.cosmo.Ob0 - * (1 + np.sqrt(self.cosmo.Ob0 * self.cosmo.h) / self.cosmo.Om0) + -self.cosmo.Ob0 * (1 + np.sqrt(self.cosmo.Ob0 * self.cosmo.h) / self.cosmo.Om0) ) q = np.exp(lnk) / Gamma @@ -795,4 +764,3 @@ def lnt(self, lnk): class EH(EH_BAO): """Alias of :class:`EH_BAO`.""" - diff --git a/src/hmf/halos/mass_definitions.py b/src/hmf/halos/mass_definitions.py index 51912041..809ef805 100644 --- a/src/hmf/halos/mass_definitions.py +++ b/src/hmf/halos/mass_definitions.py @@ -18,7 +18,7 @@ __all__ = [ "FOF", "MassDefinition", - "OptimizationException", + "OptimizationError", "SOCritical", "SOMean", "SOVirial", @@ -78,9 +78,7 @@ def m_to_r(self, m, z=0, cosmo=Planck15): try: return (3 * m / (4 * np.pi * self.halo_density(z, cosmo))) ** (1.0 / 3.0) except AttributeError as e: - raise AttributeError( - f"{self.__class__.__name__} cannot convert mass to radius." - ) from e + raise AttributeError(f"{self.__class__.__name__} cannot convert mass to radius.") from e def r_to_m(self, r, z=0, cosmo=Planck15): r""" @@ -99,17 +97,13 @@ def r_to_m(self, r, z=0, cosmo=Planck15): try: return 4 * np.pi * r**3 * self.halo_density(z, cosmo) / 3 except AttributeError as e: - raise AttributeError( - f"{self.__class__.__name__} cannot convert radius to mass." - ) from e + raise AttributeError(f"{self.__class__.__name__} cannot convert radius to mass.") from e def _duffy_concentration(self, m, z=0): a, b, c, ms = 6.71, -0.091, 0.44, 2e12 return a / (1 + z) ** c * (m / ms) ** b - def change_definition( - self, m: np.ndarray, mdef, profile=None, c=None, z=0, cosmo=Planck15 - ): + def change_definition(self, m: np.ndarray, mdef, profile=None, c=None, z=0, cosmo=Planck15): r""" Change the spherical overdensity mass definition. @@ -138,15 +132,8 @@ def change_definition( c_f : float or array_like The concentrations of the halos in the new definition. """ - if ( - c is not None - and not np.isscalar(c) - and not np.isscalar(m) - and len(m) != len(c) - ): - raise ValueError( - "If both m and c are arrays, they must be of the same length" - ) + if c is not None and not np.isscalar(c) and not np.isscalar(m) and len(m) != len(c): + raise ValueError("If both m and c are arrays, they must be of the same length") if c is not None and np.isscalar(c) and not np.isscalar(m): c = np.ones_like(m) * c if c is not None and np.isscalar(m) and not np.isscalar(c): @@ -160,9 +147,7 @@ def change_definition( from halomod.concentration import Duffy08 from halomod.profiles import NFW - profile = NFW( - cm_relation=Duffy08(cosmo=Cosmology(cosmo)), mdef=self, z=z - ) + profile = NFW(cm_relation=Duffy08(cosmo=Cosmology(cosmo)), mdef=self, z=z) except ImportError as e: raise ImportError( "Cannot change mass definitions without halomod installed!" @@ -171,7 +156,8 @@ def change_definition( if profile.z != z: warnings.warn( f"Redshift of given profile ({profile.z})does not match redshift " - f"passed to change_definition(). Using the redshift directly passed.", stacklevel=2 + f"passed to change_definition(). Using the redshift directly passed.", + stacklevel=2, ) profile.z = z @@ -189,9 +175,7 @@ def change_definition( c_new = np.array( [ - _find_new_concentration( - rho, mdef.halo_density(z, cosmo), profile._h, cc - ) + _find_new_concentration(rho, mdef.halo_density(z, cosmo), profile._h, cc) for rho, cc in zip(rhos, c, strict=True) ] ) @@ -208,10 +192,7 @@ def change_definition( def __eq__(self, other): """Test equality with another object.""" - return ( - self.__class__.__name__ == other.__class__.__name__ - and self.params == other.params - ) + return self.__class__.__name__ == other.__class__.__name__ and self.params == other.params class SphericalOverdensity(MassDefinition): @@ -306,7 +287,7 @@ def halo_density(self, z=0, cosmo=Planck15): ---------- .. [1] White, Martin, Lars Hernquist, and Volker Springel. “The Halo Model and Numerical Simulations.” The Astrophysical Journal 550, no. 2 (April 2001): - L129–32. https://doi.org/10.1086/319644. + L129-32. https://doi.org/10.1086/319644. """ overdensity = 9 / (2 * np.pi * self.params["linking_length"] ** 3) return overdensity * self.mean_density(z, cosmo) @@ -384,7 +365,7 @@ def fnc(x): i += 1 if x is None: - raise OptimizationException( + raise OptimizationError( "Could not determine x where the density threshold " f"{halo_density / rho_s:.2f} is satisfied. Largest x-range tried was " f"x={xmin} -- {xmax} which brackets {fnc(xmin)} -- {fnc(xmax)}" @@ -393,6 +374,5 @@ def fnc(x): return x -class OptimizationException(Exception): +class OptimizationError(Exception): """Exception class related to failed optimization.""" - diff --git a/src/hmf/helpers/__init__.py b/src/hmf/helpers/__init__.py index ba9890d3..ba026ac4 100644 --- a/src/hmf/helpers/__init__.py +++ b/src/hmf/helpers/__init__.py @@ -1,6 +1,4 @@ -"""A collection of helper functions which can operate on several of the Frameworks in the -rest of the code. -""" +"""Helper functions which can operate on several of the Frameworks in the rest of the code.""" from . import sample from .functional import get_best_param_order, get_hmf diff --git a/src/hmf/helpers/cfg_utils.py b/src/hmf/helpers/cfg_utils.py index 66f9f94e..5cbd9cf5 100644 --- a/src/hmf/helpers/cfg_utils.py +++ b/src/hmf/helpers/cfg_utils.py @@ -37,9 +37,7 @@ def framework_to_dict(obj: Framework) -> dict: val = getattr(obj, k) if val is None: obj_val = getattr(obj, k.split("_model")[0]) - out["params"][k] = ( - None if obj_val is None else obj_val.__class__.__name__ - ) + out["params"][k] = None if obj_val is None else obj_val.__class__.__name__ else: out["params"][k] = val.__name__ diff --git a/src/hmf/mass_function/fitting_functions.py b/src/hmf/mass_function/fitting_functions.py index f4b5b18b..4fe8903e 100644 --- a/src/hmf/mass_function/fitting_functions.py +++ b/src/hmf/mass_function/fitting_functions.py @@ -211,9 +211,7 @@ class FittingFunction(_framework.Component): req_neff = False #: Whether `n_eff` is required for this subclass req_mass = False #: Whether `m` is required for this subclass - sim_definition = ( - None #: Details of the defining simulation, instance of :class:`SimDetails` - ) + sim_definition = None #: Details of the defining simulation, instance of :class:`SimDetails` normalized = False #: Whether this model is normalized so that all mass is in halos @@ -275,19 +273,19 @@ def get_measured_mdef(cls): # A Generic SO that will accept any SO definition, but has a # preferred one. measured = md.SOGeneric( - preferred=md.from_colossus_name( - delta_h.split("(")[-1].split(")")[0] - ) + preferred=md.from_colossus_name(delta_h.split("(")[-1].split(")")[0]) ) else: warnings.warn( "Unrecognized overdensity criterion format. " - "Changing mass definitions will be impossible.", stacklevel=2 + "Changing mass definitions will be impossible.", + stacklevel=2, ) else: warnings.warn( "Unknown halo finder type in the sim_definition. " - "Changing mass definitions will be impossible.", stacklevel=2 + "Changing mass definitions will be impossible.", + stacklevel=2, ) return measured @@ -420,7 +418,6 @@ class ST(SMT): """Alias of :class:`SMT`.""" - class Jenkins(FittingFunction): """Jenkins mass function fit.""" @@ -488,7 +485,11 @@ class Warren(FittingFunction): __doc__ = _makedoc(FittingFunction._pdocs, "Warren", "Warren", _eq, _ref) _defaults: ClassVar[Final[dict[str, float]]] = { - "A": 0.7234, "b": 1.625, "c": 0.2538, "d": 1.1982, "e": 1 + "A": 0.7234, + "b": 1.625, + "c": 0.2538, + "d": 1.1982, + "e": 1, } normalized = False @@ -581,9 +582,7 @@ class Reed03(SMT): @property def fsigma(self): vfv = super().fsigma - return vfv * np.exp( - -self.params["c"] / (self.sigma * np.cosh(2.0 * self.sigma) ** 5) - ) + return vfv * np.exp(-self.params["c"] / (self.sigma * np.cosh(2.0 * self.sigma) ** 5)) @override @property @@ -671,9 +670,7 @@ def fsigma(self): * np.sqrt(2.0 * a / np.pi) * (1.0 + (1.0 / (a * self.nu**2)) ** p + 0.6 * G_1 + 0.4 * G_2) * self.nu - * np.exp( - -c * a * self.nu**2 / 2.0 - 0.03 * self.nu**0.6 / (self.n_eff + 3) ** 2 - ) + * np.exp(-c * a * self.nu**2 / 2.0 - 0.03 * self.nu**0.6 / (self.n_eff + 3) ** 2) ) @override @@ -779,7 +776,11 @@ class Watson_FoF(Warren): ) __doc__ = _makedoc(FittingFunction._pdocs, "Watson FoF", "WatF", Warren._eq, _ref) _defaults: ClassVar[Final[dict[str, float]]] = { - "A": 0.282, "b": 2.163, "c": 1, "d": 1.21, "e": 1.406 + "A": 0.282, + "b": 2.163, + "c": 1, + "d": 1.21, + "e": 1.406, } sim_definition = SimDetails( @@ -858,9 +859,7 @@ def gamma(self): delta_halo = 178.0 elif not isinstance(self.mass_definition, md.SphericalOverdensity): - raise ValueError( - "The Watson fitting function is a spherical-overdensity function." - ) + raise ValueError("The Watson fitting function is a spherical-overdensity function.") else: delta_halo = self.mass_definition.halo_overdensity_mean(self.z, self.cosmo) C = np.exp(self.params["C_a"] * (delta_halo / 178 - 1)) @@ -868,11 +867,7 @@ def gamma(self): p = self.params["p"] q = self.params["q"] - return ( - C - * (delta_halo / 178) ** d - * np.exp(p * (1 - delta_halo / 178) / self.sigma**q) - ) + return C * (delta_halo / 178) ** d * np.exp(p * (1 - delta_halo / 178) / self.sigma**q) @override @property @@ -890,8 +885,7 @@ def fsigma(self): else: omz = self.omegam_z A = omz * ( - self.params["A_a"] * (1 + self.z) ** (-self.params["A_b"]) - + self.params["A_c"] + self.params["A_a"] * (1 + self.z) ** (-self.params["A_b"]) + self.params["A_c"] ) alpha = omz * ( self.params["alpha_a"] * (1 + self.z) ** (-self.params["alpha_b"]) @@ -904,10 +898,7 @@ def fsigma(self): gamma = self.params["gamma_z"] return ( - self.gamma() - * A - * ((beta / self.sigma) ** alpha + 1) - * np.exp(-gamma / self.sigma**2) + self.gamma() * A * ((beta / self.sigma) ** alpha + 1) * np.exp(-gamma / self.sigma**2) ) @override @@ -1372,9 +1363,7 @@ def __init__(self, **model_parameters): super().__init__(**model_parameters) if not isinstance(self.mass_definition, md.SphericalOverdensity): - raise ValueError( - "The Tinker fitting function is a spherical-overdensity function." - ) + raise ValueError("The Tinker fitting function is a spherical-overdensity function.") delta_halo = self.mass_definition.halo_overdensity_mean(self.z, self.cosmo) if delta_halo not in self.delta_virs: @@ -1407,22 +1396,14 @@ def __init__(self, **model_parameters): @override @property def fsigma(self): - return ( - self.A - * ((self.sigma / self.b) ** (-self.a) + 1) - * np.exp(-self.c / self.sigma**2) - ) + return self.A * ((self.sigma / self.b) ** (-self.a) + 1) * np.exp(-self.c / self.sigma**2) @override @property def cutmask(self): if self.z == 0.0: - return np.logical_and( - self.lnsigma / np.log(10) > -0.6, self.lnsigma / np.log(10) < 0.4 - ) - return np.logical_and( - self.lnsigma / np.log(10) > -0.2, self.lnsigma / np.log(10) < 0.4 - ) + return np.logical_and(self.lnsigma / np.log(10) > -0.6, self.lnsigma / np.log(10) < 0.4) + return np.logical_and(self.lnsigma / np.log(10) > -0.2, self.lnsigma / np.log(10) < 0.4) class Tinker10(FittingFunction): @@ -1506,18 +1487,14 @@ def __init__(self, **model_parameters): delta_halo = 200 elif not isinstance(self.mass_definition, md.SphericalOverdensity): - raise ValueError( - "The Tinker10 fitting function is a spherical-overdensity function." - ) + raise ValueError("The Tinker10 fitting function is a spherical-overdensity function.") else: delta_halo = self.mass_definition.halo_overdensity_mean(self.z, self.cosmo) self.delta_halo = delta_halo if int(delta_halo) not in self.delta_virs: beta_array = np.array([self.params[f"beta_{d}"] for d in self.delta_virs]) - gamma_array = np.array( - [self.params[f"gamma_{d}"] for d in self.delta_virs] - ) + gamma_array = np.array([self.params[f"gamma_{d}"] for d in self.delta_virs]) phi_array = np.array([self.params[f"phi_{d}"] for d in self.delta_virs]) eta_array = np.array([self.params[f"eta_{d}"] for d in self.delta_virs]) @@ -1536,19 +1513,10 @@ def __init__(self, **model_parameters): phi_0 = self.params[f"phi_{int(delta_halo)}"] eta_0 = self.params[f"eta_{int(delta_halo)}"] - self.beta = ( - beta_0 * (1 + min(self.z, self.params["max_z"])) ** self.params["beta_exp"] - ) - self.phi = ( - phi_0 * (1 + min(self.z, self.params["max_z"])) ** self.params["phi_exp"] - ) - self.eta = ( - eta_0 * (1 + min(self.z, self.params["max_z"])) ** self.params["eta_exp"] - ) - self.gamma = ( - gamma_0 - * (1 + min(self.z, self.params["max_z"])) ** self.params["gamma_exp"] - ) + self.beta = beta_0 * (1 + min(self.z, self.params["max_z"])) ** self.params["beta_exp"] + self.phi = phi_0 * (1 + min(self.z, self.params["max_z"])) ** self.params["phi_exp"] + self.eta = eta_0 * (1 + min(self.z, self.params["max_z"])) ** self.params["eta_exp"] + self.gamma = gamma_0 * (1 + min(self.z, self.params["max_z"])) ** self.params["gamma_exp"] # The normalisation only works with specific conditions # gamma > 0 @@ -1564,9 +1532,7 @@ def __init__(self, **model_parameters): # eta-phi >-0.5 if self.eta - self.phi <= -0.5: if self.terminate: - raise ValueError( - "eta-phi must be > -0.5, got " + str(self.eta - self.phi) - ) + raise ValueError("eta-phi must be > -0.5, got " + str(self.eta - self.phi)) self.phi = self.eta + 0.499 if self.beta <= 0: if self.terminate: @@ -1602,18 +1568,16 @@ def fsigma(self): @property def cutmask(self): if self.z == 0.0: - return np.logical_and( - self.lnsigma / np.log(10) > -0.6, self.lnsigma / np.log(10) < 0.4 - ) - return np.logical_and( - self.lnsigma / np.log(10) > -0.2, self.lnsigma / np.log(10) < 0.4 - ) + return np.logical_and(self.lnsigma / np.log(10) > -0.6, self.lnsigma / np.log(10) < 0.4) + return np.logical_and(self.lnsigma / np.log(10) > -0.2, self.lnsigma / np.log(10) < 0.4) class Behroozi(Tinker08): """Behroozi mass function fit.""" - _ref = r"""Behroozi, P., Weschler, R. and Conroy, C., ApJ, 2013, http://arxiv.org/abs/1207.6105""" + _ref = ( + r"""Behroozi, P., Weschler, R. and Conroy, C., ApJ, 2013, http://arxiv.org/abs/1207.6105""" + ) __doc__ = rf""" Behroozi mass function fit [1]_. @@ -1681,11 +1645,13 @@ class Pillepich(Warren): """Pillepich mass function fit.""" _ref = r"""Pillepich, A., et al., 2010, arxiv:0811.4176""" - __doc__ = _makedoc( - FittingFunction._pdocs, "Pillepich", "Pillepich", Warren._eq, _ref - ) + __doc__ = _makedoc(FittingFunction._pdocs, "Pillepich", "Pillepich", Warren._eq, _ref) _defaults: ClassVar[Final[dict[str, float]]] = { - "A": 0.6853, "b": 1.868, "c": 0.3324, "d": 1.2266, "e": 1 + "A": 0.6853, + "b": 1.868, + "c": 0.3324, + "d": 1.2266, + "e": 1, } normalized = False @@ -1753,7 +1719,11 @@ class Ishiyama(Warren): __doc__ = _makedoc(FittingFunction._pdocs, "Ishiyama", "Ishiyama", _eq, _ref) _defaults: ClassVar[Final[dict[str, float]]] = { - "A": 0.193, "b": 1.550, "c": 1, "d": 1.186, "e": 2.184 + "A": 0.193, + "b": 1.550, + "c": 1, + "d": 1.186, + "e": 2.184, } sim_definition = SimDetails( @@ -1849,12 +1819,7 @@ def convert_mass(self): def fsigma(self): A, b, d, e = self.get_params() mass_conversion = self.convert_mass() - return ( - A - * ((e / self.sigma) ** b + 1) - * np.exp(-d / self.sigma**2) - * mass_conversion - ) + return A * ((e / self.sigma) ** b + 1) * np.exp(-d / self.sigma**2) * mass_conversion class Bocquet200mHydro(Bocquet200mDMOnly): diff --git a/src/hmf/mass_function/hmf.py b/src/hmf/mass_function/hmf.py index 98b40f88..a3be3c1e 100644 --- a/src/hmf/mass_function/hmf.py +++ b/src/hmf/mass_function/hmf.py @@ -304,7 +304,7 @@ def mdef(self) -> MassDef: f"definition in which the hmf fit {self.hmf_model.__name__} was measured:" f"'{self.hmf_model.get_measured_mdef()}'. " f"{extra_msg if not self.disable_mass_conversion else ''}", - stacklevel=2 + stacklevel=2, ) return mdef @@ -414,21 +414,14 @@ def mass_nonlinear(self): """The nonlinear mass, nu(Mstar) = 1.""" if self.nu.min() > 1 or self.nu.max() < 1: warnings.warn("Nonlinear mass outside mass range", stacklevel=2) - if self.nu.min() > 1: - startr = np.log(self.radii.min()) - else: - startr = np.log(self.radii.max()) + + startr = np.log(self.radii.min()) if self.nu.min() > 1 else np.log(self.radii.max()) def model(lnr): return ( - ( - self.filter.sigma(np.exp(lnr)) - * self._normalisation - * self.growth_factor - - self.delta_c - ) - ** 2 - ) + self.filter.sigma(np.exp(lnr)) * self._normalisation * self.growth_factor + - self.delta_c + ) ** 2 res = minimize( model, @@ -479,8 +472,9 @@ def fsigma(self): @cached_quantity def dndm(self): - r"""The number density of haloes, ``len=len(m)`` [units :math:`h^4 M_\odot^{-1} - Mpc^{-3}`]. + r"""The number density of haloes, ``len=len(m)``. + + Units: :math:`h^4 M_\odot^{-1} Mpc^{-3}`]. """ # if self.z2 is None: # #This is normally the case dndm = self.fsigma * self.mean_density0 * np.abs(self._dlnsdlnm) / self.m**2 @@ -488,9 +482,7 @@ def dndm(self): ngtm_tinker = self._gtm(dndm) # THe Behroozi paper corrections assume masses in Msun, not Msun/h - dndm = self.hmf._modify_dndm( - self.m * self.cosmo.h, dndm, self.z, ngtm_tinker - ) + dndm = self.hmf._modify_dndm(self.m * self.cosmo.h, dndm, self.z, ngtm_tinker) # Alter the mass definition if ( @@ -510,15 +502,17 @@ def dndm(self): @cached_quantity def dndlnm(self): - r"""The differential mass function in terms of natural log of `m`, ``len=len(m)`` - [units :math:`h^3 Mpc^{-3}`]. + r"""The differential mass function in terms of natural log of `m`, ``len=len(m)``. + + Units: :math:`h^3 Mpc^{-3}` """ return self.m * self.dndm @cached_quantity def dndlog10m(self): - r"""The differential mass function in terms of log of `m`, ``len=len(m)`` - [units :math:`h^3 Mpc^{-3}`]. + r"""The differential mass function in terms of log of `m`, ``len=len(m)``. + + Units: :math:`h^3 Mpc^{-3}` """ return self.m * self.dndm * np.log(10) @@ -544,14 +538,14 @@ def _gtm(self, dndm, mass_density=False): # If the highest mass is very low, we try calculating it to higher masses # The dlog10m is NOT CHANGED, so the input needs to be finely spaced. # If the top value of dndm is NaN, don't try calculating higher masses. - if m[-1] < 10**16.5 and not np.isnan(dndm[-1]) and dndm[-1] != 0: - # ff.Behroozi function won't work here. - if not isinstance(self.hmf, ff.Behroozi): - new_mf = copy.deepcopy(self) - new_mf.update(Mmin=np.log10(self.m[-1]) + self.dlog10m, Mmax=18) - dndm = np.concatenate((dndm, new_mf.dndm)) + if (m[-1] < 10**16.5 and not np.isnan(dndm[-1]) and dndm[-1] != 0) and not isinstance( + self.hmf, ff.Behroozi + ): + new_mf = copy.deepcopy(self) + new_mf.update(Mmin=np.log10(self.m[-1]) + self.dlog10m, Mmax=18) + dndm = np.concatenate((dndm, new_mf.dndm)) - m = np.concatenate((m, new_mf.m)) + m = np.concatenate((m, new_mf.m)) ngtm = int_gtm(m[dndm > 0], dndm[dndm > 0], mass_density) @@ -559,7 +553,6 @@ def _gtm(self, dndm, mass_density=False): # they were originally if len(ngtm) < len(m): # Will happen if some dndlnm are NaN ngtm_temp = np.zeros(len(dndm)) - # ngtm_temp[:] = np.nan ngtm_temp[dndm > 0] = ngtm ngtm = ngtm_temp diff --git a/src/hmf/mass_function/integrate_hmf.py b/src/hmf/mass_function/integrate_hmf.py index 8994ee5c..e8bd305f 100644 --- a/src/hmf/mass_function/integrate_hmf.py +++ b/src/hmf/mass_function/integrate_hmf.py @@ -1,17 +1,14 @@ -"""A supporting module that provides a routine to integrate the differential hmf in a robust -manner. -""" +"""A supporting module with a routine to integrate the differential hmf in a robust manner.""" import numpy as np import scipy.integrate as intg from scipy.interpolate import InterpolatedUnivariateSpline as Spline -class NaNException(Exception): +class NaNError(Exception): """Integrator hit a NaN.""" - def hmf_integral_gtm(m, dndm, mass_density=False): """ Cumulatively integrate dn/dm. @@ -60,7 +57,7 @@ def hmf_integral_gtm(m, dndm, mass_density=False): dndlnm = m * dndm if len(m) < 4: - raise NaNException( + raise NaNError( f"There are too few real numbers in dndm: len(dndm) = {n}, #NaN's = {n - len(m)}" ) @@ -88,9 +85,9 @@ def hmf_integral_gtm(m, dndm, mass_density=False): else: ngtm = np.concatenate( ( - intg.cumulative_trapezoid( - m[::-1] * dndlnm[::-1], dx=np.log(m[1]) - np.log(m[0]) - )[::-1], + intg.cumulative_trapezoid(m[::-1] * dndlnm[::-1], dx=np.log(m[1]) - np.log(m[0]))[ + ::-1 + ], np.zeros(1), ) ) diff --git a/tests/test_cli.py b/tests/test_cli.py index 72406b15..bb76fa9b 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -37,9 +37,7 @@ def test_with_config(tmpdir: Path): with (tmpdir / "cfg.toml").open("w") as fl: fl.write(cfg) - result = runner.invoke( - main, ["run", "-i", str(tmpdir / "cfg.toml"), "-o", str(tmpdir)] - ) + result = runner.invoke(main, ["run", "-i", str(tmpdir / "cfg.toml"), "-o", str(tmpdir)]) print(result.stdout) assert result.exit_code == 0 @@ -65,9 +63,7 @@ def test_config_vs_cli(tmpdir: Path): with (tmpdir / "cfg.toml").open("w") as fl: fl.write(cfg) - result_cfg = runner.invoke( - main, ["run", "-i", str(tmpdir / "cfg.toml"), "-o", str(cfgdir)] - ) + result_cfg = runner.invoke(main, ["run", "-i", str(tmpdir / "cfg.toml"), "-o", str(cfgdir)]) result_cli = runner.invoke( main, ["run", "-o", str(clidir), "--", "--z=1.0", '--transfer_model="EH"'] ) @@ -109,18 +105,14 @@ def test_roundtrip_cfg(tmpdir): with (tmpdir / "cfg.toml").open("w") as fl: fl.write(cfg) - result = runner.invoke( - main, ["run", "-i", str(tmpdir / "cfg.toml"), "-o", str(tmpdir)] - ) + result = runner.invoke(main, ["run", "-i", str(tmpdir / "cfg.toml"), "-o", str(tmpdir)]) assert result.exit_code == 0 clidir = tmpdir / "cli" clidir.mkdir() - result2 = runner.invoke( - main, ["run", "-i", str(tmpdir / "hmf_cfg.toml"), "-o", str(clidir)] - ) + result2 = runner.invoke(main, ["run", "-i", str(tmpdir / "hmf_cfg.toml"), "-o", str(clidir)]) assert result2.exit_code == 0 diff --git a/tests/test_fcoll.py b/tests/test_fcoll.py index fcfeb9ca..45a6c45d 100644 --- a/tests/test_fcoll.py +++ b/tests/test_fcoll.py @@ -1,5 +1,5 @@ """ -This module provides some tests of mgtm/mean_density0 against analytic f_coll. +Provides some tests of mgtm/mean_density0 against analytic f_coll. As such, it is the best test of all calculations after sigma. """ diff --git a/tests/test_filters.py b/tests/test_filters.py index 7770adfd..8b9cbde0 100644 --- a/tests/test_filters.py +++ b/tests/test_filters.py @@ -1,4 +1,9 @@ -"""Analytic functions for this test are defined in "analytic_filter.ipynb" in the development/ directory.""" +""" +Tests of the filters module. + +Analytic functions for this test are defined in "analytic_filter.ipynb" +in the development/ directory. +""" import warnings @@ -135,9 +140,9 @@ def test_sigma_Rhalf(self, cls): t = 2 + 2 + 1 true = 1.0 / (2 * pi**2 * t * thisr**t) - with pytest.warns(UserWarning): - # should also raise a warning - R = 0.5 + # should also raise a warning + R = 0.5 + with pytest.warns(UserWarning, match=""): s2 = cls.sigma(R)[0] ** 2 assert np.isclose(s2, true) @@ -147,9 +152,9 @@ def test_sigma1_Rhalf(self, cls): t = 4 + 2 + 1 true = 1.0 / (2 * pi**2 * t * thisr**t) - with pytest.warns(UserWarning): - # should also raise a warning - R = 0.5 + # should also raise a warning + R = 0.5 + with pytest.warns(UserWarning, match=""): s2 = cls.sigma(R, 1)[0] ** 2 assert np.isclose(s2, true) diff --git a/tests/test_fits.py b/tests/test_fits.py index 96f4e408..7ef7635f 100644 --- a/tests/test_fits.py +++ b/tests/test_fits.py @@ -3,7 +3,6 @@ import numpy as np import pytest -from pytest import raises from hmf import MassFunction from hmf.mass_function import fitting_functions as ff @@ -96,23 +95,19 @@ def test_tinker10_dh(): def test_tinker10_neg_gam(): - with raises(ValueError): - h = MassFunction( - hmf_model="Tinker10", hmf_params={"gamma_200": -1}, transfer_model="EH" - ) + with pytest.raises(ValueError): + h = MassFunction(hmf_model="Tinker10", hmf_params={"gamma_200": -1}, transfer_model="EH") h.fsigma def test_tinker10_neg_eta(): - with raises(ValueError): - h = MassFunction( - hmf_model="Tinker10", hmf_params={"eta_200": -1}, transfer_model="EH" - ) + with pytest.raises(ValueError): + h = MassFunction(hmf_model="Tinker10", hmf_params={"eta_200": -1}, transfer_model="EH") h.fsigma def test_tinker10_neg_etaphi(): - with raises(ValueError): + with pytest.raises(ValueError): h = MassFunction( hmf_model="Tinker10", hmf_params={"eta_200": -1, "phi_200": 0}, @@ -122,8 +117,6 @@ def test_tinker10_neg_etaphi(): def test_tinker10_neg_beta(): - with raises(ValueError): - h = MassFunction( - hmf_model="Tinker10", hmf_params={"beta_200": -1}, transfer_model="EH" - ) + with pytest.raises(ValueError): + h = MassFunction(hmf_model="Tinker10", hmf_params={"beta_200": -1}, transfer_model="EH") h.fsigma diff --git a/tests/test_framework.py b/tests/test_framework.py index c95b8aa9..d80ff69a 100644 --- a/tests/test_framework.py +++ b/tests/test_framework.py @@ -1,6 +1,5 @@ import pytest from deprecation import fail_if_not_removed -from pytest import raises import hmf from hmf import GrowthFactor, MassFunction @@ -10,12 +9,12 @@ def test_incorrect_argument(): - with raises(TypeError): + with pytest.raises(TypeError): hmf.MassFunction(wrong_arg=3) def test_incorrect_update_arg(): - with raises(ValueError): + with pytest.raises(ValueError): t = hmf.MassFunction(transfer_model="EH") t.update(wrong_arg=3) @@ -98,19 +97,17 @@ def test_growth_plugins(): def test_validate_inputs(): - with pytest.raises(AssertionError): + with pytest.raises(AssertionError, match=r"Mmin > Mmax: 10, 9"): MassFunction(Mmin=10, Mmax=9, transfer_model="EH") m = MassFunction(Mmin=10, Mmax=11, transfer_model="EH") - with pytest.raises(AssertionError): + with pytest.raises(AssertionError, match="Mmin > Mmax: 10, 9"): m.update(Mmax=9) # Without checking on, we can still manually set it, but it will warn us - with pytest.warns(DeprecationWarning): - m.Mmax = 9 + with pytest.warns(UserWarning, match="You are setting Mmin directly."): m.Mmin = 8 - # But with checking on, we can't - m._validate_every_param_set = True - with pytest.raises(AssertionError): + # Ensure that validation still runs. + with pytest.raises(AssertionError, match="Mmin > Mmax: 8, 7"): m.Mmax = 7 diff --git a/tests/test_genmf.py b/tests/test_genmf.py index 1039fcee..993894b9 100644 --- a/tests/test_genmf.py +++ b/tests/test_genmf.py @@ -1,5 +1,5 @@ """ -This module contains a number of tests that check hmf's results against those of genmf. +A module containing a number of tests that check hmf's results against those of genmf. We check results for sigma, lnsigma, and the differential and cumulative mass functions against genmf for two different redshifts (0 and 2). We use precisely the same transfer function here @@ -52,9 +52,7 @@ def rms_diff(vec1, vec2, tol): - mask = np.logical_and( - np.logical_not(np.isnan(vec1)), np.logical_not(np.isnan(vec2)) - ) + mask = np.logical_and(np.logical_not(np.isnan(vec1)), np.logical_not(np.isnan(vec2))) vec1 = vec1[mask] vec2 = vec2[mask] err = np.sqrt(np.mean(((vec1 - vec2) / vec2) ** 2)) @@ -63,9 +61,7 @@ def rms_diff(vec1, vec2, tol): def max_diff_rel(vec1, vec2, tol): - mask = np.logical_and( - np.logical_not(np.isnan(vec1)), np.logical_not(np.isnan(vec2)) - ) + mask = np.logical_and(np.logical_not(np.isnan(vec1)), np.logical_not(np.isnan(vec2))) vec1 = vec1[mask] vec2 = vec2[mask] err = np.max(np.abs((vec1 - vec2) / vec2)) @@ -74,9 +70,7 @@ def max_diff_rel(vec1, vec2, tol): def max_diff(vec1, vec2, tol): - mask = np.logical_and( - np.logical_not(np.isnan(vec1)), np.logical_not(np.isnan(vec2)) - ) + mask = np.logical_and(np.logical_not(np.isnan(vec1)), np.logical_not(np.isnan(vec2))) vec1 = vec1[mask] vec2 = vec2[mask] err = np.max(np.abs(vec1 - vec2)) @@ -110,9 +104,7 @@ def hmf(self): @staticmethod def check_col(pert, fit, redshift, col): """Able to check all columns.""" - data = np.genfromtxt("tests/data/" + fit + "_" + str(int(redshift)))[::-1][ - 400:1201 - ] + data = np.genfromtxt("tests/data/" + fit + "_" + str(int(redshift)))[::-1][400:1201] # We have to do funky stuff to the data if its been cut by genmf if col == "sigma": diff --git a/tests/test_growth.py b/tests/test_growth.py index b1f6fe3a..5e72a34c 100644 --- a/tests/test_growth.py +++ b/tests/test_growth.py @@ -37,9 +37,7 @@ def test_gfunc(gf, genf): genf_func = genf.growth_factor_fn(0.0) print(gf_func(np.linspace(0, 5, 10)), genf_func(np.linspace(0, 5, 10))) - assert np.allclose( - gf_func(np.linspace(0, 5, 10)), genf_func(np.linspace(0, 5, 10)), rtol=1e-2 - ) + assert np.allclose(gf_func(np.linspace(0, 5, 10)), genf_func(np.linspace(0, 5, 10)), rtol=1e-2) def test_gr_func(gf, genf): @@ -47,9 +45,7 @@ def test_gr_func(gf, genf): genf_func = genf.growth_rate_fn(0.0) print(gr_func(np.linspace(0, 5, 10)), genf_func(np.linspace(0, 5, 10))) - assert np.allclose( - gr_func(np.linspace(0, 5, 10)), genf_func(np.linspace(0, 5, 10)), rtol=1e-2 - ) + assert np.allclose(gr_func(np.linspace(0, 5, 10)), genf_func(np.linspace(0, 5, 10)), rtol=1e-2) def test_inverse(gf, genf): @@ -63,7 +59,7 @@ def test_inverse(gf, genf): def test_unsupported_cosmo(): cosmo = w0waCDM(H0=70.0, Om0=0.3, Ode0=0.7, w0=-0.9, Ob0=0.05, Tcmb0=2.7) - with pytest.raises(ValueError): + with pytest.raises(ValueError, match="not supported by GenMFGrowth"): growth_factor.GenMFGrowth(cosmo=cosmo) # But shouldn't raise error for CAMBGrowth @@ -88,9 +84,7 @@ def test_pickleability_of_cambgrowth(): def test_from_file(datadir): cosmo = w0waCDM(H0=70.0, Om0=0.3, Ode0=0.7, w0=-0.9, Ob0=0.05, Tcmb0=2.7) - gf = growth_factor.FromFile( - cosmo=cosmo, fname=f"{datadir}/growth_for_hmf_tests.dat" - ) + gf = growth_factor.FromFile(cosmo=cosmo, fname=f"{datadir}/growth_for_hmf_tests.dat") data_in = np.genfromtxt(f"{datadir}/growth_for_hmf_tests.dat")[:, [0, 1]] z = data_in[:, 0] d = data_in[:, 1] diff --git a/tests/test_halofit.py b/tests/test_halofit.py index a4c8a8f8..8ffc192e 100644 --- a/tests/test_halofit.py +++ b/tests/test_halofit.py @@ -9,9 +9,7 @@ def test_takahashi(): assert np.isclose(t.nonlinear_power[0], tt.nonlinear_power[0], rtol=1e-4) print(t.nonlinear_power[-1] / tt.nonlinear_power[-1]) - assert np.logical_not( - np.isclose(t.nonlinear_power[-1] / tt.nonlinear_power[-1], 1, rtol=0.4) - ) + assert np.logical_not(np.isclose(t.nonlinear_power[-1] / tt.nonlinear_power[-1], 1, rtol=0.4)) def test_takahashi_hiz(): @@ -21,15 +19,11 @@ def test_takahashi_hiz(): assert np.isclose(t.nonlinear_power[0], tt.nonlinear_power[0], rtol=1e-4) print(t.nonlinear_power[-1] / tt.nonlinear_power[-1]) - assert np.logical_not( - np.isclose(t.nonlinear_power[-1] / tt.nonlinear_power[-1], 1, rtol=0.4) - ) + assert np.logical_not(np.isclose(t.nonlinear_power[-1] / tt.nonlinear_power[-1], 1, rtol=0.4)) t.update(z=0) - assert np.logical_not( - np.isclose(t.nonlinear_power[0] / tt.nonlinear_power[0], 0.9, rtol=0.1) - ) + assert np.logical_not(np.isclose(t.nonlinear_power[0] / tt.nonlinear_power[0], 0.9, rtol=0.1)) assert np.logical_not( np.isclose(t.nonlinear_power[-1] / tt.nonlinear_power[-1], 0.99, rtol=0.1) ) @@ -37,9 +31,7 @@ def test_takahashi_hiz(): def test_halofit_high_s8(): t = transfer.Transfer(transfer_model="EH", lnk_max=7, sigma_8=0.999) - thi = transfer.Transfer( - transfer_model="EH", lnk_max=7, sigma_8=1.001 - ) # just above threshold + thi = transfer.Transfer(transfer_model="EH", lnk_max=7, sigma_8=1.001) # just above threshold print( t.nonlinear_power[0] / thi.nonlinear_power[0] - 1, diff --git a/tests/test_hmf.py b/tests/test_hmf.py index 8be18a0e..464ddf86 100644 --- a/tests/test_hmf.py +++ b/tests/test_hmf.py @@ -2,38 +2,37 @@ import numpy as np import pytest -from pytest import raises from hmf import MassFunction def test_wrong_filter(): - with raises(ValueError): + with pytest.raises(ValueError, match=r"2 must be str or Component subclass"): MassFunction(filter_model=2) def test_string_dc(): - with raises(ValueError): + with pytest.raises(ValueError, match=r"delta_c must be a number"): MassFunction(delta_c="this") def test_neg_dc(): - with raises(ValueError): + with pytest.raises(ValueError, match=r"delta_c must be > 0"): MassFunction(delta_c=-1) def test_big_dc(): - with raises(ValueError): + with pytest.raises(ValueError, match=r"delta_c must be < 10.0"): MassFunction(delta_c=20.0) def test_wrong_fit(): - with raises(ValueError): + with pytest.raises(ValueError, match=r"must be str or Component subclass"): MassFunction(hmf_model=1) def test_wrong_mf_par(): - with raises(ValueError): + with pytest.raises(ValueError, match=r"hmf_params must be a dictionary"): MassFunction(hmf_params=2) @@ -46,7 +45,7 @@ def test_str_filter(): def test_mass_nonlinear_outside_range(): h = MassFunction(Mmin=8, Mmax=9, transfer_model="EH") - with pytest.warns(UserWarning): + with pytest.warns(UserWarning, match="Nonlinear mass outside mass range"): assert h.mass_nonlinear > 0 @@ -62,6 +61,4 @@ def test_sigma8z(): def test_neff_at_collapse(): h = MassFunction(Mmin=8, Mmax=18, transfer_model="EH") - assert np.allclose( - h.n_eff_at_collapse, h.n_eff[np.argmin(np.abs(h.nu - 1.0))], rtol=0.05 - ) + assert np.allclose(h.n_eff_at_collapse, h.n_eff[np.argmin(np.abs(h.nu - 1.0))], rtol=0.05) diff --git a/tests/test_integrate_hmf.py b/tests/test_integrate_hmf.py index 5274dbd5..aed980d3 100644 --- a/tests/test_integrate_hmf.py +++ b/tests/test_integrate_hmf.py @@ -28,22 +28,6 @@ def anl_int(self, m, loghs, alpha, beta): def anl_m_int(self, m, loghs, alpha, beta): return 10 ** (2 * loghs) * gammainc((alpha + 2) / beta, (m / 10**loghs) ** beta) - # def test_basic(self): - # m = np.logspace(10,18,500) - # dndm = self.tggd(m,14.0,-1.9,0.8) - # ngtm = self.anl_int(m,14.0,-1.9,0.8) - # - # print ngtm/hmf_integral_gtm(m,dndm) - # assert np.allclose(ngtm,hmf_integral_gtm(m,dndm),rtol=0.03) - # - # def test_basic_mgtm(self): - # m = np.logspace(10,18,500) - # dndm = self.tggd(m,14.0,-1.9,0.8) - # ngtm = self.anl_m_int(m,14.0,-1.9,0.8) - # - # print ngtm/hmf_integral_gtm(m,dndm,True) - # assert np.allclose(ngtm,hmf_integral_gtm(m,dndm,True),rtol=0.03) - def test_high_z(self): m = np.logspace(10, 18, 500) dndm = self.tggd(m, 9.0, -1.93, 0.4) @@ -53,14 +37,6 @@ def test_high_z(self): ngtm[mask], hmf_integral_gtm(m, dndm)[mask], rtol=0.03, atol=1e-8 ) - # def test_low_mmax_z0(self): - # m = np.logspace(10,15,500) - # dndm = self.tggd(m,14.0,-1.9,0.8) - # ngtm = self.anl_int(m,14.0,-1.9,0.8) - # - # print ngtm/hmf_integral_gtm(m,dndm) - # assert np.allclose(ngtm,hmf_integral_gtm(m,dndm),rtol=0.03) - def test_low_mmax_high_z(self): m = np.logspace(10, 15, 500) dndm = self.tggd(m, 9.0, -1.93, 0.4) diff --git a/tests/test_mdef.py b/tests/test_mdef.py index 698489fb..a938c9ee 100644 --- a/tests/test_mdef.py +++ b/tests/test_mdef.py @@ -89,15 +89,16 @@ def test_from_colossus_name(colossus_cosmo): assert md.from_colossus_name("800c") == md.SOCritical(overdensity=800) assert md.from_colossus_name("vir") == md.SOVirial() - with pytest.raises(ValueError): + with pytest.raises(ValueError, match=r"name 'derp' is an unknown mass definition to colossus"): md.from_colossus_name("derp") def test_change_dndm(colossus_cosmo): - with pytest.warns(UserWarning): - h = MassFunction( - mdef_model="SOVirial", hmf_model="Warren", disable_mass_conversion=False - ) + with pytest.warns( + UserWarning, + match=r"Your input mass definition 'SOVirial' does not match the mass definition", + ): + h = MassFunction(mdef_model="SOVirial", hmf_model="Warren", disable_mass_conversion=False) dndm = h.dndm diff --git a/tests/test_sample.py b/tests/test_sample.py index 6a218f1a..70ac24f2 100644 --- a/tests/test_sample.py +++ b/tests/test_sample.py @@ -1,5 +1,5 @@ import numpy as np -from scipy.interpolate import InterpolatedUnivariateSpline as spline +from scipy.interpolate import InterpolatedUnivariateSpline as Spline from hmf.helpers.sample import dndm_from_sample, sample_mf @@ -9,7 +9,7 @@ def test_circular(): m, h = sample_mf(1e5, 11, transfer_model="EH", rng=rng) centres, hist = dndm_from_sample(m, 1e5 / h.ngtm[0]) - s = spline(np.log10(h.m), np.log10(h.dndm)) + s = Spline(np.log10(h.m), np.log10(h.dndm)) print(hist, 10 ** s(centres)) assert np.allclose(hist, 10 ** s(centres), rtol=0.05) @@ -19,6 +19,4 @@ def test_mmax_big(): rng = np.random.default_rng(12345) m, h = sample_mf(1e5, 11, transfer_model="EH", Mmax=18, rng=rng) - # centres,hist = dndm_from_sample(m,1e5/h.ngtm[0]) - # print centres,hist dndm_from_sample(m, 1e5 / h.ngtm[0]) diff --git a/tests/test_transfer.py b/tests/test_transfer.py index e28ce3c3..5b73836f 100644 --- a/tests/test_transfer.py +++ b/tests/test_transfer.py @@ -18,30 +18,18 @@ def transfers(): def test_updates(transfers, name, val): t, t2 = transfers t.update(**{name: val}) - assert ( - np.mean(np.abs((t.power - t2.power) / t.power)) < 1 - ) - assert ( - np.mean(np.abs((t.power - t2.power) / t.power)) > 1e-6 - ) + assert np.mean(np.abs((t.power - t2.power) / t.power)) < 1 + assert np.mean(np.abs((t.power - t2.power) / t.power)) > 1e-6 def test_updates_from_file_array(datadir): tdata = np.genfromtxt(f"{datadir}/transfer_for_hmf_tests.dat") - t = Transfer( - transfer_model="FromArray", transfer_params={"k": tdata[:, 0], "T": tdata[:, 1]} - ) - t2 = Transfer( - transfer_model="FromArray", transfer_params={"k": tdata[:, 0], "T": tdata[:, 1]} - ) + t = Transfer(transfer_model="FromArray", transfer_params={"k": tdata[:, 0], "T": tdata[:, 1]}) + t2 = Transfer(transfer_model="FromArray", transfer_params={"k": tdata[:, 0], "T": tdata[:, 1]}) t2.update(transfer_params={"k": tdata[::2, 0], "T": tdata[::2, 1]}) # This test for both FromArray transfer model and caching of dictionaries - assert ( - np.mean(np.abs((t.power - t2.power) / t.power)) < 1 - ) - assert ( - np.mean(np.abs((t.power - t2.power) / t.power)) > 1e-6 - ) + assert np.mean(np.abs((t.power - t2.power) / t.power)) < 1 + assert np.mean(np.abs((t.power - t2.power) / t.power)) > 1e-6 def test_halofit(): @@ -96,9 +84,7 @@ def test_camb_extrapolation(): def test_camb_neutrinos(): # Correct parameter settings: - cosmo_model = FlatLambdaCDM( - Om0=0.3, H0=70.0, Ob0=0.05, m_nu=[0, 0, 0.06], Tcmb0=2.7255 - ) + cosmo_model = FlatLambdaCDM(Om0=0.3, H0=70.0, Ob0=0.05, m_nu=[0, 0, 0.06], Tcmb0=2.7255) t_nu = Transfer( cosmo_model=cosmo_model, @@ -142,13 +128,9 @@ def test_camb_neutrinos(): diff = np.abs((camb_t - hmf_t) / camb_t) camb_cosmo = camb.get_background(t_nu.transfer.params["camb_params"]) - sum_omega_astropy = ( - t_nu.cosmo_model.Odm0 + t_nu.cosmo_model.Ob0 + t_nu.cosmo_model.Onu0 - ) + sum_omega_astropy = t_nu.cosmo_model.Odm0 + t_nu.cosmo_model.Ob0 + t_nu.cosmo_model.Onu0 sum_omega_camb = ( - camb_cosmo.get_Omega("tot") - - camb_cosmo.get_Omega("photon") - - camb_cosmo.omega_de + camb_cosmo.get_Omega("tot") - camb_cosmo.get_Omega("photon") - camb_cosmo.omega_de ) assert diff <= 1e-3 @@ -170,9 +152,7 @@ def test_camb_w0wa(): """Essentially just test that CAMB doesn't fall over with a w0wa model.""" t = Transfer( transfer_model="CAMB", - cosmo_model=w0waCDM( - Om0=0.3, Ode0=0.7, w0=-1, wa=0.03, Ob0=0.05, H0=70.0, Tcmb0=2.7 - ), + cosmo_model=w0waCDM(Om0=0.3, Ode0=0.7, w0=-1, wa=0.03, Ob0=0.05, H0=70.0, Tcmb0=2.7), transfer_params={"extrapolate_with_eh": True}, ) assert t.transfer_function.shape == t.k.shape diff --git a/tests/test_wdm.py b/tests/test_wdm.py index 7a5c01c0..4b04259d 100644 --- a/tests/test_wdm.py +++ b/tests/test_wdm.py @@ -1,13 +1,13 @@ import numpy as np -from pytest import raises +import pytest import hmf from hmf.alternatives import wdm def test_null(): - with raises(NotImplementedError): - w = wdm.WDM(mx=1.0) + w = wdm.WDM(mx=1.0) + with pytest.raises(NotImplementedError): w.transfer(1.0) @@ -68,16 +68,14 @@ def setup_class(self): class TestTransfer: def setup_class(self): - self.wdm = wdm.TransferWDM( - wdm_mass=3.0, wdm_model=wdm.Viel05, transfer_model="EH" - ) + self.wdm = wdm.TransferWDM(wdm_mass=3.0, wdm_model=wdm.Viel05, transfer_model="EH") self.cdm = hmf.MassFunction(transfer_model="EH") def test_wdm_model(self): assert isinstance(self.wdm.wdm, wdm.Viel05) def test_wrong_model_type(self): - with raises(ValueError): + with pytest.raises(ValueError, match="must be str or Component subclass"): wdm.TransferWDM(wdm_mass=3.0, wdm_model=3, transfer_model="EH") def test_power(self): From ce0674725a45d91e243a757a1dba50cd80fd08c9 Mon Sep 17 00:00:00 2001 From: Steven Murray Date: Sun, 22 Feb 2026 16:54:36 +0200 Subject: [PATCH 11/18] style: run pre-commit --- .pre-commit-config.yaml | 13 +++++++++++++ pyproject.toml | 8 ++++---- ruff_failures.txt | 4 ++-- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 674a88f6..37538693 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -22,3 +22,16 @@ repos: rev: v1.10.0 hooks: - id: rst-backticks + + + +- repo: https://github.com/astral-sh/ruff-pre-commit + # Ruff version. + rev: v0.14.14 + hooks: + # Run the linter. + - id: ruff + args: [--fix] + + # Run the formatter. + - id: ruff-format diff --git a/pyproject.toml b/pyproject.toml index fba6a78d..ff719fa4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -47,17 +47,17 @@ docs = [ "numpydoc>=0.8.0", "nbsphinx" ] - + tests = [ "coverage>=4.5.1", "pytest>=3.5.1", - "pytest-cov>=2.5.1", + "pytest-cov>=2.5.1", "mpmath>=1.0.0", "colossus>=1.2.1", "halomod>=1.4.6", "numba", ] - + dev = [ "hmf[docs,tests]", "ruff", @@ -183,4 +183,4 @@ property-decorators = [ ] [tool.ruff.lint.mccabe] -max-complexity = 21 \ No newline at end of file +max-complexity = 21 diff --git a/ruff_failures.txt b/ruff_failures.txt index 092879d2..983e2df9 100644 --- a/ruff_failures.txt +++ b/ruff_failures.txt @@ -276,7 +276,7 @@ W291 Trailing whitespace --> docs/examples/your_first_plot.ipynb:cell 3:6:19 | 5 | # This just serves to render plots inline in the notebook. Do not use in a script. -6 | %matplotlib inline +6 | %matplotlib inline | ^^^^^^^^^^^^^^^ | help: Remove trailing whitespace @@ -309,7 +309,7 @@ W293 Blank line contains whitespace | 4 | mf.update(z=z) 5 | plt.plot(mf.m,mf.dndm,color="darkblue",alpha=1-z) -6 | +6 | | ^^^^ 7 | plt.xscale('log') 8 | plt.yscale('log') From 65811ee622ea531a5c8f75a5fc3266b2e253477f Mon Sep 17 00:00:00 2001 From: Steven Murray Date: Sun, 22 Feb 2026 17:03:07 +0200 Subject: [PATCH 12/18] ci: update which python versions are supported --- .github/workflows/test_suite.yaml | 7 +- .github/workflows/warnings-tests.yaml | 4 +- ruff_failures.txt | 6924 -------------------- src/hmf/_internals/_framework.py | 4 +- src/hmf/alternatives/wdm.py | 10 +- src/hmf/cosmology/growth_factor.py | 12 +- src/hmf/density_field/filters.py | 6 +- src/hmf/density_field/transfer_models.py | 14 +- src/hmf/halos/mass_definitions.py | 8 +- src/hmf/mass_function/fitting_functions.py | 54 +- 10 files changed, 59 insertions(+), 6984 deletions(-) delete mode 100644 ruff_failures.txt diff --git a/.github/workflows/test_suite.yaml b/.github/workflows/test_suite.yaml index 06c449c5..edcecbfa 100644 --- a/.github/workflows/test_suite.yaml +++ b/.github/workflows/test_suite.yaml @@ -11,7 +11,6 @@ on: jobs: tests: - if: "!contains(github.event.pull_request.labels.*.name, 'auto-pr')" env: ENV_NAME: tests PYTHON: ${{ matrix.python-version }} @@ -23,7 +22,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest, macos-latest] - python-version: [3.9, "3.10", "3.11", "3.12"] + python-version: ["3.11", "3.12", "3.13", "3.14"] steps: - uses: actions/checkout@master with: @@ -40,9 +39,9 @@ jobs: run: pip install .[dev] - name: Run Tests run: | - python -m pytest --cov=hmf --cov-config=.coveragerc --cov-report xml:./coverage.xml --durations=25 + python -m pytest --cov-report xml:./coverage.xml --durations=25 - uses: codecov/codecov-action@v5 - if: matrix.os == 'ubuntu-latest' && success() && !contains(github.event.pull_request.labels.*.name, 'auto-pr') + if: matrix.os == 'ubuntu-latest' && success() with: files: ./coverage.xml # optional fail_ci_if_error: true diff --git a/.github/workflows/warnings-tests.yaml b/.github/workflows/warnings-tests.yaml index d94fd1d7..2ed26354 100644 --- a/.github/workflows/warnings-tests.yaml +++ b/.github/workflows/warnings-tests.yaml @@ -22,7 +22,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest] - python-version: ["3.12"] + python-version: ["3.14"] steps: - uses: actions/checkout@master with: @@ -39,7 +39,7 @@ jobs: run: pip install .[dev] - name: Run Tests run: | - python -m pytest -Werror --cov=hmf --cov-config=.coveragerc --cov-report xml:./coverage.xml --durations=25 + python -m pytest -Werror --cov-report xml:./coverage.xml --durations=25 - uses: codecov/codecov-action@v5 if: matrix.os == 'ubuntu-latest' && success() with: diff --git a/ruff_failures.txt b/ruff_failures.txt deleted file mode 100644 index 983e2df9..00000000 --- a/ruff_failures.txt +++ /dev/null @@ -1,6924 +0,0 @@ -PTH123 `open()` should be replaced by `Path.open()` - --> changethelog.py:10:10 - | - 8 | newversion = sys.argv[1] - 9 | -10 | with open("CHANGELOG.rst") as fl: - | ^^^^ -11 | lines = fl.readlines() - | -help: Replace with `Path.open()` - -DTZ005 `datetime.datetime.now()` called without a `tz` argument - --> changethelog.py:20:44 - | -19 | lines.insert(_i + 2, "----------------------\n") -20 | lines.insert(_i + 2, f"v{newversion} [{datetime.now().strftime('%d %b %Y')}]\n") - | ^^^^^^^^^^^^^^ -21 | lines.insert(_i + 2, "\n") - | -help: Pass a `datetime.timezone` object to the `tz` parameter - -PTH123 `open()` should be replaced by `Path.open()` - --> changethelog.py:23:10 - | -21 | lines.insert(_i + 2, "\n") -22 | -23 | with open("CHANGELOG.rst", "w") as fl: - | ^^^^ -24 | fl.writelines(lines) - | -help: Replace with `Path.open()` - -invalid-syntax: Simple statements must be separated by newlines or semicolons - --> development/analytic_filter.ipynb:cell 4:7:11 - | -5 | integ = integ.subs(x,k*R) -6 | res = integrate(integ,(k,kmin,kmax)) -7 | print res - | ^^^ -8 | return res - | - -invalid-syntax: Simple statements must be separated by newlines or semicolons - --> development/analytic_filter.ipynb:cell 4:19:11 - | -17 | s = sigma(W,0,p,kmin,kmax) -18 | res = integrate(integ,(k,kmin,kmax))/(pi**2*s) -19 | print res - | ^^^ -20 | return res - | - -E501 Line too long (150 > 88) - --> development/halofit_testing.ipynb:cell 9:95:89 - | -93 | …kahashi=True -94 | … -95 | …, sigma_8, zbin, cosmo=my_cosmo, takahashi=True) #Generate (?) non-linear no-wiggles with halofit - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - -D100 Missing docstring in public module ---> docs/conf.py:1:1 - -PTH100 `os.path.abspath()` should be replaced by `Path.resolve()` - --> docs/conf.py:22:20 - | -20 | # add these directories to sys.path here. If the directory is relative to the -21 | # documentation root, use os.path.abspath to make it absolute, like shown here. -22 | sys.path.insert(0, os.path.abspath("../")) - | ^^^^^^^^^^^^^^^ -23 | -24 | # -- General configuration ----------------------------------------------------- - | -help: Replace with `Path(...).resolve()` - -E501 Line too long (112 > 88) - --> docs/examples/broad_overview.ipynb:cell 5:2:89 - | -1 | from hmf import ( -2 | density_field, # Defines power spectra and transfer functions, as well as window functions/filters on those - | ^^^^^^^^^^^^^^^^^^^^^^^^ -3 | ) - | - -NPY002 Replace legacy `np.random.uniform` call with `np.random.Generator` - --> docs/examples/broad_overview.ipynb:cell 28:1:13 - | -1 | redshifts = np.random.uniform(0, 3, size=20) - | ^^^^^^^^^^^^^^^^^ - | - -invalid-syntax: Simple statements must be separated by newlines or semicolons - --> docs/examples/deal_with_cosmology.ipynb:cell 8:1:7 - | -1 | print "Matter density: ", my_cosmo.cosmo.Om0 - | ^^^^^^^^^^^^^^^^^^ -2 | print "Hubble constant: ", my_cosmo.cosmo.H0 -3 | print "Dark Energy density: ", my_cosmo.cosmo.Ode0 - | - -invalid-syntax: Simple statements must be separated by newlines or semicolons - --> docs/examples/deal_with_cosmology.ipynb:cell 8:2:7 - | -1 | print "Matter density: ", my_cosmo.cosmo.Om0 -2 | print "Hubble constant: ", my_cosmo.cosmo.H0 - | ^^^^^^^^^^^^^^^^^^^ -3 | print "Dark Energy density: ", my_cosmo.cosmo.Ode0 -4 | print "Baryon density: ", my_cosmo.cosmo.Ob0 - | - -invalid-syntax: Simple statements must be separated by newlines or semicolons - --> docs/examples/deal_with_cosmology.ipynb:cell 8:3:7 - | -1 | print "Matter density: ", my_cosmo.cosmo.Om0 -2 | print "Hubble constant: ", my_cosmo.cosmo.H0 -3 | print "Dark Energy density: ", my_cosmo.cosmo.Ode0 - | ^^^^^^^^^^^^^^^^^^^^^^^ -4 | print "Baryon density: ", my_cosmo.cosmo.Ob0 -5 | print "Curvature density: ", my_cosmo.cosmo.Ok0 - | - -invalid-syntax: Simple statements must be separated by newlines or semicolons - --> docs/examples/deal_with_cosmology.ipynb:cell 8:4:7 - | -2 | print "Hubble constant: ", my_cosmo.cosmo.H0 -3 | print "Dark Energy density: ", my_cosmo.cosmo.Ode0 -4 | print "Baryon density: ", my_cosmo.cosmo.Ob0 - | ^^^^^^^^^^^^^^^^^^ -5 | print "Curvature density: ", my_cosmo.cosmo.Ok0 - | - -invalid-syntax: Simple statements must be separated by newlines or semicolons - --> docs/examples/deal_with_cosmology.ipynb:cell 8:5:7 - | -3 | print "Dark Energy density: ", my_cosmo.cosmo.Ode0 -4 | print "Baryon density: ", my_cosmo.cosmo.Ob0 -5 | print "Curvature density: ", my_cosmo.cosmo.Ok0 - | ^^^^^^^^^^^^^^^^^^^^^ - | - -invalid-syntax: Simple statements must be separated by newlines or semicolons - --> docs/examples/deal_with_cosmology.ipynb:cell 13:3:7 - | -1 | my_cosmo = cosmo.Cosmology(cosmo_model=cosmo.WMAP5) -2 | -3 | print "WMAP5 baryon density: ", my_cosmo.cosmo.Ob0 - | ^^^^^^^^^^^^^^^^^^^^^^^^ - | - -invalid-syntax: Simple statements must be separated by newlines or semicolons - --> docs/examples/deal_with_cosmology.ipynb:cell 17:2:7 - | -1 | my_cosmo = cosmo.Cosmology(cosmo_model = new_model) -2 | print "Crazy cosmology baryon density: ", my_cosmo.cosmo.Ob0 - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - -invalid-syntax: Simple statements must be separated by newlines or semicolons - --> docs/examples/deal_with_cosmology.ipynb:cell 19:5:7 - | -4 | my_cosmo = cosmo.Cosmology(cosmo_model = new_model) -5 | print "Crazy cosmology curvature density: ", my_cosmo.cosmo.Ok0 - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - -invalid-syntax: Simple statements must be separated by newlines or semicolons - --> docs/examples/deal_with_cosmology.ipynb:cell 22:2:7 - | -1 | my_cosmo = cosmo.Cosmology(cosmo_params={"Om0":0.2}) -2 | print "Custom cosmology matter density: ", my_cosmo.cosmo.Om0 - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - -invalid-syntax: Simple statements must be separated by newlines or semicolons - --> docs/examples/deal_with_cosmology.ipynb:cell 24:2:7 - | -1 | my_cosmo = cosmo.Cosmology(new_model,{"Om0":0.2,"Ode0":0.0,"Ob0":0.2}) -2 | print "Custom cosmology curvature density: ", my_cosmo.cosmo.Ok0 - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - -invalid-syntax: Simple statements must be separated by newlines or semicolons - --> docs/examples/deal_with_cosmology.ipynb:cell 27:3:7 - | -1 | my_cosmo = cosmo.Cosmology(new_model) -2 | my_cosmo.update(cosmo_params={"Om0":0.2,"Ode0":0.0,"Ob0":0.2}) -3 | print "Custom cosmology curvature density: ", my_cosmo.cosmo.Ok0 - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - -invalid-syntax: Simple statements must be separated by newlines or semicolons - --> docs/examples/deal_with_cosmology.ipynb:cell 29:2:7 - | -1 | my_cosmo.update(cosmo_params={"H0":10.0}) -2 | print "Custom cosmology curvature density: ", my_cosmo.cosmo.Ok0 - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -3 | print "Custom parameters: ", my_cosmo.cosmo_params - | - -invalid-syntax: Simple statements must be separated by newlines or semicolons - --> docs/examples/deal_with_cosmology.ipynb:cell 29:3:7 - | -1 | my_cosmo.update(cosmo_params={"H0":10.0}) -2 | print "Custom cosmology curvature density: ", my_cosmo.cosmo.Ok0 -3 | print "Custom parameters: ", my_cosmo.cosmo_params - | ^^^^^^^^^^^^^^^^^^^^^ - | - -invalid-syntax: Simple statements must be separated by newlines or semicolons - --> docs/examples/deal_with_cosmology.ipynb:cell 31:2:7 - | -1 | my_cosmo.update(cosmo_model=cosmo.Planck13,cosmo_params={}) -2 | print "Flat cosmology curvature density: ", my_cosmo.cosmo.Ok0 - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - -A004 Import `display` is shadowing a Python builtin - --> docs/examples/fitting.ipynb:cell 3:6:39 - | -4 | import matplotlib.pyplot as plt -5 | import numpy as np -6 | from IPython.display import Markdown, display - | ^^^^^^^ -7 | from scipy.stats import poisson - | - -NPY002 Replace legacy `np.random.poisson` call with `np.random.Generator` - --> docs/examples/fitting.ipynb:cell 11:1:18 - | -1 | counts_per_bin = np.random.poisson(model.dndlog10m * volume * model.dlog10m) - | ^^^^^^^^^^^^^^^^^ - | - -NPY002 Replace legacy `np.random.normal` call with `np.random.Generator` - --> docs/examples/fitting.ipynb:cell 32:3:12 - | -1 | initialpos = np.array( -2 | [fiducial_model.sigma_8, fiducial_model.n] -3 | ) + 1e-4 * np.random.normal(size=(sampler.nwalkers, sampler.ndim)) - | ^^^^^^^^^^^^^^^^ - | - -NPY002 Replace legacy `np.random.poisson` call with `np.random.Generator` - --> docs/examples/fitting.ipynb:cell 45:3:18 - | -1 | volume = 500**3 # Mpc^3 / h^3 -2 | -3 | counts_per_bin = np.random.poisson( - | ^^^^^^^^^^^^^^^^^ -4 | fiducial_model.dndlog10m * volume * fiducial_model.dlog10m -5 | ) - | - -NPY002 Replace legacy `np.random.normal` call with `np.random.Generator` - --> docs/examples/fitting.ipynb:cell 49:3:12 - | -1 | init_pos = np.array( -2 | [smt_model.hmf.params["a"], smt_model.hmf.params["p"], smt_model.hmf.params["A"]] -3 | ) + 1e-4 * np.random.normal(size=(sampler_hmf.nwalkers, sampler_hmf.ndim)) - | ^^^^^^^^^^^^^^^^ - | - -RUF012 Mutable default value for class attribute - --> docs/examples/plugins_and_extending.ipynb:cell 25:2:17 - | -1 | class MyNewFitParameterized(FittingFunction): -2 | _defaults = {"a": 0.5} - | ^^^^^^^^^^ -3 | -4 | @property - | -help: Consider initializing in `__init__` or annotating with `typing.ClassVar` - -W291 Trailing whitespace - --> docs/examples/your_first_plot.ipynb:cell 3:6:19 - | -5 | # This just serves to render plots inline in the notebook. Do not use in a script. -6 | %matplotlib inline - | ^^^^^^^^^^^^^^^ - | -help: Remove trailing whitespace - -E501 Line too long (154 > 88) - --> docs/examples/your_first_plot.ipynb:cell 7:1:89 - | -1 | … #The parameter names passed filter the output. Call with no parameters to get info on all of them. - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - -invalid-syntax: Simple statements must be separated by newlines or semicolons - --> docs/examples/your_first_plot.ipynb:cell 11:1:7 - | -1 | print mf.quantities_available() - | ^^ - | - -E501 Line too long (135 > 88) - --> docs/examples/your_first_plot.ipynb:cell 19:1:89 - | -1 | mf = MassFunction(cosmo_model="WMAP5") # Note how to set all cosmological parameters (except sigma_8 and n) to a given common cosmology - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -2 | -3 | for z in np.linspace(0,1,100): - | - -W293 Blank line contains whitespace - --> docs/examples/your_first_plot.ipynb:cell 19:6:1 - | -4 | mf.update(z=z) -5 | plt.plot(mf.m,mf.dndm,color="darkblue",alpha=1-z) -6 | - | ^^^^ -7 | plt.xscale('log') -8 | plt.yscale('log') - | -help: Remove whitespace from blank line - -SIM105 Use `contextlib.suppress(PackageNotFoundError)` instead of `try`-`except`-`pass` - --> src/hmf/__init__.py:8:1 - | - 6 | from importlib_metadata import PackageNotFoundError, version - 7 | - 8 | / try: - 9 | | __version__ = version(__name__) -10 | | except PackageNotFoundError: -11 | | # package is not installed -12 | | pass - | |________^ -13 | -14 | from ._internals import ( - | -help: Replace `try`-`except`-`pass` with `with contextlib.suppress(PackageNotFoundError): ...` - -F401 `._internals.Component` imported but unused; consider removing, adding to `__all__`, or using a redundant alias - --> src/hmf/__init__.py:15:5 - | -14 | from ._internals import ( -15 | Component, - | ^^^^^^^^^ -16 | Framework, -17 | cached_quantity, - | -help: Use an explicit re-export: `Component as Component` - -F401 `._internals.Framework` imported but unused; consider removing, adding to `__all__`, or using a redundant alias - --> src/hmf/__init__.py:16:5 - | -14 | from ._internals import ( -15 | Component, -16 | Framework, - | ^^^^^^^^^ -17 | cached_quantity, -18 | get_base_component, - | -help: Use an explicit re-export: `Framework as Framework` - -F401 `._internals.cached_quantity` imported but unused; consider removing, adding to `__all__`, or using a redundant alias - --> src/hmf/__init__.py:17:5 - | -15 | Component, -16 | Framework, -17 | cached_quantity, - | ^^^^^^^^^^^^^^^ -18 | get_base_component, -19 | get_base_components, - | -help: Use an explicit re-export: `cached_quantity as cached_quantity` - -F401 `._internals.get_base_component` imported but unused; consider removing, adding to `__all__`, or using a redundant alias - --> src/hmf/__init__.py:18:5 - | -16 | Framework, -17 | cached_quantity, -18 | get_base_component, - | ^^^^^^^^^^^^^^^^^^ -19 | get_base_components, -20 | get_mdl, - | -help: Use an explicit re-export: `get_base_component as get_base_component` - -F401 `._internals.get_base_components` imported but unused; consider removing, adding to `__all__`, or using a redundant alias - --> src/hmf/__init__.py:19:5 - | -17 | cached_quantity, -18 | get_base_component, -19 | get_base_components, - | ^^^^^^^^^^^^^^^^^^^ -20 | get_mdl, -21 | parameter, - | -help: Use an explicit re-export: `get_base_components as get_base_components` - -F401 `._internals.get_mdl` imported but unused; consider removing, adding to `__all__`, or using a redundant alias - --> src/hmf/__init__.py:20:5 - | -18 | get_base_component, -19 | get_base_components, -20 | get_mdl, - | ^^^^^^^ -21 | parameter, -22 | ) - | -help: Use an explicit re-export: `get_mdl as get_mdl` - -F401 `._internals.parameter` imported but unused; consider removing, adding to `__all__`, or using a redundant alias - --> src/hmf/__init__.py:21:5 - | -19 | get_base_components, -20 | get_mdl, -21 | parameter, - | ^^^^^^^^^ -22 | ) -23 | from .alternatives import wdm - | -help: Use an explicit re-export: `parameter as parameter` - -F401 `.alternatives.wdm` imported but unused; consider removing, adding to `__all__`, or using a redundant alias - --> src/hmf/__init__.py:23:27 - | -21 | parameter, -22 | ) -23 | from .alternatives import wdm - | ^^^ -24 | from .cosmology import Cosmology, GrowthFactor, cosmo, growth_factor -25 | from .density_field import CAMB, Transfer, filters, halofit, transfer, transfer_models - | -help: Use an explicit re-export: `wdm as wdm` - -F401 `.cosmology.Cosmology` imported but unused; consider removing, adding to `__all__`, or using a redundant alias - --> src/hmf/__init__.py:24:24 - | -22 | ) -23 | from .alternatives import wdm -24 | from .cosmology import Cosmology, GrowthFactor, cosmo, growth_factor - | ^^^^^^^^^ -25 | from .density_field import CAMB, Transfer, filters, halofit, transfer, transfer_models -26 | from .halos import mass_definitions - | -help: Use an explicit re-export: `Cosmology as Cosmology` - -F401 `.cosmology.GrowthFactor` imported but unused; consider removing, adding to `__all__`, or using a redundant alias - --> src/hmf/__init__.py:24:35 - | -22 | ) -23 | from .alternatives import wdm -24 | from .cosmology import Cosmology, GrowthFactor, cosmo, growth_factor - | ^^^^^^^^^^^^ -25 | from .density_field import CAMB, Transfer, filters, halofit, transfer, transfer_models -26 | from .halos import mass_definitions - | -help: Use an explicit re-export: `GrowthFactor as GrowthFactor` - -F401 `.cosmology.cosmo` imported but unused; consider removing, adding to `__all__`, or using a redundant alias - --> src/hmf/__init__.py:24:49 - | -22 | ) -23 | from .alternatives import wdm -24 | from .cosmology import Cosmology, GrowthFactor, cosmo, growth_factor - | ^^^^^ -25 | from .density_field import CAMB, Transfer, filters, halofit, transfer, transfer_models -26 | from .halos import mass_definitions - | -help: Use an explicit re-export: `cosmo as cosmo` - -F401 `.cosmology.growth_factor` imported but unused; consider removing, adding to `__all__`, or using a redundant alias - --> src/hmf/__init__.py:24:56 - | -22 | ) -23 | from .alternatives import wdm -24 | from .cosmology import Cosmology, GrowthFactor, cosmo, growth_factor - | ^^^^^^^^^^^^^ -25 | from .density_field import CAMB, Transfer, filters, halofit, transfer, transfer_models -26 | from .halos import mass_definitions - | -help: Use an explicit re-export: `growth_factor as growth_factor` - -F401 `.density_field.CAMB` imported but unused; consider removing, adding to `__all__`, or using a redundant alias - --> src/hmf/__init__.py:25:28 - | -23 | from .alternatives import wdm -24 | from .cosmology import Cosmology, GrowthFactor, cosmo, growth_factor -25 | from .density_field import CAMB, Transfer, filters, halofit, transfer, transfer_models - | ^^^^ -26 | from .halos import mass_definitions -27 | from .helpers import functional, get_best_param_order, get_hmf, sample - | -help: Use an explicit re-export: `CAMB as CAMB` - -F401 `.density_field.Transfer` imported but unused; consider removing, adding to `__all__`, or using a redundant alias - --> src/hmf/__init__.py:25:34 - | -23 | from .alternatives import wdm -24 | from .cosmology import Cosmology, GrowthFactor, cosmo, growth_factor -25 | from .density_field import CAMB, Transfer, filters, halofit, transfer, transfer_models - | ^^^^^^^^ -26 | from .halos import mass_definitions -27 | from .helpers import functional, get_best_param_order, get_hmf, sample - | -help: Use an explicit re-export: `Transfer as Transfer` - -F401 `.density_field.filters` imported but unused; consider removing, adding to `__all__`, or using a redundant alias - --> src/hmf/__init__.py:25:44 - | -23 | from .alternatives import wdm -24 | from .cosmology import Cosmology, GrowthFactor, cosmo, growth_factor -25 | from .density_field import CAMB, Transfer, filters, halofit, transfer, transfer_models - | ^^^^^^^ -26 | from .halos import mass_definitions -27 | from .helpers import functional, get_best_param_order, get_hmf, sample - | -help: Use an explicit re-export: `filters as filters` - -F401 `.density_field.halofit` imported but unused; consider removing, adding to `__all__`, or using a redundant alias - --> src/hmf/__init__.py:25:53 - | -23 | from .alternatives import wdm -24 | from .cosmology import Cosmology, GrowthFactor, cosmo, growth_factor -25 | from .density_field import CAMB, Transfer, filters, halofit, transfer, transfer_models - | ^^^^^^^ -26 | from .halos import mass_definitions -27 | from .helpers import functional, get_best_param_order, get_hmf, sample - | -help: Use an explicit re-export: `halofit as halofit` - -F401 `.density_field.transfer` imported but unused; consider removing, adding to `__all__`, or using a redundant alias - --> src/hmf/__init__.py:25:62 - | -23 | from .alternatives import wdm -24 | from .cosmology import Cosmology, GrowthFactor, cosmo, growth_factor -25 | from .density_field import CAMB, Transfer, filters, halofit, transfer, transfer_models - | ^^^^^^^^ -26 | from .halos import mass_definitions -27 | from .helpers import functional, get_best_param_order, get_hmf, sample - | -help: Use an explicit re-export: `transfer as transfer` - -F401 `.density_field.transfer_models` imported but unused; consider removing, adding to `__all__`, or using a redundant alias - --> src/hmf/__init__.py:25:72 - | -23 | from .alternatives import wdm -24 | from .cosmology import Cosmology, GrowthFactor, cosmo, growth_factor -25 | from .density_field import CAMB, Transfer, filters, halofit, transfer, transfer_models - | ^^^^^^^^^^^^^^^ -26 | from .halos import mass_definitions -27 | from .helpers import functional, get_best_param_order, get_hmf, sample - | -help: Use an explicit re-export: `transfer_models as transfer_models` - -F401 `.halos.mass_definitions` imported but unused; consider removing, adding to `__all__`, or using a redundant alias - --> src/hmf/__init__.py:26:20 - | -24 | from .cosmology import Cosmology, GrowthFactor, cosmo, growth_factor -25 | from .density_field import CAMB, Transfer, filters, halofit, transfer, transfer_models -26 | from .halos import mass_definitions - | ^^^^^^^^^^^^^^^^ -27 | from .helpers import functional, get_best_param_order, get_hmf, sample -28 | from .mass_function import MassFunction, fitting_functions, hmf, integrate_hmf - | -help: Use an explicit re-export: `mass_definitions as mass_definitions` - -F401 `.helpers.functional` imported but unused; consider removing, adding to `__all__`, or using a redundant alias - --> src/hmf/__init__.py:27:22 - | -25 | from .density_field import CAMB, Transfer, filters, halofit, transfer, transfer_models -26 | from .halos import mass_definitions -27 | from .helpers import functional, get_best_param_order, get_hmf, sample - | ^^^^^^^^^^ -28 | from .mass_function import MassFunction, fitting_functions, hmf, integrate_hmf - | -help: Use an explicit re-export: `functional as functional` - -F401 `.helpers.get_best_param_order` imported but unused; consider removing, adding to `__all__`, or using a redundant alias - --> src/hmf/__init__.py:27:34 - | -25 | from .density_field import CAMB, Transfer, filters, halofit, transfer, transfer_models -26 | from .halos import mass_definitions -27 | from .helpers import functional, get_best_param_order, get_hmf, sample - | ^^^^^^^^^^^^^^^^^^^^ -28 | from .mass_function import MassFunction, fitting_functions, hmf, integrate_hmf - | -help: Use an explicit re-export: `get_best_param_order as get_best_param_order` - -F401 `.helpers.get_hmf` imported but unused; consider removing, adding to `__all__`, or using a redundant alias - --> src/hmf/__init__.py:27:56 - | -25 | from .density_field import CAMB, Transfer, filters, halofit, transfer, transfer_models -26 | from .halos import mass_definitions -27 | from .helpers import functional, get_best_param_order, get_hmf, sample - | ^^^^^^^ -28 | from .mass_function import MassFunction, fitting_functions, hmf, integrate_hmf - | -help: Use an explicit re-export: `get_hmf as get_hmf` - -F401 `.helpers.sample` imported but unused; consider removing, adding to `__all__`, or using a redundant alias - --> src/hmf/__init__.py:27:65 - | -25 | from .density_field import CAMB, Transfer, filters, halofit, transfer, transfer_models -26 | from .halos import mass_definitions -27 | from .helpers import functional, get_best_param_order, get_hmf, sample - | ^^^^^^ -28 | from .mass_function import MassFunction, fitting_functions, hmf, integrate_hmf - | -help: Use an explicit re-export: `sample as sample` - -F401 `.mass_function.MassFunction` imported but unused; consider removing, adding to `__all__`, or using a redundant alias - --> src/hmf/__init__.py:28:28 - | -26 | from .halos import mass_definitions -27 | from .helpers import functional, get_best_param_order, get_hmf, sample -28 | from .mass_function import MassFunction, fitting_functions, hmf, integrate_hmf - | ^^^^^^^^^^^^ - | -help: Use an explicit re-export: `MassFunction as MassFunction` - -F401 `.mass_function.fitting_functions` imported but unused; consider removing, adding to `__all__`, or using a redundant alias - --> src/hmf/__init__.py:28:42 - | -26 | from .halos import mass_definitions -27 | from .helpers import functional, get_best_param_order, get_hmf, sample -28 | from .mass_function import MassFunction, fitting_functions, hmf, integrate_hmf - | ^^^^^^^^^^^^^^^^^ - | -help: Use an explicit re-export: `fitting_functions as fitting_functions` - -F401 `.mass_function.hmf` imported but unused; consider removing, adding to `__all__`, or using a redundant alias - --> src/hmf/__init__.py:28:61 - | -26 | from .halos import mass_definitions -27 | from .helpers import functional, get_best_param_order, get_hmf, sample -28 | from .mass_function import MassFunction, fitting_functions, hmf, integrate_hmf - | ^^^ - | -help: Use an explicit re-export: `hmf as hmf` - -F401 `.mass_function.integrate_hmf` imported but unused; consider removing, adding to `__all__`, or using a redundant alias - --> src/hmf/__init__.py:28:66 - | -26 | from .halos import mass_definitions -27 | from .helpers import functional, get_best_param_order, get_hmf, sample -28 | from .mass_function import MassFunction, fitting_functions, hmf, integrate_hmf - | ^^^^^^^^^^^^^ - | -help: Use an explicit re-export: `integrate_hmf as integrate_hmf` - -PTH123 `open()` should be replaced by `Path.open()` - --> src/hmf/_cli.py:29:10 - | -27 | return {} -28 | -29 | with open(config) as fl: - | ^^^^ -30 | cfg = toml.load(fl) - | -help: Replace with `Path.open()` - -PTH123 `open()` should be replaced by `Path.open()` - --> src/hmf/_cli.py:198:14 - | -196 | dct = framework_to_dict(obj) -197 | dct["quantities"] = quantities -198 | with open(outdir / f"{lab}_cfg.toml", "w") as fl: - | ^^^^ -199 | toml.dump(dct, fl, encoder=toml.TomlNumpyEncoder()) - | -help: Replace with `Path.open()` - -F401 `._cache.cached_quantity` imported but unused; consider removing, adding to `__all__`, or using a redundant alias - --> src/hmf/_internals/__init__.py:6:21 - | -4 | """ -5 | -6 | from ._cache import cached_quantity, parameter - | ^^^^^^^^^^^^^^^ -7 | from ._framework import ( -8 | Component, - | -help: Use an explicit re-export: `cached_quantity as cached_quantity` - -F401 `._cache.parameter` imported but unused; consider removing, adding to `__all__`, or using a redundant alias - --> src/hmf/_internals/__init__.py:6:38 - | -4 | """ -5 | -6 | from ._cache import cached_quantity, parameter - | ^^^^^^^^^ -7 | from ._framework import ( -8 | Component, - | -help: Use an explicit re-export: `parameter as parameter` - -F401 `._framework.Component` imported but unused; consider removing, adding to `__all__`, or using a redundant alias - --> src/hmf/_internals/__init__.py:8:5 - | - 6 | from ._cache import cached_quantity, parameter - 7 | from ._framework import ( - 8 | Component, - | ^^^^^^^^^ - 9 | Framework, -10 | get_base_component, - | -help: Use an explicit re-export: `Component as Component` - -F401 `._framework.Framework` imported but unused; consider removing, adding to `__all__`, or using a redundant alias - --> src/hmf/_internals/__init__.py:9:5 - | - 7 | from ._framework import ( - 8 | Component, - 9 | Framework, - | ^^^^^^^^^ -10 | get_base_component, -11 | get_base_components, - | -help: Use an explicit re-export: `Framework as Framework` - -F401 `._framework.get_base_component` imported but unused; consider removing, adding to `__all__`, or using a redundant alias - --> src/hmf/_internals/__init__.py:10:5 - | - 8 | Component, - 9 | Framework, -10 | get_base_component, - | ^^^^^^^^^^^^^^^^^^ -11 | get_base_components, -12 | get_mdl, - | -help: Use an explicit re-export: `get_base_component as get_base_component` - -F401 `._framework.get_base_components` imported but unused; consider removing, adding to `__all__`, or using a redundant alias - --> src/hmf/_internals/__init__.py:11:5 - | - 9 | Framework, -10 | get_base_component, -11 | get_base_components, - | ^^^^^^^^^^^^^^^^^^^ -12 | get_mdl, -13 | pluggable, - | -help: Use an explicit re-export: `get_base_components as get_base_components` - -F401 `._framework.get_mdl` imported but unused; consider removing, adding to `__all__`, or using a redundant alias - --> src/hmf/_internals/__init__.py:12:5 - | -10 | get_base_component, -11 | get_base_components, -12 | get_mdl, - | ^^^^^^^ -13 | pluggable, -14 | ) - | -help: Use an explicit re-export: `get_mdl as get_mdl` - -F401 `._framework.pluggable` imported but unused; consider removing, adding to `__all__`, or using a redundant alias - --> src/hmf/_internals/__init__.py:13:5 - | -11 | get_base_components, -12 | get_mdl, -13 | pluggable, - | ^^^^^^^^^ -14 | ) -15 | from ._utils import inherit_docstrings - | -help: Use an explicit re-export: `pluggable as pluggable` - -F401 `._utils.inherit_docstrings` imported but unused; consider removing, adding to `__all__`, or using a redundant alias - --> src/hmf/_internals/__init__.py:15:21 - | -13 | pluggable, -14 | ) -15 | from ._utils import inherit_docstrings - | ^^^^^^^^^^^^^^^^^^ - | -help: Use an explicit re-export: `inherit_docstrings as inherit_docstrings` - -D205 1 blank line required between summary line and description - --> src/hmf/_internals/_cache.py:1:1 - | - 1 | / """ - 2 | | This module defines two decorators, based on the code from - 3 | | http://forrst.com/posts/Yet_another_caching_property_decorator_for_Pytho-PBy. - 4 | | - 5 | | They are both designed to cache class properties, but have the added - 6 | | functionality of being automatically updated when a parent property is - 7 | | updated. - 8 | | """ - | |___^ - 9 | -10 | import warnings - | -help: Insert single blank line - -D404 First word of the docstring should not be "This" - --> src/hmf/_internals/_cache.py:1:1 - | - 1 | / """ - 2 | | This module defines two decorators, based on the code from - 3 | | http://forrst.com/posts/Yet_another_caching_property_decorator_for_Pytho-PBy. - 4 | | - 5 | | They are both designed to cache class properties, but have the added - 6 | | functionality of being automatically updated when a parent property is - 7 | | updated. - 8 | | """ - | |___^ - 9 | -10 | import warnings - | - -D401 First line of docstring should be in imperative mood: "A robust property caching decorator." - --> src/hmf/_internals/_cache.py:27:5 - | -26 | def cached_quantity(f): -27 | / """ -28 | | A robust property caching decorator. -29 | | -30 | | This decorator is intended for use with the complementary `parameter` decorator. -31 | | It caches the decorated quantity, contingent on the parameters it depends on. -32 | | When those parameters are modified, a further call to the quantity will result -33 | | in a recalculation. -34 | | -35 | | Examples -36 | | -------- -37 | | >>> class CachedClass: -38 | | >>> @parameter -39 | | >>> def a_param(self,val): -40 | | >>> return val -41 | | >>> -42 | | >>> @cached_quantity -43 | | >>> def a_quantity(self): -44 | | >>> return 2*self.a_param -45 | | >>> -46 | | >>> @cached_quantity -47 | | >>> def a_child_quantity(self): -48 | | >>> return self.a_quantity**3 -49 | | -50 | | This code will calculate ``a_child_quantity`` on the first call, but return the cached -51 | | value on all subsequent calls. If `a_param` is modified, the -52 | | calculation of either `a_quantity` and `a_child_quantity` will be re-performed when requested. -53 | | """ - | |_______^ -54 | name = f.__name__ - | - -E501 Line too long (90 > 88) - --> src/hmf/_internals/_cache.py:50:89 - | -48 | >>> return self.a_quantity**3 -49 | -50 | This code will calculate ``a_child_quantity`` on the first call, but return the cached - | ^^ -51 | value on all subsequent calls. If `a_param` is modified, the -52 | calculation of either `a_quantity` and `a_child_quantity` will be re-performed when requested. - | - -E501 Line too long (98 > 88) - --> src/hmf/_internals/_cache.py:52:89 - | -50 | This code will calculate ``a_child_quantity`` on the first call, but return the cached -51 | value on all subsequent calls. If `a_param` is modified, the -52 | calculation of either `a_quantity` and `a_child_quantity` will be re-performed when requested. - | ^^^^^^^^^^ -53 | """ -54 | name = f.__name__ - | - -B904 Within an `except` clause, raise exceptions with `raise ... from err` or `raise ... from None` to distinguish them from errors in exception handling - --> src/hmf/_internals/_cache.py:82:21 - | -80 | recalc_prpa[pr].update(recalc_prpa[name]) -81 | except KeyError: -82 | / raise KeyError( -83 | | f"When getting {name}, couldn't find {pr} in recalc_prpa. Had {list(recalc_prpa.keys())}." -84 | | ) - | |_____________________^ -85 | -86 | # check all quantities for dependence on subframeworks and update their entries - | - -E501 Line too long (114 > 88) - --> src/hmf/_internals/_cache.py:83:89 - | -81 | except KeyError: -82 | raise KeyError( -83 | f"When getting {name}, couldn't find {pr} in recalc_prpa. Had {list(recalc_prpa.keys())}." - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -84 | ) - | - -E501 Line too long (91 > 88) - --> src/hmf/_internals/_cache.py:86:89 - | -84 | ) -85 | -86 | # check all quantities for dependence on subframeworks and update their entries - | ^^^ -87 | for s in subframeworks: -88 | if getattr(s, hidden_loc(s, "recalc")).get(":" + name, False): - | - -E501 Line too long (99 > 88) - --> src/hmf/_internals/_cache.py:115:89 - | -113 | activeq.add(name) -114 | -115 | # Go ahead and calculate the value -- each parameter accessed will add itself to the index. - | ^^^^^^^^^^^ -116 | value = f(self) -117 | setattr(self, prop, value) - | - -D401 First line of docstring should be in imperative mood: "A decorator which indicates a parameter of a calculation." - --> src/hmf/_internals/_cache.py:189:5 - | -188 | def parameter(kind): -189 | / """ -190 | | A decorator which indicates a parameter of a calculation. -191 | | -192 | | This decorator is intended for use with the complementary `cached_quantity` decorator. -193 | | It provides the mechanisms by which the quantities are re-calculated intelligently. -194 | | Parameters should be set by the `__init__` call in any class, so that they are set before any -195 | | dependent quantity is accessed. -196 | | -197 | | Parameters -198 | | ---------- -199 | | kind : str -200 | | Either "param", "option", "model", "switch" or "res". Changes the behaviour of the parameter. -201 | | "param", "option", "model" and "res" all behave the same currently, while when a "switch" is modified, -202 | | all dependent quantities have their dependencies re-indexed. -203 | | -204 | | Examples -205 | | -------- -206 | | >>> class CachedClass(object): -207 | | >>> @parameter -208 | | >>> def a_param(self,val): -209 | | >>> return val -210 | | >>> -211 | | >>> @cached_quantity -212 | | >>> def a_quantity(self): -213 | | >>> return 2*self.a_param -214 | | >>> -215 | | >>> @cached_quantity -216 | | >>> def a_child_quantity(self): -217 | | >>> return self.a_quantity**3 -218 | | -219 | | This code will calculate ``a_child_quantity`` on the first call, but return the cached -220 | | value on all subsequent calls. If `a_param` is modified, the -221 | | calculation of either `a_quantity` and `a_child_quantity` will be re-performed when requested. -222 | | """ - | |_______^ -223 | -224 | def param(f): - | - -E501 Line too long (90 > 88) - --> src/hmf/_internals/_cache.py:192:89 - | -190 | A decorator which indicates a parameter of a calculation. -191 | -192 | This decorator is intended for use with the complementary `cached_quantity` decorator. - | ^^ -193 | It provides the mechanisms by which the quantities are re-calculated intelligently. -194 | Parameters should be set by the `__init__` call in any class, so that they are set before any - | - -E501 Line too long (97 > 88) - --> src/hmf/_internals/_cache.py:194:89 - | -192 | This decorator is intended for use with the complementary `cached_quantity` decorator. -193 | It provides the mechanisms by which the quantities are re-calculated intelligently. -194 | Parameters should be set by the `__init__` call in any class, so that they are set before any - | ^^^^^^^^^ -195 | dependent quantity is accessed. - | - -E501 Line too long (101 > 88) - --> src/hmf/_internals/_cache.py:200:89 - | -198 | ---------- -199 | kind : str -200 | Either "param", "option", "model", "switch" or "res". Changes the behaviour of the parameter. - | ^^^^^^^^^^^^^ -201 | "param", "option", "model" and "res" all behave the same currently, while when a "switch" is modified, -202 | all dependent quantities have their dependencies re-indexed. - | - -E501 Line too long (110 > 88) - --> src/hmf/_internals/_cache.py:201:89 - | -199 | kind : str -200 | Either "param", "option", "model", "switch" or "res". Changes the behaviour of the parameter. -201 | "param", "option", "model" and "res" all behave the same currently, while when a "switch" is modified, - | ^^^^^^^^^^^^^^^^^^^^^^ -202 | all dependent quantities have their dependencies re-indexed. - | - -E501 Line too long (90 > 88) - --> src/hmf/_internals/_cache.py:219:89 - | -217 | >>> return self.a_quantity**3 -218 | -219 | This code will calculate ``a_child_quantity`` on the first call, but return the cached - | ^^ -220 | value on all subsequent calls. If `a_param` is modified, the -221 | calculation of either `a_quantity` and `a_child_quantity` will be re-performed when requested. - | - -E501 Line too long (98 > 88) - --> src/hmf/_internals/_cache.py:221:89 - | -219 | This code will calculate ``a_child_quantity`` on the first call, but return the cached -220 | value on all subsequent calls. If `a_param` is modified, the -221 | calculation of either `a_quantity` and `a_child_quantity` will be re-performed when requested. - | ^^^^^^^^^^ -222 | """ - | - -E501 Line too long (93 > 88) - --> src/hmf/_internals/_cache.py:233:89 - | -231 | val = f(self, val) -232 | -233 | # Here put any custom code that should be run, dependent on the type of parameter - | ^^^^^ -234 | if ( -235 | name.endswith("_params") - | - -E501 Line too long (90 > 88) - --> src/hmf/_internals/_cache.py:269:89 - | -267 | setattr(self, recalc_papr, {name: set()}) -268 | -269 | # If either the new value is different from the old, or we never set it before - | ^^ -270 | if not obj_eq(val, old_val) or doset: -271 | # Then if its a dict, we update it - | - -E501 Line too long (90 > 88) - --> src/hmf/_internals/_cache.py:295:89 - | -293 | else: -294 | warnings.warn( -295 | f"You are setting {name} directly. This is unstable, as less " - | ^^ -296 | f"validation is performed. You can turn on extra validation " -297 | f"for directly set parameters by setting framework._validate_every_param_set=True." - | - -E501 Line too long (89 > 88) - --> src/hmf/_internals/_cache.py:296:89 - | -294 | warnings.warn( -295 | f"You are setting {name} directly. This is unstable, as less " -296 | f"validation is performed. You can turn on extra validation " - | ^ -297 | f"for directly set parameters by setting framework._validate_every_param_set=True." -298 | f"However, this can be brittle, since intermediate states may not be valid.", - | - -E501 Line too long (111 > 88) - --> src/hmf/_internals/_cache.py:297:89 - | -295 | … f"You are setting {name} directly. This is unstable, as less " -296 | … f"validation is performed. You can turn on extra validation " -297 | … f"for directly set parameters by setting framework._validate_every_param_set=True." - | ^^^^^^^^^^^^^^^^^^^^^^^ -298 | … f"However, this can be brittle, since intermediate states may not be valid.", -299 | … stacklevel=2, category=DeprecationWarning, - | - -E501 Line too long (105 > 88) - --> src/hmf/_internals/_cache.py:298:89 - | -296 | f"validation is performed. You can turn on extra validation " -297 | f"for directly set parameters by setting framework._validate_every_param_set=True." -298 | f"However, this can be brittle, since intermediate states may not be valid.", - | ^^^^^^^^^^^^^^^^^ -299 | stacklevel=2, category=DeprecationWarning, -300 | ) - | - -D401 First line of docstring should be in imperative mood: "A quantity that is essentially a sub-framework." - --> src/hmf/_internals/_cache.py:326:5 - | -325 | def subframework(f): -326 | / """ -327 | | A quantity that is essentially a sub-framework. -328 | | -329 | | Parameters -330 | | ---------- -331 | | f -332 | | -333 | | Returns -334 | | ------- -335 | | """ - | |_______^ -336 | name = f.__name__ - | - -D414 Section has no content ("Returns") - --> src/hmf/_internals/_cache.py:333:5 - | -331 | f -332 | -333 | Returns - | ^^^^^^^ -334 | ------- -335 | """ - | - -RUF012 Mutable default value for class attribute - --> src/hmf/_internals/_framework.py:27:17 - | -25 | """ -26 | -27 | _defaults = {} - | ^^ -28 | -29 | def __init__(self, **model_params): - | -help: Consider initializing in `__init__` or annotating with `typing.ClassVar` - -E501 Line too long (96 > 88) - --> src/hmf/_internals/_framework.py:75:89 - | -73 | if len(avail) > 1: -74 | warnings.warn( -75 | f"More than one component called '{name}'. Returning {avail[-1]}.", stacklevel=2 - | ^^^^^^^^ -76 | ) -77 | return avail[-1] - | - -B904 Within an `except` clause, raise exceptions with `raise ... from err` or `raise ... from None` to distinguish them from errors in exception handling - --> src/hmf/_internals/_framework.py:82:9 - | -80 | return name -81 | except TypeError: -82 | raise ValueError(f"{name} must be str or a Component subclass") - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - -D401 First line of docstring should be in imperative mood: "A decorator that adds pluggable capabilities." - --> src/hmf/_internals/_framework.py:86:5 - | -85 | def pluggable(cls): -86 | """A decorator that adds pluggable capabilities.""" - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -87 | cls._plugins = {} - | - -B904 Within an `except` clause, raise exceptions with `raise ... from err` or `raise ... from None` to distinguish them from errors in exception handling - --> src/hmf/_internals/_framework.py:126:17 - | -124 | return kind._plugins[name] -125 | except KeyError: -126 | / raise ValueError( -127 | | f"The model {name} is not a defined {kind} model. Available: " -128 | | f"{tuple(kind._plugins.keys())}" -129 | | ) - | |_________________^ -130 | else: -131 | # Try to get *any* model called by this name. - | - -B904 Within an `except` clause, raise exceptions with `raise ... from err` or `raise ... from None` to distinguish them from errors in exception handling - --> src/hmf/_internals/_framework.py:151:13 - | -149 | return name -150 | except TypeError: -151 | raise ValueError(f"{name} must be str or Component subclass") - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - -D401 First line of docstring should be in imperative mood: "Returns a class ``name`` from the module ``mod``." - --> src/hmf/_internals/_framework.py:158:5 - | -156 | ) -157 | def get_model_(name, mod): -158 | / """ -159 | | Returns a class ``name`` from the module ``mod``. -160 | | -161 | | Parameters -162 | | ---------- -163 | | name : str -164 | | The class name of the appropriate model -165 | | -166 | | mod : str -167 | | The module name of the appropriate module -168 | | """ - | |_______^ -169 | return getattr(sys.modules[mod], name) - | - -D401 First line of docstring should be in imperative mood: "Returns an instance of ``name`` from the module ``mod``, with given params." - --> src/hmf/_internals/_framework.py:176:5 - | -174 | ) -175 | def get_model(name, mod, **kwargs): -176 | / r""" -177 | | Returns an instance of ``name`` from the module ``mod``, with given params. -178 | | -179 | | Parameters -180 | | ---------- -181 | | name : str -182 | | The class name of the appropriate model -183 | | mod : str -184 | | The module name of the appropriate module -185 | | -186 | | \*\*kwargs : -187 | | Any parameters for the instantiated model (including model parameters) -188 | | """ - | |_______^ -189 | return get_model_(name, mod)(**kwargs) - | - -D401 First line of docstring should be in imperative mood: "Called when you call MyNewClass()." - --> src/hmf/_internals/_framework.py:194:9 - | -192 | class _Validator(type): -193 | def __call__(cls, *args, **kwargs): -194 | """Called when you call MyNewClass().""" - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -195 | obj = type.__call__(cls, *args, **kwargs) -196 | obj.validate() - | - -N806 Variable `K` in function should be lowercase - --> src/hmf/_internals/_framework.py:255:9 - | -253 | def get_all_parameter_names(cls): -254 | """Yield all parameter names in the class.""" -255 | K = cls() - | ^ -256 | return getattr(K, "_" + K.__class__.__name__ + "__recalc_par_prop") - | - -D401 First line of docstring should be in imperative mood: "Dictionary of all parameters and defaults." - --> src/hmf/_internals/_framework.py:260:9 - | -258 | @classmethod -259 | def get_all_parameter_defaults(cls, recursive=True): -260 | """Dictionary of all parameters and defaults.""" - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -261 | K = cls() -262 | out = {name: getattr(K, name) for name in cls.get_all_parameter_names()} - | - -N806 Variable `K` in function should be lowercase - --> src/hmf/_internals/_framework.py:261:9 - | -259 | def get_all_parameter_defaults(cls, recursive=True): -260 | """Dictionary of all parameters and defaults.""" -261 | K = cls() - | ^ -262 | out = {name: getattr(K, name) for name in cls.get_all_parameter_names()} - | - -D401 First line of docstring should be in imperative mood: "Prints information about each parameter in the class." - --> src/hmf/_internals/_framework.py:336:9 - | -334 | @classmethod -335 | def parameter_info(cls, names=None): -336 | / """ -337 | | Prints information about each parameter in the class. -338 | | -339 | | Optionally, restrict printed parameters to those found in the list of names -340 | | provided. -341 | | """ - | |___________^ -342 | docs = "" -343 | for name, obj in cls._get_all_parameters(): - | - -D205 1 blank line required between summary line and description - --> src/hmf/alternatives/__init__.py:1:1 - | -1 | / """ -2 | | A subpackage dedicated to providing "plugin"-style alternatives to the standard halo mass function, for example -3 | | Warm Dark Matter cosmologies. -4 | | """ - | |___^ -5 | -6 | from . import wdm - | -help: Insert single blank line - -E501 Line too long (111 > 88) - --> src/hmf/alternatives/__init__.py:2:89 - | -1 | """ -2 | A subpackage dedicated to providing "plugin"-style alternatives to the standard halo mass function, for example - | ^^^^^^^^^^^^^^^^^^^^^^^ -3 | Warm Dark Matter cosmologies. -4 | """ - | - -F401 `.wdm` imported but unused; consider removing, adding to `__all__`, or using a redundant alias - --> src/hmf/alternatives/__init__.py:6:15 - | -4 | """ -5 | -6 | from . import wdm - | ^^^ - | -help: Use an explicit re-export: `wdm as wdm` - -N814 Camelcase `MassFunction` imported as constant `_MF` - --> src/hmf/alternatives/wdm.py:17:33 - | -15 | from ..cosmology.cosmo import Planck15 -16 | from ..density_field.transfer import Transfer as _Tr -17 | from ..mass_function.hmf import MassFunction as _MF - | ^^^^^^^^^^^^^^^^^^^ - | - -RUF012 Mutable default value for class attribute - --> src/hmf/alternatives/wdm.py:103:17 - | -101 | """ -102 | -103 | _defaults = {"mu": 1.12, "g_x": 1.5} - | ^^^^^^^^^^^^^^^^^^^^^^^^ -104 | -105 | def transfer(self, k): - | -help: Consider initializing in `__init__` or annotating with `typing.ClassVar` - -N801 Class name `Schneider12_vCDM` should use CapWords convention - --> src/hmf/alternatives/wdm.py:197:7 - | -197 | class Schneider12_vCDM(WDMRecalibrateMF): - | ^^^^^^^^^^^^^^^^ -198 | r""" -199 | Schneider+2012 recalibration of the CDM HMF. - | - -RUF012 Mutable default value for class attribute - --> src/hmf/alternatives/wdm.py:215:17 - | -213 | """ -214 | -215 | _defaults = {"beta": 1.16} - | ^^^^^^^^^^^^^^ -216 | -217 | def dndm_alter(self): - | -help: Consider initializing in `__init__` or annotating with `typing.ClassVar` - -D102 Missing docstring in public method - --> src/hmf/alternatives/wdm.py:217:9 - | -215 | _defaults = {"beta": 1.16} -216 | -217 | def dndm_alter(self): - | ^^^^^^^^^^ -218 | return self.dndm0 * (1 + self.wdm.m_hm / self.m) ** (-self.params["beta"]) - | - -RUF012 Mutable default value for class attribute - --> src/hmf/alternatives/wdm.py:239:17 - | -237 | """ -238 | -239 | _defaults = {"alpha": 0.6} - | ^^^^^^^^^^^^^^ -240 | -241 | def dndm_alter(self): - | -help: Consider initializing in `__init__` or annotating with `typing.ClassVar` - -D102 Missing docstring in public method - --> src/hmf/alternatives/wdm.py:241:9 - | -239 | _defaults = {"alpha": 0.6} -240 | -241 | def dndm_alter(self): - | ^^^^^^^^^^ -242 | return self.dndm0 * (1 + self.wdm.m_hm / self.m) ** (-self.params["alpha"]) - | - -RUF012 Mutable default value for class attribute - --> src/hmf/alternatives/wdm.py:263:17 - | -261 | """ -262 | -263 | _defaults = {"beta": 0.99, "gamma": 2.7} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -264 | -265 | def dndm_alter(self): - | -help: Consider initializing in `__init__` or annotating with `typing.ClassVar` - -D102 Missing docstring in public method - --> src/hmf/alternatives/wdm.py:265:9 - | -263 | _defaults = {"beta": 0.99, "gamma": 2.7} -264 | -265 | def dndm_alter(self): - | ^^^^^^^^^^ -266 | return self.dndm0 * (1 + self.params["gamma"] * self.wdm.m_hm / self.m) ** ( -267 | -self.params["beta"] - | - -D401 First line of docstring should be in imperative mood: "A model for the WDM effect on the transfer function." - --> src/hmf/alternatives/wdm.py:302:9 - | -300 | @parameter("model") -301 | def wdm_model(self, val): -302 | / """ -303 | | A model for the WDM effect on the transfer function. -304 | | -305 | | :type: str or :class:`WDM` subclass -306 | | """ - | |___________^ -307 | return get_mdl(val, WDM) - | - -B904 Within an `except` clause, raise exceptions with `raise ... from err` or `raise ... from None` to distinguish them from errors in exception handling - --> src/hmf/alternatives/wdm.py:328:13 - | -326 | val = float(val) -327 | except ValueError: -328 | raise ValueError("wdm_mass must be a number (", val, ")") - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -329 | -330 | if val <= 0: - | - -D401 First line of docstring should be in imperative mood: "The instantiated WDM model." - --> src/hmf/alternatives/wdm.py:336:9 - | -334 | @cached_quantity -335 | def wdm(self): -336 | / """ -337 | | The instantiated WDM model. -338 | | -339 | | Contains quantities relevant to WDM. -340 | | """ - | |___________^ -341 | return self.wdm_model( -342 | mx=self.wdm_mass, cosmo=self.cosmo, z=self.z, **self.wdm_params - | - -N802 Function name `_unnormalised_lnT` should be lowercase - --> src/hmf/alternatives/wdm.py:346:9 - | -345 | @cached_quantity -346 | def _unnormalised_lnT(self): - | ^^^^^^^^^^^^^^^^^ -347 | return super()._unnormalised_lnT + np.log(self.wdm.transfer(self.k)) - | -help: Consider adding `@typing.override` if this method overrides a method from a superclass - -D401 First line of docstring should be in imperative mood: "A model for empirical recalibration of the HMF." - --> src/hmf/alternatives/wdm.py:371:9 - | -369 | @parameter("switch") -370 | def alter_model(self, val): -371 | / """ -372 | | A model for empirical recalibration of the HMF. -373 | | -374 | | :type: None, str, or :class`WDMRecalibrateMF` subclass. -375 | | """ - | |___________^ -376 | if val is None: -377 | return None - | - -D401 First line of docstring should be in imperative mood: "The number density of haloes in WDM, ``len=len(m)``." - --> src/hmf/alternatives/wdm.py:387:9 - | -385 | @cached_quantity -386 | def dndm(self): -387 | / r""" -388 | | The number density of haloes in WDM, ``len=len(m)``. -389 | | -390 | | Units of :math:`h^4 M_\odot^{-1} Mpc^{-3}` -391 | | """ - | |___________^ -392 | dndm = super().dndm - | - -E501 Line too long (97 > 88) - --> src/hmf/cosmology/__init__.py:1:89 - | -1 | """Cosmographic calculations, and other purely cosmological quantities, such as growth factor.""" - | ^^^^^^^^^ -2 | -3 | from . import cosmo - | - -F401 `.cosmo` imported but unused; consider removing, adding to `__all__`, or using a redundant alias - --> src/hmf/cosmology/__init__.py:3:15 - | -1 | """Cosmographic calculations, and other purely cosmological quantities, such as growth factor.""" -2 | -3 | from . import cosmo - | ^^^^^ -4 | from .cosmo import Cosmology, astropy_to_colossus -5 | from .growth_factor import GrowthFactor - | -help: Use an explicit re-export: `cosmo as cosmo` - -F401 `.cosmo.Cosmology` imported but unused; consider removing, adding to `__all__`, or using a redundant alias - --> src/hmf/cosmology/__init__.py:4:20 - | -3 | from . import cosmo -4 | from .cosmo import Cosmology, astropy_to_colossus - | ^^^^^^^^^ -5 | from .growth_factor import GrowthFactor - | -help: Use an explicit re-export: `Cosmology as Cosmology` - -F401 `.cosmo.astropy_to_colossus` imported but unused; consider removing, adding to `__all__`, or using a redundant alias - --> src/hmf/cosmology/__init__.py:4:31 - | -3 | from . import cosmo -4 | from .cosmo import Cosmology, astropy_to_colossus - | ^^^^^^^^^^^^^^^^^^^ -5 | from .growth_factor import GrowthFactor - | -help: Use an explicit re-export: `astropy_to_colossus as astropy_to_colossus` - -F401 `.growth_factor.GrowthFactor` imported but unused; consider removing, adding to `__all__`, or using a redundant alias - --> src/hmf/cosmology/__init__.py:5:28 - | -3 | from . import cosmo -4 | from .cosmo import Cosmology, astropy_to_colossus -5 | from .growth_factor import GrowthFactor - | ^^^^^^^^^^^^ - | -help: Use an explicit re-export: `GrowthFactor as GrowthFactor` - -E501 Line too long (103 > 88) - --> src/hmf/cosmology/cosmo.py:9:89 - | - 8 | Also provided in the namespace are the pre-defined cosmologies from `astropy`: - 9 | `WMAP5`, `WMAP7`, `WMAP9`, `Planck13`, `Planck15` and `Planck18`, which may be used as arguments to the - | ^^^^^^^^^^^^^^^ -10 | Cosmology framework. All custom subclasses of :class:`astropy.cosmology.FLRW` -11 | may be used as inputs. - | - -B904 Within an `except` clause, raise exceptions with `raise ... from err` or `raise ... from None` to distinguish them from errors in exception handling - --> src/hmf/cosmology/cosmo.py:45:9 - | -43 | return cosmology.fromAstropy(astropy_cosmo=cosmo, cosmo_name=name, **kwargs) -44 | except ImportError: # pragma: nocover -45 | / raise ImportError( -46 | | "Cannot convert to COLOSSUS cosmology without installing COLOSSUS!" -47 | | ) - | |_________^ - | - -E501 Line too long (89 > 88) - --> src/hmf/cosmology/cosmo.py:68:89 - | -66 | update will *update* the dictionary, rather than replacing it. -67 | -68 | To read a standard documented list of parameters, use ``Cosmology.parameter_info()``. - | ^ -69 | If you want to just see the plain list of available parameters, use ``Cosmology.get_all_parameters()``. -70 | To see the actual defaults for each parameter, use ``Cosmology.get_all_parameter_defaults()``. - | - -E501 Line too long (107 > 88) - --> src/hmf/cosmology/cosmo.py:69:89 - | -68 | To read a standard documented list of parameters, use ``Cosmology.parameter_info()``. -69 | If you want to just see the plain list of available parameters, use ``Cosmology.get_all_parameters()``. - | ^^^^^^^^^^^^^^^^^^^ -70 | To see the actual defaults for each parameter, use ``Cosmology.get_all_parameter_defaults()``. -71 | """ - | - -E501 Line too long (98 > 88) - --> src/hmf/cosmology/cosmo.py:70:89 - | -68 | To read a standard documented list of parameters, use ``Cosmology.parameter_info()``. -69 | If you want to just see the plain list of available parameters, use ``Cosmology.get_all_parameters()``. -70 | To see the actual defaults for each parameter, use ``Cosmology.get_all_parameter_defaults()``. - | ^^^^^^^^^^ -71 | """ - | - -D205 1 blank line required between summary line and description - --> src/hmf/cosmology/cosmo.py:83:9 - | -81 | @_cache.parameter("model") -82 | def cosmo_model(self, val): -83 | / """ -84 | | The basis for the cosmology -- see astropy documentation. Can be a custom -85 | | subclass. Defaults to Planck18. -86 | | -87 | | :type: instance of `astropy.cosmology.FLRW` subclass -88 | | """ - | |___________^ -89 | if isinstance(val, str): -90 | return get_cosmo(val) - | -help: Insert single blank line - -D401 First line of docstring should be in imperative mood: "The basis for the cosmology -- see astropy documentation. Can be a custom" - --> src/hmf/cosmology/cosmo.py:83:9 - | -81 | @_cache.parameter("model") -82 | def cosmo_model(self, val): -83 | / """ -84 | | The basis for the cosmology -- see astropy documentation. Can be a custom -85 | | subclass. Defaults to Planck18. -86 | | -87 | | :type: instance of `astropy.cosmology.FLRW` subclass -88 | | """ - | |___________^ -89 | if isinstance(val, str): -90 | return get_cosmo(val) - | - -D205 1 blank line required between summary line and description - --> src/hmf/cosmology/cosmo.py:100:9 - | - 98 | @_cache.parameter("param") - 99 | def cosmo_params(self, val): -100 | / """ -101 | | Parameters for the cosmology that deviate from the base cosmology passed. -102 | | This is useful for repeated updates of a single parameter (leaving others -103 | | the same). Default is the empty dict. The parameters passed must match -104 | | the allowed parameters of `cosmo_model`. For the basic class this is. -105 | | -106 | | :Tcmb0: Temperature of the CMB at z=0 -107 | | :Neff: Number of massless neutrino species -108 | | :m_nu: Mass of neutrino species (list) -109 | | :H0: The hubble constant at z=0 -110 | | :Om0: The normalised matter density at z=0 -111 | | -112 | | :type: dict -113 | | """ - | |___________^ -114 | return val - | -help: Insert single blank line - -D205 1 blank line required between summary line and description - --> src/hmf/cosmology/cosmo.py:121:9 - | -119 | @_cache.cached_quantity -120 | def cosmo(self): -121 | / """ -122 | | Cosmographic object (:class:`astropy.cosmology.FLRW` object), with custom -123 | | cosmology from :attr:`~.cosmo_params` applied. -124 | | """ - | |___________^ -125 | return self.cosmo_model.clone(**self.cosmo_params) - | -help: Insert single blank line - -D401 First line of docstring should be in imperative mood: "Returns a FLRW cosmology given a string (must be one defined in this module)." - --> src/hmf/cosmology/cosmo.py:138:5 - | -137 | def get_cosmo(name): -138 | / """ -139 | | Returns a FLRW cosmology given a string (must be one defined in this module). -140 | | -141 | | Parameters -142 | | ---------- -143 | | name : str -144 | | The class name of the appropriate model -145 | | """ - | |_______^ -146 | if isinstance(getattr(sys.modules[__name__], name), FLRW): -147 | return getattr(sys.modules[__name__], name) - | - -N813 Camelcase `InterpolatedUnivariateSpline` imported as lowercase `_spline` - --> src/hmf/cosmology/growth_factor.py:14:31 - | -12 | import numpy as np -13 | from astropy import cosmology -14 | from scipy.interpolate import InterpolatedUnivariateSpline as _spline - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -15 | -16 | from .._internals._framework import Component as Cmpt - | - -RUF012 Mutable default value for class attribute - --> src/hmf/cosmology/growth_factor.py:67:17 - | -65 | """ -66 | -67 | _defaults = {"dlna": 0.01, "amin": 1e-8} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -68 | -69 | def __init__(self, *args, **kwargs): - | -help: Consider initializing in `__init__` or annotating with `typing.ClassVar` - -D102 Missing docstring in public method - --> src/hmf/cosmology/growth_factor.py:84:9 - | -83 | @cached_property -84 | def integral(self): - | ^^^^^^^^ -85 | a = np.exp(self._lna) -86 | return _spline( - | - -D401 First line of docstring should be in imperative mood: "Finds the factor :math:`D^+(a)`, from Lukic et. al. 2007, eq. 8." - --> src/hmf/cosmology/growth_factor.py:91:9 - | - 90 | def _d_plus(self, z: float | np.ndarray) -> float | np.ndarray: - 91 | / r""" - 92 | | Finds the factor :math:`D^+(a)`, from Lukic et. al. 2007, eq. 8. - 93 | | - 94 | | Parameters - 95 | | ---------- - 96 | | z - 97 | | The redshift - 98 | | - 99 | | Returns -100 | | ------- -101 | | dplus -102 | | The un-normalised growth factor -- same type as ``z``. -103 | | """ - | |___________^ -104 | a_min = np.exp(self._lna).min() -105 | a = 1 / (1 + z) - | - -RUF012 Mutable default value for class attribute - --> src/hmf/cosmology/growth_factor.py:222:17 - | -221 | supported_cosmos = (cosmology.LambdaCDM, cosmology.w0waCDM, cosmology.wCDM) -222 | _defaults = {"dlna": 0.01, "amin": 1e-8, "fname": ""} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -223 | -224 | def growth_factor(self, z): - | -help: Consider initializing in `__init__` or annotating with `typing.ClassVar` - -D401 First line of docstring should be in imperative mood: "The growth factor, :math:`d(a) = D^+(a)/D^+(a=1)`." - --> src/hmf/cosmology/growth_factor.py:225:9 - | -224 | def growth_factor(self, z): -225 | / r""" -226 | | The growth factor, :math:`d(a) = D^+(a)/D^+(a=1)`. -227 | | -228 | | Parameters -229 | | ---------- -230 | | z : array_like -231 | | Redshift. -232 | | -233 | | Returns -234 | | ------- -235 | | gf : array_like -236 | | The growth factor at `z`. -237 | | """ - | |___________^ -238 | G = np.genfromtxt(self.params["fname"])[:, [0, 1]].T - | - -N806 Variable `G` in function should be lowercase - --> src/hmf/cosmology/growth_factor.py:238:9 - | -236 | The growth factor at `z`. -237 | """ -238 | G = np.genfromtxt(self.params["fname"])[:, [0, 1]].T - | ^ -239 | -240 | z_out = G[0, :] - | - -RUF012 Mutable default value for class attribute - --> src/hmf/cosmology/growth_factor.py:265:17 - | -264 | supported_cosmos = (cosmology.LambdaCDM, cosmology.w0waCDM, cosmology.wCDM) -265 | _defaults = {"dlna": 0.01, "amin": 1e-8, "z": None, "d": None} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -266 | -267 | def growth_factor(self, z): - | -help: Consider initializing in `__init__` or annotating with `typing.ClassVar` - -D401 First line of docstring should be in imperative mood: "The growth factor, :math:`d(a) = D^+(a)/D^+(a=1)`." - --> src/hmf/cosmology/growth_factor.py:268:9 - | -267 | def growth_factor(self, z): -268 | / r""" -269 | | The growth factor, :math:`d(a) = D^+(a)/D^+(a=1)`. -270 | | -271 | | Parameters -272 | | ---------- -273 | | z : array_like -274 | | Redshift. -275 | | -276 | | Returns -277 | | ------- -278 | | gf : array_like -279 | | The growth factor at `z`. -280 | | """ - | |___________^ -281 | z_out = self.params["z"] -282 | d_out = self.params["d"] - | - -RUF012 Mutable default value for class attribute - --> src/hmf/cosmology/growth_factor.py:312:17 - | -310 | """ -311 | -312 | _defaults = {"dz": 0.01, "zmax": 1000.0} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -313 | -314 | @cached_property - | -help: Consider initializing in `__init__` or annotating with `typing.ClassVar` - -D205 1 blank line required between summary line and description - --> src/hmf/cosmology/growth_factor.py:323:9 - | -322 | def _d_plus(self, z): -323 | / """ -324 | | This is not implemented in this class. It is not -325 | | required to calculate :meth:`growth_factor`. -326 | | """ - | |___________^ -327 | raise NotImplementedError # pragma: nocover - | -help: Insert single blank line - -D401 First line of docstring should be in imperative mood: "This is not implemented in this class. It is not" - --> src/hmf/cosmology/growth_factor.py:323:9 - | -322 | def _d_plus(self, z): -323 | / """ -324 | | This is not implemented in this class. It is not -325 | | required to calculate :meth:`growth_factor`. -326 | | """ - | |___________^ -327 | raise NotImplementedError # pragma: nocover - | - -D404 First word of the docstring should not be "This" - --> src/hmf/cosmology/growth_factor.py:323:9 - | -322 | def _d_plus(self, z): -323 | / """ -324 | | This is not implemented in this class. It is not -325 | | required to calculate :meth:`growth_factor`. -326 | | """ - | |___________^ -327 | raise NotImplementedError # pragma: nocover - | - -D401 First line of docstring should be in imperative mood: "The growth factor, :math:`d(a) = D^+(a)/D^+(a=1)`." - --> src/hmf/cosmology/growth_factor.py:339:9 - | -338 | def growth_factor(self, z): -339 | / """ -340 | | The growth factor, :math:`d(a) = D^+(a)/D^+(a=1)`. -341 | | -342 | | This uses an approximation only valid in closed or -343 | | flat cosmologies, ported from ``genmf``. -344 | | -345 | | Parameters -346 | | ---------- -347 | | z : array_like -348 | | Redshift. -349 | | -350 | | Returns -351 | | ------- -352 | | gf : array_like -353 | | The growth factor at `z`. -354 | | """ - | |___________^ -355 | a = 1 / (1 + z) -356 | w = 1 / self.cosmo.Om0 - 1.0 - | - -E501 Line too long (103 > 88) - --> src/hmf/cosmology/growth_factor.py:401:89 - | -400 | :dz: Step-size for redshift spline -401 | :zmax: Maximum redshift of spline. Only used for :meth:`growth_factor_fn`, when `inverse=True`. - | ^^^^^^^^^^^^^^^ -402 | """ - | - -RUF012 Mutable default value for class attribute - --> src/hmf/cosmology/growth_factor.py:404:17 - | -402 | """ -403 | -404 | _defaults = {"dz": 0.01, "zmax": 1000.0} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -405 | -406 | @cached_property - | -help: Consider initializing in `__init__` or annotating with `typing.ClassVar` - -D205 1 blank line required between summary line and description - --> src/hmf/cosmology/growth_factor.py:415:9 - | -414 | def _d_plus(self, z): -415 | / """ -416 | | Calculate un-normalised growth factor as a function -417 | | of redshift. Note that the `getvec` argument is not -418 | | used in this function. -419 | | """ - | |___________^ -420 | a = 1 / (1 + z) - | -help: Insert single blank line - -N806 Variable `Omega_m` in function should be lowercase - --> src/hmf/cosmology/growth_factor.py:424:9 - | -422 | om = self.cosmo.Om0 / a**3 -423 | denom = self.cosmo.Ode0 + om -424 | Omega_m = om / denom - | ^^^^^^^ -425 | Omega_L = self.cosmo.Ode0 / denom -426 | coeff = 5.0 * Omega_m / (2.0 / a) - | - -N806 Variable `Omega_L` in function should be lowercase - --> src/hmf/cosmology/growth_factor.py:425:9 - | -423 | denom = self.cosmo.Ode0 + om -424 | Omega_m = om / denom -425 | Omega_L = self.cosmo.Ode0 / denom - | ^^^^^^^ -426 | coeff = 5.0 * Omega_m / (2.0 / a) -427 | term1 = Omega_m ** (4.0 / 7.0) - | - -D205 1 blank line required between summary line and description - --> src/hmf/cosmology/growth_factor.py:436:9 - | -434 | @_inherit -435 | class CambGrowth(GrowthFactor): -436 | / """ -437 | | Uses CAMB to generate the growth factor, at k/h = 1.0. This class is recommended -438 | | if the cosmology is not LambdaCDM (but instead wCDM), as it correctly deals with -439 | | the growth in this case. However, it standard LCDM is used, other classes are -440 | | preferred, as this class needs to re-calculate the transfer function. -441 | | """ - | |___________^ -442 | -443 | supported_cosmos = (cosmology.LambdaCDM, cosmology.w0waCDM, cosmology.wCDM) - | -help: Insert single blank line - -E501 Line too long (96 > 88) - --> src/hmf/cosmology/growth_factor.py:458:89 - | -456 | if cosmo.Ob0 is None: -457 | raise ValueError( -458 | "If using CAMB, the baryon density must be set explicitly in the cosmology." - | ^^^^^^^^ -459 | ) - | - -E501 Line too long (97 > 88) - --> src/hmf/cosmology/growth_factor.py:463:89 - | -461 | if cosmo.Tcmb0.value == 0: -462 | raise ValueError( -463 | "If using CAMB, the CMB temperature must be set explicitly in the cosmology." - | ^^^^^^^^^ -464 | ) - | - -D105 Missing docstring in magic method - --> src/hmf/cosmology/growth_factor.py:521:13 - | -519 | return growth -520 | -521 | def __getstate__(self): - | ^^^^^^^^^^^^ -522 | dct = self.__dict__.copy() - | - -D105 Missing docstring in magic method - --> src/hmf/cosmology/growth_factor.py:531:13 - | -529 | return dct -530 | -531 | def __setstate__(self, state): - | ^^^^^^^^^^^^ -532 | self.__dict__ = state - | - -D205 1 blank line required between summary line and description - --> src/hmf/density_field/__init__.py:1:1 - | -1 | / """ -2 | | A subpackage dedicated to basic measures of the matter density field -- its 2-point structure, cosmological transfer -3 | | functions, and filter functions which can be applied to it. -4 | | """ - | |___^ -5 | -6 | from . import filters, transfer, transfer_models - | -help: Insert single blank line - -E501 Line too long (116 > 88) - --> src/hmf/density_field/__init__.py:2:89 - | -1 | """ -2 | A subpackage dedicated to basic measures of the matter density field -- its 2-point structure, cosmological transfer - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -3 | functions, and filter functions which can be applied to it. -4 | """ - | - -F401 `.filters` imported but unused; consider removing, adding to `__all__`, or using a redundant alias - --> src/hmf/density_field/__init__.py:6:15 - | -4 | """ -5 | -6 | from . import filters, transfer, transfer_models - | ^^^^^^^ -7 | from .filters import Filter -8 | from .halofit import halofit - | -help: Use an explicit re-export: `filters as filters` - -F401 `.transfer` imported but unused; consider removing, adding to `__all__`, or using a redundant alias - --> src/hmf/density_field/__init__.py:6:24 - | -4 | """ -5 | -6 | from . import filters, transfer, transfer_models - | ^^^^^^^^ -7 | from .filters import Filter -8 | from .halofit import halofit - | -help: Use an explicit re-export: `transfer as transfer` - -F401 `.transfer_models` imported but unused; consider removing, adding to `__all__`, or using a redundant alias - --> src/hmf/density_field/__init__.py:6:34 - | -4 | """ -5 | -6 | from . import filters, transfer, transfer_models - | ^^^^^^^^^^^^^^^ -7 | from .filters import Filter -8 | from .halofit import halofit - | -help: Use an explicit re-export: `transfer_models as transfer_models` - -F401 `.filters.Filter` imported but unused; consider removing, adding to `__all__`, or using a redundant alias - --> src/hmf/density_field/__init__.py:7:22 - | -6 | from . import filters, transfer, transfer_models -7 | from .filters import Filter - | ^^^^^^ -8 | from .halofit import halofit -9 | from .transfer import Transfer - | -help: Use an explicit re-export: `Filter as Filter` - -F401 `.halofit.halofit` imported but unused; consider removing, adding to `__all__`, or using a redundant alias - --> src/hmf/density_field/__init__.py:8:22 - | - 6 | from . import filters, transfer, transfer_models - 7 | from .filters import Filter - 8 | from .halofit import halofit - | ^^^^^^^ - 9 | from .transfer import Transfer -10 | from .transfer_models import CAMB, EH - | -help: Use an explicit re-export: `halofit as halofit` - -F401 `.transfer.Transfer` imported but unused; consider removing, adding to `__all__`, or using a redundant alias - --> src/hmf/density_field/__init__.py:9:23 - | - 7 | from .filters import Filter - 8 | from .halofit import halofit - 9 | from .transfer import Transfer - | ^^^^^^^^ -10 | from .transfer_models import CAMB, EH - | -help: Use an explicit re-export: `Transfer as Transfer` - -F401 `.transfer_models.CAMB` imported but unused; consider removing, adding to `__all__`, or using a redundant alias - --> src/hmf/density_field/__init__.py:10:30 - | - 8 | from .halofit import halofit - 9 | from .transfer import Transfer -10 | from .transfer_models import CAMB, EH - | ^^^^ - | -help: Use an explicit re-export: `CAMB as CAMB` - -F401 `.transfer_models.EH` imported but unused; consider removing, adding to `__all__`, or using a redundant alias - --> src/hmf/density_field/__init__.py:10:36 - | - 8 | from .halofit import halofit - 9 | from .transfer import Transfer -10 | from .transfer_models import CAMB, EH - | ^^ - | -help: Use an explicit re-export: `EH as EH` - -N813 Camelcase `InterpolatedUnivariateSpline` imported as lowercase `_spline` - --> src/hmf/density_field/filters.py:8:31 - | - 6 | import numpy as np - 7 | import scipy.integrate as intg - 8 | from scipy.interpolate import InterpolatedUnivariateSpline as _spline - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - 9 | -10 | from .._internals import _framework, _utils - | - -N803 Argument name `R` should be lowercase - --> src/hmf/density_field/filters.py:66:26 - | -64 | super().__init__(**model_parameters) -65 | -66 | def real_space(self, R, r): - | ^ -67 | r""" -68 | Filter definition in real space. - | - -D401 First line of docstring should be in imperative mood: "The derivative of the (fourier-transformed) filter with :math:`\ln(kr)`." - --> src/hmf/density_field/filters.py:137:9 - | -136 | def dw_dlnkr(self, kr): -137 | / r""" -138 | | The derivative of the (fourier-transformed) filter with :math:`\ln(kr)`. -139 | | -140 | | Parameters -141 | | ---------- -142 | | kr : array_like -143 | | Scale(s) at which the derivative is evaluated. -144 | | -145 | | Notes -146 | | ----- -147 | | In terms of :math:`\frac{dw^2}{dm}`, which is a commonly used -148 | | quantity, this has the relationship -149 | | -150 | | .. math:: w\frac{dw}{d\ln r} = \frac{2}{r}\frac{dw^2}{dm}\frac{dm}{dr}. -151 | | """ - | |___________^ -152 | -153 | def dlnss_dlnr(self, r): - | - -D401 First line of docstring should be in imperative mood: "The derivative of the mass variance with radius." - --> src/hmf/density_field/filters.py:154:9 - | -153 | def dlnss_dlnr(self, r): -154 | / r""" -155 | | The derivative of the mass variance with radius. -156 | | -157 | | Parameters -158 | | ---------- -159 | | r : array_like -160 | | Radii -161 | | -162 | | Returns -163 | | ------- -164 | | dlnss_dlnr : array_like -165 | | The derivative of the the mass variance with radius. -166 | | -167 | | Notes -168 | | ----- -169 | | Given a prescription for how radius grows with mass (typically with -170 | | a log-slope of 1/3, and set in :meth:`dlnr_dlnm`), this specifies -171 | | the quantity :math:`\frac{d \ln \sigma^2}{d\ln m}`. -172 | | -173 | | The general formula is -174 | | -175 | | .. math:: \frac{d\ln \sigma^2}{d\ln R} = \frac{1}{\pi^2\sigma^2} \int_0^\infty -176 | | W(kR) \frac{dW(kR)}{d\ln(kR)} P(k)k^2 dk -177 | | """ - | |___________^ -178 | dlnk = np.log(self.k[1] / self.k[0]) -179 | s = self.sigma(r) - | - -D401 First line of docstring should be in imperative mood: "The derivative of log radius with log mass." - --> src/hmf/density_field/filters.py:189:9 - | -188 | def dlnr_dlnm(self, r): -189 | / r""" -190 | | The derivative of log radius with log mass. -191 | | -192 | | For the usual :math:`m\propto r^3` mass assignment, this is just 1/3. -193 | | -194 | | Parameters -195 | | ---------- -196 | | r : array_like -197 | | Radii. -198 | | """ - | |___________^ -199 | return 1.0 / 3.0 - | - -D401 First line of docstring should be in imperative mood: "The logarithmic slope of mass variance with mass." - --> src/hmf/density_field/filters.py:202:9 - | -201 | def dlnss_dlnm(self, r): -202 | / r""" -203 | | The logarithmic slope of mass variance with mass. -204 | | -205 | | This is an important quantity, and is used directly to calculate -206 | | :math:`\frac{dn}{dm}`. -207 | | -208 | | Parameters -209 | | ---------- -210 | | r : array_like -211 | | Radii. -212 | | """ - | |___________^ -213 | return self.dlnss_dlnr(r) * self.dlnr_dlnm(r) - | - -D102 Missing docstring in public method - --> src/hmf/density_field/filters.py:298:9 - | -296 | """ -297 | -298 | def real_space(self, R, r): - | ^^^^^^^^^^ -299 | a = np.where(r < R, 1, 0) -300 | return np.where(r == R, 0.5, a) - | - -N803 Argument name `R` should be lowercase - --> src/hmf/density_field/filters.py:298:26 - | -296 | """ -297 | -298 | def real_space(self, R, r): - | ^ -299 | a = np.where(r < R, 1, 0) -300 | return np.where(r == R, 0.5, a) - | - -D102 Missing docstring in public method - --> src/hmf/density_field/filters.py:302:9 - | -300 | return np.where(r == R, 0.5, a) -301 | -302 | def k_space(self, kr): - | ^^^^^^^ -303 | return np.where(kr > 1.4e-6, (3 / kr**3) * (np.sin(kr) - kr * np.cos(kr)), 1) - | - -D102 Missing docstring in public method - --> src/hmf/density_field/filters.py:305:9 - | -303 | return np.where(kr > 1.4e-6, (3 / kr**3) * (np.sin(kr) - kr * np.cos(kr)), 1) -304 | -305 | def mass_to_radius(self, m, rho_mean): - | ^^^^^^^^^^^^^^ -306 | return (3.0 * m / (4.0 * np.pi * rho_mean)) ** (1.0 / 3.0) - | - -D102 Missing docstring in public method - --> src/hmf/density_field/filters.py:308:9 - | -306 | return (3.0 * m / (4.0 * np.pi * rho_mean)) ** (1.0 / 3.0) -307 | -308 | def radius_to_mass(self, r, rho_mean): - | ^^^^^^^^^^^^^^ -309 | return 4 * np.pi * r**3 * rho_mean / 3 - | - -D102 Missing docstring in public method - --> src/hmf/density_field/filters.py:311:9 - | -309 | return 4 * np.pi * r**3 * rho_mean / 3 -310 | -311 | def dw_dlnkr(self, kr): - | ^^^^^^^^ -312 | return np.where( -313 | kr > 1e-3, - | - -D102 Missing docstring in public method - --> src/hmf/density_field/filters.py:348:9 - | -346 | """ -347 | -348 | def real_space(self, R, r): - | ^^^^^^^^^^ -349 | return np.exp(-(r**2) / 2 / R**2) / (2 * np.pi) ** 1.5 / R**3 - | - -N803 Argument name `R` should be lowercase - --> src/hmf/density_field/filters.py:348:26 - | -346 | """ -347 | -348 | def real_space(self, R, r): - | ^ -349 | return np.exp(-(r**2) / 2 / R**2) / (2 * np.pi) ** 1.5 / R**3 - | - -D102 Missing docstring in public method - --> src/hmf/density_field/filters.py:351:9 - | -349 | return np.exp(-(r**2) / 2 / R**2) / (2 * np.pi) ** 1.5 / R**3 -350 | -351 | def k_space(self, kr): - | ^^^^^^^ -352 | return np.exp(-(kr**2) / 2.0) - | - -D102 Missing docstring in public method - --> src/hmf/density_field/filters.py:354:9 - | -352 | return np.exp(-(kr**2) / 2.0) -353 | -354 | def mass_to_radius(self, m, rho_mean): - | ^^^^^^^^^^^^^^ -355 | return (m / rho_mean) ** (1.0 / 3.0) / np.sqrt(2 * np.pi) - | - -D102 Missing docstring in public method - --> src/hmf/density_field/filters.py:357:9 - | -355 | return (m / rho_mean) ** (1.0 / 3.0) / np.sqrt(2 * np.pi) -356 | -357 | def radius_to_mass(self, r, rho_mean): - | ^^^^^^^^^^^^^^ -358 | return (2 * np.pi) ** 1.5 * r**3 * rho_mean - | - -D102 Missing docstring in public method - --> src/hmf/density_field/filters.py:360:9 - | -358 | return (2 * np.pi) ** 1.5 * r**3 * rho_mean -359 | -360 | def dw_dlnkr(self, kr): - | ^^^^^^^^ -361 | return -(kr**2) * self.k_space(kr) - | - -RUF012 Mutable default value for class attribute - --> src/hmf/density_field/filters.py:399:17 - | -397 | """ -398 | -399 | _defaults = {"c": 2.5} - | ^^^^^^^^^^ -400 | -401 | def k_space(self, kr): - | -help: Consider initializing in `__init__` or annotating with `typing.ClassVar` - -D102 Missing docstring in public method - --> src/hmf/density_field/filters.py:401:9 - | -399 | _defaults = {"c": 2.5} -400 | -401 | def k_space(self, kr): - | ^^^^^^^ -402 | a = np.where(kr > 1, 0, 1) -403 | return np.where(kr == 1, 0.5, a) - | - -D102 Missing docstring in public method - --> src/hmf/density_field/filters.py:405:9 - | -403 | return np.where(kr == 1, 0.5, a) -404 | -405 | def real_space(self, R, r): - | ^^^^^^^^^^ -406 | return (np.sin(r / R) - (r / R) * np.cos(r / R)) / (2 * np.pi**2 * r**3) - | - -N803 Argument name `R` should be lowercase - --> src/hmf/density_field/filters.py:405:26 - | -403 | return np.where(kr == 1, 0.5, a) -404 | -405 | def real_space(self, R, r): - | ^ -406 | return (np.sin(r / R) - (r / R) * np.cos(r / R)) / (2 * np.pi**2 * r**3) - | - -D102 Missing docstring in public method - --> src/hmf/density_field/filters.py:408:9 - | -406 | return (np.sin(r / R) - (r / R) * np.cos(r / R)) / (2 * np.pi**2 * r**3) -407 | -408 | def dw_dlnkr(self, kr): - | ^^^^^^^^ -409 | return np.where(kr == 1, 1.0, 0.0) - | - -D102 Missing docstring in public method - --> src/hmf/density_field/filters.py:411:9 - | -409 | return np.where(kr == 1, 1.0, 0.0) -410 | -411 | def dlnss_dlnr(self, r): - | ^^^^^^^^^^ -412 | sigma = self.sigma(r) -413 | power = _spline(self.k, self.power)(1 / r) - | - -D102 Missing docstring in public method - --> src/hmf/density_field/filters.py:416:9 - | -414 | return -power / (2 * np.pi**2 * sigma**2 * r**3) -415 | -416 | def mass_to_radius(self, m, rho_mean): - | ^^^^^^^^^^^^^^ -417 | return (1.0 / self.params["c"]) * (3.0 * m / (4.0 * np.pi * rho_mean)) ** ( -418 | 1.0 / 3.0 - | - -D102 Missing docstring in public method - --> src/hmf/density_field/filters.py:421:9 - | -419 | ) -420 | -421 | def radius_to_mass(self, r, rho_mean): - | ^^^^^^^^^^^^^^ -422 | return 4 * np.pi * (self.params["c"] * r) ** 3 * rho_mean / 3 - | - -D102 Missing docstring in public method - --> src/hmf/density_field/filters.py:424:9 - | -422 | return 4 * np.pi * (self.params["c"] * r) ** 3 * rho_mean / 3 -423 | -424 | def sigma(self, r, order=0): - | ^^^^^ -425 | if not isinstance(r, collections.abc.Iterable): -426 | r = np.atleast_1d(r) - | - -RUF012 Mutable default value for class attribute - --> src/hmf/density_field/filters.py:460:17 - | -458 | """ -459 | -460 | _defaults = {"c": 2.0} - | ^^^^^^^^^^ -461 | -462 | def xm(self, g, v): - | -help: Consider initializing in `__init__` or annotating with `typing.ClassVar` - -D401 First line of docstring should be in imperative mood: "The average ellipticity of a patch as a function of peak tensor." - --> src/hmf/density_field/filters.py:478:9 - | -477 | def em(self, xm): -478 | """The average ellipticity of a patch as a function of peak tensor.""" - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -479 | return 1 / np.sqrt(5 * xm**2 + 6) - | - -D401 First line of docstring should be in imperative mood: "The average prolateness of a patch as a function of peak tensor." - --> src/hmf/density_field/filters.py:482:9 - | -481 | def pm(self, xm): -482 | """The average prolateness of a patch as a function of peak tensor.""" - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -483 | return 30.0 / (5 * xm**2 + 6) ** 2 - | - -D401 First line of docstring should be in imperative mood: "The short:long axis ratio of an ellipsoid given its ellipticity and prolateness." - --> src/hmf/density_field/filters.py:486:9 - | -485 | def a3a1(self, e, p): -486 | """The short:long axis ratio of an ellipsoid given its ellipticity and prolateness.""" - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -487 | return np.sqrt((1 - 3 * e + p) / (1 + 3 * e + p)) - | - -E501 Line too long (94 > 88) - --> src/hmf/density_field/filters.py:486:89 - | -485 | def a3a1(self, e, p): -486 | """The short:long axis ratio of an ellipsoid given its ellipticity and prolateness.""" - | ^^^^^^ -487 | return np.sqrt((1 - 3 * e + p) / (1 + 3 * e + p)) - | - -D401 First line of docstring should be in imperative mood: "The short:medium axis ratio of an ellipsoid given its ellipticity/prolateness." - --> src/hmf/density_field/filters.py:490:9 - | -489 | def a3a2(self, e, p): -490 | """The short:medium axis ratio of an ellipsoid given its ellipticity/prolateness.""" - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -491 | return np.sqrt((1 - 2 * p) / (1 + 3 * e + p)) - | - -E501 Line too long (92 > 88) - --> src/hmf/density_field/filters.py:490:89 - | -489 | def a3a2(self, e, p): -490 | """The short:medium axis ratio of an ellipsoid given its ellipticity/prolateness.""" - | ^^^^ -491 | return np.sqrt((1 - 2 * p) / (1 + 3 * e + p)) - | - -D102 Missing docstring in public method - --> src/hmf/density_field/filters.py:500:9 - | -498 | return sig_1**2 / (sig_0 * sig_2) -499 | -500 | def xi(self, pm, em): - | ^^ -501 | return ((1 + 4 * pm) ** 2 / (1 - 3 * em + pm) / (1 - 2 * pm)) ** (1.0 / 6.0) - | - -D102 Missing docstring in public method - --> src/hmf/density_field/filters.py:503:9 - | -501 | return ((1 + 4 * pm) ** 2 / (1 - 3 * em + pm) / (1 - 2 * pm)) ** (1.0 / 6.0) -502 | -503 | def a3(self, r): - | ^^ -504 | g = self.gamma(r) -505 | xm = self.xm(g, self.nu(r)) - | - -D102 Missing docstring in public method - --> src/hmf/density_field/filters.py:510:9 - | -508 | return r / self.xi(pm, em) -509 | -510 | def r_a3(self, rmin, rmax): - | ^^^^ -511 | r = np.logspace(np.log(rmin), np.log(rmax), 200, base=np.e) -512 | a3 = self.a3(r) - | - -D102 Missing docstring in public method - --> src/hmf/density_field/filters.py:515:9 - | -513 | return _spline(a3, r) -514 | -515 | def dlnss_dlnr(self, r): - | ^^^^^^^^^^ -516 | a3 = self.a3(r) -517 | sigma = self.sigma(a3) - | - -D102 Missing docstring in public method - --> src/hmf/density_field/filters.py:521:9 - | -519 | return -power / (2 * np.pi**2 * sigma**2 * a3**3) -520 | -521 | def dlnr_dlnm(self, r): - | ^^^^^^^^^ -522 | a3 = self.a3(r) -523 | xi = r / a3 - | - -N813 Camelcase `InterpolatedUnivariateSpline` imported as lowercase `_spline` - --> src/hmf/density_field/halofit.py:14:31 - | -12 | import numpy as np -13 | from scipy.integrate import simpson as _simps -14 | from scipy.interpolate import InterpolatedUnivariateSpline as _spline - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -15 | from scipy.optimize import minimize - | - -N813 Camelcase `Cosmology` imported as lowercase `csm` - --> src/hmf/density_field/halofit.py:17:31 - | -15 | from scipy.optimize import minimize -16 | -17 | from ..cosmology.cosmo import Cosmology as csm - | ^^^^^^^^^^^^^^^^ - | - -D205 1 blank line required between summary line and description - --> src/hmf/density_field/halofit.py:23:5 - | -21 | k: np.ndarray, delta_k: np.ndarray, sigma_8=None -22 | ) -> tuple[float, float, float]: -23 | / """ -24 | | Calculate nonlinear wavenumber, effective spectral index and curvature -25 | | of the power spectrum. -26 | | -27 | | Parameters -28 | | ---------- -29 | | k : array_like -30 | | Wavenumbers -31 | | delta_k : array_like -32 | | Dimensionless power spectrum at `k` -33 | | sigma_8 : scalar -34 | | RMS linear density fluctuations in spheres of radius 8 Mpc/h at z=0. Not -35 | | used any more at all! -36 | | -37 | | Returns -38 | | ------- -39 | | knl : float -40 | | Non-linear wavenumber -41 | | n_eff : float -42 | | Effective spectral index -43 | | n_curv : float -44 | | Curvature of the spectrum -45 | | """ - | |_______^ -46 | -47 | # Initialize sigma spline - | -help: Insert single blank line - -N806 Variable `R` in function should be lowercase - --> src/hmf/density_field/halofit.py:49:9 - | -47 | # Initialize sigma spline -48 | def get_log_sigma2(lnr): -49 | R = np.exp(lnr) - | ^ -50 | integrand = delta_k * np.exp(-((k * R) ** 2)) -51 | return np.log(_simps(integrand, x=np.log(k))) - | - -E501 Line too long (122 > 88) - --> src/hmf/density_field/halofit.py:63:89 - | -61 | warnings.warn( -62 | f"Could not determine non-linear scale! Failed with error: {res.message}. " -63 | f"Continuing with best-fit non-linear scale: r_nl={np.exp(res.x)}, with log_sigma^2 = {res.fun}", stacklevel=2 - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -64 | ) - | - -D401 First line of docstring should be in imperative mood: "Implementation of HALOFIT (Smith+2003)." - --> src/hmf/density_field/halofit.py:81:5 - | - 80 | def halofit(k, delta_k, *, sigma_8=None, z=0, cosmo=None, takahashi=True): - 81 | / """ - 82 | | Implementation of HALOFIT (Smith+2003). - 83 | | - 84 | | Parameters - 85 | | ---------- - 86 | | k : array_like - 87 | | Wavenumbers [h/Mpc]. - 88 | | delta_k : array_like - 89 | | Dimensionless power (linear) at `k`. - 90 | | sigma_8 : float - 91 | | RMS linear density fluctuations in spheres of radius 8 Mpc/h at z=0. Not used - 92 | | at all. - 93 | | z : float - 94 | | Redshift - 95 | | cosmo : :class:`hmf.cosmo.Cosmology` instance, optional - 96 | | An instance of either the `Cosmology` class provided in the `hmf` package, or - 97 | | any subclass of `FLRW` from `astropy`. Defualt is the default cosmology from - 98 | | the :mod:`hmf.cosmo` module. - 99 | | takahashi : bool, optional -100 | | Whether to use updated parameters from Takahashi+2012. Otherwise use -101 | | original from Smith+2003. -102 | | -103 | | Returns -104 | | ------- -105 | | nonlinear_delta_k : array_like -106 | | Dimensionless power at `k`, with nonlinear corrections applied. -107 | | """ - | |_______^ -108 | if sigma_8 is not None: -109 | warnings.warn("sigma_8 is not used any more, and will be removed in v4", stacklevel=2) - | - -E501 Line too long (94 > 88) - --> src/hmf/density_field/halofit.py:109:89 - | -107 | """ -108 | if sigma_8 is not None: -109 | warnings.warn("sigma_8 is not used any more, and will be removed in v4", stacklevel=2) - | ^^^^^^ -110 | -111 | if cosmo is None: - | - -E501 Line too long (89 > 88) - --> src/hmf/density_field/halofit.py:215:89 - | -213 | pnl = pq + ph -214 | -215 | # We have to copy so the original data is not overwritten, giving unexpected results. - | ^ -216 | nonlinear_delta_k = delta_k.copy() -217 | nonlinear_delta_k[mask] = pnl - | - -D102 Missing docstring in public method - --> src/hmf/density_field/transfer.py:89:9 - | -87 | # Parameters -88 | # =========================================================================== -89 | def validate(self): - | ^^^^^^^^ -90 | super().validate() -91 | assert self.lnk_min < self.lnk_max, ( - | - -D401 First line of docstring should be in imperative mood: "The model to use to calculate the growth function/growth rate." - --> src/hmf/density_field/transfer.py:98:9 - | - 96 | @parameter("model") - 97 | def growth_model(self, val): - 98 | / """ - 99 | | The model to use to calculate the growth function/growth rate. -100 | | -101 | | :type: `hmf.growth_factor._GrowthFactor` subclass -102 | | """ - | |___________^ -103 | return get_mdl(val, "_GrowthFactor") - | - -D401 First line of docstring should be in imperative mood: "Defines which transfer function model to use." - --> src/hmf/density_field/transfer.py:116:9 - | -114 | @parameter("model") -115 | def transfer_model(self, val): -116 | / """ -117 | | Defines which transfer function model to use. -118 | | -119 | | Built-in available models are found in the :mod:`hmf.transfer_models` module. -120 | | Default is CAMB if installed, otherwise EH. -121 | | -122 | | :type: str or :class:`hmf.transfer_models.TransferComponent` subclass, optional -123 | | """ - | |___________^ -124 | if not HAVE_CAMB and val in ["CAMB", tm.CAMB]: -125 | raise ValueError( - | - -B904 Within an `except` clause, raise exceptions with `raise ... from err` or `raise ... from None` to distinguish them from errors in exception handling - --> src/hmf/density_field/transfer.py:213:13 - | -211 | val = float(val) -212 | except ValueError: -213 | raise ValueError("z must be a number (", val, ")") - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -214 | -215 | if val < 0: - | - -D401 First line of docstring should be in imperative mood: "The instantiated transfer model." - --> src/hmf/density_field/transfer.py:230:9 - | -228 | @cached_quantity -229 | def transfer(self): -230 | """The instantiated transfer model.""" - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -231 | return self.transfer_model(self.cosmo, **self.transfer_params) - | - -N802 Function name `_unnormalised_lnT` should be lowercase - --> src/hmf/density_field/transfer.py:234:9 - | -233 | @cached_quantity -234 | def _unnormalised_lnT(self): - | ^^^^^^^^^^^^^^^^^ -235 | """The un-normalised transfer function.""" -236 | return self.transfer.lnt(np.log(self.k)) - | -help: Consider adding `@typing.override` if this method overrides a method from a superclass - -D401 First line of docstring should be in imperative mood: "The un-normalised transfer function." - --> src/hmf/density_field/transfer.py:235:9 - | -233 | @cached_quantity -234 | def _unnormalised_lnT(self): -235 | """The un-normalised transfer function.""" - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -236 | return self.transfer.lnt(np.log(self.k)) - | - -D401 First line of docstring should be in imperative mood: "The instantiated growth model." - --> src/hmf/density_field/transfer.py:273:9 - | -271 | @cached_quantity -272 | def growth(self): -273 | """The instantiated growth model.""" - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -274 | return self.growth_model(self.cosmo, **self.growth_params) - | - -D401 First line of docstring should be in imperative mood: "Function that efficiently returns the growth factor." - --> src/hmf/density_field/transfer.py:278:9 - | -276 | @cached_quantity -277 | def _growth_factor_fn(self): -278 | """Function that efficiently returns the growth factor.""" - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -279 | return self.growth.growth_factor_fn() - | - -D401 First line of docstring should be in imperative mood: "The growth factor." - --> src/hmf/density_field/transfer.py:283:9 - | -281 | @cached_quantity -282 | def growth_factor(self): -283 | r"""The growth factor.""" - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -284 | if self.use_splined_growth: -285 | return self._growth_factor_fn(self.z) - | - -N813 Camelcase `InterpolatedUnivariateSpline` imported as lowercase `spline` - --> src/hmf/density_field/transfer_models.py:14:31 - | -12 | import numpy as np -13 | from astropy import cosmology -14 | from scipy.interpolate import InterpolatedUnivariateSpline as spline - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -15 | -16 | from .._internals._framework import Component, pluggable - | - -RUF012 Mutable default value for class attribute - --> src/hmf/density_field/transfer_models.py:44:17 - | -42 | """ -43 | -44 | _defaults = {} - | ^^ -45 | -46 | def __init__(self, cosmo, **model_parameters): - | -help: Consider initializing in `__init__` or annotating with `typing.ClassVar` - -RUF012 Mutable default value for class attribute - --> src/hmf/density_field/transfer_models.py:86:17 - | -84 | """ -85 | -86 | _defaults = {"fname": ""} - | ^^^^^^^^^^^^^ -87 | -88 | def _check_low_k(self, lnk, lnT, lnkmin): - | -help: Consider initializing in `__init__` or annotating with `typing.ClassVar` - -N803 Argument name `lnT` should be lowercase - --> src/hmf/density_field/transfer_models.py:88:33 - | -86 | _defaults = {"fname": ""} -87 | -88 | def _check_low_k(self, lnk, lnT, lnkmin): - | ^^^ -89 | """ -90 | Check convergence of transfer function at low k. - | - -N806 Variable `lnT` in function should be lowercase - --> src/hmf/density_field/transfer_models.py:107:9 - | -105 | start = i -106 | break -107 | lnT = lnT[start:-1] - | ^^^ -108 | lnk = lnk[start:-1] - | - -N806 Variable `T` in function should be lowercase - --> src/hmf/density_field/transfer_models.py:128:13 - | -126 | """ -127 | try: -128 | T = np.log(np.genfromtxt(self.params["fname"])[:, [0, 6]].T) - | ^ -129 | except IndexError: -130 | T = np.log(np.genfromtxt(self.params["fname"])[:, [0, 1]].T) - | - -N806 Variable `T` in function should be lowercase - --> src/hmf/density_field/transfer_models.py:130:13 - | -128 | T = np.log(np.genfromtxt(self.params["fname"])[:, [0, 6]].T) -129 | except IndexError: -130 | T = np.log(np.genfromtxt(self.params["fname"])[:, [0, 1]].T) - | ^ -131 | -132 | if lnk[0] < T[0, 0]: - | - -N806 Variable `lnT` in function should be lowercase - --> src/hmf/density_field/transfer_models.py:133:21 - | -132 | if lnk[0] < T[0, 0]: -133 | lnkout, lnT = self._check_low_k(T[0, :], T[1, :], lnk[0]) - | ^^^ -134 | else: -135 | lnkout = T[0, :] - | - -N806 Variable `lnT` in function should be lowercase - --> src/hmf/density_field/transfer_models.py:136:13 - | -134 | else: -135 | lnkout = T[0, :] -136 | lnT = T[1, :] - | ^^^ -137 | return spline(lnkout, lnT, k=1)(lnk) - | - -RUF012 Mutable default value for class attribute - --> src/hmf/density_field/transfer_models.py:164:21 - | -162 | """ -163 | -164 | _defaults = { - | _____________________^ -165 | | "camb_params": None, -166 | | "dark_energy_params": {}, -167 | | "extrapolate_with_eh": None, -168 | | "kmax": None, -169 | | } - | |_________^ -170 | -171 | def __init__(self, *args, **kwargs): - | -help: Consider initializing in `__init__` or annotating with `typing.ClassVar` - -E501 Line too long (106 > 88) - --> src/hmf/density_field/transfer_models.py:235:89 - | -233 | "'extrapolate_with_eh' was not set. Defaulting to True, which is " -234 | "different behaviour than versions <=3.4.4. This warning may be " -235 | "removed in v4.0. Silence it by setting extrapolate_with_eh explicitly.", stacklevel=2 - | ^^^^^^^^^^^^^^^^^^ -236 | ) -237 | self.params["extrapolate_with_eh"] = True - | - -N806 Variable `T` in function should be lowercase - --> src/hmf/density_field/transfer_models.py:258:13 - | -256 | """ -257 | camb_transfers = camb.get_transfer_functions(self.params["camb_params"]) -258 | T = camb_transfers.get_matter_transfer_data().transfer_data - | ^ -259 | T = np.log(T[[0, 6], :, 0]) - | - -N806 Variable `T` in function should be lowercase - --> src/hmf/density_field/transfer_models.py:259:13 - | -257 | camb_transfers = camb.get_transfer_functions(self.params["camb_params"]) -258 | T = camb_transfers.get_matter_transfer_data().transfer_data -259 | T = np.log(T[[0, 6], :, 0]) - | ^ -260 | -261 | if lnk[0] < T[0, 0]: - | - -N806 Variable `lnT` in function should be lowercase - --> src/hmf/density_field/transfer_models.py:262:25 - | -261 | if lnk[0] < T[0, 0]: -262 | lnkout, lnT = self._check_low_k(T[0, :], T[1, :], lnk[0]) - | ^^^ -263 | else: -264 | lnkout = T[0, :] - | - -N806 Variable `lnT` in function should be lowercase - --> src/hmf/density_field/transfer_models.py:265:17 - | -263 | else: -264 | lnkout = T[0, :] -265 | lnT = T[1, :] - | ^^^ -266 | -267 | lnT -= lnT[0] - | - -N806 Variable `lnT` in function should be lowercase - --> src/hmf/density_field/transfer_models.py:267:13 - | -265 | lnT = T[1, :] -266 | -267 | lnT -= lnT[0] - | ^^^ -268 | -269 | if not self.params["extrapolate_with_eh"]: - | - -N806 Variable `lnT` in function should be lowercase - --> src/hmf/density_field/transfer_models.py:276:13 - | -274 | # normalise EH at the final CAMB point. -275 | norm = self._eh.lnt(lnkout[-2]) - lnT[-1] -276 | lnT = np.concatenate((lnT, [self._eh.lnt(lnkout[-1]) - norm])) - | ^^^ -277 | -278 | lnkmin = lnkout.min() - | - -D105 Missing docstring in magic method - --> src/hmf/density_field/transfer_models.py:292:13 - | -290 | return out -291 | -292 | def __getstate__(self): - | ^^^^^^^^^^^^ -293 | # We need to get rid of the CAMBparams() object, as it cannot be pickled. -294 | p = self.params["camb_params"] - | - -E501 Line too long (93 > 88) - --> src/hmf/density_field/transfer_models.py:352:89 - | -351 | # Unsaveable parameters: -352 | # "nu_mass_degeneracies", "nu_mass_fractions", "nu_mass_numbers", "CustomSources" - | ^^^^^ -353 | -354 | dct = {} - | - -D105 Missing docstring in magic method - --> src/hmf/density_field/transfer_models.py:380:13 - | -378 | return this -379 | -380 | def __setstate__(self, state): - | ^^^^^^^^^^^^ -381 | self.__dict__ = state - | - -RUF012 Mutable default value for class attribute - --> src/hmf/density_field/transfer_models.py:406:17 - | -404 | """ -405 | -406 | _defaults = {"k": None, "T": None} - | ^^^^^^^^^^^^^^^^^^^^^^ -407 | -408 | def lnt(self, lnk): - | -help: Consider initializing in `__init__` or annotating with `typing.ClassVar` - -N806 Variable `T` in function should be lowercase - --> src/hmf/density_field/transfer_models.py:423:9 - | -421 | """ -422 | k = self.params["k"] -423 | T = self.params["T"] - | ^ -424 | -425 | if k is None or T is None: - | - -N806 Variable `lnT` in function should be lowercase - --> src/hmf/density_field/transfer_models.py:433:21 - | -432 | if lnk[0] < np.log(k.min()): -433 | lnkout, lnT = self._check_low_k(np.log(k), np.log(T), lnk[0]) - | ^^^ -434 | else: -435 | lnkout = np.log(k) - | - -N806 Variable `lnT` in function should be lowercase - --> src/hmf/density_field/transfer_models.py:436:13 - | -434 | else: -435 | lnkout = np.log(k) -436 | lnT = np.log(T) - | ^^^ -437 | return spline(lnkout, lnT, k=1)(lnk) - | - -N801 Class name `EH_BAO` should use CapWords convention - --> src/hmf/density_field/transfer_models.py:440:7 - | -440 | class EH_BAO(TransferComponent): - | ^^^^^^ -441 | r""" -442 | Eisenstein & Hu (1998) fitting function with BAO wiggles. - | - -N806 Variable `alpha_b_G` in function should be lowercase - --> src/hmf/density_field/transfer_models.py:515:9 - | -514 | y = self.z_eq / (1 + self.z_drag) -515 | alpha_b_G = y * ( - | ^^^^^^^^^ -516 | -6 * np.sqrt(1 + y) -517 | + (2 + 3 * y) * np.log((np.sqrt(1 + y) + 1) / (np.sqrt(1 + y) - 1)) - | - -D102 Missing docstring in public method - --> src/hmf/density_field/transfer_models.py:535:9 - | -534 | @property -535 | def k_peak(self): - | ^^^^^^ -536 | return 2.5 * np.pi * (1 + 0.217 * self.Omh2) / self.sound_horizon - | - -N806 Variable `T_c_ln_beta` in function should be lowercase - --> src/hmf/density_field/transfer_models.py:568:9 - | -566 | ks = k * self.sound_horizon -567 | -568 | T_c_ln_beta = np.log(np.e + 1.8 * self.beta_c * q) - | ^^^^^^^^^^^ -569 | T_c_ln_nobeta = np.log(np.e + 1.8 * q) -570 | T_c_C_alpha = (14.2 / self.alpha_c) + 386.0 / (1.0 + 69.9 * q**1.08) - | - -N806 Variable `T_c_ln_nobeta` in function should be lowercase - --> src/hmf/density_field/transfer_models.py:569:9 - | -568 | T_c_ln_beta = np.log(np.e + 1.8 * self.beta_c * q) -569 | T_c_ln_nobeta = np.log(np.e + 1.8 * q) - | ^^^^^^^^^^^^^ -570 | T_c_C_alpha = (14.2 / self.alpha_c) + 386.0 / (1.0 + 69.9 * q**1.08) -571 | T_c_C_noalpha = 14.2 + 386.0 / (1.0 + 69.9 * q**1.08) - | - -N806 Variable `T_c_C_alpha` in function should be lowercase - --> src/hmf/density_field/transfer_models.py:570:9 - | -568 | T_c_ln_beta = np.log(np.e + 1.8 * self.beta_c * q) -569 | T_c_ln_nobeta = np.log(np.e + 1.8 * q) -570 | T_c_C_alpha = (14.2 / self.alpha_c) + 386.0 / (1.0 + 69.9 * q**1.08) - | ^^^^^^^^^^^ -571 | T_c_C_noalpha = 14.2 + 386.0 / (1.0 + 69.9 * q**1.08) - | - -N806 Variable `T_c_C_noalpha` in function should be lowercase - --> src/hmf/density_field/transfer_models.py:571:9 - | -569 | T_c_ln_nobeta = np.log(np.e + 1.8 * q) -570 | T_c_C_alpha = (14.2 / self.alpha_c) + 386.0 / (1.0 + 69.9 * q**1.08) -571 | T_c_C_noalpha = 14.2 + 386.0 / (1.0 + 69.9 * q**1.08) - | ^^^^^^^^^^^^^ -572 | -573 | T_c_f = 1.0 / (1.0 + (ks / 5.4) ** 4) - | - -N806 Variable `T_c_f` in function should be lowercase - --> src/hmf/density_field/transfer_models.py:573:9 - | -571 | T_c_C_noalpha = 14.2 + 386.0 / (1.0 + 69.9 * q**1.08) -572 | -573 | T_c_f = 1.0 / (1.0 + (ks / 5.4) ** 4) - | ^^^^^ -574 | -575 | def term(a, b): - | - -N806 Variable `T_c` in function should be lowercase - --> src/hmf/density_field/transfer_models.py:578:9 - | -576 | return a / (a + b * q**2) -577 | -578 | T_c = T_c_f * term(T_c_ln_beta, T_c_C_noalpha) + (1 - T_c_f) * term( - | ^^^ -579 | T_c_ln_beta, T_c_C_alpha -580 | ) - | - -N806 Variable `T_b_T0` in function should be lowercase - --> src/hmf/density_field/transfer_models.py:585:9 - | -583 | ks_tilde = k * s_tilde -584 | -585 | T_b_T0 = term(T_c_ln_nobeta, T_c_C_noalpha) - | ^^^^^^ -586 | Tb1 = T_b_T0 / (1.0 + (ks / 5.2) ** 2) -587 | Tb2 = (self.alpha_b / (1.0 + (self.beta_b / ks) ** 3)) * np.exp( - | - -N806 Variable `Tb1` in function should be lowercase - --> src/hmf/density_field/transfer_models.py:586:9 - | -585 | T_b_T0 = term(T_c_ln_nobeta, T_c_C_noalpha) -586 | Tb1 = T_b_T0 / (1.0 + (ks / 5.2) ** 2) - | ^^^ -587 | Tb2 = (self.alpha_b / (1.0 + (self.beta_b / ks) ** 3)) * np.exp( -588 | -((k / self.k_silk) ** 1.4) - | - -N806 Variable `Tb2` in function should be lowercase - --> src/hmf/density_field/transfer_models.py:587:9 - | -585 | T_b_T0 = term(T_c_ln_nobeta, T_c_C_noalpha) -586 | Tb1 = T_b_T0 / (1.0 + (ks / 5.2) ** 2) -587 | Tb2 = (self.alpha_b / (1.0 + (self.beta_b / ks) ** 3)) * np.exp( - | ^^^ -588 | -((k / self.k_silk) ** 1.4) -589 | ) - | - -N806 Variable `T_b` in function should be lowercase - --> src/hmf/density_field/transfer_models.py:590:9 - | -588 | -((k / self.k_silk) ** 1.4) -589 | ) -590 | T_b = np.sin(ks_tilde) / ks_tilde * (Tb1 + Tb2) - | ^^^ -591 | -592 | return np.log(self.f_baryon * T_b + (1 - self.f_baryon) * T_c) - | - -N801 Class name `EH_NoBAO` should use CapWords convention - --> src/hmf/density_field/transfer_models.py:595:7 - | -595 | class EH_NoBAO(EH_BAO): - | ^^^^^^^^ -596 | r""" -597 | Eisenstein & Hu (1998) fitting function without BAO wiggles. - | - -D102 Missing docstring in public method - --> src/hmf/density_field/transfer_models.py:611:9 - | -610 | @property -611 | def alpha_gamma(self): - | ^^^^^^^^^^^ -612 | return ( -613 | 1 - | - -N806 Variable `L0` in function should be lowercase - --> src/hmf/density_field/transfer_models.py:643:9 - | -641 | q_eff = q * self.Omh2 / gamma_eff -642 | -643 | L0 = np.log(2 * np.e + 1.8 * q_eff) - | ^^ -644 | C0 = 14.2 + 731.0 / (1 + 62.5 * q_eff) -645 | return np.log(L0 / (L0 + C0 * q_eff * q_eff)) - | - -N806 Variable `C0` in function should be lowercase - --> src/hmf/density_field/transfer_models.py:644:9 - | -643 | L0 = np.log(2 * np.e + 1.8 * q_eff) -644 | C0 = 14.2 + 731.0 / (1 + 62.5 * q_eff) - | ^^ -645 | return np.log(L0 / (L0 + C0 * q_eff * q_eff)) - | - -RUF012 Mutable default value for class attribute - --> src/hmf/density_field/transfer_models.py:691:17 - | -689 | """ -690 | -691 | _defaults = { - | _________________^ -692 | | "a": 2.34, -693 | | "b": 3.89, -694 | | "c": 16.1, -695 | | "d": 5.46, -696 | | "e": 6.71, -697 | | "use_sugiyama_baryons": False, -698 | | "use_liddle_baryons": True, -699 | | } - | |_____^ -700 | -701 | def lnt(self, lnk): - | -help: Consider initializing in `__init__` or annotating with `typing.ClassVar` - -N806 Variable `Gamma` in function should be lowercase - --> src/hmf/density_field/transfer_models.py:721:9 - | -719 | e = self.params["e"] -720 | -721 | Gamma = self.cosmo.Om0 * self.cosmo.h - | ^^^^^ -722 | -723 | if self.params["use_sugiyama_baryons"]: - | - -N806 Variable `Gamma` in function should be lowercase - --> src/hmf/density_field/transfer_models.py:724:13 - | -723 | if self.params["use_sugiyama_baryons"]: -724 | Gamma *= np.exp(-self.cosmo.Ob0 * (1 + 1 / self.cosmo.Om0)) - | ^^^^^ -725 | elif self.params["use_liddle_baryons"]: -726 | Gamma *= np.exp( - | - -N806 Variable `Gamma` in function should be lowercase - --> src/hmf/density_field/transfer_models.py:726:13 - | -724 | Gamma *= np.exp(-self.cosmo.Ob0 * (1 + 1 / self.cosmo.Om0)) -725 | elif self.params["use_liddle_baryons"]: -726 | Gamma *= np.exp( - | ^^^^^ -727 | -self.cosmo.Ob0 -728 | * (1 + np.sqrt(self.cosmo.Ob0 * self.cosmo.h) / self.cosmo.Om0) - | - -RUF012 Mutable default value for class attribute - --> src/hmf/density_field/transfer_models.py:766:17 - | -764 | """ -765 | -766 | _defaults = {"a": 37.1, "b": 21.1, "c": 10.8, "nu": 1.12} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -767 | -768 | def lnt(self, lnk): - | -help: Consider initializing in `__init__` or annotating with `typing.ClassVar` - -D205 1 blank line required between summary line and description - --> src/hmf/halos/__init__.py:1:1 - | -1 | / """ -2 | | A subpackage dedicated to descriptions of internal halo properties, such as their mass. See ``halomod`` for more -3 | | extended quantities in this regard. -4 | | """ - | |___^ -5 | -6 | from . import mass_definitions - | -help: Insert single blank line - -E501 Line too long (112 > 88) - --> src/hmf/halos/__init__.py:2:89 - | -1 | """ -2 | A subpackage dedicated to descriptions of internal halo properties, such as their mass. See ``halomod`` for more - | ^^^^^^^^^^^^^^^^^^^^^^^^ -3 | extended quantities in this regard. -4 | """ - | - -F401 `.mass_definitions` imported but unused; consider removing, adding to `__all__`, or using a redundant alias - --> src/hmf/halos/__init__.py:6:15 - | -4 | """ -5 | -6 | from . import mass_definitions - | ^^^^^^^^^^^^^^^^ -7 | from .mass_definitions import MassDefinition - | -help: Use an explicit re-export: `mass_definitions as mass_definitions` - -F401 `.mass_definitions.MassDefinition` imported but unused; consider removing, adding to `__all__`, or using a redundant alias - --> src/hmf/halos/__init__.py:7:31 - | -6 | from . import mass_definitions -7 | from .mass_definitions import MassDefinition - | ^^^^^^^^^^^^^^ - | -help: Use an explicit re-export: `MassDefinition as MassDefinition` - -D401 First line of docstring should be in imperative mood: "The density of haloes under this definition." - --> src/hmf/halos/mass_definitions.py:43:9 - | -42 | def halo_density(self, z=0, cosmo=Planck15): -43 | / r""" -44 | | The density of haloes under this definition. -45 | | -46 | | May not exist in some definitions. Units are :math:`M_\odot h^2/{\rm Mpc}^3`. -47 | | """ - | |___________^ -48 | raise AttributeError("halo_density does not exist for this Mass Definition") - | - -D102 Missing docstring in public method - --> src/hmf/halos/mass_definitions.py:55:9 - | -53 | return None -54 | -55 | def halo_overdensity_mean(self, z=0, cosmo=Planck15): - | ^^^^^^^^^^^^^^^^^^^^^ -56 | return self.halo_density(z, cosmo) / self.mean_density(z, cosmo) - | - -D102 Missing docstring in public method - --> src/hmf/halos/mass_definitions.py:58:9 - | -56 | return self.halo_density(z, cosmo) / self.mean_density(z, cosmo) -57 | -58 | def halo_overdensity_crit(self, z=0, cosmo=Planck15): - | ^^^^^^^^^^^^^^^^^^^^^ -59 | return self.halo_density(z, cosmo) / self.critical_density(z, cosmo) - | - -B904 Within an `except` clause, raise exceptions with `raise ... from err` or `raise ... from None` to distinguish them from errors in exception handling - --> src/hmf/halos/mass_definitions.py:78:13 - | -76 | return (3 * m / (4 * np.pi * self.halo_density(z, cosmo))) ** (1.0 / 3.0) -77 | except AttributeError: -78 | / raise AttributeError( -79 | | f"{self.__class__.__name__} cannot convert mass to radius." -80 | | ) - | |_____________^ -81 | -82 | def r_to_m(self, r, z=0, cosmo=Planck15): - | - -B904 Within an `except` clause, raise exceptions with `raise ... from err` or `raise ... from None` to distinguish them from errors in exception handling - --> src/hmf/halos/mass_definitions.py:99:13 - | - 97 | return 4 * np.pi * r**3 * self.halo_density(z, cosmo) / 3 - 98 | except AttributeError: - 99 | / raise AttributeError( -100 | | f"{self.__class__.__name__} cannot convert radius to mass." -101 | | ) - | |_____________^ -102 | -103 | def _duffy_concentration(self, m, z=0): - | - -B904 Within an `except` clause, raise exceptions with `raise ... from err` or `raise ... from None` to distinguish them from errors in exception handling - --> src/hmf/halos/mass_definitions.py:164:17 - | -162 | ) -163 | except ImportError: -164 | / raise ImportError( -165 | | "Cannot change mass definitions without halomod installed!" -166 | | ) - | |_________________^ -167 | -168 | if profile.z != z: - | - -E501 Line too long (99 > 88) - --> src/hmf/halos/mass_definitions.py:171:89 - | -169 | warnings.warn( -170 | f"Redshift of given profile ({profile.z})does not match redshift " -171 | f"passed to change_definition(). Using the redshift directly passed.", stacklevel=2 - | ^^^^^^^^^^^ -172 | ) -173 | profile.z = z - | - -RUF012 Mutable default value for class attribute - --> src/hmf/halos/mass_definitions.py:240:17 - | -238 | """A mass definition based on spherical overdensity wrt mean background density.""" -239 | -240 | _defaults = {"overdensity": 200} - | ^^^^^^^^^^^^^^^^^^^^ -241 | -242 | def halo_density(self, z=0, cosmo=Planck15): - | -help: Consider initializing in `__init__` or annotating with `typing.ClassVar` - -D401 First line of docstring should be in imperative mood: "The density of haloes under this definition." - --> src/hmf/halos/mass_definitions.py:243:9 - | -242 | def halo_density(self, z=0, cosmo=Planck15): -243 | """The density of haloes under this definition.""" - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -244 | return self.params["overdensity"] * self.mean_density(z, cosmo) - | - -D102 Missing docstring in public method - --> src/hmf/halos/mass_definitions.py:247:9 - | -246 | @property -247 | def colossus_name(self): - | ^^^^^^^^^^^^^ -248 | return f"{int(self.params['overdensity'])}m" - | - -RUF012 Mutable default value for class attribute - --> src/hmf/halos/mass_definitions.py:254:17 - | -252 | """A mass definition based on spherical overdensity wrt critical density.""" -253 | -254 | _defaults = {"overdensity": 200} - | ^^^^^^^^^^^^^^^^^^^^ -255 | -256 | def halo_density(self, z=0, cosmo=Planck15): - | -help: Consider initializing in `__init__` or annotating with `typing.ClassVar` - -D401 First line of docstring should be in imperative mood: "The density of haloes under this definition." - --> src/hmf/halos/mass_definitions.py:257:9 - | -256 | def halo_density(self, z=0, cosmo=Planck15): -257 | """The density of haloes under this definition.""" - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -258 | return self.params["overdensity"] * self.critical_density(z, cosmo) - | - -D102 Missing docstring in public method - --> src/hmf/halos/mass_definitions.py:261:9 - | -260 | @property -261 | def colossus_name(self): - | ^^^^^^^^^^^^^ -262 | return f"{int(self.params['overdensity'])}c" - | - -D401 First line of docstring should be in imperative mood: "The density of haloes under this definition." - --> src/hmf/halos/mass_definitions.py:272:9 - | -271 | def halo_density(self, z=0, cosmo=Planck15): -272 | """The density of haloes under this definition.""" - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -273 | x = cosmo.Om(z) - 1 -274 | overdensity = 18 * np.pi**2 + 82 * x - 39 * x**2 - | - -D102 Missing docstring in public method - --> src/hmf/halos/mass_definitions.py:278:9 - | -277 | @property -278 | def colossus_name(self): - | ^^^^^^^^^^^^^ -279 | return "vir" - | - -RUF012 Mutable default value for class attribute - --> src/hmf/halos/mass_definitions.py:289:17 - | -287 | """A mass definition based on FroF networks with given linking length.""" -288 | -289 | _defaults = {"linking_length": 0.2} - | ^^^^^^^^^^^^^^^^^^^^^^^ -290 | -291 | def halo_density(self, z=0, cosmo=Planck15): - | -help: Consider initializing in `__init__` or annotating with `typing.ClassVar` - -D401 First line of docstring should be in imperative mood: "The density of halos under this mass definition." - --> src/hmf/halos/mass_definitions.py:292:9 - | -291 | def halo_density(self, z=0, cosmo=Planck15): -292 | / r""" -293 | | The density of halos under this mass definition. -294 | | -295 | | Note that for FoF halos, this is very approximate. We follow [1]_ and define -296 | | :math:`rho_{FOF} = 9/(2\pi b^3) \rho_m`, with *b* the linking length. This -297 | | assumes all groups are spherical and singular isothermal spheres. -298 | | -299 | | References -300 | | ---------- -301 | | .. [1] White, Martin, Lars Hernquist, and Volker Springel. “The Halo Model and -302 | | Numerical Simulations.” The Astrophysical Journal 550, no. 2 (April 2001): -303 | | L129–32. https://doi.org/10.1086/319644. -304 | | """ - | |___________^ -305 | overdensity = 9 / (2 * np.pi * self.params["linking_length"] ** 3) -306 | return overdensity * self.mean_density(z, cosmo) - | - -RUF002 Docstring contains ambiguous `–` (EN DASH). Did you mean `-` (HYPHEN-MINUS)? - --> src/hmf/halos/mass_definitions.py:303:16 - | -301 | .. [1] White, Martin, Lars Hernquist, and Volker Springel. “The Halo Model and -302 | Numerical Simulations.” The Astrophysical Journal 550, no. 2 (April 2001): -303 | L129–32. https://doi.org/10.1086/319644. - | ^ -304 | """ -305 | overdensity = 9 / (2 * np.pi * self.params["linking_length"] ** 3) - | - -D102 Missing docstring in public method - --> src/hmf/halos/mass_definitions.py:309:9 - | -308 | @property -309 | def colossus_name(self): - | ^^^^^^^^^^^^^ -310 | return "fof" - | - -N806 Variable `XDELTA_GUESS_FACTORS` in function should be lowercase - --> src/hmf/halos/mass_definitions.py:360:5 - | -358 | x = None -359 | i = 0 -360 | XDELTA_GUESS_FACTORS = [5.0, 10.0, 20.0, 100.0, 10000.0] - | ^^^^^^^^^^^^^^^^^^^^ -361 | -362 | if h is None: - | - -N818 Exception name `OptimizationException` should be named with an Error suffix - --> src/hmf/halos/mass_definitions.py:389:7 - | -389 | class OptimizationException(Exception): - | ^^^^^^^^^^^^^^^^^^^^^ -390 | """Exception class related to failed optimization.""" - | - -E501 Line too long (110 > 88) - --> src/hmf/helpers/__init__.py:1:89 - | -1 | """A collection of helper functions which can operate on several of the Frameworks in the rest of the code.""" - | ^^^^^^^^^^^^^^^^^^^^^^ -2 | -3 | from .functional import get_best_param_order, get_hmf - | - -F401 `.functional.get_best_param_order` imported but unused; consider removing, adding to `__all__`, or using a redundant alias - --> src/hmf/helpers/__init__.py:3:25 - | -1 | """A collection of helper functions which can operate on several of the Frameworks in the rest of the code.""" -2 | -3 | from .functional import get_best_param_order, get_hmf - | ^^^^^^^^^^^^^^^^^^^^ - | -help: Use an explicit re-export: `get_best_param_order as get_best_param_order` - -F401 `.functional.get_hmf` imported but unused; consider removing, adding to `__all__`, or using a redundant alias - --> src/hmf/helpers/__init__.py:3:47 - | -1 | """A collection of helper functions which can operate on several of the Frameworks in the rest of the code.""" -2 | -3 | from .functional import get_best_param_order, get_hmf - | ^^^^^^^ - | -help: Use an explicit re-export: `get_hmf as get_hmf` - -DTZ005 `datetime.datetime.now()` called without a `tz` argument - --> src/hmf/helpers/cfg_utils.py:15:26 - | -13 | def framework_to_dict(obj: Framework) -> dict: -14 | """Serialize a framework instance to a simple TOML-able dictionary.""" -15 | out = {"created_on": datetime.now(), "hmf_version": __version__, "params": {}} - | ^^^^^^^^^^^^^^ -16 | -17 | for k, v in obj.parameter_values.items(): - | -help: Pass a `datetime.timezone` object to the `tz` parameter - -E501 Line too long (91 > 88) - --> src/hmf/helpers/functional.py:225:89 - | -223 | ordered_list = [ordered_kwargs[k] for k in ordered_kwargs] -224 | final_list = [ -225 | collections.OrderedDict(list(zip(list(ordered_kwargs.keys()), v, strict=True))) - | ^^^ -226 | for v in itertools.product(*ordered_list) -227 | ] - | - -N813 Camelcase `InterpolatedUnivariateSpline` imported as lowercase `_spline` - --> src/hmf/helpers/sample.py:8:31 - | - 7 | import numpy as np - 8 | from scipy.interpolate import InterpolatedUnivariateSpline as _spline - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - 9 | -10 | from ..mass_function import hmf - | - -N803 Argument name `N` should be lowercase - --> src/hmf/helpers/sample.py:22:29 - | -22 | def _choose_halo_masses_num(N, icdf, xmin=0, rng=None): - | ^ -23 | # Generate random variates from 0 to maxcum -24 | if rng is None: - | - -N803 Argument name `N` should be lowercase - --> src/hmf/helpers/sample.py:33:15 - | -33 | def sample_mf(N, log_mmin, sort=False, rng=None, **mf_kwargs): - | ^ -34 | """ -35 | Create a sample of halo masses from a theoretical mass function. - | - -N803 Argument name `V` should be lowercase - --> src/hmf/helpers/sample.py:75:25 - | -75 | def dndm_from_sample(m, V, nm=None, bins=50): - | ^ -76 | """ -77 | Generate a binned dn/dm from a sample of halo masses. - | - -N806 Variable `histN` in function should be lowercase - --> src/hmf/helpers/sample.py:119:13 - | -117 | if hist[-1] == 0: -118 | try: -119 | histN = np.where(hist != 0)[0][-1] - | ^^^^^ -120 | hist[histN] = np.nan -121 | except IndexError: - | - -F401 `.fitting_functions` imported but unused; consider removing, adding to `__all__`, or using a redundant alias - --> src/hmf/mass_function/__init__.py:3:15 - | -1 | """Subpackage for determining the halo mass function in Spherical Collapse.""" -2 | -3 | from . import fitting_functions, hmf, integrate_hmf - | ^^^^^^^^^^^^^^^^^ -4 | from .fitting_functions import PS, SMT, FittingFunction, Tinker08 -5 | from .hmf import MassFunction - | -help: Use an explicit re-export: `fitting_functions as fitting_functions` - -F401 `.hmf` imported but unused; consider removing, adding to `__all__`, or using a redundant alias - --> src/hmf/mass_function/__init__.py:3:34 - | -1 | """Subpackage for determining the halo mass function in Spherical Collapse.""" -2 | -3 | from . import fitting_functions, hmf, integrate_hmf - | ^^^ -4 | from .fitting_functions import PS, SMT, FittingFunction, Tinker08 -5 | from .hmf import MassFunction - | -help: Use an explicit re-export: `hmf as hmf` - -F401 `.integrate_hmf` imported but unused; consider removing, adding to `__all__`, or using a redundant alias - --> src/hmf/mass_function/__init__.py:3:39 - | -1 | """Subpackage for determining the halo mass function in Spherical Collapse.""" -2 | -3 | from . import fitting_functions, hmf, integrate_hmf - | ^^^^^^^^^^^^^ -4 | from .fitting_functions import PS, SMT, FittingFunction, Tinker08 -5 | from .hmf import MassFunction - | -help: Use an explicit re-export: `integrate_hmf as integrate_hmf` - -F401 `.fitting_functions.PS` imported but unused; consider removing, adding to `__all__`, or using a redundant alias - --> src/hmf/mass_function/__init__.py:4:32 - | -3 | from . import fitting_functions, hmf, integrate_hmf -4 | from .fitting_functions import PS, SMT, FittingFunction, Tinker08 - | ^^ -5 | from .hmf import MassFunction - | -help: Use an explicit re-export: `PS as PS` - -F401 `.fitting_functions.SMT` imported but unused; consider removing, adding to `__all__`, or using a redundant alias - --> src/hmf/mass_function/__init__.py:4:36 - | -3 | from . import fitting_functions, hmf, integrate_hmf -4 | from .fitting_functions import PS, SMT, FittingFunction, Tinker08 - | ^^^ -5 | from .hmf import MassFunction - | -help: Use an explicit re-export: `SMT as SMT` - -F401 `.fitting_functions.FittingFunction` imported but unused; consider removing, adding to `__all__`, or using a redundant alias - --> src/hmf/mass_function/__init__.py:4:41 - | -3 | from . import fitting_functions, hmf, integrate_hmf -4 | from .fitting_functions import PS, SMT, FittingFunction, Tinker08 - | ^^^^^^^^^^^^^^^ -5 | from .hmf import MassFunction - | -help: Use an explicit re-export: `FittingFunction as FittingFunction` - -F401 `.fitting_functions.Tinker08` imported but unused; consider removing, adding to `__all__`, or using a redundant alias - --> src/hmf/mass_function/__init__.py:4:58 - | -3 | from . import fitting_functions, hmf, integrate_hmf -4 | from .fitting_functions import PS, SMT, FittingFunction, Tinker08 - | ^^^^^^^^ -5 | from .hmf import MassFunction - | -help: Use an explicit re-export: `Tinker08 as Tinker08` - -F401 `.hmf.MassFunction` imported but unused; consider removing, adding to `__all__`, or using a redundant alias - --> src/hmf/mass_function/__init__.py:5:18 - | -3 | from . import fitting_functions, hmf, integrate_hmf -4 | from .fitting_functions import PS, SMT, FittingFunction, Tinker08 -5 | from .hmf import MassFunction - | ^^^^^^^^^^^^ - | -help: Use an explicit re-export: `MassFunction as MassFunction` - -N813 Camelcase `InterpolatedUnivariateSpline` imported as lowercase `_spline` - --> src/hmf/mass_function/fitting_functions.py:13:31 - | -11 | import numpy as np -12 | import scipy.special as sp -13 | from scipy.interpolate import InterpolatedUnivariateSpline as _spline - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -14 | -15 | from .._internals import _framework - | - -N803 Argument name `L` should be lowercase - --> src/hmf/mass_function/fitting_functions.py:69:9 - | -67 | def __init__( -68 | self, -69 | L, - | ^ -70 | N, -71 | halo_finder_type, - | - -N803 Argument name `N` should be lowercase - --> src/hmf/mass_function/fitting_functions.py:70:9 - | -68 | self, -69 | L, -70 | N, - | ^ -71 | halo_finder_type, -72 | omegam, - | - -N803 Argument name `ICS` should be lowercase - --> src/hmf/mass_function/fitting_functions.py:80:9 - | -78 | z_start=None, -79 | z_meas=None, -80 | ICS=None, - | ^^^^^^^^ -81 | nmin=None, -82 | hmf_analysis_notes="", - | - -RUF012 Mutable default value for class attribute - --> src/hmf/mass_function/fitting_functions.py:207:17 - | -205 | """ -206 | __doc__ += _pdocs -207 | _defaults = {} - | ^^ -208 | -209 | # Subclass requirements - | -help: Consider initializing in `__init__` or annotating with `typing.ClassVar` - -D102 Missing docstring in public method - --> src/hmf/mass_function/fitting_functions.py:254:9 - | -253 | @classmethod -254 | def get_measured_mdef(cls): - | ^^^^^^^^^^^^^^^^^ -255 | # Try to set the measured mass definition -256 | measured = None - | - -D205 1 blank line required between summary line and description - --> src/hmf/mass_function/fitting_functions.py:314:9 - | -312 | @property -313 | def cutmask(self): -314 | / r""" -315 | | A logical mask array specifying which elements of :attr:`fsigma` are within -316 | | the fitted range. -317 | | """ - | |___________^ -318 | return np.ones(len(self.nu2), dtype=bool) - | -help: Insert single blank line - -D101 Missing docstring in public class - --> src/hmf/mass_function/fitting_functions.py:325:7 - | -325 | class PS(FittingFunction): - | ^^ -326 | # Subclass requirements -327 | req_sigma = False #: Whether sigma is required to compute this model. - | - -D102 Missing docstring in public method - --> src/hmf/mass_function/fitting_functions.py:340:9 - | -339 | @property -340 | def fsigma(self): - | ^^^^^^ -341 | return np.sqrt(2.0 / np.pi) * self.nu * np.exp(-0.5 * self.nu2) - | - -D101 Missing docstring in public class - --> src/hmf/mass_function/fitting_functions.py:344:7 - | -344 | class SMT(FittingFunction): - | ^^^ -345 | # Subclass requirements -346 | req_sigma = False - | - -RUF012 Mutable default value for class attribute - --> src/hmf/mass_function/fitting_functions.py:356:17 - | -354 | __doc__ = _makedoc(FittingFunction._pdocs, "Sheth-Mo-Tormen", "SMT", _eq, _ref) -355 | -356 | _defaults = {"a": 0.707, "p": 0.3, "A": None} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -357 | normalized = True - | -help: Consider initializing in `__init__` or annotating with `typing.ClassVar` - -D102 Missing docstring in public method - --> src/hmf/mass_function/fitting_functions.py:387:9 - | -386 | @property -387 | def fsigma(self): - | ^^^^^^ -388 | A = self.norm() -389 | a = self.params["a"] - | - -N806 Variable `A` in function should be lowercase - --> src/hmf/mass_function/fitting_functions.py:388:9 - | -386 | @property -387 | def fsigma(self): -388 | A = self.norm() - | ^ -389 | a = self.params["a"] -390 | p = self.params["p"] - | - -D102 Missing docstring in public method - --> src/hmf/mass_function/fitting_functions.py:400:9 - | -398 | ) -399 | -400 | def norm(self): - | ^^^^ -401 | if self.params["A"] is not None: -402 | return self.params["A"] - | - -D101 Missing docstring in public class - --> src/hmf/mass_function/fitting_functions.py:413:7 - | -413 | class Jenkins(FittingFunction): - | ^^^^^^^ -414 | # Subclass requirements -415 | req_z = False - | - -RUF012 Mutable default value for class attribute - --> src/hmf/mass_function/fitting_functions.py:423:17 - | -421 | ) -422 | __doc__ = _makedoc(FittingFunction._pdocs, "Jenkins", "Jenkins", _eq, _ref) -423 | _defaults = {"A": 0.315, "b": 0.61, "c": 3.8} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -424 | normalized = False - | -help: Consider initializing in `__init__` or annotating with `typing.ClassVar` - -D102 Missing docstring in public method - --> src/hmf/mass_function/fitting_functions.py:447:9 - | -446 | @property -447 | def cutmask(self): - | ^^^^^^^ -448 | return np.logical_and(self.lnsigma > -1.2, self.lnsigma < 1.05) - | - -D102 Missing docstring in public method - --> src/hmf/mass_function/fitting_functions.py:451:9 - | -450 | @property -451 | def fsigma(self): - | ^^^^^^ -452 | A = self.params["A"] -453 | b = self.params["b"] - | - -N806 Variable `A` in function should be lowercase - --> src/hmf/mass_function/fitting_functions.py:452:9 - | -450 | @property -451 | def fsigma(self): -452 | A = self.params["A"] - | ^ -453 | b = self.params["b"] -454 | c = self.params["c"] - | - -D101 Missing docstring in public class - --> src/hmf/mass_function/fitting_functions.py:458:7 - | -458 | class Warren(FittingFunction): - | ^^^^^^ -459 | # Subclass requirements -460 | req_z = False - | - -RUF012 Mutable default value for class attribute - --> src/hmf/mass_function/fitting_functions.py:473:17 - | -471 | __doc__ = _makedoc(FittingFunction._pdocs, "Warren", "Warren", _eq, _ref) -472 | -473 | _defaults = {"A": 0.7234, "b": 1.625, "c": 0.2538, "d": 1.1982, "e": 1} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -474 | normalized = False - | -help: Consider initializing in `__init__` or annotating with `typing.ClassVar` - -RUF012 Mutable default value for class attribute - --> src/hmf/mass_function/fitting_functions.py:476:21 - | -474 | normalized = False -475 | -476 | uncertainties = { - | _____________________^ -477 | | "A": 0.0073, -478 | | "a": 0.028, -479 | | "b": 0.0051, -480 | | "c": 0.0075, -481 | | } #: Quoted uncertainties of the model parameters. - | |_____^ -482 | sim_definition = SimDetails( -483 | L=[96, 135, 192, 272, 384, 543, 768, 1086, 1536, 2172, 2583, 3072], - | -help: Consider initializing in `__init__` or annotating with `typing.ClassVar` - -D102 Missing docstring in public method - --> src/hmf/mass_function/fitting_functions.py:514:9 - | -513 | @property -514 | def fsigma(self): - | ^^^^^^ -515 | A = self.params["A"] -516 | b = self.params["b"] - | - -N806 Variable `A` in function should be lowercase - --> src/hmf/mass_function/fitting_functions.py:515:9 - | -513 | @property -514 | def fsigma(self): -515 | A = self.params["A"] - | ^ -516 | b = self.params["b"] -517 | c = self.params["c"] - | - -D102 Missing docstring in public method - --> src/hmf/mass_function/fitting_functions.py:524:9 - | -523 | @property -524 | def cutmask(self): - | ^^^^^^^ -525 | return np.logical_and(self.m > 1e10, self.m < 1e15) - | - -D101 Missing docstring in public class - --> src/hmf/mass_function/fitting_functions.py:528:7 - | -528 | class Reed03(SMT): - | ^^^^^^ -529 | # Subclass requirements -530 | req_sigma = True - | - -RUF012 Mutable default value for class attribute - --> src/hmf/mass_function/fitting_functions.py:536:17 - | -534 | __doc__ = _makedoc(FittingFunction._pdocs, "Reed03", "R03", _eq, _ref) -535 | -536 | _defaults = {"a": 0.707, "p": 0.3, "A": 0.3222, "c": 0.7} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -537 | normalized = False - | -help: Consider initializing in `__init__` or annotating with `typing.ClassVar` - -D102 Missing docstring in public method - --> src/hmf/mass_function/fitting_functions.py:558:9 - | -557 | @property -558 | def fsigma(self): - | ^^^^^^ -559 | vfv = super().fsigma -560 | return vfv * np.exp( - | - -D102 Missing docstring in public method - --> src/hmf/mass_function/fitting_functions.py:565:9 - | -564 | @property -565 | def cutmask(self): - | ^^^^^^^ -566 | return np.logical_and(self.lnsigma > -1.7, self.lnsigma < 0.9) - | - -D101 Missing docstring in public class - --> src/hmf/mass_function/fitting_functions.py:569:7 - | -569 | class Reed07(FittingFunction): - | ^^^^^^ -570 | req_neff = True -571 | req_z = False - | - -E501 Line too long (146 > 88) - --> src/hmf/mass_function/fitting_functions.py:573:89 - | -571 | … -572 | … -573 | …)^p+0.6G_1+0.4G_2\right]\nu\exp\left(-ca\nu^2/2-\frac{0.03\nu^{0.6}}{(n_{\rm eff}+3)^2}\right)" - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -574 | … 374 (1), 2-15. http://adsabs.harvard.edu/abs/2007MNRAS.374....2R""" -575 | …d07", "R07", _eq, _ref) - | - -RUF012 Mutable default value for class attribute - --> src/hmf/mass_function/fitting_functions.py:577:17 - | -575 | __doc__ = _makedoc(FittingFunction._pdocs, "Reed07", "R07", _eq, _ref) -576 | -577 | _defaults = {"A": 0.3222, "p": 0.3, "c": 1.08, "a": 0.764} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -578 | -579 | sim_definition = SimDetails( - | -help: Consider initializing in `__init__` or annotating with `typing.ClassVar` - -D102 Missing docstring in public method - --> src/hmf/mass_function/fitting_functions.py:626:9 - | -625 | @property -626 | def fsigma(self): - | ^^^^^^ -627 | G_1 = np.exp(-((self.lnsigma - 0.4) ** 2) / (2 * 0.6**2)) -628 | G_2 = np.exp(-((self.lnsigma - 0.75) ** 2) / (2 * 0.2**2)) - | - -N806 Variable `G_1` in function should be lowercase - --> src/hmf/mass_function/fitting_functions.py:627:9 - | -625 | @property -626 | def fsigma(self): -627 | G_1 = np.exp(-((self.lnsigma - 0.4) ** 2) / (2 * 0.6**2)) - | ^^^ -628 | G_2 = np.exp(-((self.lnsigma - 0.75) ** 2) / (2 * 0.2**2)) - | - -N806 Variable `G_2` in function should be lowercase - --> src/hmf/mass_function/fitting_functions.py:628:9 - | -626 | def fsigma(self): -627 | G_1 = np.exp(-((self.lnsigma - 0.4) ** 2) / (2 * 0.6**2)) -628 | G_2 = np.exp(-((self.lnsigma - 0.75) ** 2) / (2 * 0.2**2)) - | ^^^ -629 | -630 | c = self.params["c"] - | - -N806 Variable `A` in function should be lowercase - --> src/hmf/mass_function/fitting_functions.py:632:9 - | -630 | c = self.params["c"] -631 | a = self.params["a"] / self.params["c"] -632 | A = self.params["A"] - | ^ -633 | p = self.params["p"] - | - -D102 Missing docstring in public method - --> src/hmf/mass_function/fitting_functions.py:646:9 - | -645 | @property -646 | def cutmask(self): - | ^^^^^^^ -647 | return np.logical_and(self.lnsigma > -0.5, self.lnsigma < 1.2) - | - -D101 Missing docstring in public class - --> src/hmf/mass_function/fitting_functions.py:650:7 - | -650 | class Peacock(FittingFunction): - | ^^^^^^^ -651 | req_z = False -652 | req_mass = True - | - -RUF012 Mutable default value for class attribute - --> src/hmf/mass_function/fitting_functions.py:657:17 - | -655 | _ref = """Peacock, J. A., Aug. 2007. MNRAS 379 (3), 1067-1074. http://adsabs.harvard.edu/abs/2007MNRAS.379.1067P""" -656 | __doc__ = _makedoc(FittingFunction._pdocs, "Peacock", "Pck", _eq, _ref) -657 | _defaults = {"a": 1.529, "b": 0.704, "c": 0.412} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -658 | -659 | sim_definition = copy(Warren.sim_definition) - | -help: Consider initializing in `__init__` or annotating with `typing.ClassVar` - -D102 Missing docstring in public method - --> src/hmf/mass_function/fitting_functions.py:664:9 - | -663 | @property -664 | def fsigma(self): - | ^^^^^^ -665 | a = self.params["a"] -666 | b = self.params["b"] - | - -D102 Missing docstring in public method - --> src/hmf/mass_function/fitting_functions.py:678:9 - | -677 | @property -678 | def cutmask(self): - | ^^^^^^^ -679 | return np.logical_and(self.m < 1e10, self.m > 1e15) - | - -D101 Missing docstring in public class - --> src/hmf/mass_function/fitting_functions.py:682:7 - | -682 | class Angulo(FittingFunction): - | ^^^^^^ -683 | req_mass = True -684 | _ref = """Angulo, R. E., et al., 2012. arXiv:1203.3216v1""" - | - -RUF012 Mutable default value for class attribute - --> src/hmf/mass_function/fitting_functions.py:687:17 - | -685 | _eq = r"$A \left[\left(\frac{d}{\sigma}\right)^b + 1 \right] \exp(-c/\sigma^2)$" -686 | __doc__ = _makedoc(FittingFunction._pdocs, "Angulo", "Ang", _eq, _ref) -687 | _defaults = {"A": 0.201, "b": 1.7, "c": 1.172, "d": 2.08} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -688 | -689 | sim_definition = SimDetails( - | -help: Consider initializing in `__init__` or annotating with `typing.ClassVar` - -D102 Missing docstring in public method - --> src/hmf/mass_function/fitting_functions.py:708:9 - | -707 | @property -708 | def fsigma(self): - | ^^^^^^ -709 | A = self.params["A"] -710 | b = self.params["b"] - | - -N806 Variable `A` in function should be lowercase - --> src/hmf/mass_function/fitting_functions.py:709:9 - | -707 | @property -708 | def fsigma(self): -709 | A = self.params["A"] - | ^ -710 | b = self.params["b"] -711 | c = self.params["c"] - | - -D102 Missing docstring in public method - --> src/hmf/mass_function/fitting_functions.py:717:9 - | -716 | @property -717 | def cutmask(self): - | ^^^^^^^ -718 | return np.logical_and(self.m > 1e8, self.m < 1e16) - | - -D101 Missing docstring in public class - --> src/hmf/mass_function/fitting_functions.py:721:7 - | -721 | class AnguloBound(Angulo): - | ^^^^^^^^^^^ -722 | __doc__ = Angulo.__doc__ -723 | _defaults = {"A": 0.265, "b": 1.9, "c": 1.4, "d": 1.675} - | - -RUF012 Mutable default value for class attribute - --> src/hmf/mass_function/fitting_functions.py:723:17 - | -721 | class AnguloBound(Angulo): -722 | __doc__ = Angulo.__doc__ -723 | _defaults = {"A": 0.265, "b": 1.9, "c": 1.4, "d": 1.675} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: Consider initializing in `__init__` or annotating with `typing.ClassVar` - -N801 Class name `Watson_FoF` should use CapWords convention - --> src/hmf/mass_function/fitting_functions.py:726:7 - | -726 | class Watson_FoF(Warren): - | ^^^^^^^^^^ -727 | req_mass = False - | - -D101 Missing docstring in public class - --> src/hmf/mass_function/fitting_functions.py:726:7 - | -726 | class Watson_FoF(Warren): - | ^^^^^^^^^^ -727 | req_mass = False - | - -E501 Line too long (103 > 88) - --> src/hmf/mass_function/fitting_functions.py:729:89 - | -727 | req_mass = False -728 | -729 | _ref = """Watson, W. A., et al., MNRAS, 2013. http://adsabs.harvard.edu/abs/2013MNRAS.433.1230W """ - | ^^^^^^^^^^^^^^^ -730 | __doc__ = _makedoc(FittingFunction._pdocs, "Watson FoF", "WatF", Warren._eq, _ref) -731 | _defaults = {"A": 0.282, "b": 2.163, "c": 1, "d": 1.21, "e": 1.406} - | - -RUF012 Mutable default value for class attribute - --> src/hmf/mass_function/fitting_functions.py:731:17 - | -729 | _ref = """Watson, W. A., et al., MNRAS, 2013. http://adsabs.harvard.edu/abs/2013MNRAS.433.1230W """ -730 | __doc__ = _makedoc(FittingFunction._pdocs, "Watson FoF", "WatF", Warren._eq, _ref) -731 | _defaults = {"A": 0.282, "b": 2.163, "c": 1, "d": 1.21, "e": 1.406} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -732 | -733 | sim_definition = SimDetails( - | -help: Consider initializing in `__init__` or annotating with `typing.ClassVar` - -E501 Line too long (91 > 88) - --> src/hmf/mass_function/fitting_functions.py:747:89 - | -745 | ICS="1LPT", -746 | nmin=1000, -747 | hmf_analysis_notes="Warren FOF correction applied. Finite-box correction applied.", - | ^^^ -748 | other_cosmo={"omegav": 0.73, "omegab": 0.044, "h": 0.7, "n": 0.96}, -749 | ) - | - -D102 Missing docstring in public method - --> src/hmf/mass_function/fitting_functions.py:752:9 - | -751 | @property -752 | def cutmask(self): - | ^^^^^^^ -753 | return np.logical_and(self.lnsigma > -0.55, self.lnsigma < 1.31) - | - -D101 Missing docstring in public class - --> src/hmf/mass_function/fitting_functions.py:756:7 - | -756 | class Watson(FittingFunction): - | ^^^^^^ -757 | req_cosmo = True -758 | req_dhalo = True - | - -E501 Line too long (103 > 88) - --> src/hmf/mass_function/fitting_functions.py:761:89 - | -759 | req_omz = True -760 | -761 | _ref = """Watson, W. A., et al., MNRAS, 2013. http://adsabs.harvard.edu/abs/2013MNRAS.433.1230W """ - | ^^^^^^^^^^^^^^^ -762 | _eq = r"\Gamma A \left((\frac{\beta}{\sigma}^\alpha+1\right)\exp(-\gamma/\sigma^2)" -763 | __doc__ = _makedoc(FittingFunction._pdocs, "Watson", "WatS", _eq, Watson_FoF._ref) - | - -RUF012 Mutable default value for class attribute - --> src/hmf/mass_function/fitting_functions.py:770:17 - | -768 | sim_definition.halo_overdensity = "*(vir)" -769 | -770 | _defaults = { - | _________________^ -771 | | "C_a": 0.023, -772 | | "d_a": 0.456, -773 | | "d_b": 0.139, -774 | | "p": 0.072, -775 | | "q": 2.13, -776 | | "A_0": 0.194, -777 | | "alpha_0": 1.805, -778 | | "beta_0": 2.267, -779 | | "gamma_0": 1.287, -780 | | "z_hi": 6, -781 | | "A_hi": 0.563, -782 | | "alpha_hi": 3.810, -783 | | "beta_hi": 0.874, -784 | | "gamma_hi": 1.453, -785 | | "A_a": 1.097, -786 | | "A_b": 3.216, -787 | | "A_c": 0.074, -788 | | "alpha_a": 3.136, -789 | | "alpha_b": 3.058, -790 | | "alpha_c": 2.349, -791 | | "beta_a": 5.907, -792 | | "beta_b": 3.599, -793 | | "beta_c": 2.344, -794 | | "gamma_z": 1.318, -795 | | } - | |_____^ -796 | -797 | def gamma(self): - | -help: Consider initializing in `__init__` or annotating with `typing.ClassVar` - -N806 Variable `C` in function should be lowercase - --> src/hmf/mass_function/fitting_functions.py:808:9 - | -806 | else: -807 | delta_halo = self.mass_definition.halo_overdensity_mean(self.z, self.cosmo) -808 | C = np.exp(self.params["C_a"] * (delta_halo / 178 - 1)) - | ^ -809 | d = -self.params["d_a"] * self.omegam_z - self.params["d_b"] -810 | p = self.params["p"] - | - -D102 Missing docstring in public method - --> src/hmf/mass_function/fitting_functions.py:820:9 - | -819 | @property -820 | def fsigma(self): - | ^^^^^^ -821 | if self.z == 0: -822 | A = self.params["A_0"] - | - -N806 Variable `A` in function should be lowercase - --> src/hmf/mass_function/fitting_functions.py:822:13 - | -820 | def fsigma(self): -821 | if self.z == 0: -822 | A = self.params["A_0"] - | ^ -823 | alpha = self.params["alpha_0"] -824 | beta = self.params["beta_0"] - | - -N806 Variable `A` in function should be lowercase - --> src/hmf/mass_function/fitting_functions.py:827:13 - | -825 | gamma = self.params["gamma_0"] -826 | elif self.z >= self.params["z_hi"]: -827 | A = self.params["A_hi"] - | ^ -828 | alpha = self.params["alpha_hi"] -829 | beta = self.params["beta_hi"] - | - -N806 Variable `A` in function should be lowercase - --> src/hmf/mass_function/fitting_functions.py:833:13 - | -831 | else: -832 | omz = self.omegam_z -833 | A = omz * ( - | ^ -834 | self.params["A_a"] * (1 + self.z) ** (-self.params["A_b"]) -835 | + self.params["A_c"] - | - -D102 Missing docstring in public method - --> src/hmf/mass_function/fitting_functions.py:855:9 - | -854 | @property -855 | def cutmask(self): - | ^^^^^^^ -856 | return np.logical_and(self.lnsigma > -0.55, self.lnsigma < 1.05) - | - -D101 Missing docstring in public class - --> src/hmf/mass_function/fitting_functions.py:859:7 - | -859 | class Crocce(Warren): - | ^^^^^^ -860 | req_z = True - | - -RUF012 Mutable default value for class attribute - --> src/hmf/mass_function/fitting_functions.py:864:17 - | -862 | _ref = """Crocce, M., et al. MNRAS 403 (3), 1353-1367. http://doi.wiley.com/10.1111/j.1365-2966.2009.16194.x""" -863 | __doc__ = _makedoc(FittingFunction._pdocs, "Crocce", "Cro", Warren._eq, _ref) -864 | _defaults = { - | _________________^ -865 | | "A_a": 0.58, -866 | | "A_b": 0.13, -867 | | "b_a": 1.37, -868 | | "b_b": 0.15, -869 | | "c_a": 0.3, -870 | | "c_b": 0.084, -871 | | "d_a": 1.036, -872 | | "d_b": 0.024, -873 | | "e": 1, -874 | | } - | |_____^ -875 | -876 | sim_definition = SimDetails( - | -help: Consider initializing in `__init__` or annotating with `typing.ClassVar` - -D102 Missing docstring in public method - --> src/hmf/mass_function/fitting_functions.py:903:9 - | -902 | @property -903 | def cutmask(self): - | ^^^^^^^ -904 | return np.logical_and(self.m > 10**10.5, self.m < 10**15.5) - | - -D101 Missing docstring in public class - --> src/hmf/mass_function/fitting_functions.py:907:7 - | -907 | class Courtin(SMT): - | ^^^^^^^ -908 | req_sigma = True -909 | _ref = """Courtin, J., et al., Oct. 2010. MNRAS 1931. http://doi.wiley.com/10.1111/j.1365-2966.2010.17573.x""" - | - -RUF012 Mutable default value for class attribute - --> src/hmf/mass_function/fitting_functions.py:911:17 - | -909 | _ref = """Courtin, J., et al., Oct. 2010. MNRAS 1931. http://doi.wiley.com/10.1111/j.1365-2966.2010.17573.x""" -910 | __doc__ = _makedoc(FittingFunction._pdocs, "Courtin", "Ctn", SMT._eq, _ref) -911 | _defaults = {"A": 0.348, "a": 0.695, "p": 0.1} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -912 | -913 | normalized = False - | -help: Consider initializing in `__init__` or annotating with `typing.ClassVar` - -D102 Missing docstring in public method - --> src/hmf/mass_function/fitting_functions.py:934:9 - | -933 | @property -934 | def cutmask(self): - | ^^^^^^^ -935 | return np.logical_and(self.lnsigma > -0.8, self.lnsigma < 0.7) - | - -D101 Missing docstring in public class - --> src/hmf/mass_function/fitting_functions.py:938:7 - | -938 | class Bhattacharya(SMT): - | ^^^^^^^^^^^^ -939 | req_z = True -940 | req_mass = True - | - -RUF012 Mutable default value for class attribute - --> src/hmf/mass_function/fitting_functions.py:945:17 - | -943 | _ref = """Bhattacharya, S., et al., May 2011. ApJ 732 (2), 122. http://labs.adsabs.harvard.edu/ui/abs/2011ApJ...732..122B""" -944 | __doc__ = _makedoc(FittingFunction._pdocs, "Bhattacharya", "Btc", _eq, _ref) -945 | _defaults = { - | _________________^ -946 | | "A_a": 0.333, -947 | | "A_b": 0.11, -948 | | "a_a": 0.788, -949 | | "a_b": 0.01, -950 | | "p": 0.807, -951 | | "q": 1.795, -952 | | "normed": False, -953 | | } - | |_____^ -954 | -955 | normalized = False - | -help: Consider initializing in `__init__` or annotating with `typing.ClassVar` - -E501 Line too long (96 > 88) - --> src/hmf/mass_function/fitting_functions.py:971:89 - | -969 | ICS=["2LPT", "2LPT", "2LPT", "1LPT", "1LPT"], -970 | nmin=400, -971 | hmf_analysis_notes="Finite force correction. FOF Correction. Finite volume correction.", - | ^^^^^^^^ -972 | other_cosmo={ -973 | "omegav": 0.74, - | - -D102 Missing docstring in public method - --> src/hmf/mass_function/fitting_functions.py:1014:9 - | -1013 | @property -1014 | def cutmask(self): - | ^^^^^^^ -1015 | return np.logical_and(self.m > 6 * 10**11, self.m < 3 * 10**15) - | - -D102 Missing docstring in public method - --> src/hmf/mass_function/fitting_functions.py:1017:9 - | -1015 | return np.logical_and(self.m > 6 * 10**11, self.m < 3 * 10**15) -1016 | -1017 | def norm(self): - | ^^^^ -1018 | if self.params["A"] is not None: -1019 | return self.params["A"] - | - -D101 Missing docstring in public class - --> src/hmf/mass_function/fitting_functions.py:1029:7 - | -1029 | class Tinker08(FittingFunction): - | ^^^^^^^^ -1030 | req_z = True -1031 | req_dhalo = True - | - -RUF012 Mutable default value for class attribute - --> src/hmf/mass_function/fitting_functions.py:1251:17 - | -1249 | ) -1250 | -1251 | _defaults = { # -- A - | _________________^ -1252 | | "A_200": 1.858659e-01, -1253 | | "A_300": 1.995973e-01, -1254 | | "A_400": 2.115659e-01, -1255 | | "A_600": 2.184113e-01, -1256 | | "A_800": 2.480968e-01, -1257 | | "A_1200": 2.546053e-01, -1258 | | "A_1600": 2.600000e-01, -1259 | | "A_2400": 2.600000e-01, -1260 | | "A_3200": 2.600000e-01, -1261 | | # -- a -1262 | | "a_200": 1.466904, -1263 | | "a_300": 1.521782, -1264 | | "a_400": 1.559186, -1265 | | "a_600": 1.614585, -1266 | | "a_800": 1.869936, -1267 | | "a_1200": 2.128056, -1268 | | "a_1600": 2.301275, -1269 | | "a_2400": 2.529241, -1270 | | "a_3200": 2.661983, -1271 | | # --- b -1272 | | "b_200": 2.571104, -1273 | | "b_300": 2.254217, -1274 | | "b_400": 2.048674, -1275 | | "b_600": 1.869559, -1276 | | "b_800": 1.588649, -1277 | | "b_1200": 1.507134, -1278 | | "b_1600": 1.464374, -1279 | | "b_2400": 1.436827, -1280 | | "b_3200": 1.405210, -1281 | | # --- c -1282 | | "c_200": 1.193958, -1283 | | "c_300": 1.270316, -1284 | | "c_400": 1.335191, -1285 | | "c_600": 1.446266, -1286 | | "c_800": 1.581345, -1287 | | "c_1200": 1.795050, -1288 | | "c_1600": 1.965613, -1289 | | "c_2400": 2.237466, -1290 | | "c_3200": 2.439729, -1291 | | # -- others -1292 | | "A_exp": 0.14, -1293 | | "a_exp": 0.06, -1294 | | } - | |_____^ -1295 | -1296 | delta_virs = np.array([200, 300, 400, 600, 800, 1200, 1600, 2400, 3200]) - | -help: Consider initializing in `__init__` or annotating with `typing.ClassVar` - -N806 Variable `A_array` in function should be lowercase - --> src/hmf/mass_function/fitting_functions.py:1308:13 - | -1307 | if delta_halo not in self.delta_virs: -1308 | A_array = np.array([self.params[f"A_{d}"] for d in self.delta_virs]) - | ^^^^^^^ -1309 | a_array = np.array([self.params[f"a_{d}"] for d in self.delta_virs]) -1310 | b_array = np.array([self.params[f"b_{d}"] for d in self.delta_virs]) - | - -N806 Variable `A_func` in function should be lowercase - --> src/hmf/mass_function/fitting_functions.py:1313:13 - | -1311 | c_array = np.array([self.params[f"c_{d}"] for d in self.delta_virs]) -1312 | -1313 | A_func = _spline(self.delta_virs, A_array) - | ^^^^^^ -1314 | a_func = _spline(self.delta_virs, a_array) -1315 | b_func = _spline(self.delta_virs, b_array) - | - -N806 Variable `A_0` in function should be lowercase - --> src/hmf/mass_function/fitting_functions.py:1318:13 - | -1316 | c_func = _spline(self.delta_virs, c_array) -1317 | -1318 | A_0 = A_func(delta_halo) - | ^^^ -1319 | a_0 = a_func(delta_halo) -1320 | b_0 = b_func(delta_halo) - | - -N806 Variable `A_0` in function should be lowercase - --> src/hmf/mass_function/fitting_functions.py:1323:13 - | -1321 | c_0 = c_func(delta_halo) -1322 | else: -1323 | A_0 = self.params[f"A_{int(delta_halo)}"] - | ^^^ -1324 | a_0 = self.params[f"a_{int(delta_halo)}"] -1325 | b_0 = self.params[f"b_{int(delta_halo)}"] - | - -D102 Missing docstring in public method - --> src/hmf/mass_function/fitting_functions.py:1335:9 - | -1334 | @property -1335 | def fsigma(self): - | ^^^^^^ -1336 | return ( -1337 | self.A - | - -D102 Missing docstring in public method - --> src/hmf/mass_function/fitting_functions.py:1343:9 - | -1342 | @property -1343 | def cutmask(self): - | ^^^^^^^ -1344 | if self.z == 0.0: -1345 | return np.logical_and( - | - -D101 Missing docstring in public class - --> src/hmf/mass_function/fitting_functions.py:1353:7 - | -1353 | class Tinker10(FittingFunction): - | ^^^^^^^^ -1354 | req_z = True -1355 | req_dhalo = True - | - -RUF012 Mutable default value for class attribute - --> src/hmf/mass_function/fitting_functions.py:1363:17 - | -1361 | sim_definition = copy(Tinker08.sim_definition) -1362 | -1363 | _defaults = { # --- alpha - | _________________^ -1364 | | "alpha_200": 0.368, -1365 | | "alpha_300": 0.363, -1366 | | "alpha_400": 0.385, -1367 | | "alpha_600": 0.389, -1368 | | "alpha_800": 0.393, -1369 | | "alpha_1200": 0.365, -1370 | | "alpha_1600": 0.379, -1371 | | "alpha_2400": 0.355, -1372 | | "alpha_3200": 0.327, -1373 | | # --- beta -1374 | | "beta_200": 0.589, -1375 | | "beta_300": 0.585, -1376 | | "beta_400": 0.544, -1377 | | "beta_600": 0.543, -1378 | | "beta_800": 0.564, -1379 | | "beta_1200": 0.623, -1380 | | "beta_1600": 0.637, -1381 | | "beta_2400": 0.673, -1382 | | "beta_3200": 0.702, -1383 | | # --- gamma -1384 | | "gamma_200": 0.864, -1385 | | "gamma_300": 0.922, -1386 | | "gamma_400": 0.987, -1387 | | "gamma_600": 1.09, -1388 | | "gamma_800": 1.2, -1389 | | "gamma_1200": 1.34, -1390 | | "gamma_1600": 1.5, -1391 | | "gamma_2400": 1.68, -1392 | | "gamma_3200": 1.81, -1393 | | # --- phi -1394 | | "phi_200": -0.729, -1395 | | "phi_300": -0.789, -1396 | | "phi_400": -0.910, -1397 | | "phi_600": -1.05, -1398 | | "phi_800": -1.2, -1399 | | "phi_1200": -1.26, -1400 | | "phi_1600": -1.45, -1401 | | "phi_2400": -1.5, -1402 | | "phi_3200": -1.49, -1403 | | # -- eta -1404 | | "eta_200": -0.243, -1405 | | "eta_300": -0.261, -1406 | | "eta_400": -0.261, -1407 | | "eta_600": -0.273, -1408 | | "eta_800": -0.278, -1409 | | "eta_1200": -0.301, -1410 | | "eta_1600": -0.301, -1411 | | "eta_2400": -0.319, -1412 | | "eta_3200": -0.336, -1413 | | # --others -1414 | | "beta_exp": 0.2, -1415 | | "phi_exp": -0.08, -1416 | | "eta_exp": 0.27, -1417 | | "gamma_exp": -0.01, -1418 | | "max_z": 3, -1419 | | } - | |_____^ -1420 | -1421 | delta_virs = np.array([200, 300, 400, 600, 800, 1200, 1600, 2400, 3200]) - | -help: Consider initializing in `__init__` or annotating with `typing.ClassVar` - -D102 Missing docstring in public method - --> src/hmf/mass_function/fitting_functions.py:1500:9 - | -1499 | @property -1500 | def normalise(self): - | ^^^^^^^^^ -1501 | if int(self.delta_halo) in self.delta_virs and self.z == 0: -1502 | return self.params[f"alpha_{int(self.delta_halo)}"] - | - -D102 Missing docstring in public method - --> src/hmf/mass_function/fitting_functions.py:1514:9 - | -1513 | @property -1514 | def fsigma(self): - | ^^^^^^ -1515 | fv = ( -1516 | (1 + (self.beta * self.nu) ** (-2 * self.phi)) - | - -D102 Missing docstring in public method - --> src/hmf/mass_function/fitting_functions.py:1524:9 - | -1523 | @property -1524 | def cutmask(self): - | ^^^^^^^ -1525 | if self.z == 0.0: -1526 | return np.logical_and( - | - -D101 Missing docstring in public class - --> src/hmf/mass_function/fitting_functions.py:1534:7 - | -1534 | class Behroozi(Tinker08): - | ^^^^^^^^ -1535 | _ref = r"""Behroozi, P., Weschler, R. and Conroy, C., ApJ, 2013, http://arxiv.org/abs/1207.6105""" -1536 | __doc__ = rf""" - | - -N806 Variable `dthetadM` in function should be lowercase - --> src/hmf/mass_function/fitting_functions.py:1586:9 - | -1584 | ) -1585 | ngtm_behroozi = 10 ** (theta + np.log10(ngtm_tinker)) -1586 | dthetadM = ( - | ^^^^^^^^ -1587 | 0.144 -1588 | / (1 + np.exp(14.79 * (a - 0.213))) - | - -D101 Missing docstring in public class - --> src/hmf/mass_function/fitting_functions.py:1599:7 - | -1599 | class Pillepich(Warren): - | ^^^^^^^^^ -1600 | _ref = r"""Pillepich, A., et al., 2010, arxiv:0811.4176""" -1601 | __doc__ = _makedoc( - | - -RUF012 Mutable default value for class attribute - --> src/hmf/mass_function/fitting_functions.py:1604:17 - | -1602 | FittingFunction._pdocs, "Pillepich", "Pillepich", Warren._eq, _ref -1603 | ) -1604 | _defaults = {"A": 0.6853, "b": 1.868, "c": 0.3324, "d": 1.2266, "e": 1} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -1605 | normalized = False - | -help: Consider initializing in `__init__` or annotating with `typing.ClassVar` - -D101 Missing docstring in public class - --> src/hmf/mass_function/fitting_functions.py:1631:7 - | -1631 | class Manera(SMT): - | ^^^^^^ -1632 | _ref = r"""Manera, M., et al., 2010, arxiv:0906.1314""" -1633 | __doc__ = _makedoc(FittingFunction._pdocs, "Manera", "Man", SMT._eq, _ref) - | - -RUF012 Mutable default value for class attribute - --> src/hmf/mass_function/fitting_functions.py:1635:17 - | -1633 | __doc__ = _makedoc(FittingFunction._pdocs, "Manera", "Man", SMT._eq, _ref) -1634 | # These are for z=0, new ML method, l_linnk = 0.2 -1635 | _defaults = {"A": None, "a": 0.709, "p": 0.289} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -1636 | -1637 | sim_definition = SimDetails( - | -help: Consider initializing in `__init__` or annotating with `typing.ClassVar` - -D101 Missing docstring in public class - --> src/hmf/mass_function/fitting_functions.py:1661:7 - | -1661 | class Ishiyama(Warren): - | ^^^^^^^^ -1662 | _eq = r"A\left[\left(\frac{e}{\sigma}\right)^b + 1\right]\exp(\frac{d}{\sigma^2})" -1663 | _ref = r"""Ishiyama, T., et al., 2015, arxiv:1412.2860""" - | - -RUF012 Mutable default value for class attribute - --> src/hmf/mass_function/fitting_functions.py:1666:17 - | -1664 | __doc__ = _makedoc(FittingFunction._pdocs, "Ishiyama", "Ishiyama", _eq, _ref) -1665 | -1666 | _defaults = {"A": 0.193, "b": 1.550, "c": 1, "d": 1.186, "e": 2.184} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -1667 | -1668 | sim_definition = SimDetails( - | -help: Consider initializing in `__init__` or annotating with `typing.ClassVar` - -D102 Missing docstring in public method - --> src/hmf/mass_function/fitting_functions.py:1692:9 - | -1691 | @property -1692 | def cutmask(self): - | ^^^^^^^ -1693 | return np.logical_and(self.m > 1e8, self.m < 1e16) - | - -D101 Missing docstring in public class - --> src/hmf/mass_function/fitting_functions.py:1696:7 - | -1696 | class Bocquet200mDMOnly(Warren): - | ^^^^^^^^^^^^^^^^^ -1697 | _eq = r"A\left[\left(\frac{e}{\sigma}\right)^b + 1\right]\exp(-\frac{d}{\sigma^2})" -1698 | _ref = r"""Bocuet, S., et al., 2016, MNRAS 456 2361""" - | - -RUF012 Mutable default value for class attribute - --> src/hmf/mass_function/fitting_functions.py:1700:17 - | -1698 | _ref = r"""Bocuet, S., et al., 2016, MNRAS 456 2361""" -1699 | __doc__ = _makedoc(FittingFunction._pdocs, "Bocquet", "Bocquet", _eq, _ref) -1700 | _defaults = { - | _________________^ -1701 | | "A": 0.216, -1702 | | "b": 1.87, -1703 | | "c": 1, -1704 | | "d": 1.31, -1705 | | "e": 2.02, -1706 | | "A_z": 0.018, -1707 | | "b_z": -0.0748, -1708 | | "d_z": -0.0689, -1709 | | "e_z": -0.215, -1710 | | } - | |_____^ -1711 | -1712 | sim_definition = SimDetails( - | -help: Consider initializing in `__init__` or annotating with `typing.ClassVar` - -D401 First line of docstring should be in imperative mood: "Function to compute mass in this definition compared to 200m." - --> src/hmf/mass_function/fitting_functions.py:1745:9 - | -1744 | def convert_mass(self): -1745 | / """Function to compute mass in this definition compared to 200m. -1746 | | -1747 | | This is an analytic approximation, not a full mass translation, and is calibrated -1748 | | to the NFW profile with Duffy+08 concentration-mass relation. This ratio is -1749 | | applied in :meth:`fsigma`. -1750 | | """ - | |___________^ -1751 | return 1 - | - -E501 Line too long (89 > 88) - --> src/hmf/mass_function/fitting_functions.py:1747:89 - | -1745 | """Function to compute mass in this definition compared to 200m. -1746 | -1747 | This is an analytic approximation, not a full mass translation, and is calibrated - | ^ -1748 | to the NFW profile with Duffy+08 concentration-mass relation. This ratio is -1749 | applied in :meth:`fsigma`. - | - -D102 Missing docstring in public method - --> src/hmf/mass_function/fitting_functions.py:1754:9 - | -1753 | @property -1754 | def fsigma(self): - | ^^^^^^ -1755 | A, b, d, e = self.get_params() -1756 | mass_conversion = self.convert_mass() - | - -N806 Variable `A` in function should be lowercase - --> src/hmf/mass_function/fitting_functions.py:1755:9 - | -1753 | @property -1754 | def fsigma(self): -1755 | A, b, d, e = self.get_params() - | ^ -1756 | mass_conversion = self.convert_mass() -1757 | return ( - | - -D101 Missing docstring in public class - --> src/hmf/mass_function/fitting_functions.py:1765:7 - | -1765 | class Bocquet200mHydro(Bocquet200mDMOnly): - | ^^^^^^^^^^^^^^^^ -1766 | __doc__ = _makedoc( -1767 | FittingFunction._pdocs, - | - -RUF012 Mutable default value for class attribute - --> src/hmf/mass_function/fitting_functions.py:1773:17 - | -1771 | Bocquet200mDMOnly._ref, -1772 | ) -1773 | _defaults = { - | _________________^ -1774 | | "A": 0.240, -1775 | | "b": 2.43, -1776 | | "c": 1, -1777 | | "d": 1.41, -1778 | | "e": 1.65, -1779 | | "A_z": 0.365, -1780 | | "b_z": -0.129, -1781 | | "d_z": -0.138, -1782 | | "e_z": -0.453, -1783 | | } - | |_____^ - | -help: Consider initializing in `__init__` or annotating with `typing.ClassVar` - -D101 Missing docstring in public class - --> src/hmf/mass_function/fitting_functions.py:1786:7 - | -1786 | class Bocquet200cDMOnly(Bocquet200mDMOnly): - | ^^^^^^^^^^^^^^^^^ -1787 | __doc__ = _makedoc( -1788 | FittingFunction._pdocs, - | - -RUF012 Mutable default value for class attribute - --> src/hmf/mass_function/fitting_functions.py:1795:17 - | -1793 | ) -1794 | -1795 | _defaults = { - | _________________^ -1796 | | "A": 0.256, -1797 | | "b": 2.01, -1798 | | "c": 1, -1799 | | "d": 1.59, -1800 | | "e": 1.97, -1801 | | "A_z": 0.218, -1802 | | "b_z": 0.290, -1803 | | "d_z": -0.174, -1804 | | "e_z": -0.518, -1805 | | } - | |_____^ -1806 | sim_definition = copy(Bocquet200mDMOnly.sim_definition) -1807 | sim_definition.halo_overdensity = "200c" - | -help: Consider initializing in `__init__` or annotating with `typing.ClassVar` - -D102 Missing docstring in public method - --> src/hmf/mass_function/fitting_functions.py:1809:9 - | -1807 | sim_definition.halo_overdensity = "200c" -1808 | -1809 | def convert_mass(self): - | ^^^^^^^^^^^^ -1810 | g0 = 3.54e-2 + self.cosmo.Om0**0.09 -1811 | g1 = 4.56e-2 + 2.68e-2 / self.cosmo.Om0 - | - -D101 Missing docstring in public class - --> src/hmf/mass_function/fitting_functions.py:1822:7 - | -1822 | class Bocquet200cHydro(Bocquet200cDMOnly): - | ^^^^^^^^^^^^^^^^ -1823 | __doc__ = _makedoc( -1824 | FittingFunction._pdocs, - | - -RUF012 Mutable default value for class attribute - --> src/hmf/mass_function/fitting_functions.py:1831:17 - | -1829 | ) -1830 | -1831 | _defaults = { - | _________________^ -1832 | | "A": 0.290, -1833 | | "b": 2.69, -1834 | | "c": 1, -1835 | | "d": 1.70, -1836 | | "e": 1.58, -1837 | | "A_z": 0.216, -1838 | | "b_z": 0.027, -1839 | | "d_z": -0.226, -1840 | | "e_z": -0.352, -1841 | | } - | |_____^ - | -help: Consider initializing in `__init__` or annotating with `typing.ClassVar` - -D101 Missing docstring in public class - --> src/hmf/mass_function/fitting_functions.py:1844:7 - | -1844 | class Bocquet500cDMOnly(Bocquet200cDMOnly): - | ^^^^^^^^^^^^^^^^^ -1845 | __doc__ = _makedoc( -1846 | FittingFunction._pdocs, - | - -RUF012 Mutable default value for class attribute - --> src/hmf/mass_function/fitting_functions.py:1853:17 - | -1851 | ) -1852 | -1853 | _defaults = { - | _________________^ -1854 | | "A": 0.390, -1855 | | "b": 3.05, -1856 | | "c": 1, -1857 | | "d": 2.32, -1858 | | "e": 1.72, -1859 | | "A_z": -0.924, -1860 | | "b_z": -0.421, -1861 | | "d_z": -0.509, -1862 | | "e_z": 0.190, -1863 | | } - | |_____^ -1864 | sim_definition = copy(Bocquet200mDMOnly.sim_definition) -1865 | sim_definition.halo_overdensity = "500c" - | -help: Consider initializing in `__init__` or annotating with `typing.ClassVar` - -D102 Missing docstring in public method - --> src/hmf/mass_function/fitting_functions.py:1867:9 - | -1865 | sim_definition.halo_overdensity = "500c" -1866 | -1867 | def convert_mass(self): - | ^^^^^^^^^^^^ -1868 | alpha_0 = 0.880 + 0.329 * self.cosmo.Om0 -1869 | alpha_1 = 1.0 + 4.31 * 1e-2 / self.cosmo.Om0 - | - -D101 Missing docstring in public class - --> src/hmf/mass_function/fitting_functions.py:1876:7 - | -1876 | class Bocquet500cHydro(Bocquet500cDMOnly): - | ^^^^^^^^^^^^^^^^ -1877 | __doc__ = _makedoc( -1878 | FittingFunction._pdocs, - | - -RUF012 Mutable default value for class attribute - --> src/hmf/mass_function/fitting_functions.py:1885:17 - | -1883 | ) -1884 | -1885 | _defaults = { - | _________________^ -1886 | | "A": 0.322, -1887 | | "b": 3.24, -1888 | | "c": 1, -1889 | | "d": 2.29, -1890 | | "e": 1.71, -1891 | | "A_z": 0.0142, -1892 | | "b_z": -0.219, -1893 | | "d_z": -0.428, -1894 | | "e_z": -0.275, -1895 | | } - | |_____^ - | -help: Consider initializing in `__init__` or annotating with `typing.ClassVar` - -N813 Camelcase `InterpolatedUnivariateSpline` imported as lowercase `spline` - --> src/hmf/mass_function/hmf.py:13:31 - | -12 | import numpy as np -13 | from scipy.interpolate import InterpolatedUnivariateSpline as spline - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -14 | from scipy.optimize import minimize - | - -N813 Camelcase `MassDefinition` imported as lowercase `md` - --> src/hmf/mass_function/hmf.py:20:38 - | -18 | from ..density_field import transfer -19 | from ..density_field.filters import Filter, TopHat -20 | from ..halos.mass_definitions import MassDefinition as md - | ^^^^^^^^^^^^^^^^^^^^ -21 | from ..halos.mass_definitions import SOGeneric, SOMean -22 | from . import fitting_functions as ff - | - -E501 Line too long (89 > 88) - --> src/hmf/mass_function/hmf.py:63:89 - | -61 | mdef_model -62 | The mass definition model to use. By default, use the mass definition in which -63 | the chosen HMF was measured. If that does not exist, use ``SOMean(200)``. If set, - | ^ -64 | this must be compatible with the halo definition used in measuring the chosen -65 | HMF -- unless ``disable_mass_conversion`` is set to False, in which case the - | - -N803 Argument name `Mmin` should be lowercase - --> src/hmf/mass_function/hmf.py:100:9 - | - 98 | def __init__( - 99 | self, -100 | Mmin: float = 10.0, - | ^^^^^^^^^^^^^^^^^^ -101 | Mmax: float = 15.0, -102 | dlog10m: float = 0.01, - | - -N803 Argument name `Mmax` should be lowercase - --> src/hmf/mass_function/hmf.py:101:9 - | - 99 | self, -100 | Mmin: float = 10.0, -101 | Mmax: float = 15.0, - | ^^^^^^^^^^^^^^^^^^ -102 | dlog10m: float = 0.01, -103 | hmf_model: str | ff.FittingFunction = ff.Tinker08, - | - -D102 Missing docstring in public method - --> src/hmf/mass_function/hmf.py:132:9 - | -130 | # PARAMETERS -131 | # =========================================================================== -132 | def validate(self): - | ^^^^^^^^ -133 | super().validate() -134 | assert self.Mmin < self.Mmax, f"Mmin > Mmax: {self.Mmin}, {self.Mmax}" - | - -B018 Found useless expression. Either assign it to a variable or remove it. - --> src/hmf/mass_function/hmf.py:138:9 - | -137 | # Check whether the hmf component validates. -138 | self.hmf - | ^^^^^^^^ -139 | -140 | @parameter("res") - | - -N802 Function name `Mmin` should be lowercase - --> src/hmf/mass_function/hmf.py:141:9 - | -140 | @parameter("res") -141 | def Mmin(self, val): - | ^^^^ -142 | r""" -143 | Minimum mass at which to perform analysis [units :math:`\log_{10}M_\odot h^{-1}`]. - | -help: Consider adding `@typing.override` if this method overrides a method from a superclass - -E501 Line too long (90 > 88) - --> src/hmf/mass_function/hmf.py:143:89 - | -141 | def Mmin(self, val): -142 | r""" -143 | Minimum mass at which to perform analysis [units :math:`\log_{10}M_\odot h^{-1}`]. - | ^^ -144 | -145 | :type: float - | - -N802 Function name `Mmax` should be lowercase - --> src/hmf/mass_function/hmf.py:150:9 - | -149 | @parameter("res") -150 | def Mmax(self, val): - | ^^^^ -151 | r""" -152 | Maximum mass at which to perform analysis [units :math:`\log_{10}M_\odot h^{-1}`]. - | -help: Consider adding `@typing.override` if this method overrides a method from a superclass - -E501 Line too long (90 > 88) - --> src/hmf/mass_function/hmf.py:152:89 - | -150 | def Mmax(self, val): -151 | r""" -152 | Maximum mass at which to perform analysis [units :math:`\log_{10}M_\odot h^{-1}`]. - | ^^ -153 | -154 | :type: float - | - -D401 First line of docstring should be in imperative mood: "A model for the window/filter function." - --> src/hmf/mass_function/hmf.py:177:9 - | -175 | @parameter("model") -176 | def filter_model(self, val): -177 | / """ -178 | | A model for the window/filter function. -179 | | -180 | | :type: :class:`hmf.filters.Filter` subclass -181 | | """ - | |___________^ -182 | return get_mdl(val, "Filter") - | - -D401 First line of docstring should be in imperative mood: "The critical overdensity for collapse, :math:`\delta_c`." - --> src/hmf/mass_function/hmf.py:195:9 - | -193 | @parameter("param") -194 | def delta_c(self, val): -195 | / r""" -196 | | The critical overdensity for collapse, :math:`\delta_c`. -197 | | -198 | | :type: float -199 | | """ - | |___________^ -200 | try: -201 | val = float(val) - | - -B904 Within an `except` clause, raise exceptions with `raise ... from err` or `raise ... from None` to distinguish them from errors in exception handling - --> src/hmf/mass_function/hmf.py:203:13 - | -201 | val = float(val) -202 | except ValueError: -203 | raise ValueError("delta_c must be a number: ", val) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -204 | -205 | if val <= 0: - | - -D401 First line of docstring should be in imperative mood: "A model to use as the fitting function :math:`f(\sigma)`." - --> src/hmf/mass_function/hmf.py:214:9 - | -212 | @parameter("model") -213 | def hmf_model(self, val): -214 | / r""" -215 | | A model to use as the fitting function :math:`f(\sigma)`. -216 | | -217 | | :type: str or `hmf.fitting_functions.FittingFunction` subclass -218 | | """ - | |___________^ -219 | if val is None: -220 | return val - | - -D401 First line of docstring should be in imperative mood: "A model to use as the mass definition." - --> src/hmf/mass_function/hmf.py:234:9 - | -232 | @parameter("model") -233 | def mdef_model(self, val): -234 | / """ -235 | | A model to use as the mass definition. -236 | | -237 | | :type: str or :class:`hmf.halos.mass_definitions.MassDefinition` subclass -238 | | """ - | |___________^ -239 | if val is None or (isinstance(val, str) and val.lower() == "none"): -240 | return None - | - -D205 1 blank line required between summary line and description - --> src/hmf/mass_function/hmf.py:245:9 - | -243 | @parameter("param") -244 | def mdef_params(self, val): -245 | / """ -246 | | Model parameters for `mdef_model`. -247 | | :type: dict. -248 | | """ - | |___________^ -249 | return val - | -help: Insert single blank line - -D401 First line of docstring should be in imperative mood: "The halo mass-definition model instance." - --> src/hmf/mass_function/hmf.py:259:9 - | -257 | @cached_quantity -258 | def mdef(self) -> md: -259 | / """The halo mass-definition model instance. -260 | | -261 | | Default mass definition is the one the chosen hmf model was measured with. -262 | | """ - | |___________^ -263 | if self.mdef_model is None: -264 | # Get the default from the mass function definition - | - -E501 Line too long (89 > 88) - --> src/hmf/mass_function/hmf.py:288:89 - | -286 | raise ValueError( -287 | f"Your input mass definition '{mdef}' does not match the mass " -288 | f"definition in which the hmf fit {self.hmf_model.__name__} was " - | ^ -289 | f"measured: '{self.hmf_model.get_measured_mdef()}' Either allow " -290 | f"automatic mass conversion by setting `disable_mass_conversion=False, " - | - -E501 Line too long (89 > 88) - --> src/hmf/mass_function/hmf.py:289:89 - | -287 | f"Your input mass definition '{mdef}' does not match the mass " -288 | f"definition in which the hmf fit {self.hmf_model.__name__} was " -289 | f"measured: '{self.hmf_model.get_measured_mdef()}' Either allow " - | ^ -290 | f"automatic mass conversion by setting `disable_mass_conversion=False, " -291 | "or use the correct mass definition." - | - -E501 Line too long (96 > 88) - --> src/hmf/mass_function/hmf.py:290:89 - | -288 | f"definition in which the hmf fit {self.hmf_model.__name__} was " -289 | f"measured: '{self.hmf_model.get_measured_mdef()}' Either allow " -290 | f"automatic mass conversion by setting `disable_mass_conversion=False, " - | ^^^^^^^^ -291 | "or use the correct mass definition." -292 | ) - | - -E501 Line too long (94 > 88) - --> src/hmf/mass_function/hmf.py:302:89 - | -300 | warnings.warn( -301 | f"Your input mass definition '{mdef}' does not match the mass " -302 | f"definition in which the hmf fit {self.hmf_model.__name__} was measured:" - | ^^^^^^ -303 | f"'{self.hmf_model.get_measured_mdef()}'. {extra_msg if not self.disable_mass_conversion else ''}", stacklevel=2 -304 | ) - | - -E501 Line too long (132 > 88) - --> src/hmf/mass_function/hmf.py:303:89 - | -301 | f"Your input mass definition '{mdef}' does not match the mass " -302 | f"definition in which the hmf fit {self.hmf_model.__name__} was measured:" -303 | f"'{self.hmf_model.get_measured_mdef()}'. {extra_msg if not self.disable_mass_conversion else ''}", stacklevel=2 - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -304 | ) - | - -D401 First line of docstring should be in imperative mood: "Instantiated model for the hmf fitting function." - --> src/hmf/mass_function/hmf.py:310:9 - | -308 | @cached_quantity -309 | def hmf(self): -310 | """Instantiated model for the hmf fitting function.""" - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -311 | return self.hmf_model( -312 | m=self.m, - | - -D401 First line of docstring should be in imperative mood: "Instantiated model for filter/window functions." - --> src/hmf/mass_function/hmf.py:324:9 - | -322 | @cached_quantity -323 | def filter(self): -324 | / """Instantiated model for filter/window functions. -325 | | -326 | | Note that this filter is *not* normalised -- i.e. the output of `filter.sigma(8)` -327 | | will not be the input `sigma_8`. -328 | | """ - | |___________^ -329 | return self.filter_model(self.k, self._unnormalised_power, **self.filter_params) - | - -E501 Line too long (89 > 88) - --> src/hmf/mass_function/hmf.py:326:89 - | -324 | """Instantiated model for filter/window functions. -325 | -326 | Note that this filter is *not* normalised -- i.e. the output of `filter.sigma(8)` - | ^ -327 | will not be the input `sigma_8`. -328 | """ - | - -D401 First line of docstring should be in imperative mood: "The halo overdensity with respect to the mean background." - --> src/hmf/mass_function/hmf.py:333:9 - | -331 | @cached_quantity -332 | def halo_overdensity_mean(self): -333 | """The halo overdensity with respect to the mean background.""" - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -334 | return self.mdef.halo_overdensity_mean(self.z, self.cosmo) - | - -D401 First line of docstring should be in imperative mood: "The halo overdensity with respect to the critical density." - --> src/hmf/mass_function/hmf.py:338:9 - | -336 | @cached_quantity -337 | def halo_overdensity_crit(self): -338 | """The halo overdensity with respect to the critical density.""" - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -339 | return self.mdef.halo_overdensity_crit(self.z, self.cosmo) - | - -D401 First line of docstring should be in imperative mood: "A normalised filter, such that filter.sigma(8) == sigma8." - --> src/hmf/mass_function/hmf.py:343:9 - | -341 | @cached_quantity -342 | def normalised_filter(self): -343 | """A normalised filter, such that filter.sigma(8) == sigma8.""" - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -344 | return self.filter_model(self.k, self.power, **self.filter_params) - | - -D401 First line of docstring should be in imperative mood: "The normalised mass variance at z=0 :math:`\sigma`." - --> src/hmf/mass_function/hmf.py:358:9 - | -356 | @cached_quantity -357 | def _sigma_0(self): -358 | r"""The normalised mass variance at z=0 :math:`\sigma`.""" - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -359 | return self._normalisation * self._unn_sigma0 - | - -D401 First line of docstring should be in imperative mood: "The radii corresponding to the masses `m`." - --> src/hmf/mass_function/hmf.py:368:9 - | -366 | @cached_quantity -367 | def radii(self): -368 | / """The radii corresponding to the masses `m`. -369 | | -370 | | Note that these are not the halo radii -- they are the radii containing mass -371 | | m given a purely background density. -372 | | """ - | |___________^ -373 | return self.filter.mass_to_radius(self.m, self.mean_density0) - | - -D401 First line of docstring should be in imperative mood: "The value of :math:`\left|\frac{\d \ln \sigma}{\d \ln m}\right|`, ``len=len(m)``." - --> src/hmf/mass_function/hmf.py:377:9 - | -375 | @cached_quantity -376 | def _dlnsdlnm(self): -377 | / r""" -378 | | The value of :math:`\left|\frac{\d \ln \sigma}{\d \ln m}\right|`, ``len=len(m)``. -379 | | -380 | | Notes -381 | | ----- -382 | | .. math:: frac{d\ln\sigma}{d\ln m} = \frac{3}{2\sigma^2\pi^2R^4}\int_0^\infty \frac{dW^2(kR)}{dM}\frac{P(k)}{k^2}dk -383 | | """ - | |___________^ -384 | return 0.5 * self.filter.dlnss_dlnm(self.radii) - | - -E501 Line too long (89 > 88) - --> src/hmf/mass_function/hmf.py:378:89 - | -376 | def _dlnsdlnm(self): -377 | r""" -378 | The value of :math:`\left|\frac{\d \ln \sigma}{\d \ln m}\right|`, ``len=len(m)``. - | ^ -379 | -380 | Notes - | - -E501 Line too long (123 > 88) - --> src/hmf/mass_function/hmf.py:382:89 - | -380 | Notes -381 | ----- -382 | .. math:: frac{d\ln\sigma}{d\ln m} = \frac{3}{2\sigma^2\pi^2R^4}\int_0^\infty \frac{dW^2(kR)}{dM}\frac{P(k)}{k^2}dk - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -383 | """ -384 | return 0.5 * self.filter.dlnss_dlnm(self.radii) - | - -D401 First line of docstring should be in imperative mood: "The sqrt of the mass variance at `z`, ``len=len(m)``." - --> src/hmf/mass_function/hmf.py:388:9 - | -386 | @cached_quantity -387 | def sigma(self): -388 | """The sqrt of the mass variance at `z`, ``len=len(m)``.""" - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -389 | return self._sigma_0 * self.growth_factor - | - -D401 First line of docstring should be in imperative mood: "The parameter :math:`\nu = \left(\frac{\delta_c}{\sigma}\right)^2`, ``len=len(m)``." - --> src/hmf/mass_function/hmf.py:393:9 - | -391 | @cached_quantity -392 | def nu(self): -393 | r"""The parameter :math:`\nu = \left(\frac{\delta_c}{\sigma}\right)^2`, ``len=len(m)``.""" - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -394 | return (self.delta_c / self.sigma) ** 2 - | - -E501 Line too long (98 > 88) - --> src/hmf/mass_function/hmf.py:393:89 - | -391 | @cached_quantity -392 | def nu(self): -393 | r"""The parameter :math:`\nu = \left(\frac{\delta_c}{\sigma}\right)^2`, ``len=len(m)``.""" - | ^^^^^^^^^^ -394 | return (self.delta_c / self.sigma) ** 2 - | - -D205 1 blank line required between summary line and description - --> src/hmf/mass_function/hmf.py:398:9 - | -396 | @cached_quantity -397 | def nu_fn(self): -398 | / r""" -399 | | The parameter :math:`\nu = \left(\frac{\delta_c}{\sigma}\right)^2`, ``len=len(m)`` -400 | | as a callable function. -401 | | """ - | |___________^ -402 | return spline(self.m, self.nu, k=5) - | -help: Insert single blank line - -D401 First line of docstring should be in imperative mood: "The parameter :math:`\nu = \left(\frac{\delta_c}{\sigma}\right)^2`, ``len=len(m)``" - --> src/hmf/mass_function/hmf.py:398:9 - | -396 | @cached_quantity -397 | def nu_fn(self): -398 | / r""" -399 | | The parameter :math:`\nu = \left(\frac{\delta_c}{\sigma}\right)^2`, ``len=len(m)`` -400 | | as a callable function. -401 | | """ - | |___________^ -402 | return spline(self.m, self.nu, k=5) - | - -E501 Line too long (90 > 88) - --> src/hmf/mass_function/hmf.py:399:89 - | -397 | def nu_fn(self): -398 | r""" -399 | The parameter :math:`\nu = \left(\frac{\delta_c}{\sigma}\right)^2`, ``len=len(m)`` - | ^^ -400 | as a callable function. -401 | """ - | - -D401 First line of docstring should be in imperative mood: "The nonlinear mass, nu(Mstar) = 1." - --> src/hmf/mass_function/hmf.py:406:9 - | -404 | @cached_quantity -405 | def mass_nonlinear(self): -406 | """The nonlinear mass, nu(Mstar) = 1.""" - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -407 | if self.nu.min() > 1 or self.nu.max() < 1: -408 | warnings.warn("Nonlinear mass outside mass range", stacklevel=2) - | - -D401 First line of docstring should be in imperative mood: "The multiplicity function, :math:`f(\sigma)`, for `hmf_model`. ``len=len(m)``." - --> src/hmf/mass_function/hmf.py:469:9 - | -467 | @cached_quantity -468 | def fsigma(self): -469 | r"""The multiplicity function, :math:`f(\sigma)`, for `hmf_model`. ``len=len(m)``.""" - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -470 | return self.hmf.fsigma - | - -E501 Line too long (93 > 88) - --> src/hmf/mass_function/hmf.py:469:89 - | -467 | @cached_quantity -468 | def fsigma(self): -469 | r"""The multiplicity function, :math:`f(\sigma)`, for `hmf_model`. ``len=len(m)``.""" - | ^^^^^ -470 | return self.hmf.fsigma - | - -D401 First line of docstring should be in imperative mood: "The number density of haloes, ``len=len(m)`` [units :math:`h^4 M_\odot^{-1} Mpc^{-3}`]." - --> src/hmf/mass_function/hmf.py:474:9 - | -472 | @cached_quantity -473 | def dndm(self): -474 | r"""The number density of haloes, ``len=len(m)`` [units :math:`h^4 M_\odot^{-1} Mpc^{-3}`].""" - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -475 | # if self.z2 is None: # #This is normally the case -476 | dndm = self.fsigma * self.mean_density0 * np.abs(self._dlnsdlnm) / self.m**2 - | - -E501 Line too long (102 > 88) - --> src/hmf/mass_function/hmf.py:474:89 - | -472 | @cached_quantity -473 | def dndm(self): -474 | r"""The number density of haloes, ``len=len(m)`` [units :math:`h^4 M_\odot^{-1} Mpc^{-3}`].""" - | ^^^^^^^^^^^^^^ -475 | # if self.z2 is None: # #This is normally the case -476 | dndm = self.fsigma * self.mean_density0 * np.abs(self._dlnsdlnm) / self.m**2 - | - -D401 First line of docstring should be in imperative mood: "The differential mass function in terms of natural log of `m`, ``len=len(m)`` [units :math:`h^3 Mpc^{-3}`]." - --> src/hmf/mass_function/hmf.py:503:9 - | -501 | @cached_quantity -502 | def dndlnm(self): -503 | r"""The differential mass function in terms of natural log of `m`, ``len=len(m)`` [units :math:`h^3 Mpc^{-3}`].""" - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -504 | return self.m * self.dndm - | - -E501 Line too long (122 > 88) - --> src/hmf/mass_function/hmf.py:503:89 - | -501 | @cached_quantity -502 | def dndlnm(self): -503 | r"""The differential mass function in terms of natural log of `m`, ``len=len(m)`` [units :math:`h^3 Mpc^{-3}`].""" - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -504 | return self.m * self.dndm - | - -D401 First line of docstring should be in imperative mood: "The differential mass function in terms of log of `m`, ``len=len(m)`` [units :math:`h^3 Mpc^{-3}`]." - --> src/hmf/mass_function/hmf.py:508:9 - | -506 | @cached_quantity -507 | def dndlog10m(self): -508 | r"""The differential mass function in terms of log of `m`, ``len=len(m)`` [units :math:`h^3 Mpc^{-3}`].""" - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -509 | return self.m * self.dndm * np.log(10) - | - -E501 Line too long (114 > 88) - --> src/hmf/mass_function/hmf.py:508:89 - | -506 | @cached_quantity -507 | def dndlog10m(self): -508 | r"""The differential mass function in terms of log of `m`, ``len=len(m)`` [units :math:`h^3 Mpc^{-3}`].""" - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -509 | return self.m * self.dndm * np.log(10) - | - -SIM102 Use a single `if` statement instead of nested `if` statements - --> src/hmf/mass_function/hmf.py:533:9 - | -531 | # The dlog10m is NOT CHANGED, so the input needs to be finely spaced. -532 | # If the top value of dndm is NaN, don't try calculating higher masses. -533 | / if m[-1] < 10**16.5 and not np.isnan(dndm[-1]) and dndm[-1] != 0: -534 | | # ff.Behroozi function won't work here. -535 | | if not isinstance(self.hmf, ff.Behroozi): - | |_____________________________________________________^ -536 | new_mf = copy.deepcopy(self) -537 | new_mf.update(Mmin=np.log10(self.m[-1]) + self.dlog10m, Mmax=18) - | -help: Combine `if` statements using `and` - -ERA001 Found commented-out code - --> src/hmf/mass_function/hmf.py:548:13 - | -546 | if len(ngtm) < len(m): # Will happen if some dndlnm are NaN -547 | ngtm_temp = np.zeros(len(dndm)) -548 | # ngtm_temp[:] = np.nan - | ^^^^^^^^^^^^^^^^^^^^^^^ -549 | ngtm_temp[dndm > 0] = ngtm -550 | ngtm = ngtm_temp - | -help: Remove commented-out code - -D401 First line of docstring should be in imperative mood: "The cumulative mass function above `m`, ``len=len(m)`` [units :math:`h^3 Mpc^{-3}`]." - --> src/hmf/mass_function/hmf.py:557:9 - | -555 | @cached_quantity -556 | def ngtm(self): -557 | / r""" -558 | | The cumulative mass function above `m`, ``len=len(m)`` [units :math:`h^3 Mpc^{-3}`]. -559 | | -560 | | In the case that `m` does not extend to sufficiently high masses, this -561 | | routine will auto-generate ``dndm`` for an extended mass range. -562 | | -563 | | In the case of the ff.Behroozi fit, it is impossible to auto-extend the mass -564 | | range except by the power-law fit, thus one should be careful to supply -565 | | appropriate mass ranges in this case. -566 | | """ - | |___________^ -567 | return self._gtm(self.dndm) - | - -E501 Line too long (92 > 88) - --> src/hmf/mass_function/hmf.py:558:89 - | -556 | def ngtm(self): -557 | r""" -558 | The cumulative mass function above `m`, ``len=len(m)`` [units :math:`h^3 Mpc^{-3}`]. - | ^^^^ -559 | -560 | In the case that `m` does not extend to sufficiently high masses, this - | - -E501 Line too long (89 > 88) - --> src/hmf/mass_function/hmf.py:572:89 - | -570 | def rho_gtm(self): -571 | r""" -572 | Mass density in haloes `>m`, ``len=len(m)`` [units :math:`M_\odot h^2 Mpc^{-3}`]. - | ^ -573 | -574 | In the case that `m` does not extend to sufficiently high masses, this - | - -E501 Line too long (89 > 88) - --> src/hmf/mass_function/hmf.py:586:89 - | -584 | def rho_ltm(self): -585 | r""" -586 | Mass density in haloes ` src/hmf/mass_function/hmf.py:606:9 - | -604 | @cached_quantity -605 | def how_big(self): -606 | / r""" -607 | | Size of simulation volume in which to expect one halo of mass m (with 95% probability), ` -608 | | `len=len(m)`` [units :math:`Mpch^{-1}`]. -609 | | """ - | |___________^ -610 | return (0.366362 / self.ngtm) ** (1.0 / 3.0) - | -help: Insert single blank line - -E501 Line too long (97 > 88) - --> src/hmf/mass_function/hmf.py:607:89 - | -605 | def how_big(self): -606 | r""" -607 | Size of simulation volume in which to expect one halo of mass m (with 95% probability), ` - | ^^^^^^^^^ -608 | `len=len(m)`` [units :math:`Mpch^{-1}`]. -609 | """ - | - -E501 Line too long (103 > 88) - --> src/hmf/mass_function/integrate_hmf.py:1:89 - | -1 | """A supporting module that provides a routine to integrate the differential hmf in a robust manner.""" - | ^^^^^^^^^^^^^^^ -2 | -3 | import numpy as np - | - -N813 Camelcase `InterpolatedUnivariateSpline` imported as lowercase `_spline` - --> src/hmf/mass_function/integrate_hmf.py:5:31 - | -3 | import numpy as np -4 | import scipy.integrate as intg -5 | from scipy.interpolate import InterpolatedUnivariateSpline as _spline - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - -N818 Exception name `NaNException` should be named with an Error suffix - --> src/hmf/mass_function/integrate_hmf.py:8:7 - | -8 | class NaNException(Exception): - | ^^^^^^^^^^^^ -9 | """Integrator hit a NaN.""" - | - -E501 Line too long (93 > 88) - --> src/hmf/mass_function/integrate_hmf.py:62:89 - | -60 | if len(m) < 4: -61 | raise NaNException( -62 | f"There are too few real numbers in dndm: len(dndm) = {n}, #NaN's = {n - len(m)}" - | ^^^^^ -63 | ) - | - -PTH123 `open()` should be replaced by `Path.open()` - --> tests/test_cli.py:37:10 - | -35 | """ -36 | -37 | with open(tmpdir / "cfg.toml", "w") as fl: - | ^^^^ -38 | fl.write(cfg) - | -help: Replace with `Path.open()` - -PTH123 `open()` should be replaced by `Path.open()` - --> tests/test_cli.py:65:10 - | -63 | """ -64 | -65 | with open(tmpdir / "cfg.toml", "w") as fl: - | ^^^^ -66 | fl.write(cfg) - | -help: Replace with `Path.open()` - -PTH123 `open()` should be replaced by `Path.open()` - --> tests/test_cli.py:109:10 - | -107 | """ -108 | -109 | with open(tmpdir / "cfg.toml", "w") as fl: - | ^^^^ -110 | fl.write(cfg) - | -help: Replace with `Path.open()` - -D404 First word of the docstring should not be "This" - --> tests/test_fcoll.py:1:1 - | -1 | / """ -2 | | This module provides some tests of mgtm/mean_density0 against analytic f_coll. -3 | | -4 | | As such, it is the best test of all calculations after sigma. -5 | | """ - | |___^ -6 | -7 | import numpy as np - | - -N802 Function name `fcoll_PS` should be lowercase - --> tests/test_fcoll.py:40:5 - | -40 | def fcoll_PS(nu): - | ^^^^^^^^ -41 | return erfc(nu / np.sqrt(2)) - | - -N802 Function name `fcoll_Peacock` should be lowercase - --> tests/test_fcoll.py:44:5 - | -44 | def fcoll_Peacock(nu): - | ^^^^^^^^^^^^^ -45 | a = 1.529 -46 | b = 0.704 - | - -N803 Argument name `Mmin` should be lowercase - --> tests/test_fcoll.py:77:40 - | -75 | ], -76 | ) -77 | def test_ranges_cut(self, peacock, Mmin, Mmax): - | ^^^^ -78 | peacock.update(Mmin=Mmin, Mmax=Mmax) - | - -N803 Argument name `Mmax` should be lowercase - --> tests/test_fcoll.py:77:46 - | -75 | ], -76 | ) -77 | def test_ranges_cut(self, peacock, Mmin, Mmax): - | ^^^^ -78 | peacock.update(Mmin=Mmin, Mmax=Mmax) - | - -N803 Argument name `Mmax` should be lowercase - --> tests/test_fcoll.py:90:29 - | -89 | @pytest.mark.parametrize("Mmax", [14, 15, 16, 18, 19]) -90 | def test_mgtm(self, ps, Mmax): - | ^^^^ -91 | ps.update(Mmax=Mmax) -92 | print("rhogtm: ", ps.rho_gtm) - | - -N803 Argument name `Mmax` should be lowercase - --> tests/test_fcoll.py:99:29 - | - 98 | @pytest.mark.parametrize("Mmax", [14, 15, 16, 18, 19]) - 99 | def test_mltm(self, ps, Mmax): - | ^^^^ -100 | ps.update(Mmax=Mmax) -101 | print(np.abs(ps.rho_ltm[-1] / ps.mean_density0 - 1)) - | - -E501 Line too long (108 > 88) - --> tests/test_filters.py:1:89 - | -1 | """Analytic functions for this test are defined in "analytic_filter.ipynb" in the development/ directory.""" - | ^^^^^^^^^^^^^^^^^^^^ -2 | -3 | import warnings - | - -N806 Variable `R` in function should be lowercase - --> tests/test_filters.py:23:9 - | -22 | def test_sigma(self, cls): -23 | R = 1.0 - | ^ -24 | true = ( -25 | 9 * R**2 * sin(R) ** 2 / 2 - | - -N806 Variable `R` in function should be lowercase - --> tests/test_filters.py:35:9 - | -34 | def test_sigma1(self, cls): -35 | R = 1.0 - | ^ -36 | true = ( -37 | 3 * R**2 * sin(R) ** 2 / 2 - | - -N806 Variable `R` in function should be lowercase - --> tests/test_filters.py:54:9 - | -53 | def test_dlnssdlnr(self, cls): -54 | R = 1.0 - | ^ -55 | true = ( -56 | 2 - | - -N806 Variable `R` in function should be lowercase - --> tests/test_filters.py:84:9 - | -83 | def test_sigma(self, cls): -84 | R = 1.0 - | ^ -85 | t = 2 + 2 + 1 -86 | true = 1.0 / (2 * pi**2 * t * R**t) - | - -N806 Variable `R` in function should be lowercase - --> tests/test_filters.py:92:9 - | -91 | def test_sigma1(self, cls): -92 | R = 1.0 - | ^ -93 | t = 4 + 2 + 1 -94 | true = 1.0 / (2 * pi**2 * t * R**t) - | - -N806 Variable `R` in function should be lowercase - --> tests/test_filters.py:100:9 - | - 99 | def test_dlnssdlnr(self, cls): -100 | R = 1.0 - | ^ -101 | t = 2 + 2 + 1 -102 | sigma2 = 1.0 / (2 * pi**2 * t * R**t) - | - -N802 Function name `test_sigma_R3` should be lowercase - --> tests/test_filters.py:108:9 - | -106 | assert np.isclose(cls.dlnss_dlnr(R), true) -107 | -108 | def test_sigma_R3(self, cls): - | ^^^^^^^^^^^^^ -109 | R = 3.0 -110 | t = 2 + 2 + 1 - | -help: Consider adding `@typing.override` if this method overrides a method from a superclass - -N806 Variable `R` in function should be lowercase - --> tests/test_filters.py:109:9 - | -108 | def test_sigma_R3(self, cls): -109 | R = 3.0 - | ^ -110 | t = 2 + 2 + 1 -111 | true = 1.0 / (2 * pi**2 * t * R**t) - | - -N802 Function name `test_sigma1_R3` should be lowercase - --> tests/test_filters.py:116:9 - | -114 | assert np.isclose(cls.sigma(R)[0] ** 2, true) -115 | -116 | def test_sigma1_R3(self, cls): - | ^^^^^^^^^^^^^^ -117 | R = 3.0 -118 | t = 4 + 2 + 1 - | -help: Consider adding `@typing.override` if this method overrides a method from a superclass - -N806 Variable `R` in function should be lowercase - --> tests/test_filters.py:117:9 - | -116 | def test_sigma1_R3(self, cls): -117 | R = 3.0 - | ^ -118 | t = 4 + 2 + 1 -119 | true = 1.0 / (2 * pi**2 * t * R**t) - | - -N802 Function name `test_dlnssdlnr_R3` should be lowercase - --> tests/test_filters.py:124:9 - | -122 | assert np.isclose(cls.sigma(R, 1)[0] ** 2, true) -123 | -124 | def test_dlnssdlnr_R3(self, cls): - | ^^^^^^^^^^^^^^^^^ -125 | R = 3.0 -126 | t = 2 + 2 + 1 - | -help: Consider adding `@typing.override` if this method overrides a method from a superclass - -N806 Variable `R` in function should be lowercase - --> tests/test_filters.py:125:9 - | -124 | def test_dlnssdlnr_R3(self, cls): -125 | R = 3.0 - | ^ -126 | t = 2 + 2 + 1 -127 | sigma2 = 1.0 / (2 * pi**2 * t * R**t) - | - -N802 Function name `test_sigma_Rhalf` should be lowercase - --> tests/test_filters.py:133:9 - | -131 | assert np.isclose(cls.dlnss_dlnr(R), true) -132 | -133 | def test_sigma_Rhalf(self, cls): - | ^^^^^^^^^^^^^^^^ -134 | thisr = 1.0 / cls.k.max() -135 | t = 2 + 2 + 1 - | -help: Consider adding `@typing.override` if this method overrides a method from a superclass - -PT031 `pytest.warns()` block should contain a single simple statement - --> tests/test_filters.py:138:9 - | -136 | true = 1.0 / (2 * pi**2 * t * thisr**t) -137 | -138 | / with pytest.warns(UserWarning): -139 | | # should also raise a warning -140 | | R = 0.5 -141 | | s2 = cls.sigma(R)[0] ** 2 - | |_____________________________________^ -142 | assert np.isclose(s2, true) - | - -PT030 `pytest.warns(UserWarning)` is too broad, set the `match` parameter or use a more specific warning - --> tests/test_filters.py:138:27 - | -136 | true = 1.0 / (2 * pi**2 * t * thisr**t) -137 | -138 | with pytest.warns(UserWarning): - | ^^^^^^^^^^^ -139 | # should also raise a warning -140 | R = 0.5 - | - -N806 Variable `R` in function should be lowercase - --> tests/test_filters.py:140:13 - | -138 | with pytest.warns(UserWarning): -139 | # should also raise a warning -140 | R = 0.5 - | ^ -141 | s2 = cls.sigma(R)[0] ** 2 -142 | assert np.isclose(s2, true) - | - -N802 Function name `test_sigma1_Rhalf` should be lowercase - --> tests/test_filters.py:144:9 - | -142 | assert np.isclose(s2, true) -143 | -144 | def test_sigma1_Rhalf(self, cls): - | ^^^^^^^^^^^^^^^^^ -145 | thisr = 1.0 / cls.k.max() - | -help: Consider adding `@typing.override` if this method overrides a method from a superclass - -PT031 `pytest.warns()` block should contain a single simple statement - --> tests/test_filters.py:150:9 - | -148 | true = 1.0 / (2 * pi**2 * t * thisr**t) -149 | -150 | / with pytest.warns(UserWarning): -151 | | # should also raise a warning -152 | | R = 0.5 -153 | | s2 = cls.sigma(R, 1)[0] ** 2 - | |________________________________________^ -154 | assert np.isclose(s2, true) - | - -PT030 `pytest.warns(UserWarning)` is too broad, set the `match` parameter or use a more specific warning - --> tests/test_filters.py:150:27 - | -148 | true = 1.0 / (2 * pi**2 * t * thisr**t) -149 | -150 | with pytest.warns(UserWarning): - | ^^^^^^^^^^^ -151 | # should also raise a warning -152 | R = 0.5 - | - -N806 Variable `R` in function should be lowercase - --> tests/test_filters.py:152:13 - | -150 | with pytest.warns(UserWarning): -151 | # should also raise a warning -152 | R = 0.5 - | ^ -153 | s2 = cls.sigma(R, 1)[0] ** 2 -154 | assert np.isclose(s2, true) - | - -N802 Function name `test_dlnssdlnr_Rhalf` should be lowercase - --> tests/test_filters.py:156:9 - | -154 | assert np.isclose(s2, true) -155 | -156 | def test_dlnssdlnr_Rhalf(self, cls): - | ^^^^^^^^^^^^^^^^^^^^ -157 | R = 3.0 -158 | t = 2 + 2 + 1 - | -help: Consider adding `@typing.override` if this method overrides a method from a superclass - -N806 Variable `R` in function should be lowercase - --> tests/test_filters.py:157:9 - | -156 | def test_dlnssdlnr_Rhalf(self, cls): -157 | R = 3.0 - | ^ -158 | t = 2 + 2 + 1 -159 | sigma2 = 1.0 / (2 * pi**2 * t * R**t) - | - -N806 Variable `R` in function should be lowercase - --> tests/test_filters.py:174:9 - | -173 | def test_sigma(self, cls): -174 | R = 10.0 - | ^ -175 | true = 3.0 / (16 * pi ** (3.0 / 2.0) * R**5) - | - -N806 Variable `R` in function should be lowercase - --> tests/test_filters.py:181:9 - | -180 | def test_sigma1(self, cls): -181 | R = 10.0 - | ^ -182 | true = 15 / (32 * pi ** (3.0 / 2.0) * R**7) - | - -N806 Variable `R` in function should be lowercase - --> tests/test_filters.py:188:9 - | -187 | def test_dlnssdlnr(self, cls): -188 | R = 10.0 - | ^ -189 | true = -5 - | - -PT013 Incorrect import of `pytest`; use `import pytest` instead - --> tests/test_fits.py:6:1 - | -4 | import numpy as np -5 | import pytest -6 | from pytest import raises - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -7 | -8 | from hmf import MassFunction - | - -D205 1 blank line required between summary line and description - --> tests/test_fits.py:51:5 - | -49 | @pytest.mark.parametrize(("redshift", "fit"), itertools.product([0.0, 2.0], allfits)) -50 | def test_allfits(hmf, ps_max, redshift, fit): -51 | / """ -52 | | This basically tests all implemented fits to check the form for three things: -53 | | 1) whether the maximum fsigma is less than in the PS formula (which is known to overestimate) -54 | | 2) whether the slope is positive below this maximum -55 | | 3) whether the slope is negative above this maximum. -56 | | -57 | | Since it calls each class, any blatant errors should also pop up. -58 | | """ - | |_______^ -59 | hmf.update(z=redshift, hmf_model=fit) -60 | maxarg = np.argmax(hmf.fsigma) - | -help: Insert single blank line - -D404 First word of the docstring should not be "This" - --> tests/test_fits.py:51:5 - | -49 | @pytest.mark.parametrize(("redshift", "fit"), itertools.product([0.0, 2.0], allfits)) -50 | def test_allfits(hmf, ps_max, redshift, fit): -51 | / """ -52 | | This basically tests all implemented fits to check the form for three things: -53 | | 1) whether the maximum fsigma is less than in the PS formula (which is known to overestimate) -54 | | 2) whether the slope is positive below this maximum -55 | | 3) whether the slope is negative above this maximum. -56 | | -57 | | Since it calls each class, any blatant errors should also pop up. -58 | | """ - | |_______^ -59 | hmf.update(z=redshift, hmf_model=fit) -60 | maxarg = np.argmax(hmf.fsigma) - | - -E501 Line too long (97 > 88) - --> tests/test_fits.py:53:89 - | -51 | """ -52 | This basically tests all implemented fits to check the form for three things: -53 | 1) whether the maximum fsigma is less than in the PS formula (which is known to overestimate) - | ^^^^^^^^^ -54 | 2) whether the slope is positive below this maximum -55 | 3) whether the slope is negative above this maximum. - | - -PT012 `pytest.raises()` block should contain a single simple statement - --> tests/test_fits.py:96:5 - | - 95 | def test_tinker10_neg_gam(): - 96 | / with raises(ValueError): - 97 | | h = MassFunction( - 98 | | hmf_model="Tinker10", hmf_params={"gamma_200": -1}, transfer_model="EH" - 99 | | ) -100 | | h.fsigma - | |________________^ - | - -PT011 `pytest.raises(ValueError)` is too broad, set the `match` parameter or use a more specific exception - --> tests/test_fits.py:96:17 - | -95 | def test_tinker10_neg_gam(): -96 | with raises(ValueError): - | ^^^^^^^^^^ -97 | h = MassFunction( -98 | hmf_model="Tinker10", hmf_params={"gamma_200": -1}, transfer_model="EH" - | - -B018 Found useless expression. Either assign it to a variable or remove it. - --> tests/test_fits.py:100:9 - | - 98 | hmf_model="Tinker10", hmf_params={"gamma_200": -1}, transfer_model="EH" - 99 | ) -100 | h.fsigma - | ^^^^^^^^ - | - -PT012 `pytest.raises()` block should contain a single simple statement - --> tests/test_fits.py:104:5 - | -103 | def test_tinker10_neg_eta(): -104 | / with raises(ValueError): -105 | | h = MassFunction( -106 | | hmf_model="Tinker10", hmf_params={"eta_200": -1}, transfer_model="EH" -107 | | ) -108 | | h.fsigma - | |________________^ - | - -PT011 `pytest.raises(ValueError)` is too broad, set the `match` parameter or use a more specific exception - --> tests/test_fits.py:104:17 - | -103 | def test_tinker10_neg_eta(): -104 | with raises(ValueError): - | ^^^^^^^^^^ -105 | h = MassFunction( -106 | hmf_model="Tinker10", hmf_params={"eta_200": -1}, transfer_model="EH" - | - -B018 Found useless expression. Either assign it to a variable or remove it. - --> tests/test_fits.py:108:9 - | -106 | hmf_model="Tinker10", hmf_params={"eta_200": -1}, transfer_model="EH" -107 | ) -108 | h.fsigma - | ^^^^^^^^ - | - -PT012 `pytest.raises()` block should contain a single simple statement - --> tests/test_fits.py:112:5 - | -111 | def test_tinker10_neg_etaphi(): -112 | / with raises(ValueError): -113 | | h = MassFunction( -114 | | hmf_model="Tinker10", -115 | | hmf_params={"eta_200": -1, "phi_200": 0}, -116 | | transfer_model="EH", -117 | | ) -118 | | h.fsigma - | |________________^ - | - -PT011 `pytest.raises(ValueError)` is too broad, set the `match` parameter or use a more specific exception - --> tests/test_fits.py:112:17 - | -111 | def test_tinker10_neg_etaphi(): -112 | with raises(ValueError): - | ^^^^^^^^^^ -113 | h = MassFunction( -114 | hmf_model="Tinker10", - | - -B018 Found useless expression. Either assign it to a variable or remove it. - --> tests/test_fits.py:118:9 - | -116 | transfer_model="EH", -117 | ) -118 | h.fsigma - | ^^^^^^^^ - | - -PT012 `pytest.raises()` block should contain a single simple statement - --> tests/test_fits.py:122:5 - | -121 | def test_tinker10_neg_beta(): -122 | / with raises(ValueError): -123 | | h = MassFunction( -124 | | hmf_model="Tinker10", hmf_params={"beta_200": -1}, transfer_model="EH" -125 | | ) -126 | | h.fsigma - | |________________^ - | - -PT011 `pytest.raises(ValueError)` is too broad, set the `match` parameter or use a more specific exception - --> tests/test_fits.py:122:17 - | -121 | def test_tinker10_neg_beta(): -122 | with raises(ValueError): - | ^^^^^^^^^^ -123 | h = MassFunction( -124 | hmf_model="Tinker10", hmf_params={"beta_200": -1}, transfer_model="EH" - | - -B018 Found useless expression. Either assign it to a variable or remove it. - --> tests/test_fits.py:126:9 - | -124 | hmf_model="Tinker10", hmf_params={"beta_200": -1}, transfer_model="EH" -125 | ) -126 | h.fsigma - | ^^^^^^^^ - | - -PT013 Incorrect import of `pytest`; use `import pytest` instead - --> tests/test_framework.py:3:1 - | -1 | import pytest -2 | from deprecation import fail_if_not_removed -3 | from pytest import raises - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -4 | -5 | import hmf - | - -PT012 `pytest.raises()` block should contain a single simple statement - --> tests/test_framework.py:18:5 - | -17 | def test_incorrect_update_arg(): -18 | / with raises(ValueError): -19 | | t = hmf.MassFunction(transfer_model="EH") -20 | | t.update(wrong_arg=3) - | |_____________________________^ - | - -PT011 `pytest.raises(ValueError)` is too broad, set the `match` parameter or use a more specific exception - --> tests/test_framework.py:18:17 - | -17 | def test_incorrect_update_arg(): -18 | with raises(ValueError): - | ^^^^^^^^^^ -19 | t = hmf.MassFunction(transfer_model="EH") -20 | t.update(wrong_arg=3) - | - -PT031 `pytest.warns()` block should contain a single simple statement - --> tests/test_framework.py:109:5 - | -108 | # Without checking on, we can still manually set it, but it will warn us -109 | / with pytest.warns(DeprecationWarning): -110 | | m.Mmax = 9 -111 | | m.Mmin = 8 - | |__________________^ -112 | -113 | # But with checking on, we can't - | - -PT030 `pytest.warns(DeprecationWarning)` is too broad, set the `match` parameter or use a more specific warning - --> tests/test_framework.py:109:23 - | -108 | # Without checking on, we can still manually set it, but it will warn us -109 | with pytest.warns(DeprecationWarning): - | ^^^^^^^^^^^^^^^^^^ -110 | m.Mmax = 9 -111 | m.Mmin = 8 - | - -D404 First word of the docstring should not be "This" - --> tests/test_genmf.py:1:1 - | - 1 | / """ - 2 | | This module contains a number of tests that check hmf's results against those of genmf. - 3 | | - 4 | | We check results for sigma, lnsigma, and the differential and cumulative mass functions against - 5 | | genmf for two different redshifts (0 and 2). We use precisely the same transfer function here - 6 | | as we use in genmf (tabulated). Another test tests if the power spectrum is generated - 7 | | correctly according to this tabulated version. - 8 | | - 9 | | The data files in the data/ directory are the following: -10 | | ST_0 etc :: output from genmf with given fit and redshift, produced with default cosmology here -11 | | power_for_hmf_tests.dat :: the power spectrum used in genmf -12 | | transfer_for_hmf_tests.dat :: the transfer function used in hmf (corresponds directly to the power) -13 | | -14 | | The power was generated with hmf.transfer itself, so can be used as a direct test -15 | | for later versions. -16 | | -17 | | To be more explicit, the power spectrum in all cases is produced with the following parameters: -18 | | -19 | | "w_lam" :-1, -20 | | "omegab" : 0.05, -21 | | "omegac" : 0.25, -22 | | "omegav" : 0.7, -23 | | "omegan" : 0.0, -24 | | "H0" : 70, -25 | | 'cs2_lam' : 1, -26 | | 'TCMB' : 2.725, -27 | | 'yhe' : 0.24, -28 | | 'Num_NuMassless' : 3.04, -29 | | 'reion__redshift': 10.3, -30 | | 'reion__optical_depth': 0.085 -31 | | "sigma_8":0.8, -32 | | "n":1, -33 | | "delta_c":1.686, -34 | | "crit_dens":27.755 * 10 ** 10 -35 | | 'Num_NuMassive' : 0, -36 | | 'reion__fraction' :-1, -37 | | 'reion__delta_redshift' : 1.5, -38 | | 'lAccuracyBoost' : 1, -39 | | 'lSampleBoost' : 1, -40 | | 'AccuracyBoost' : 1, -41 | | 'transfer__k_per_logint': 0, -42 | | 'transfer__kmax':100.0 -43 | | """ - | |___^ -44 | -45 | from itertools import product - | - -E501 Line too long (95 > 88) - --> tests/test_genmf.py:4:89 - | -2 | This module contains a number of tests that check hmf's results against those of genmf. -3 | -4 | We check results for sigma, lnsigma, and the differential and cumulative mass functions against - | ^^^^^^^ -5 | genmf for two different redshifts (0 and 2). We use precisely the same transfer function here -6 | as we use in genmf (tabulated). Another test tests if the power spectrum is generated - | - -E501 Line too long (93 > 88) - --> tests/test_genmf.py:5:89 - | -4 | We check results for sigma, lnsigma, and the differential and cumulative mass functions against -5 | genmf for two different redshifts (0 and 2). We use precisely the same transfer function here - | ^^^^^ -6 | as we use in genmf (tabulated). Another test tests if the power spectrum is generated -7 | correctly according to this tabulated version. - | - -E501 Line too long (95 > 88) - --> tests/test_genmf.py:10:89 - | - 9 | The data files in the data/ directory are the following: -10 | ST_0 etc :: output from genmf with given fit and redshift, produced with default cosmology here - | ^^^^^^^ -11 | power_for_hmf_tests.dat :: the power spectrum used in genmf -12 | transfer_for_hmf_tests.dat :: the transfer function used in hmf (corresponds directly to the power) - | - -E501 Line too long (99 > 88) - --> tests/test_genmf.py:12:89 - | -10 | ST_0 etc :: output from genmf with given fit and redshift, produced with default cosmology here -11 | power_for_hmf_tests.dat :: the power spectrum used in genmf -12 | transfer_for_hmf_tests.dat :: the transfer function used in hmf (corresponds directly to the power) - | ^^^^^^^^^^^ -13 | -14 | The power was generated with hmf.transfer itself, so can be used as a direct test - | - -E501 Line too long (95 > 88) - --> tests/test_genmf.py:17:89 - | -15 | for later versions. -16 | -17 | To be more explicit, the power spectrum in all cases is produced with the following parameters: - | ^^^^^^^ -18 | -19 | "w_lam" :-1, - | - -PT011 `pytest.raises(ValueError)` is too broad, set the `match` parameter or use a more specific exception - --> tests/test_growth.py:66:24 - | -64 | def test_unsupported_cosmo(): -65 | cosmo = w0waCDM(H0=70.0, Om0=0.3, Ode0=0.7, w0=-0.9, Ob0=0.05, Tcmb0=2.7) -66 | with pytest.raises(ValueError): - | ^^^^^^^^^^ -67 | growth_factor.GenMFGrowth(cosmo=cosmo) - | - -PT013 Incorrect import of `pytest`; use `import pytest` instead - --> tests/test_hmf.py:5:1 - | -3 | import numpy as np -4 | import pytest -5 | from pytest import raises - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -6 | -7 | from hmf import MassFunction - | - -PT011 `pytest.raises(ValueError)` is too broad, set the `match` parameter or use a more specific exception - --> tests/test_hmf.py:11:17 - | -10 | def test_wrong_filter(): -11 | with raises(ValueError): - | ^^^^^^^^^^ -12 | MassFunction(filter_model=2) - | - -PT011 `pytest.raises(ValueError)` is too broad, set the `match` parameter or use a more specific exception - --> tests/test_hmf.py:16:17 - | -15 | def test_string_dc(): -16 | with raises(ValueError): - | ^^^^^^^^^^ -17 | MassFunction(delta_c="this") - | - -PT011 `pytest.raises(ValueError)` is too broad, set the `match` parameter or use a more specific exception - --> tests/test_hmf.py:21:17 - | -20 | def test_neg_dc(): -21 | with raises(ValueError): - | ^^^^^^^^^^ -22 | MassFunction(delta_c=-1) - | - -PT011 `pytest.raises(ValueError)` is too broad, set the `match` parameter or use a more specific exception - --> tests/test_hmf.py:26:17 - | -25 | def test_big_dc(): -26 | with raises(ValueError): - | ^^^^^^^^^^ -27 | MassFunction(delta_c=20.0) - | - -PT011 `pytest.raises(ValueError)` is too broad, set the `match` parameter or use a more specific exception - --> tests/test_hmf.py:31:17 - | -30 | def test_wrong_fit(): -31 | with raises(ValueError): - | ^^^^^^^^^^ -32 | MassFunction(hmf_model=1) - | - -PT011 `pytest.raises(ValueError)` is too broad, set the `match` parameter or use a more specific exception - --> tests/test_hmf.py:36:17 - | -35 | def test_wrong_mf_par(): -36 | with raises(ValueError): - | ^^^^^^^^^^ -37 | MassFunction(hmf_params=2) - | - -PT030 `pytest.warns(UserWarning)` is too broad, set the `match` parameter or use a more specific warning - --> tests/test_hmf.py:49:23 - | -47 | def test_mass_nonlinear_outside_range(): -48 | h = MassFunction(Mmin=8, Mmax=9, transfer_model="EH") -49 | with pytest.warns(UserWarning): - | ^^^^^^^^^^^ -50 | assert h.mass_nonlinear > 0 - | - -ERA001 Found commented-out code - --> tests/test_integrate_hmf.py:32:5 - | -31 | # def test_basic(self): -32 | # m = np.logspace(10,18,500) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -33 | # dndm = self.tggd(m,14.0,-1.9,0.8) -34 | # ngtm = self.anl_int(m,14.0,-1.9,0.8) - | -help: Remove commented-out code - -ERA001 Found commented-out code - --> tests/test_integrate_hmf.py:33:5 - | -31 | # def test_basic(self): -32 | # m = np.logspace(10,18,500) -33 | # dndm = self.tggd(m,14.0,-1.9,0.8) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -34 | # ngtm = self.anl_int(m,14.0,-1.9,0.8) -35 | # - | -help: Remove commented-out code - -ERA001 Found commented-out code - --> tests/test_integrate_hmf.py:34:5 - | -32 | # m = np.logspace(10,18,500) -33 | # dndm = self.tggd(m,14.0,-1.9,0.8) -34 | # ngtm = self.anl_int(m,14.0,-1.9,0.8) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -35 | # -36 | # print ngtm/hmf_integral_gtm(m,dndm) - | -help: Remove commented-out code - -ERA001 Found commented-out code - --> tests/test_integrate_hmf.py:37:5 - | -35 | # -36 | # print ngtm/hmf_integral_gtm(m,dndm) -37 | # assert np.allclose(ngtm,hmf_integral_gtm(m,dndm),rtol=0.03) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -38 | # -39 | # def test_basic_mgtm(self): - | -help: Remove commented-out code - -ERA001 Found commented-out code - --> tests/test_integrate_hmf.py:40:5 - | -38 | # -39 | # def test_basic_mgtm(self): -40 | # m = np.logspace(10,18,500) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -41 | # dndm = self.tggd(m,14.0,-1.9,0.8) -42 | # ngtm = self.anl_m_int(m,14.0,-1.9,0.8) - | -help: Remove commented-out code - -ERA001 Found commented-out code - --> tests/test_integrate_hmf.py:41:5 - | -39 | # def test_basic_mgtm(self): -40 | # m = np.logspace(10,18,500) -41 | # dndm = self.tggd(m,14.0,-1.9,0.8) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -42 | # ngtm = self.anl_m_int(m,14.0,-1.9,0.8) -43 | # - | -help: Remove commented-out code - -ERA001 Found commented-out code - --> tests/test_integrate_hmf.py:42:5 - | -40 | # m = np.logspace(10,18,500) -41 | # dndm = self.tggd(m,14.0,-1.9,0.8) -42 | # ngtm = self.anl_m_int(m,14.0,-1.9,0.8) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -43 | # -44 | # print ngtm/hmf_integral_gtm(m,dndm,True) - | -help: Remove commented-out code - -ERA001 Found commented-out code - --> tests/test_integrate_hmf.py:45:5 - | -43 | # -44 | # print ngtm/hmf_integral_gtm(m,dndm,True) -45 | # assert np.allclose(ngtm,hmf_integral_gtm(m,dndm,True),rtol=0.03) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -46 | -47 | def test_high_z(self): - | -help: Remove commented-out code - -ERA001 Found commented-out code - --> tests/test_integrate_hmf.py:57:5 - | -56 | # def test_low_mmax_z0(self): -57 | # m = np.logspace(10,15,500) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -58 | # dndm = self.tggd(m,14.0,-1.9,0.8) -59 | # ngtm = self.anl_int(m,14.0,-1.9,0.8) - | -help: Remove commented-out code - -ERA001 Found commented-out code - --> tests/test_integrate_hmf.py:58:5 - | -56 | # def test_low_mmax_z0(self): -57 | # m = np.logspace(10,15,500) -58 | # dndm = self.tggd(m,14.0,-1.9,0.8) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -59 | # ngtm = self.anl_int(m,14.0,-1.9,0.8) -60 | # - | -help: Remove commented-out code - -ERA001 Found commented-out code - --> tests/test_integrate_hmf.py:59:5 - | -57 | # m = np.logspace(10,15,500) -58 | # dndm = self.tggd(m,14.0,-1.9,0.8) -59 | # ngtm = self.anl_int(m,14.0,-1.9,0.8) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -60 | # -61 | # print ngtm/hmf_integral_gtm(m,dndm) - | -help: Remove commented-out code - -ERA001 Found commented-out code - --> tests/test_integrate_hmf.py:62:5 - | -60 | # -61 | # print ngtm/hmf_integral_gtm(m,dndm) -62 | # assert np.allclose(ngtm,hmf_integral_gtm(m,dndm),rtol=0.03) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -63 | -64 | def test_low_mmax_high_z(self): - | -help: Remove commented-out code - -PT011 `pytest.raises(ValueError)` is too broad, set the `match` parameter or use a more specific exception - --> tests/test_mdef.py:92:24 - | -90 | assert md.from_colossus_name("vir") == md.SOVirial() -91 | -92 | with pytest.raises(ValueError): - | ^^^^^^^^^^ -93 | md.from_colossus_name("derp") - | - -PT030 `pytest.warns(UserWarning)` is too broad, set the `match` parameter or use a more specific warning - --> tests/test_mdef.py:97:23 - | -96 | def test_change_dndm(colossus_cosmo): -97 | with pytest.warns(UserWarning): - | ^^^^^^^^^^^ -98 | h = MassFunction( -99 | mdef_model="SOVirial", hmf_model="Warren", disable_mass_conversion=False - | - -N813 Camelcase `InterpolatedUnivariateSpline` imported as lowercase `spline` - --> tests/test_sample.py:2:31 - | -1 | import numpy as np -2 | from scipy.interpolate import InterpolatedUnivariateSpline as spline - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -3 | -4 | from hmf.helpers.sample import dndm_from_sample, sample_mf - | - -ERA001 Found commented-out code - --> tests/test_sample.py:22:5 - | -21 | m, h = sample_mf(1e5, 11, transfer_model="EH", Mmax=18, rng=rng) -22 | # centres,hist = dndm_from_sample(m,1e5/h.ngtm[0]) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -23 | # print centres,hist -24 | dndm_from_sample(m, 1e5 / h.ngtm[0]) - | -help: Remove commented-out code - -N806 Variable `T` in function should be lowercase - --> tests/test_transfer.py:165:5 - | -163 | assert t.transfer.params["camb_params"].Transfer.kmax == 1.0 -164 | camb_transfers = camb.get_transfer_functions(t.transfer.params["camb_params"]) -165 | T = camb_transfers.get_matter_transfer_data().transfer_data - | ^ -166 | assert np.max(T[0]) < 2.0 - | - -B018 Found useless expression. Either assign it to a variable or remove it. - --> tests/test_transfer.py:203:9 - | -201 | ) -202 | with pytest.raises(ValueError, match="the CMB temperature must be set explicitly"): -203 | t.transfer - | ^^^^^^^^^^ -204 | -205 | t = Transfer( - | - -B018 Found useless expression. Either assign it to a variable or remove it. - --> tests/test_transfer.py:210:9 - | -208 | ) -209 | with pytest.raises(ValueError, match="you must set the baryon density"): -210 | t.transfer - | ^^^^^^^^^^ - | - -PT013 Incorrect import of `pytest`; use `import pytest` instead - --> tests/test_wdm.py:2:1 - | -1 | import numpy as np -2 | from pytest import raises - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -3 | -4 | import hmf - | - -PT012 `pytest.raises()` block should contain a single simple statement - --> tests/test_wdm.py:9:5 - | - 8 | def test_null(): - 9 | / with raises(NotImplementedError): -10 | | w = wdm.WDM(mx=1.0) -11 | | w.transfer(1.0) - | |_______________________^ - | - -N801 Class name `TestSchneider12_vCDM` should use CapWords convention - --> tests/test_wdm.py:39:7 - | -39 | class TestSchneider12_vCDM: - | ^^^^^^^^^^^^^^^^^^^^ -40 | def setup_class(self): -41 | self.cdm = hmf.MassFunction(transfer_model="EH") - | - -PT011 `pytest.raises(ValueError)` is too broad, set the `match` parameter or use a more specific exception - --> tests/test_wdm.py:80:21 - | -79 | def test_wrong_model_type(self): -80 | with raises(ValueError): - | ^^^^^^^^^^ -81 | wdm.TransferWDM(wdm_mass=3.0, wdm_model=3, transfer_model="EH") - | - -Found 594 errors. diff --git a/src/hmf/_internals/_framework.py b/src/hmf/_internals/_framework.py index d62f2e51..66154bf3 100644 --- a/src/hmf/_internals/_framework.py +++ b/src/hmf/_internals/_framework.py @@ -4,7 +4,7 @@ import logging import sys import warnings -from typing import Any, ClassVar, Final +from typing import Any, ClassVar import deprecation @@ -25,7 +25,7 @@ class Component: the __init__ method. """ - _defaults: ClassVar[Final[dict[str, Any]]] = {} + _defaults: ClassVar[dict[str, Any]] = {} def __init__(self, **model_params): # Check that all parameters passed are valid diff --git a/src/hmf/alternatives/wdm.py b/src/hmf/alternatives/wdm.py index 67754b0c..68fdc4e3 100644 --- a/src/hmf/alternatives/wdm.py +++ b/src/hmf/alternatives/wdm.py @@ -7,7 +7,7 @@ for other alternative cosmologies. """ -from typing import ClassVar, Final, override +from typing import ClassVar, override import astropy.units as u import numpy as np @@ -101,7 +101,7 @@ class attribute. :g_x: """ - _defaults: ClassVar[Final[dict[str, float]]] = {"mu": 1.12, "g_x": 1.5} + _defaults: ClassVar[dict[str, float]] = {"mu": 1.12, "g_x": 1.5} def transfer(self, k): """Compute the modified WDM transfer function.""" @@ -210,7 +210,7 @@ class Schneider12_vCDM(WDMRecalibrateMF): class attribute. """ - _defaults: ClassVar[Final[dict[str, float]]] = {"beta": 1.16} + _defaults: ClassVar[dict[str, float]] = {"beta": 1.16} @override def dndm_alter(self): @@ -235,7 +235,7 @@ class Schneider12(WDMRecalibrateMF): class attribute. """ - _defaults: ClassVar[Final[dict[str, float]]] = {"alpha": 0.6} + _defaults: ClassVar[dict[str, float]] = {"alpha": 0.6} @override def dndm_alter(self): @@ -260,7 +260,7 @@ class Lovell14(WDMRecalibrateMF): class attribute. """ - _defaults: ClassVar[Final[dict[str, float]]] = {"beta": 0.99, "gamma": 2.7} + _defaults: ClassVar[dict[str, float]] = {"beta": 0.99, "gamma": 2.7} @override def dndm_alter(self): diff --git a/src/hmf/cosmology/growth_factor.py b/src/hmf/cosmology/growth_factor.py index 6849aefe..ce72dcff 100644 --- a/src/hmf/cosmology/growth_factor.py +++ b/src/hmf/cosmology/growth_factor.py @@ -8,7 +8,7 @@ """ from functools import cached_property -from typing import Any, ClassVar, Final +from typing import Any, ClassVar import numpy as np from astropy import cosmology @@ -65,7 +65,7 @@ class GrowthFactor(_GrowthFactor): .. [1] Lukic et. al., ApJ, 2007, http://adsabs.harvard.edu/abs/2007ApJ...671.1160L """ - _defaults: ClassVar[Final[dict[str, float]]] = {"dlna": 0.01, "amin": 1e-8} + _defaults: ClassVar[dict[str, float]] = {"dlna": 0.01, "amin": 1e-8} def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) @@ -222,7 +222,7 @@ class FromFile(GrowthFactor): """ supported_cosmos = (cosmology.LambdaCDM, cosmology.w0waCDM, cosmology.wCDM) - _defaults: ClassVar[Final[dict[str, Any]]] = {"dlna": 0.01, "amin": 1e-8, "fname": ""} + _defaults: ClassVar[dict[str, Any]] = {"dlna": 0.01, "amin": 1e-8, "fname": ""} def growth_factor(self, z): r""" @@ -265,7 +265,7 @@ class FromArray(FromFile): """ supported_cosmos = (cosmology.LambdaCDM, cosmology.w0waCDM, cosmology.wCDM) - _defaults: ClassVar[Final[dict[str, Any]]] = {"dlna": 0.01, "amin": 1e-8, "z": None, "d": None} + _defaults: ClassVar[dict[str, Any]] = {"dlna": 0.01, "amin": 1e-8, "z": None, "d": None} def growth_factor(self, z): r""" @@ -310,7 +310,7 @@ class GenMFGrowth(GrowthFactor): :zmax: Maximum redshift to integrate to. Only used for :meth:`growth_factor_fn`. """ - _defaults: ClassVar[Final[dict[str, float]]] = {"dz": 0.01, "zmax": 1000.0} + _defaults: ClassVar[dict[str, float]] = {"dz": 0.01, "zmax": 1000.0} @cached_property def _lna(self): @@ -398,7 +398,7 @@ class Carroll1992(GrowthFactor): `inverse=True`. """ - _defaults: ClassVar[Final[dict[str, float]]] = {"dz": 0.01, "zmax": 1000.0} + _defaults: ClassVar[dict[str, float]] = {"dz": 0.01, "zmax": 1000.0} @cached_property def _lna(self): diff --git a/src/hmf/density_field/filters.py b/src/hmf/density_field/filters.py index 7ba49863..b54ce5f0 100644 --- a/src/hmf/density_field/filters.py +++ b/src/hmf/density_field/filters.py @@ -2,7 +2,7 @@ import collections import warnings -from typing import ClassVar, Final, override +from typing import ClassVar, override import numpy as np import scipy.integrate as intg @@ -407,7 +407,7 @@ class SharpK(Filter): .. math:: \frac{d\ln \sigma^2}{d \ln R} = -\frac{P(1/R)}{2\pi^2\sigma^2(R)R^3}. """ - _defaults: ClassVar[Final[dict[str, float]]] = {"c": 2.5} + _defaults: ClassVar[dict[str, float]] = {"c": 2.5} @override def k_space(self, kr): @@ -473,7 +473,7 @@ class SharpKEllipsoid(SharpK): Refer to :class:`~Filter` for more details. """ - _defaults: ClassVar[Final[dict[str, float]]] = {"c": 2.0} + _defaults: ClassVar[dict[str, float]] = {"c": 2.0} def xm(self, g, v): """ diff --git a/src/hmf/density_field/transfer_models.py b/src/hmf/density_field/transfer_models.py index 0063bc0d..c2e1442e 100644 --- a/src/hmf/density_field/transfer_models.py +++ b/src/hmf/density_field/transfer_models.py @@ -8,7 +8,7 @@ import pickle import warnings from copy import deepcopy -from typing import Any, ClassVar, Final +from typing import Any, ClassVar import numpy as np from astropy import cosmology @@ -42,7 +42,7 @@ class TransferComponent(Component): Any model-specific parameters. """ - _defaults: ClassVar[Final[dict[str, Any]]] = {} + _defaults: ClassVar[dict[str, Any]] = {} def __init__(self, cosmo, **model_parameters): self.cosmo = cosmo @@ -84,7 +84,7 @@ class FromFile(TransferComponent): Location of the file to import. """ - _defaults: ClassVar[Final[dict[str, str]]] = {"fname": ""} + _defaults: ClassVar[dict[str, str]] = {"fname": ""} def _check_low_k(self, lnk, lnT, lnkmin): """ @@ -162,7 +162,7 @@ class CAMB(FromFile): approximation. """ - _defaults: ClassVar[Final[dict[str, Any]]] = { + _defaults: ClassVar[dict[str, Any]] = { "camb_params": None, "dark_energy_params": {}, "extrapolate_with_eh": None, @@ -402,7 +402,7 @@ class FromArray(FromFile): Transfer function """ - _defaults: ClassVar[Final[dict[str, Any]]] = {"k": None, "T": None} + _defaults: ClassVar[dict[str, Any]] = {"k": None, "T": None} def lnt(self, lnk): r""" @@ -662,7 +662,7 @@ class attribute. \exp\left(-\Omega_{b,0}(1 + \sqrt{2h}/\Omega_{m,0})\right). """ - _defaults: ClassVar[Final[dict[str, Any]]] = { + _defaults: ClassVar[dict[str, Any]] = { "a": 2.34, "b": 3.89, "c": 16.1, @@ -736,7 +736,7 @@ class attribute. .. math:: \alpha = \frac{0.3\times 0.75^2}{\Omega_{m,0} h^2}. """ - _defaults: ClassVar[Final[dict[str, float]]] = {"a": 37.1, "b": 21.1, "c": 10.8, "nu": 1.12} + _defaults: ClassVar[dict[str, float]] = {"a": 37.1, "b": 21.1, "c": 10.8, "nu": 1.12} def lnt(self, lnk): """ diff --git a/src/hmf/halos/mass_definitions.py b/src/hmf/halos/mass_definitions.py index 809ef805..a98c4372 100644 --- a/src/hmf/halos/mass_definitions.py +++ b/src/hmf/halos/mass_definitions.py @@ -5,7 +5,7 @@ """ import warnings -from typing import ClassVar, Final, override +from typing import ClassVar, override import astropy.units as u import numpy as np @@ -221,7 +221,7 @@ def __str__(self): class SOMean(SphericalOverdensity): """A mass definition based on spherical overdensity wrt mean background density.""" - _defaults: ClassVar[Final[dict[str, float]]] = {"overdensity": 200} + _defaults: ClassVar[dict[str, float]] = {"overdensity": 200} def halo_density(self, z=0, cosmo=Planck15): """The density of haloes under this definition.""" @@ -236,7 +236,7 @@ def colossus_name(self): class SOCritical(SphericalOverdensity): """A mass definition based on spherical overdensity wrt critical density.""" - _defaults: ClassVar[Final[dict[str, float]]] = {"overdensity": 200} + _defaults: ClassVar[dict[str, float]] = {"overdensity": 200} def halo_density(self, z=0, cosmo=Planck15): """The density of haloes under this definition.""" @@ -273,7 +273,7 @@ def __str__(self): class FOF(MassDefinition): """A mass definition based on FroF networks with given linking length.""" - _defaults: ClassVar[Final[dict[str, float]]] = {"linking_length": 0.2} + _defaults: ClassVar[dict[str, float]] = {"linking_length": 0.2} def halo_density(self, z=0, cosmo=Planck15): r""" diff --git a/src/hmf/mass_function/fitting_functions.py b/src/hmf/mass_function/fitting_functions.py index 4fe8903e..0c9f3fe7 100644 --- a/src/hmf/mass_function/fitting_functions.py +++ b/src/hmf/mass_function/fitting_functions.py @@ -7,7 +7,7 @@ import warnings from copy import copy -from typing import Any, ClassVar, Final, override +from typing import Any, ClassVar, override import numpy as np import scipy.special as sp @@ -205,7 +205,7 @@ class FittingFunction(_framework.Component): """ __doc__ += _pdocs - _defaults: ClassVar[Final[dict[str, Any]]] = {} + _defaults: ClassVar[dict[str, Any]] = {} # Subclass requirements req_neff = False #: Whether `n_eff` is required for this subclass @@ -361,7 +361,7 @@ class SMT(FittingFunction): ) __doc__ = _makedoc(FittingFunction._pdocs, "Sheth-Mo-Tormen", "SMT", _eq, _ref) - _defaults: ClassVar[Final[dict[str, Any]]] = {"a": 0.707, "p": 0.3, "A": None} + _defaults: ClassVar[dict[str, Any]] = {"a": 0.707, "p": 0.3, "A": None} normalized = True sim_definition = SimDetails( @@ -430,7 +430,7 @@ class Jenkins(FittingFunction): r"http://doi.wiley.com/10.1046/j.1365-8711.2001.04029.x" ) __doc__ = _makedoc(FittingFunction._pdocs, "Jenkins", "Jenkins", _eq, _ref) - _defaults: ClassVar[Final[dict[str, float]]] = {"A": 0.315, "b": 0.61, "c": 3.8} + _defaults: ClassVar[dict[str, float]] = {"A": 0.315, "b": 0.61, "c": 3.8} normalized = False sim_definition = SimDetails( @@ -484,7 +484,7 @@ class Warren(FittingFunction): ) __doc__ = _makedoc(FittingFunction._pdocs, "Warren", "Warren", _eq, _ref) - _defaults: ClassVar[Final[dict[str, float]]] = { + _defaults: ClassVar[dict[str, float]] = { "A": 0.7234, "b": 1.625, "c": 0.2538, @@ -493,7 +493,7 @@ class Warren(FittingFunction): } normalized = False - uncertainties: ClassVar[Final[dict[str, float]]] = { + uncertainties: ClassVar[dict[str, float]] = { "A": 0.0073, "a": 0.028, "b": 0.0051, @@ -557,7 +557,7 @@ class Reed03(SMT): _ref = r"""Reed, D., et al., Dec. 2003. MNRAS 346 (2), 565-572. http://adsabs.harvard.edu/abs/2003MNRAS.346..565R""" __doc__ = _makedoc(FittingFunction._pdocs, "Reed03", "R03", _eq, _ref) - _defaults: ClassVar[Final[dict[str, float]]] = {"a": 0.707, "p": 0.3, "A": 0.3222, "c": 0.7} + _defaults: ClassVar[dict[str, float]] = {"a": 0.707, "p": 0.3, "A": 0.3222, "c": 0.7} normalized = False sim_definition = SimDetails( @@ -606,7 +606,7 @@ class Reed07(FittingFunction): ) __doc__ = _makedoc(FittingFunction._pdocs, "Reed07", "R07", _eq, _ref) - _defaults: ClassVar[Final[dict[str, float]]] = {"A": 0.3222, "p": 0.3, "c": 1.08, "a": 0.764} + _defaults: ClassVar[dict[str, float]] = {"A": 0.3222, "p": 0.3, "c": 1.08, "a": 0.764} sim_definition = SimDetails( L=[1.0, 2.5, 2.5, 2.5, 2.5, 4.64, 11.6, 20, 50, 100, 500, 1340, 3000], @@ -688,7 +688,7 @@ class Peacock(FittingFunction): _eq = r"\nu\exp(-c\nu^2)(2cd\nu+ba\nu^{b-1})/d^2" _ref = """Peacock, J. A., Aug. 2007. MNRAS 379 (3), 1067-1074. http://adsabs.harvard.edu/abs/2007MNRAS.379.1067P""" __doc__ = _makedoc(FittingFunction._pdocs, "Peacock", "Pck", _eq, _ref) - _defaults: ClassVar[Final[dict[str, float]]] = {"a": 1.529, "b": 0.704, "c": 0.412} + _defaults: ClassVar[dict[str, float]] = {"a": 1.529, "b": 0.704, "c": 0.412} sim_definition = copy(Warren.sim_definition) sim_definition.hmf_analysis_notes = "Fit directly to Warren+2006 fit." @@ -722,7 +722,7 @@ class Angulo(FittingFunction): _ref = """Angulo, R. E., et al., 2012. arXiv:1203.3216v1""" _eq = r"$A \left[\left(\frac{d}{\sigma}\right)^b + 1 \right] \exp(-c/\sigma^2)$" __doc__ = _makedoc(FittingFunction._pdocs, "Angulo", "Ang", _eq, _ref) - _defaults: ClassVar[Final[dict[str, float]]] = {"A": 0.201, "b": 1.7, "c": 1.172, "d": 2.08} + _defaults: ClassVar[dict[str, float]] = {"A": 0.201, "b": 1.7, "c": 1.172, "d": 2.08} sim_definition = SimDetails( L=3000.0, @@ -762,7 +762,7 @@ class AnguloBound(Angulo): """Bounded version of Angulo mass function fit.""" __doc__ = Angulo.__doc__ - _defaults: ClassVar[Final[dict[str, float]]] = {"A": 0.265, "b": 1.9, "c": 1.4, "d": 1.675} + _defaults: ClassVar[dict[str, float]] = {"A": 0.265, "b": 1.9, "c": 1.4, "d": 1.675} class Watson_FoF(Warren): @@ -775,7 +775,7 @@ class Watson_FoF(Warren): """http://adsabs.harvard.edu/abs/2013MNRAS.433.1230W """ ) __doc__ = _makedoc(FittingFunction._pdocs, "Watson FoF", "WatF", Warren._eq, _ref) - _defaults: ClassVar[Final[dict[str, float]]] = { + _defaults: ClassVar[dict[str, float]] = { "A": 0.282, "b": 2.163, "c": 1, @@ -826,7 +826,7 @@ class Watson(FittingFunction): sim_definition.halo_finder = "AHF" sim_definition.halo_overdensity = "*(vir)" - _defaults: ClassVar[Final[dict[str, Any]]] = { + _defaults: ClassVar[dict[str, Any]] = { "C_a": 0.023, "d_a": 0.456, "d_b": 0.139, @@ -914,7 +914,7 @@ class Crocce(Warren): _ref = """Crocce, M., et al. MNRAS 403 (3), 1353-1367. http://doi.wiley.com/10.1111/j.1365-2966.2009.16194.x""" __doc__ = _makedoc(FittingFunction._pdocs, "Crocce", "Cro", Warren._eq, _ref) - _defaults: ClassVar[Final[dict[str, Any]]] = { + _defaults: ClassVar[dict[str, Any]] = { "A_a": 0.58, "A_b": 0.13, "b_a": 1.37, @@ -964,7 +964,7 @@ class Courtin(SMT): req_sigma = True _ref = """Courtin, J., et al., Oct. 2010. MNRAS 1931. http://doi.wiley.com/10.1111/j.1365-2966.2010.17573.x""" __doc__ = _makedoc(FittingFunction._pdocs, "Courtin", "Ctn", SMT._eq, _ref) - _defaults: ClassVar[Final[dict[str, float]]] = {"A": 0.348, "a": 0.695, "p": 0.1} + _defaults: ClassVar[dict[str, float]] = {"A": 0.348, "a": 0.695, "p": 0.1} normalized = False @@ -1001,7 +1001,7 @@ class Bhattacharya(SMT): _eq = r"f_{\rm SMT}(\sigma) (\nu\sqrt{a})^{q-1}" _ref = """Bhattacharya, S., et al., May 2011. ApJ 732 (2), 122. http://labs.adsabs.harvard.edu/ui/abs/2011ApJ...732..122B""" __doc__ = _makedoc(FittingFunction._pdocs, "Bhattacharya", "Btc", _eq, _ref) - _defaults: ClassVar[Final[dict[str, Any]]] = { + _defaults: ClassVar[dict[str, Any]] = { "A_a": 0.333, "A_b": 0.11, "a_a": 0.788, @@ -1312,7 +1312,7 @@ class Tinker08(FittingFunction): }, ) - _defaults: ClassVar[Final[dict[str, Any]]] = { # -- A + _defaults: ClassVar[dict[str, Any]] = { # -- A "A_200": 1.858659e-01, "A_300": 1.995973e-01, "A_400": 2.115659e-01, @@ -1418,7 +1418,7 @@ class Tinker10(FittingFunction): sim_definition = copy(Tinker08.sim_definition) - _defaults: ClassVar[Final[dict[str, Any]]] = { # --- alpha + _defaults: ClassVar[dict[str, Any]] = { # --- alpha "alpha_200": 0.368, "alpha_300": 0.363, "alpha_400": 0.385, @@ -1646,7 +1646,7 @@ class Pillepich(Warren): _ref = r"""Pillepich, A., et al., 2010, arxiv:0811.4176""" __doc__ = _makedoc(FittingFunction._pdocs, "Pillepich", "Pillepich", Warren._eq, _ref) - _defaults: ClassVar[Final[dict[str, float]]] = { + _defaults: ClassVar[dict[str, float]] = { "A": 0.6853, "b": 1.868, "c": 0.3324, @@ -1685,7 +1685,7 @@ class Manera(SMT): _ref = r"""Manera, M., et al., 2010, arxiv:0906.1314""" __doc__ = _makedoc(FittingFunction._pdocs, "Manera", "Man", SMT._eq, _ref) # These are for z=0, new ML method, l_linnk = 0.2 - _defaults: ClassVar[Final[dict[str, Any]]] = {"A": None, "a": 0.709, "p": 0.289} + _defaults: ClassVar[dict[str, Any]] = {"A": None, "a": 0.709, "p": 0.289} sim_definition = SimDetails( L=1280.0, @@ -1718,7 +1718,7 @@ class Ishiyama(Warren): _ref = r"""Ishiyama, T., et al., 2015, arxiv:1412.2860""" __doc__ = _makedoc(FittingFunction._pdocs, "Ishiyama", "Ishiyama", _eq, _ref) - _defaults: ClassVar[Final[dict[str, float]]] = { + _defaults: ClassVar[dict[str, float]] = { "A": 0.193, "b": 1.550, "c": 1, @@ -1761,7 +1761,7 @@ class Bocquet200mDMOnly(Warren): _eq = r"A\left[\left(\frac{e}{\sigma}\right)^b + 1\right]\exp(-\frac{d}{\sigma^2})" _ref = r"""Bocuet, S., et al., 2016, MNRAS 456 2361""" __doc__ = _makedoc(FittingFunction._pdocs, "Bocquet", "Bocquet", _eq, _ref) - _defaults: ClassVar[Final[dict[str, Any]]] = { + _defaults: ClassVar[dict[str, Any]] = { "A": 0.216, "b": 1.87, "c": 1, @@ -1832,7 +1832,7 @@ class Bocquet200mHydro(Bocquet200mDMOnly): Bocquet200mDMOnly._eq, Bocquet200mDMOnly._ref, ) - _defaults: ClassVar[Final[dict[str, Any]]] = { + _defaults: ClassVar[dict[str, Any]] = { "A": 0.240, "b": 2.43, "c": 1, @@ -1856,7 +1856,7 @@ class Bocquet200cDMOnly(Bocquet200mDMOnly): Bocquet200mDMOnly._ref, ) - _defaults: ClassVar[Final[dict[str, Any]]] = { + _defaults: ClassVar[dict[str, Any]] = { "A": 0.256, "b": 2.01, "c": 1, @@ -1895,7 +1895,7 @@ class Bocquet200cHydro(Bocquet200cDMOnly): Bocquet200mDMOnly._ref, ) - _defaults: ClassVar[Final[dict[str, Any]]] = { + _defaults: ClassVar[dict[str, Any]] = { "A": 0.290, "b": 2.69, "c": 1, @@ -1919,7 +1919,7 @@ class Bocquet500cDMOnly(Bocquet200cDMOnly): Bocquet200mDMOnly._ref, ) - _defaults: ClassVar[Final[dict[str, Any]]] = { + _defaults: ClassVar[dict[str, Any]] = { "A": 0.390, "b": 3.05, "c": 1, @@ -1954,7 +1954,7 @@ class Bocquet500cHydro(Bocquet500cDMOnly): Bocquet200mDMOnly._ref, ) - _defaults: ClassVar[Final[dict[str, Any]]] = { + _defaults: ClassVar[dict[str, Any]] = { "A": 0.322, "b": 3.24, "c": 1, From 2a4856704533168be0eaa0f3b61629506da99aca Mon Sep 17 00:00:00 2001 From: Steven Murray Date: Sun, 22 Feb 2026 17:12:50 +0200 Subject: [PATCH 13/18] maint: minimum python 3.12 --- .github/workflows/test_suite.yaml | 11 ++++++++--- .github/workflows/warnings-tests.yaml | 9 +++++++-- pyproject.toml | 10 +++++----- 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/.github/workflows/test_suite.yaml b/.github/workflows/test_suite.yaml index edcecbfa..8e541987 100644 --- a/.github/workflows/test_suite.yaml +++ b/.github/workflows/test_suite.yaml @@ -22,7 +22,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest, macos-latest] - python-version: ["3.11", "3.12", "3.13", "3.14"] + python-version: ["3.12", "3.13", "3.14"] steps: - uses: actions/checkout@master with: @@ -30,16 +30,21 @@ jobs: - uses: actions/setup-python@v6 with: python-version: ${{ matrix.python-version }} + - name: Install uv + uses: astral-sh/setup-uv@v7 + with: + enable-cache: true + - uses: fortran-lang/setup-fortran@v1 id: setup-fortran with: compiler: gcc version: 13 - name: Install - run: pip install .[dev] + run: uv sync --locked --all-extras --dev - name: Run Tests run: | - python -m pytest --cov-report xml:./coverage.xml --durations=25 + uv run pytest --cov-report xml:./coverage.xml --durations=25 - uses: codecov/codecov-action@v5 if: matrix.os == 'ubuntu-latest' && success() with: diff --git a/.github/workflows/warnings-tests.yaml b/.github/workflows/warnings-tests.yaml index 2ed26354..76c38128 100644 --- a/.github/workflows/warnings-tests.yaml +++ b/.github/workflows/warnings-tests.yaml @@ -30,16 +30,21 @@ jobs: - uses: actions/setup-python@v6 with: python-version: ${{ matrix.python-version }} + - name: Install uv + uses: astral-sh/setup-uv@v7 + with: + enable-cache: true + - uses: fortran-lang/setup-fortran@v1 id: setup-fortran with: compiler: gcc version: 13 - name: Install - run: pip install .[dev] + run: uv sync --locked --all-extras --dev - name: Run Tests run: | - python -m pytest -Werror --cov-report xml:./coverage.xml --durations=25 + uv run pytest -Werror --cov-report xml:./coverage.xml --durations=25 - uses: codecov/codecov-action@v5 if: matrix.os == 'ubuntu-latest' && success() with: diff --git a/pyproject.toml b/pyproject.toml index ff719fa4..6dc76064 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,7 +8,7 @@ source = "uv-dynamic-versioning" [project] name = "hmf" description = "A halo mass function calculator" -requires-python = ">=3.11" +requires-python = ">=3.12" authors = [{name = "Steven Murray", email = "murray.steveng@gmail.com"}] license = "MIT" urls = {Documentation = "https://hmf.readthedocs.org"} @@ -17,9 +17,9 @@ urls = {Documentation = "https://hmf.readthedocs.org"} # https://pypi.python.org/pypi?%3Aaction=list_classifiers classifiers = [ "Development Status :: 6 - Mature", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", "Intended Audience :: Science/Research", "License :: OSI Approved", "License :: OSI Approved :: MIT License", @@ -98,7 +98,7 @@ exclude = [ "development/*.ipynb", ] line-length=100 -target-version="py311" +target-version="py312" [tool.ruff.lint] extend-select = [ From fb64dbaa2e19e3616d08750b36e4aedcdafc03e4 Mon Sep 17 00:00:00 2001 From: Steven Murray Date: Sun, 22 Feb 2026 17:14:08 +0200 Subject: [PATCH 14/18] maint: update lockfile --- uv.lock | 292 +++++--------------------------------------------------- 1 file changed, 24 insertions(+), 268 deletions(-) diff --git a/uv.lock b/uv.lock index dd0d4402..605c2270 100644 --- a/uv.lock +++ b/uv.lock @@ -1,10 +1,6 @@ version = 1 revision = 3 -requires-python = ">=3.11" -resolution-markers = [ - "python_full_version >= '3.12'", - "python_full_version < '3.12'", -] +requires-python = ">=3.12" [[package]] name = "alabaster" @@ -142,19 +138,6 @@ dependencies = [ ] sdist = { url = "https://files.pythonhosted.org/packages/eb/56/b1ba7935a17738ae8453301356628e8147c79dbb825bcbc73dc7401f9846/cffi-2.0.0.tar.gz", hash = "sha256:44d1b5909021139fe36001ae048dbdde8214afa20200eda0f64c068cac5d5529", size = 523588, upload-time = "2025-09-08T23:24:04.541Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/12/4a/3dfd5f7850cbf0d06dc84ba9aa00db766b52ca38d8b86e3a38314d52498c/cffi-2.0.0-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:b4c854ef3adc177950a8dfc81a86f5115d2abd545751a304c5bcf2c2c7283cfe", size = 184344, upload-time = "2025-09-08T23:22:26.456Z" }, - { url = "https://files.pythonhosted.org/packages/4f/8b/f0e4c441227ba756aafbe78f117485b25bb26b1c059d01f137fa6d14896b/cffi-2.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2de9a304e27f7596cd03d16f1b7c72219bd944e99cc52b84d0145aefb07cbd3c", size = 180560, upload-time = "2025-09-08T23:22:28.197Z" }, - { url = "https://files.pythonhosted.org/packages/b1/b7/1200d354378ef52ec227395d95c2576330fd22a869f7a70e88e1447eb234/cffi-2.0.0-cp311-cp311-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:baf5215e0ab74c16e2dd324e8ec067ef59e41125d3eade2b863d294fd5035c92", size = 209613, upload-time = "2025-09-08T23:22:29.475Z" }, - { url = "https://files.pythonhosted.org/packages/b8/56/6033f5e86e8cc9bb629f0077ba71679508bdf54a9a5e112a3c0b91870332/cffi-2.0.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:730cacb21e1bdff3ce90babf007d0a0917cc3e6492f336c2f0134101e0944f93", size = 216476, upload-time = "2025-09-08T23:22:31.063Z" }, - { url = "https://files.pythonhosted.org/packages/dc/7f/55fecd70f7ece178db2f26128ec41430d8720f2d12ca97bf8f0a628207d5/cffi-2.0.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:6824f87845e3396029f3820c206e459ccc91760e8fa24422f8b0c3d1731cbec5", size = 203374, upload-time = "2025-09-08T23:22:32.507Z" }, - { url = "https://files.pythonhosted.org/packages/84/ef/a7b77c8bdc0f77adc3b46888f1ad54be8f3b7821697a7b89126e829e676a/cffi-2.0.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:9de40a7b0323d889cf8d23d1ef214f565ab154443c42737dfe52ff82cf857664", size = 202597, upload-time = "2025-09-08T23:22:34.132Z" }, - { url = "https://files.pythonhosted.org/packages/d7/91/500d892b2bf36529a75b77958edfcd5ad8e2ce4064ce2ecfeab2125d72d1/cffi-2.0.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8941aaadaf67246224cee8c3803777eed332a19d909b47e29c9842ef1e79ac26", size = 215574, upload-time = "2025-09-08T23:22:35.443Z" }, - { url = "https://files.pythonhosted.org/packages/44/64/58f6255b62b101093d5df22dcb752596066c7e89dd725e0afaed242a61be/cffi-2.0.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:a05d0c237b3349096d3981b727493e22147f934b20f6f125a3eba8f994bec4a9", size = 218971, upload-time = "2025-09-08T23:22:36.805Z" }, - { url = "https://files.pythonhosted.org/packages/ab/49/fa72cebe2fd8a55fbe14956f9970fe8eb1ac59e5df042f603ef7c8ba0adc/cffi-2.0.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:94698a9c5f91f9d138526b48fe26a199609544591f859c870d477351dc7b2414", size = 211972, upload-time = "2025-09-08T23:22:38.436Z" }, - { url = "https://files.pythonhosted.org/packages/0b/28/dd0967a76aab36731b6ebfe64dec4e981aff7e0608f60c2d46b46982607d/cffi-2.0.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:5fed36fccc0612a53f1d4d9a816b50a36702c28a2aa880cb8a122b3466638743", size = 217078, upload-time = "2025-09-08T23:22:39.776Z" }, - { url = "https://files.pythonhosted.org/packages/2b/c0/015b25184413d7ab0a410775fdb4a50fca20f5589b5dab1dbbfa3baad8ce/cffi-2.0.0-cp311-cp311-win32.whl", hash = "sha256:c649e3a33450ec82378822b3dad03cc228b8f5963c0c12fc3b1e0ab940f768a5", size = 172076, upload-time = "2025-09-08T23:22:40.95Z" }, - { url = "https://files.pythonhosted.org/packages/ae/8f/dc5531155e7070361eb1b7e4c1a9d896d0cb21c49f807a6c03fd63fc877e/cffi-2.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:66f011380d0e49ed280c789fbd08ff0d40968ee7b665575489afa95c98196ab5", size = 182820, upload-time = "2025-09-08T23:22:42.463Z" }, - { url = "https://files.pythonhosted.org/packages/95/5c/1b493356429f9aecfd56bc171285a4c4ac8697f76e9bbbbb105e537853a1/cffi-2.0.0-cp311-cp311-win_arm64.whl", hash = "sha256:c6638687455baf640e37344fe26d37c404db8b80d037c3d29f58fe8d1c3b194d", size = 177635, upload-time = "2025-09-08T23:22:43.623Z" }, { url = "https://files.pythonhosted.org/packages/ea/47/4f61023ea636104d4f16ab488e268b93008c3d0bb76893b1b31db1f96802/cffi-2.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6d02d6655b0e54f54c4ef0b94eb6be0607b70853c45ce98bd278dc7de718be5d", size = 185271, upload-time = "2025-09-08T23:22:44.795Z" }, { url = "https://files.pythonhosted.org/packages/df/a2/781b623f57358e360d62cdd7a8c681f074a71d445418a776eef0aadb4ab4/cffi-2.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8eca2a813c1cb7ad4fb74d368c2ffbbb4789d377ee5bb8df98373c2cc0dee76c", size = 181048, upload-time = "2025-09-08T23:22:45.938Z" }, { url = "https://files.pythonhosted.org/packages/ff/df/a4f0fbd47331ceeba3d37c2e51e9dfc9722498becbeec2bd8bc856c9538a/cffi-2.0.0-cp312-cp312-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:21d1152871b019407d8ac3985f6775c079416c282e431a4da6afe7aefd2bccbe", size = 212529, upload-time = "2025-09-08T23:22:47.349Z" }, @@ -218,22 +201,6 @@ version = "3.4.4" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/13/69/33ddede1939fdd074bce5434295f38fae7136463422fe4fd3e0e89b98062/charset_normalizer-3.4.4.tar.gz", hash = "sha256:94537985111c35f28720e43603b8e7b43a6ecfb2ce1d3058bbe955b73404e21a", size = 129418, upload-time = "2025-10-14T04:42:32.879Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ed/27/c6491ff4954e58a10f69ad90aca8a1b6fe9c5d3c6f380907af3c37435b59/charset_normalizer-3.4.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6e1fcf0720908f200cd21aa4e6750a48ff6ce4afe7ff5a79a90d5ed8a08296f8", size = 206988, upload-time = "2025-10-14T04:40:33.79Z" }, - { url = "https://files.pythonhosted.org/packages/94/59/2e87300fe67ab820b5428580a53cad894272dbb97f38a7a814a2a1ac1011/charset_normalizer-3.4.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5f819d5fe9234f9f82d75bdfa9aef3a3d72c4d24a6e57aeaebba32a704553aa0", size = 147324, upload-time = "2025-10-14T04:40:34.961Z" }, - { url = "https://files.pythonhosted.org/packages/07/fb/0cf61dc84b2b088391830f6274cb57c82e4da8bbc2efeac8c025edb88772/charset_normalizer-3.4.4-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:a59cb51917aa591b1c4e6a43c132f0cdc3c76dbad6155df4e28ee626cc77a0a3", size = 142742, upload-time = "2025-10-14T04:40:36.105Z" }, - { url = "https://files.pythonhosted.org/packages/62/8b/171935adf2312cd745d290ed93cf16cf0dfe320863ab7cbeeae1dcd6535f/charset_normalizer-3.4.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8ef3c867360f88ac904fd3f5e1f902f13307af9052646963ee08ff4f131adafc", size = 160863, upload-time = "2025-10-14T04:40:37.188Z" }, - { url = "https://files.pythonhosted.org/packages/09/73/ad875b192bda14f2173bfc1bc9a55e009808484a4b256748d931b6948442/charset_normalizer-3.4.4-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d9e45d7faa48ee908174d8fe84854479ef838fc6a705c9315372eacbc2f02897", size = 157837, upload-time = "2025-10-14T04:40:38.435Z" }, - { url = "https://files.pythonhosted.org/packages/6d/fc/de9cce525b2c5b94b47c70a4b4fb19f871b24995c728e957ee68ab1671ea/charset_normalizer-3.4.4-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:840c25fb618a231545cbab0564a799f101b63b9901f2569faecd6b222ac72381", size = 151550, upload-time = "2025-10-14T04:40:40.053Z" }, - { url = "https://files.pythonhosted.org/packages/55/c2/43edd615fdfba8c6f2dfbd459b25a6b3b551f24ea21981e23fb768503ce1/charset_normalizer-3.4.4-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ca5862d5b3928c4940729dacc329aa9102900382fea192fc5e52eb69d6093815", size = 149162, upload-time = "2025-10-14T04:40:41.163Z" }, - { url = "https://files.pythonhosted.org/packages/03/86/bde4ad8b4d0e9429a4e82c1e8f5c659993a9a863ad62c7df05cf7b678d75/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d9c7f57c3d666a53421049053eaacdd14bbd0a528e2186fcb2e672effd053bb0", size = 150019, upload-time = "2025-10-14T04:40:42.276Z" }, - { url = "https://files.pythonhosted.org/packages/1f/86/a151eb2af293a7e7bac3a739b81072585ce36ccfb4493039f49f1d3cae8c/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:277e970e750505ed74c832b4bf75dac7476262ee2a013f5574dd49075879e161", size = 143310, upload-time = "2025-10-14T04:40:43.439Z" }, - { url = "https://files.pythonhosted.org/packages/b5/fe/43dae6144a7e07b87478fdfc4dbe9efd5defb0e7ec29f5f58a55aeef7bf7/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:31fd66405eaf47bb62e8cd575dc621c56c668f27d46a61d975a249930dd5e2a4", size = 162022, upload-time = "2025-10-14T04:40:44.547Z" }, - { url = "https://files.pythonhosted.org/packages/80/e6/7aab83774f5d2bca81f42ac58d04caf44f0cc2b65fc6db2b3b2e8a05f3b3/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:0d3d8f15c07f86e9ff82319b3d9ef6f4bf907608f53fe9d92b28ea9ae3d1fd89", size = 149383, upload-time = "2025-10-14T04:40:46.018Z" }, - { url = "https://files.pythonhosted.org/packages/4f/e8/b289173b4edae05c0dde07f69f8db476a0b511eac556dfe0d6bda3c43384/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:9f7fcd74d410a36883701fafa2482a6af2ff5ba96b9a620e9e0721e28ead5569", size = 159098, upload-time = "2025-10-14T04:40:47.081Z" }, - { url = "https://files.pythonhosted.org/packages/d8/df/fe699727754cae3f8478493c7f45f777b17c3ef0600e28abfec8619eb49c/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ebf3e58c7ec8a8bed6d66a75d7fb37b55e5015b03ceae72a8e7c74495551e224", size = 152991, upload-time = "2025-10-14T04:40:48.246Z" }, - { url = "https://files.pythonhosted.org/packages/1a/86/584869fe4ddb6ffa3bd9f491b87a01568797fb9bd8933f557dba9771beaf/charset_normalizer-3.4.4-cp311-cp311-win32.whl", hash = "sha256:eecbc200c7fd5ddb9a7f16c7decb07b566c29fa2161a16cf67b8d068bd21690a", size = 99456, upload-time = "2025-10-14T04:40:49.376Z" }, - { url = "https://files.pythonhosted.org/packages/65/f6/62fdd5feb60530f50f7e38b4f6a1d5203f4d16ff4f9f0952962c044e919a/charset_normalizer-3.4.4-cp311-cp311-win_amd64.whl", hash = "sha256:5ae497466c7901d54b639cf42d5b8c1b6a4fead55215500d2f486d34db48d016", size = 106978, upload-time = "2025-10-14T04:40:50.844Z" }, - { url = "https://files.pythonhosted.org/packages/7a/9d/0710916e6c82948b3be62d9d398cb4fcf4e97b56d6a6aeccd66c4b2f2bd5/charset_normalizer-3.4.4-cp311-cp311-win_arm64.whl", hash = "sha256:65e2befcd84bc6f37095f5961e68a6f077bf44946771354a28ad434c2cce0ae1", size = 99969, upload-time = "2025-10-14T04:40:52.272Z" }, { url = "https://files.pythonhosted.org/packages/f3/85/1637cd4af66fa687396e757dec650f28025f2a2f5a5531a3208dc0ec43f2/charset_normalizer-3.4.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0a98e6759f854bd25a58a73fa88833fba3b7c491169f86ce1180c948ab3fd394", size = 208425, upload-time = "2025-10-14T04:40:53.353Z" }, { url = "https://files.pythonhosted.org/packages/9d/6a/04130023fef2a0d9c62d0bae2649b69f7b7d8d24ea5536feef50551029df/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b5b290ccc2a263e8d185130284f8501e3e36c5e02750fc6b6bdeb2e9e96f1e25", size = 148162, upload-time = "2025-10-14T04:40:54.558Z" }, { url = "https://files.pythonhosted.org/packages/78/29/62328d79aa60da22c9e0b9a66539feae06ca0f5a4171ac4f7dc285b83688/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74bb723680f9f7a6234dcf67aea57e708ec1fbdf5699fb91dfd6f511b0a320ef", size = 144558, upload-time = "2025-10-14T04:40:55.677Z" }, @@ -325,21 +292,6 @@ version = "7.13.4" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/24/56/95b7e30fa389756cb56630faa728da46a27b8c6eb46f9d557c68fff12b65/coverage-7.13.4.tar.gz", hash = "sha256:e5c8f6ed1e61a8b2dcdf31eb0b9bbf0130750ca79c1c49eb898e2ad86f5ccc91", size = 827239, upload-time = "2026-02-09T12:59:03.86Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b4/ad/b59e5b451cf7172b8d1043dc0fa718f23aab379bc1521ee13d4bd9bfa960/coverage-7.13.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d490ba50c3f35dd7c17953c68f3270e7ccd1c6642e2d2afe2d8e720b98f5a053", size = 219278, upload-time = "2026-02-09T12:56:31.673Z" }, - { url = "https://files.pythonhosted.org/packages/f1/17/0cb7ca3de72e5f4ef2ec2fa0089beafbcaaaead1844e8b8a63d35173d77d/coverage-7.13.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:19bc3c88078789f8ef36acb014d7241961dbf883fd2533d18cb1e7a5b4e28b11", size = 219783, upload-time = "2026-02-09T12:56:33.104Z" }, - { url = "https://files.pythonhosted.org/packages/ab/63/325d8e5b11e0eaf6d0f6a44fad444ae58820929a9b0de943fa377fe73e85/coverage-7.13.4-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:3998e5a32e62fdf410c0dbd3115df86297995d6e3429af80b8798aad894ca7aa", size = 250200, upload-time = "2026-02-09T12:56:34.474Z" }, - { url = "https://files.pythonhosted.org/packages/76/53/c16972708cbb79f2942922571a687c52bd109a7bd51175aeb7558dff2236/coverage-7.13.4-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:8e264226ec98e01a8e1054314af91ee6cde0eacac4f465cc93b03dbe0bce2fd7", size = 252114, upload-time = "2026-02-09T12:56:35.749Z" }, - { url = "https://files.pythonhosted.org/packages/eb/c2/7ab36d8b8cc412bec9ea2d07c83c48930eb4ba649634ba00cb7e4e0f9017/coverage-7.13.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a3aa4e7b9e416774b21797365b358a6e827ffadaaca81b69ee02946852449f00", size = 254220, upload-time = "2026-02-09T12:56:37.796Z" }, - { url = "https://files.pythonhosted.org/packages/d6/4d/cf52c9a3322c89a0e6febdfbc83bb45c0ed3c64ad14081b9503adee702e7/coverage-7.13.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:71ca20079dd8f27fcf808817e281e90220475cd75115162218d0e27549f95fef", size = 256164, upload-time = "2026-02-09T12:56:39.016Z" }, - { url = "https://files.pythonhosted.org/packages/78/e9/eb1dd17bd6de8289df3580e967e78294f352a5df8a57ff4671ee5fc3dcd0/coverage-7.13.4-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e2f25215f1a359ab17320b47bcdaca3e6e6356652e8256f2441e4ef972052903", size = 250325, upload-time = "2026-02-09T12:56:40.668Z" }, - { url = "https://files.pythonhosted.org/packages/71/07/8c1542aa873728f72267c07278c5cc0ec91356daf974df21335ccdb46368/coverage-7.13.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d65b2d373032411e86960604dc4edac91fdfb5dca539461cf2cbe78327d1e64f", size = 251913, upload-time = "2026-02-09T12:56:41.97Z" }, - { url = "https://files.pythonhosted.org/packages/74/d7/c62e2c5e4483a748e27868e4c32ad3daa9bdddbba58e1bc7a15e252baa74/coverage-7.13.4-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:94eb63f9b363180aff17de3e7c8760c3ba94664ea2695c52f10111244d16a299", size = 249974, upload-time = "2026-02-09T12:56:43.323Z" }, - { url = "https://files.pythonhosted.org/packages/98/9f/4c5c015a6e98ced54efd0f5cf8d31b88e5504ecb6857585fc0161bb1e600/coverage-7.13.4-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:e856bf6616714c3a9fbc270ab54103f4e685ba236fa98c054e8f87f266c93505", size = 253741, upload-time = "2026-02-09T12:56:45.155Z" }, - { url = "https://files.pythonhosted.org/packages/bd/59/0f4eef89b9f0fcd9633b5d350016f54126ab49426a70ff4c4e87446cabdc/coverage-7.13.4-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:65dfcbe305c3dfe658492df2d85259e0d79ead4177f9ae724b6fb245198f55d6", size = 249695, upload-time = "2026-02-09T12:56:46.636Z" }, - { url = "https://files.pythonhosted.org/packages/b5/2c/b7476f938deb07166f3eb281a385c262675d688ff4659ad56c6c6b8e2e70/coverage-7.13.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b507778ae8a4c915436ed5c2e05b4a6cecfa70f734e19c22a005152a11c7b6a9", size = 250599, upload-time = "2026-02-09T12:56:48.13Z" }, - { url = "https://files.pythonhosted.org/packages/b8/34/c3420709d9846ee3785b9f2831b4d94f276f38884032dca1457fa83f7476/coverage-7.13.4-cp311-cp311-win32.whl", hash = "sha256:784fc3cf8be001197b652d51d3fd259b1e2262888693a4636e18879f613a62a9", size = 221780, upload-time = "2026-02-09T12:56:50.479Z" }, - { url = "https://files.pythonhosted.org/packages/61/08/3d9c8613079d2b11c185b865de9a4c1a68850cfda2b357fae365cf609f29/coverage-7.13.4-cp311-cp311-win_amd64.whl", hash = "sha256:2421d591f8ca05b308cf0092807308b2facbefe54af7c02ac22548b88b95c98f", size = 222715, upload-time = "2026-02-09T12:56:51.815Z" }, - { url = "https://files.pythonhosted.org/packages/18/1a/54c3c80b2f056164cc0a6cdcb040733760c7c4be9d780fe655f356f433e4/coverage-7.13.4-cp311-cp311-win_arm64.whl", hash = "sha256:79e73a76b854d9c6088fe5d8b2ebe745f8681c55f7397c3c0a016192d681045f", size = 221385, upload-time = "2026-02-09T12:56:53.194Z" }, { url = "https://files.pythonhosted.org/packages/d1/81/4ce2fdd909c5a0ed1f6dedb88aa57ab79b6d1fbd9b588c1ac7ef45659566/coverage-7.13.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:02231499b08dabbe2b96612993e5fc34217cdae907a51b906ac7fca8027a4459", size = 219449, upload-time = "2026-02-09T12:56:54.889Z" }, { url = "https://files.pythonhosted.org/packages/5d/96/5238b1efc5922ddbdc9b0db9243152c09777804fb7c02ad1741eb18a11c0/coverage-7.13.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40aa8808140e55dc022b15d8aa7f651b6b3d68b365ea0398f1441e0b04d859c3", size = 219810, upload-time = "2026-02-09T12:56:56.33Z" }, { url = "https://files.pythonhosted.org/packages/78/72/2f372b726d433c9c35e56377cf1d513b4c16fe51841060d826b95caacec1/coverage-7.13.4-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:5b856a8ccf749480024ff3bd7310adaef57bf31fd17e1bfc404b7940b6986634", size = 251308, upload-time = "2026-02-09T12:56:57.858Z" }, @@ -418,11 +370,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/0d/4a/331fe2caf6799d591109bb9c08083080f6de90a823695d412a935622abb2/coverage-7.13.4-py3-none-any.whl", hash = "sha256:1af1641e57cf7ba1bd67d677c9abdbcd6cc2ab7da3bca7fa1e2b7e50e65f2ad0", size = 211242, upload-time = "2026-02-09T12:59:02.032Z" }, ] -[package.optional-dependencies] -toml = [ - { name = "tomli", marker = "python_full_version <= '3.11'" }, -] - [[package]] name = "defusedxml" version = "0.7.1" @@ -552,8 +499,7 @@ all = [ { name = "pytest" }, { name = "pytest-cov" }, { name = "ruff" }, - { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12'" }, - { name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, + { name = "sphinx" }, ] cosmo = [ { name = "colossus" }, @@ -570,14 +516,12 @@ dev = [ { name = "pytest" }, { name = "pytest-cov" }, { name = "ruff" }, - { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12'" }, - { name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, + { name = "sphinx" }, ] docs = [ { name = "nbsphinx" }, { name = "numpydoc" }, - { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12'" }, - { name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, + { name = "sphinx" }, ] fit = [ { name = "emcee" }, @@ -762,10 +706,6 @@ version = "0.46.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/74/cd/08ae687ba099c7e3d21fe2ea536500563ef1943c5105bf6ab4ee3829f68e/llvmlite-0.46.0.tar.gz", hash = "sha256:227c9fd6d09dce2783c18b754b7cd9d9b3b3515210c46acc2d3c5badd9870ceb", size = 193456, upload-time = "2025-12-08T18:15:36.295Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7a/a1/2ad4b2367915faeebe8447f0a057861f646dbf5fbbb3561db42c65659cf3/llvmlite-0.46.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:82f3d39b16f19aa1a56d5fe625883a6ab600d5cc9ea8906cca70ce94cabba067", size = 37232766, upload-time = "2025-12-08T18:14:48.836Z" }, - { url = "https://files.pythonhosted.org/packages/12/b5/99cf8772fdd846c07da4fd70f07812a3c8fd17ea2409522c946bb0f2b277/llvmlite-0.46.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:a3df43900119803bbc52720e758c76f316a9a0f34612a886862dfe0a5591a17e", size = 56275175, upload-time = "2025-12-08T18:14:51.604Z" }, - { url = "https://files.pythonhosted.org/packages/38/f2/ed806f9c003563732da156139c45d970ee435bd0bfa5ed8de87ba972b452/llvmlite-0.46.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:de183fefc8022d21b0aa37fc3e90410bc3524aed8617f0ff76732fc6c3af5361", size = 55128630, upload-time = "2025-12-08T18:14:55.107Z" }, - { url = "https://files.pythonhosted.org/packages/19/0c/8f5a37a65fc9b7b17408508145edd5f86263ad69c19d3574e818f533a0eb/llvmlite-0.46.0-cp311-cp311-win_amd64.whl", hash = "sha256:e8b10bc585c58bdffec9e0c309bb7d51be1f2f15e169a4b4d42f2389e431eb93", size = 38138652, upload-time = "2025-12-08T18:14:58.171Z" }, { url = "https://files.pythonhosted.org/packages/2b/f8/4db016a5e547d4e054ff2f3b99203d63a497465f81ab78ec8eb2ff7b2304/llvmlite-0.46.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6b9588ad4c63b4f0175a3984b85494f0c927c6b001e3a246a3a7fb3920d9a137", size = 37232767, upload-time = "2025-12-08T18:15:00.737Z" }, { url = "https://files.pythonhosted.org/packages/aa/85/4890a7c14b4fa54400945cb52ac3cd88545bbdb973c440f98ca41591cdc5/llvmlite-0.46.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3535bd2bb6a2d7ae4012681ac228e5132cdb75fefb1bcb24e33f2f3e0c865ed4", size = 56275176, upload-time = "2025-12-08T18:15:03.936Z" }, { url = "https://files.pythonhosted.org/packages/6a/07/3d31d39c1a1a08cd5337e78299fca77e6aebc07c059fbd0033e3edfab45c/llvmlite-0.46.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4cbfd366e60ff87ea6cc62f50bc4cd800ebb13ed4c149466f50cf2163a473d1e", size = 55128630, upload-time = "2025-12-08T18:15:07.196Z" }, @@ -798,17 +738,6 @@ version = "3.0.3" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/7e/99/7690b6d4034fffd95959cbe0c02de8deb3098cc577c67bb6a24fe5d7caa7/markupsafe-3.0.3.tar.gz", hash = "sha256:722695808f4b6457b320fdc131280796bdceb04ab50fe1795cd540799ebe1698", size = 80313, upload-time = "2025-09-27T18:37:40.426Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/08/db/fefacb2136439fc8dd20e797950e749aa1f4997ed584c62cfb8ef7c2be0e/markupsafe-3.0.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1cc7ea17a6824959616c525620e387f6dd30fec8cb44f649e31712db02123dad", size = 11631, upload-time = "2025-09-27T18:36:18.185Z" }, - { url = "https://files.pythonhosted.org/packages/e1/2e/5898933336b61975ce9dc04decbc0a7f2fee78c30353c5efba7f2d6ff27a/markupsafe-3.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4bd4cd07944443f5a265608cc6aab442e4f74dff8088b0dfc8238647b8f6ae9a", size = 12058, upload-time = "2025-09-27T18:36:19.444Z" }, - { url = "https://files.pythonhosted.org/packages/1d/09/adf2df3699d87d1d8184038df46a9c80d78c0148492323f4693df54e17bb/markupsafe-3.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b5420a1d9450023228968e7e6a9ce57f65d148ab56d2313fcd589eee96a7a50", size = 24287, upload-time = "2025-09-27T18:36:20.768Z" }, - { url = "https://files.pythonhosted.org/packages/30/ac/0273f6fcb5f42e314c6d8cd99effae6a5354604d461b8d392b5ec9530a54/markupsafe-3.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0bf2a864d67e76e5c9a34dc26ec616a66b9888e25e7b9460e1c76d3293bd9dbf", size = 22940, upload-time = "2025-09-27T18:36:22.249Z" }, - { url = "https://files.pythonhosted.org/packages/19/ae/31c1be199ef767124c042c6c3e904da327a2f7f0cd63a0337e1eca2967a8/markupsafe-3.0.3-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:bc51efed119bc9cfdf792cdeaa4d67e8f6fcccab66ed4bfdd6bde3e59bfcbb2f", size = 21887, upload-time = "2025-09-27T18:36:23.535Z" }, - { url = "https://files.pythonhosted.org/packages/b2/76/7edcab99d5349a4532a459e1fe64f0b0467a3365056ae550d3bcf3f79e1e/markupsafe-3.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:068f375c472b3e7acbe2d5318dea141359e6900156b5b2ba06a30b169086b91a", size = 23692, upload-time = "2025-09-27T18:36:24.823Z" }, - { url = "https://files.pythonhosted.org/packages/a4/28/6e74cdd26d7514849143d69f0bf2399f929c37dc2b31e6829fd2045b2765/markupsafe-3.0.3-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:7be7b61bb172e1ed687f1754f8e7484f1c8019780f6f6b0786e76bb01c2ae115", size = 21471, upload-time = "2025-09-27T18:36:25.95Z" }, - { url = "https://files.pythonhosted.org/packages/62/7e/a145f36a5c2945673e590850a6f8014318d5577ed7e5920a4b3448e0865d/markupsafe-3.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f9e130248f4462aaa8e2552d547f36ddadbeaa573879158d721bbd33dfe4743a", size = 22923, upload-time = "2025-09-27T18:36:27.109Z" }, - { url = "https://files.pythonhosted.org/packages/0f/62/d9c46a7f5c9adbeeeda52f5b8d802e1094e9717705a645efc71b0913a0a8/markupsafe-3.0.3-cp311-cp311-win32.whl", hash = "sha256:0db14f5dafddbb6d9208827849fad01f1a2609380add406671a26386cdf15a19", size = 14572, upload-time = "2025-09-27T18:36:28.045Z" }, - { url = "https://files.pythonhosted.org/packages/83/8a/4414c03d3f891739326e1783338e48fb49781cc915b2e0ee052aa490d586/markupsafe-3.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:de8a88e63464af587c950061a5e6a67d3632e36df62b986892331d4620a35c01", size = 15077, upload-time = "2025-09-27T18:36:29.025Z" }, - { url = "https://files.pythonhosted.org/packages/35/73/893072b42e6862f319b5207adc9ae06070f095b358655f077f69a35601f0/markupsafe-3.0.3-cp311-cp311-win_arm64.whl", hash = "sha256:3b562dd9e9ea93f13d53989d23a7e775fdfd1066c33494ff43f5418bc8c58a5c", size = 13876, upload-time = "2025-09-27T18:36:29.954Z" }, { url = "https://files.pythonhosted.org/packages/5a/72/147da192e38635ada20e0a2e1a51cf8823d2119ce8883f7053879c2199b5/markupsafe-3.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d53197da72cc091b024dd97249dfc7794d6a56530370992a5e1a08983ad9230e", size = 11615, upload-time = "2025-09-27T18:36:30.854Z" }, { url = "https://files.pythonhosted.org/packages/9a/81/7e4e08678a1f98521201c3079f77db69fb552acd56067661f8c2f534a718/markupsafe-3.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1872df69a4de6aead3491198eaf13810b565bdbeec3ae2dc8780f14458ec73ce", size = 12020, upload-time = "2025-09-27T18:36:31.971Z" }, { url = "https://files.pythonhosted.org/packages/1e/2c/799f4742efc39633a1b54a92eec4082e4f815314869865d876824c257c1e/markupsafe-3.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3a7e8ae81ae39e62a41ec302f972ba6ae23a5c5396c8e60113e9066ef893da0d", size = 24332, upload-time = "2025-09-27T18:36:32.813Z" }, @@ -957,8 +886,7 @@ dependencies = [ { name = "jinja2" }, { name = "nbconvert" }, { name = "nbformat" }, - { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12'" }, - { name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, + { name = "sphinx" }, { name = "traitlets" }, ] sdist = { url = "https://files.pythonhosted.org/packages/e7/d1/82081750f8a78ad0399c6ed831d42623b891904e8e7b8a75878225cf1dce/nbsphinx-0.9.8.tar.gz", hash = "sha256:d0765908399a8ee2b57be7ae881cf2ea58d66db3af7bbf33e6eb48f83bea5495", size = 417469, upload-time = "2025-11-28T17:41:02.336Z" } @@ -985,10 +913,6 @@ dependencies = [ ] sdist = { url = "https://files.pythonhosted.org/packages/23/c9/a0fb41787d01d621046138da30f6c2100d80857bf34b3390dd68040f27a3/numba-0.64.0.tar.gz", hash = "sha256:95e7300af648baa3308127b1955b52ce6d11889d16e8cfe637b4f85d2fca52b1", size = 2765679, upload-time = "2026-02-18T18:41:20.974Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/89/a3/1a4286a1c16136c8896d8e2090d950e79b3ec626d3a8dc9620f6234d5a38/numba-0.64.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:766156ee4b8afeeb2b2e23c81307c5d19031f18d5ce76ae2c5fb1429e72fa92b", size = 2682938, upload-time = "2026-02-18T18:40:52.897Z" }, - { url = "https://files.pythonhosted.org/packages/19/16/aa6e3ba3cd45435c117d1101b278b646444ed05b7c712af631b91353f573/numba-0.64.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d17071b4ffc9d39b75d8e6c101a36f0c81b646123859898c9799cb31807c8f78", size = 3747376, upload-time = "2026-02-18T18:40:54.925Z" }, - { url = "https://files.pythonhosted.org/packages/c0/f1/dd2f25e18d75fdf897f730b78c5a7b00cc4450f2405564dbebfaf359f21f/numba-0.64.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4ead5630434133bac87fa67526eacb264535e4e9a2d5ec780e0b4fc381a7d275", size = 3453292, upload-time = "2026-02-18T18:40:56.818Z" }, - { url = "https://files.pythonhosted.org/packages/31/29/e09d5630578a50a2b3fa154990b6b839cf95327aa0709e2d50d0b6816cd1/numba-0.64.0-cp311-cp311-win_amd64.whl", hash = "sha256:f2b1fd93e7aaac07d6fbaed059c00679f591f2423885c206d8c1b55d65ca3f2d", size = 2749824, upload-time = "2026-02-18T18:40:58.392Z" }, { url = "https://files.pythonhosted.org/packages/70/a6/9fc52cb4f0d5e6d8b5f4d81615bc01012e3cf24e1052a60f17a68deb8092/numba-0.64.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:69440a8e8bc1a81028446f06b363e28635aa67bd51b1e498023f03b812e0ce68", size = 2683418, upload-time = "2026-02-18T18:40:59.886Z" }, { url = "https://files.pythonhosted.org/packages/9b/89/1a74ea99b180b7a5587b0301ed1b183a2937c4b4b67f7994689b5d36fc34/numba-0.64.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f13721011f693ba558b8dd4e4db7f2640462bba1b855bdc804be45bbeb55031a", size = 3804087, upload-time = "2026-02-18T18:41:01.699Z" }, { url = "https://files.pythonhosted.org/packages/91/e1/583c647404b15f807410510fec1eb9b80cb8474165940b7749f026f21cbc/numba-0.64.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e0b180b1133f2b5d8b3f09d96b6d7a9e51a7da5dda3c09e998b5bcfac85d222c", size = 3504309, upload-time = "2026-02-18T18:41:03.252Z" }, @@ -1009,17 +933,6 @@ version = "2.4.2" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/57/fd/0005efbd0af48e55eb3c7208af93f2862d4b1a56cd78e84309a2d959208d/numpy-2.4.2.tar.gz", hash = "sha256:659a6107e31a83c4e33f763942275fd278b21d095094044eb35569e86a21ddae", size = 20723651, upload-time = "2026-01-31T23:13:10.135Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d3/44/71852273146957899753e69986246d6a176061ea183407e95418c2aa4d9a/numpy-2.4.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:e7e88598032542bd49af7c4747541422884219056c268823ef6e5e89851c8825", size = 16955478, upload-time = "2026-01-31T23:10:25.623Z" }, - { url = "https://files.pythonhosted.org/packages/74/41/5d17d4058bd0cd96bcbd4d9ff0fb2e21f52702aab9a72e4a594efa18692f/numpy-2.4.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7edc794af8b36ca37ef5fcb5e0d128c7e0595c7b96a2318d1badb6fcd8ee86b1", size = 14965467, upload-time = "2026-01-31T23:10:28.186Z" }, - { url = "https://files.pythonhosted.org/packages/49/48/fb1ce8136c19452ed15f033f8aee91d5defe515094e330ce368a0647846f/numpy-2.4.2-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:6e9f61981ace1360e42737e2bae58b27bf28a1b27e781721047d84bd754d32e7", size = 5475172, upload-time = "2026-01-31T23:10:30.848Z" }, - { url = "https://files.pythonhosted.org/packages/40/a9/3feb49f17bbd1300dd2570432961f5c8a4ffeff1db6f02c7273bd020a4c9/numpy-2.4.2-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:cb7bbb88aa74908950d979eeaa24dbdf1a865e3c7e45ff0121d8f70387b55f73", size = 6805145, upload-time = "2026-01-31T23:10:32.352Z" }, - { url = "https://files.pythonhosted.org/packages/3f/39/fdf35cbd6d6e2fcad42fcf85ac04a85a0d0fbfbf34b30721c98d602fd70a/numpy-2.4.2-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4f069069931240b3fc703f1e23df63443dbd6390614c8c44a87d96cd0ec81eb1", size = 15966084, upload-time = "2026-01-31T23:10:34.502Z" }, - { url = "https://files.pythonhosted.org/packages/1b/46/6fa4ea94f1ddf969b2ee941290cca6f1bfac92b53c76ae5f44afe17ceb69/numpy-2.4.2-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c02ef4401a506fb60b411467ad501e1429a3487abca4664871d9ae0b46c8ba32", size = 16899477, upload-time = "2026-01-31T23:10:37.075Z" }, - { url = "https://files.pythonhosted.org/packages/09/a1/2a424e162b1a14a5bd860a464ab4e07513916a64ab1683fae262f735ccd2/numpy-2.4.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2653de5c24910e49c2b106499803124dde62a5a1fe0eedeaecf4309a5f639390", size = 17323429, upload-time = "2026-01-31T23:10:39.704Z" }, - { url = "https://files.pythonhosted.org/packages/ce/a2/73014149ff250628df72c58204822ac01d768697913881aacf839ff78680/numpy-2.4.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1ae241bbfc6ae276f94a170b14785e561cb5e7f626b6688cf076af4110887413", size = 18635109, upload-time = "2026-01-31T23:10:41.924Z" }, - { url = "https://files.pythonhosted.org/packages/6c/0c/73e8be2f1accd56df74abc1c5e18527822067dced5ec0861b5bb882c2ce0/numpy-2.4.2-cp311-cp311-win32.whl", hash = "sha256:df1b10187212b198dd45fa943d8985a3c8cf854aed4923796e0e019e113a1bda", size = 6237915, upload-time = "2026-01-31T23:10:45.26Z" }, - { url = "https://files.pythonhosted.org/packages/76/ae/e0265e0163cf127c24c3969d29f1c4c64551a1e375d95a13d32eab25d364/numpy-2.4.2-cp311-cp311-win_amd64.whl", hash = "sha256:b9c618d56a29c9cb1c4da979e9899be7578d2e0b3c24d52079c166324c9e8695", size = 12607972, upload-time = "2026-01-31T23:10:47.021Z" }, - { url = "https://files.pythonhosted.org/packages/29/a5/c43029af9b8014d6ea157f192652c50042e8911f4300f8f6ed3336bf437f/numpy-2.4.2-cp311-cp311-win_arm64.whl", hash = "sha256:47c5a6ed21d9452b10227e5e8a0e1c22979811cad7dcc19d8e3e2fb8fa03f1a3", size = 10485763, upload-time = "2026-01-31T23:10:50.087Z" }, { url = "https://files.pythonhosted.org/packages/51/6e/6f394c9c77668153e14d4da83bcc247beb5952f6ead7699a1a2992613bea/numpy-2.4.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:21982668592194c609de53ba4933a7471880ccbaadcc52352694a59ecc860b3a", size = 16667963, upload-time = "2026-01-31T23:10:52.147Z" }, { url = "https://files.pythonhosted.org/packages/1f/f8/55483431f2b2fd015ae6ed4fe62288823ce908437ed49db5a03d15151678/numpy-2.4.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40397bda92382fcec844066efb11f13e1c9a3e2a8e8f318fb72ed8b6db9f60f1", size = 14693571, upload-time = "2026-01-31T23:10:54.789Z" }, { url = "https://files.pythonhosted.org/packages/2f/20/18026832b1845cdc82248208dd929ca14c9d8f2bac391f67440707fff27c/numpy-2.4.2-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:b3a24467af63c67829bfaa61eecf18d5432d4f11992688537be59ecd6ad32f5e", size = 5203469, upload-time = "2026-01-31T23:10:57.343Z" }, @@ -1073,13 +986,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/a5/55/6e1a61ded7af8df04016d81b5b02daa59f2ea9252ee0397cb9f631efe9e5/numpy-2.4.2-cp314-cp314t-win32.whl", hash = "sha256:8c50dd1fc8826f5b26a5ee4d77ca55d88a895f4e4819c7ecc2a9f5905047a443", size = 6153937, upload-time = "2026-01-31T23:12:47.229Z" }, { url = "https://files.pythonhosted.org/packages/45/aa/fa6118d1ed6d776b0983f3ceac9b1a5558e80df9365b1c3aa6d42bf9eee4/numpy-2.4.2-cp314-cp314t-win_amd64.whl", hash = "sha256:fcf92bee92742edd401ba41135185866f7026c502617f422eb432cfeca4fe236", size = 12631844, upload-time = "2026-01-31T23:12:48.997Z" }, { url = "https://files.pythonhosted.org/packages/32/0a/2ec5deea6dcd158f254a7b372fb09cfba5719419c8d66343bab35237b3fb/numpy-2.4.2-cp314-cp314t-win_arm64.whl", hash = "sha256:1f92f53998a17265194018d1cc321b2e96e900ca52d54c7c77837b71b9465181", size = 10565379, upload-time = "2026-01-31T23:12:51.345Z" }, - { url = "https://files.pythonhosted.org/packages/f4/f8/50e14d36d915ef64d8f8bc4a087fc8264d82c785eda6711f80ab7e620335/numpy-2.4.2-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:89f7268c009bc492f506abd6f5265defa7cb3f7487dc21d357c3d290add45082", size = 16833179, upload-time = "2026-01-31T23:12:53.5Z" }, - { url = "https://files.pythonhosted.org/packages/17/17/809b5cad63812058a8189e91a1e2d55a5a18fd04611dbad244e8aeae465c/numpy-2.4.2-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:e6dee3bb76aa4009d5a912180bf5b2de012532998d094acee25d9cb8dee3e44a", size = 14889755, upload-time = "2026-01-31T23:12:55.933Z" }, - { url = "https://files.pythonhosted.org/packages/3e/ea/181b9bcf7627fc8371720316c24db888dcb9829b1c0270abf3d288b2e29b/numpy-2.4.2-pp311-pypy311_pp73-macosx_14_0_arm64.whl", hash = "sha256:cd2bd2bbed13e213d6b55dc1d035a4f91748a7d3edc9480c13898b0353708920", size = 5399500, upload-time = "2026-01-31T23:12:58.671Z" }, - { url = "https://files.pythonhosted.org/packages/33/9f/413adf3fc955541ff5536b78fcf0754680b3c6d95103230252a2c9408d23/numpy-2.4.2-pp311-pypy311_pp73-macosx_14_0_x86_64.whl", hash = "sha256:cf28c0c1d4c4bf00f509fa7eb02c58d7caf221b50b467bcb0d9bbf1584d5c821", size = 6714252, upload-time = "2026-01-31T23:13:00.518Z" }, - { url = "https://files.pythonhosted.org/packages/91/da/643aad274e29ccbdf42ecd94dafe524b81c87bcb56b83872d54827f10543/numpy-2.4.2-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e04ae107ac591763a47398bb45b568fc38f02dbc4aa44c063f67a131f99346cb", size = 15797142, upload-time = "2026-01-31T23:13:02.219Z" }, - { url = "https://files.pythonhosted.org/packages/66/27/965b8525e9cb5dc16481b30a1b3c21e50c7ebf6e9dbd48d0c4d0d5089c7e/numpy-2.4.2-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:602f65afdef699cda27ec0b9224ae5dc43e328f4c24c689deaf77133dbee74d0", size = 16727979, upload-time = "2026-01-31T23:13:04.62Z" }, - { url = "https://files.pythonhosted.org/packages/de/e5/b7d20451657664b07986c2f6e3be564433f5dcaf3482d68eaecd79afaf03/numpy-2.4.2-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:be71bf1edb48ebbbf7f6337b5bfd2f895d1902f6335a5830b20141fc126ffba0", size = 12502577, upload-time = "2026-01-31T23:13:07.08Z" }, ] [[package]] @@ -1087,8 +993,7 @@ name = "numpydoc" version = "1.10.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12'" }, - { name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, + { name = "sphinx" }, ] sdist = { url = "https://files.pythonhosted.org/packages/e9/3c/dfccc9e7dee357fb2aa13c3890d952a370dd0ed071e0f7ed62ed0df567c1/numpydoc-1.10.0.tar.gz", hash = "sha256:3f7970f6eee30912260a6b31ac72bba2432830cd6722569ec17ee8d3ef5ffa01", size = 94027, upload-time = "2025-12-02T16:39:12.937Z" } wheels = [ @@ -1204,7 +1109,7 @@ name = "pytest-cov" version = "7.0.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "coverage", extra = ["toml"] }, + { name = "coverage" }, { name = "pluggy" }, { name = "pytest" }, ] @@ -1231,15 +1136,6 @@ version = "6.0.3" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f", size = 130960, upload-time = "2025-09-25T21:33:16.546Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/6d/16/a95b6757765b7b031c9374925bb718d55e0a9ba8a1b6a12d25962ea44347/pyyaml-6.0.3-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:44edc647873928551a01e7a563d7452ccdebee747728c1080d881d68af7b997e", size = 185826, upload-time = "2025-09-25T21:31:58.655Z" }, - { url = "https://files.pythonhosted.org/packages/16/19/13de8e4377ed53079ee996e1ab0a9c33ec2faf808a4647b7b4c0d46dd239/pyyaml-6.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:652cb6edd41e718550aad172851962662ff2681490a8a711af6a4d288dd96824", size = 175577, upload-time = "2025-09-25T21:32:00.088Z" }, - { url = "https://files.pythonhosted.org/packages/0c/62/d2eb46264d4b157dae1275b573017abec435397aa59cbcdab6fc978a8af4/pyyaml-6.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:10892704fc220243f5305762e276552a0395f7beb4dbf9b14ec8fd43b57f126c", size = 775556, upload-time = "2025-09-25T21:32:01.31Z" }, - { url = "https://files.pythonhosted.org/packages/10/cb/16c3f2cf3266edd25aaa00d6c4350381c8b012ed6f5276675b9eba8d9ff4/pyyaml-6.0.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:850774a7879607d3a6f50d36d04f00ee69e7fc816450e5f7e58d7f17f1ae5c00", size = 882114, upload-time = "2025-09-25T21:32:03.376Z" }, - { url = "https://files.pythonhosted.org/packages/71/60/917329f640924b18ff085ab889a11c763e0b573da888e8404ff486657602/pyyaml-6.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b8bb0864c5a28024fac8a632c443c87c5aa6f215c0b126c449ae1a150412f31d", size = 806638, upload-time = "2025-09-25T21:32:04.553Z" }, - { url = "https://files.pythonhosted.org/packages/dd/6f/529b0f316a9fd167281a6c3826b5583e6192dba792dd55e3203d3f8e655a/pyyaml-6.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1d37d57ad971609cf3c53ba6a7e365e40660e3be0e5175fa9f2365a379d6095a", size = 767463, upload-time = "2025-09-25T21:32:06.152Z" }, - { url = "https://files.pythonhosted.org/packages/f2/6a/b627b4e0c1dd03718543519ffb2f1deea4a1e6d42fbab8021936a4d22589/pyyaml-6.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:37503bfbfc9d2c40b344d06b2199cf0e96e97957ab1c1b546fd4f87e53e5d3e4", size = 794986, upload-time = "2025-09-25T21:32:07.367Z" }, - { url = "https://files.pythonhosted.org/packages/45/91/47a6e1c42d9ee337c4839208f30d9f09caa9f720ec7582917b264defc875/pyyaml-6.0.3-cp311-cp311-win32.whl", hash = "sha256:8098f252adfa6c80ab48096053f512f2321f0b998f98150cea9bd23d83e1467b", size = 142543, upload-time = "2025-09-25T21:32:08.95Z" }, - { url = "https://files.pythonhosted.org/packages/da/e3/ea007450a105ae919a72393cb06f122f288ef60bba2dc64b26e2646fa315/pyyaml-6.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:9f3bfb4965eb874431221a3ff3fdcddc7e74e3b07799e0e84ca4a0f867d449bf", size = 158763, upload-time = "2025-09-25T21:32:09.96Z" }, { url = "https://files.pythonhosted.org/packages/d1/33/422b98d2195232ca1826284a76852ad5a86fe23e31b009c9886b2d0fb8b2/pyyaml-6.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7f047e29dcae44602496db43be01ad42fc6f1cc0d8cd6c83d342306c32270196", size = 182063, upload-time = "2025-09-25T21:32:11.445Z" }, { url = "https://files.pythonhosted.org/packages/89/a0/6cf41a19a1f2f3feab0e9c0b74134aa2ce6849093d5517a0c550fe37a648/pyyaml-6.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fc09d0aa354569bc501d4e787133afc08552722d3ab34836a80547331bb5d4a0", size = 173973, upload-time = "2025-09-25T21:32:12.492Z" }, { url = "https://files.pythonhosted.org/packages/ed/23/7a778b6bd0b9a8039df8b1b1d80e2e2ad78aa04171592c8a5c43a56a6af4/pyyaml-6.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9149cad251584d5fb4981be1ecde53a1ca46c891a79788c0df828d2f166bda28", size = 775116, upload-time = "2025-09-25T21:32:13.652Z" }, @@ -1289,16 +1185,6 @@ dependencies = [ ] sdist = { url = "https://files.pythonhosted.org/packages/04/0b/3c9baedbdf613ecaa7aa07027780b8867f57b6293b6ee50de316c9f3222b/pyzmq-27.1.0.tar.gz", hash = "sha256:ac0765e3d44455adb6ddbf4417dcce460fc40a05978c08efdf2948072f6db540", size = 281750, upload-time = "2025-09-08T23:10:18.157Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/06/5d/305323ba86b284e6fcb0d842d6adaa2999035f70f8c38a9b6d21ad28c3d4/pyzmq-27.1.0-cp311-cp311-macosx_10_15_universal2.whl", hash = "sha256:226b091818d461a3bef763805e75685e478ac17e9008f49fce2d3e52b3d58b86", size = 1333328, upload-time = "2025-09-08T23:07:45.946Z" }, - { url = "https://files.pythonhosted.org/packages/bd/a0/fc7e78a23748ad5443ac3275943457e8452da67fda347e05260261108cbc/pyzmq-27.1.0-cp311-cp311-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:0790a0161c281ca9723f804871b4027f2e8b5a528d357c8952d08cd1a9c15581", size = 908803, upload-time = "2025-09-08T23:07:47.551Z" }, - { url = "https://files.pythonhosted.org/packages/7e/22/37d15eb05f3bdfa4abea6f6d96eb3bb58585fbd3e4e0ded4e743bc650c97/pyzmq-27.1.0-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c895a6f35476b0c3a54e3eb6ccf41bf3018de937016e6e18748317f25d4e925f", size = 668836, upload-time = "2025-09-08T23:07:49.436Z" }, - { url = "https://files.pythonhosted.org/packages/b1/c4/2a6fe5111a01005fc7af3878259ce17684fabb8852815eda6225620f3c59/pyzmq-27.1.0-cp311-cp311-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5bbf8d3630bf96550b3be8e1fc0fea5cbdc8d5466c1192887bd94869da17a63e", size = 857038, upload-time = "2025-09-08T23:07:51.234Z" }, - { url = "https://files.pythonhosted.org/packages/cb/eb/bfdcb41d0db9cd233d6fb22dc131583774135505ada800ebf14dfb0a7c40/pyzmq-27.1.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:15c8bd0fe0dabf808e2d7a681398c4e5ded70a551ab47482067a572c054c8e2e", size = 1657531, upload-time = "2025-09-08T23:07:52.795Z" }, - { url = "https://files.pythonhosted.org/packages/ab/21/e3180ca269ed4a0de5c34417dfe71a8ae80421198be83ee619a8a485b0c7/pyzmq-27.1.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:bafcb3dd171b4ae9f19ee6380dfc71ce0390fefaf26b504c0e5f628d7c8c54f2", size = 2034786, upload-time = "2025-09-08T23:07:55.047Z" }, - { url = "https://files.pythonhosted.org/packages/3b/b1/5e21d0b517434b7f33588ff76c177c5a167858cc38ef740608898cd329f2/pyzmq-27.1.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e829529fcaa09937189178115c49c504e69289abd39967cd8a4c215761373394", size = 1894220, upload-time = "2025-09-08T23:07:57.172Z" }, - { url = "https://files.pythonhosted.org/packages/03/f2/44913a6ff6941905efc24a1acf3d3cb6146b636c546c7406c38c49c403d4/pyzmq-27.1.0-cp311-cp311-win32.whl", hash = "sha256:6df079c47d5902af6db298ec92151db82ecb557af663098b92f2508c398bb54f", size = 567155, upload-time = "2025-09-08T23:07:59.05Z" }, - { url = "https://files.pythonhosted.org/packages/23/6d/d8d92a0eb270a925c9b4dd039c0b4dc10abc2fcbc48331788824ef113935/pyzmq-27.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:190cbf120fbc0fc4957b56866830def56628934a9d112aec0e2507aa6a032b97", size = 633428, upload-time = "2025-09-08T23:08:00.663Z" }, - { url = "https://files.pythonhosted.org/packages/ae/14/01afebc96c5abbbd713ecfc7469cfb1bc801c819a74ed5c9fad9a48801cb/pyzmq-27.1.0-cp311-cp311-win_arm64.whl", hash = "sha256:eca6b47df11a132d1745eb3b5b5e557a7dae2c303277aa0e69c6ba91b8736e07", size = 559497, upload-time = "2025-09-08T23:08:02.15Z" }, { url = "https://files.pythonhosted.org/packages/92/e7/038aab64a946d535901103da16b953c8c9cc9c961dadcbf3609ed6428d23/pyzmq-27.1.0-cp312-abi3-macosx_10_15_universal2.whl", hash = "sha256:452631b640340c928fa343801b0d07eb0c3789a5ffa843f6e1a9cee0ba4eb4fc", size = 1306279, upload-time = "2025-09-08T23:08:03.807Z" }, { url = "https://files.pythonhosted.org/packages/e8/5e/c3c49fdd0f535ef45eefcc16934648e9e59dace4a37ee88fc53f6cd8e641/pyzmq-27.1.0-cp312-abi3-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:1c179799b118e554b66da67d88ed66cd37a169f1f23b5d9f0a231b4e8d44a113", size = 895645, upload-time = "2025-09-08T23:08:05.301Z" }, { url = "https://files.pythonhosted.org/packages/f8/e5/b0b2504cb4e903a74dcf1ebae157f9e20ebb6ea76095f6cfffea28c42ecd/pyzmq-27.1.0-cp312-abi3-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3837439b7f99e60312f0c926a6ad437b067356dc2bc2ec96eb395fd0fe804233", size = 652574, upload-time = "2025-09-08T23:08:06.828Z" }, @@ -1331,11 +1217,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/c4/59/a5f38970f9bf07cee96128de79590bb354917914a9be11272cfc7ff26af0/pyzmq-27.1.0-cp314-cp314t-win32.whl", hash = "sha256:1f0b2a577fd770aa6f053211a55d1c47901f4d537389a034c690291485e5fe92", size = 587472, upload-time = "2025-09-08T23:08:58.18Z" }, { url = "https://files.pythonhosted.org/packages/70/d8/78b1bad170f93fcf5e3536e70e8fadac55030002275c9a29e8f5719185de/pyzmq-27.1.0-cp314-cp314t-win_amd64.whl", hash = "sha256:19c9468ae0437f8074af379e986c5d3d7d7bfe033506af442e8c879732bedbe0", size = 661401, upload-time = "2025-09-08T23:08:59.802Z" }, { url = "https://files.pythonhosted.org/packages/81/d6/4bfbb40c9a0b42fc53c7cf442f6385db70b40f74a783130c5d0a5aa62228/pyzmq-27.1.0-cp314-cp314t-win_arm64.whl", hash = "sha256:dc5dbf68a7857b59473f7df42650c621d7e8923fb03fa74a526890f4d33cc4d7", size = 575170, upload-time = "2025-09-08T23:09:01.418Z" }, - { url = "https://files.pythonhosted.org/packages/4c/c6/c4dcdecdbaa70969ee1fdced6d7b8f60cfabe64d25361f27ac4665a70620/pyzmq-27.1.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:18770c8d3563715387139060d37859c02ce40718d1faf299abddcdcc6a649066", size = 836265, upload-time = "2025-09-08T23:09:49.376Z" }, - { url = "https://files.pythonhosted.org/packages/3e/79/f38c92eeaeb03a2ccc2ba9866f0439593bb08c5e3b714ac1d553e5c96e25/pyzmq-27.1.0-pp311-pypy311_pp73-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:ac25465d42f92e990f8d8b0546b01c391ad431c3bf447683fdc40565941d0604", size = 800208, upload-time = "2025-09-08T23:09:51.073Z" }, - { url = "https://files.pythonhosted.org/packages/49/0e/3f0d0d335c6b3abb9b7b723776d0b21fa7f3a6c819a0db6097059aada160/pyzmq-27.1.0-pp311-pypy311_pp73-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:53b40f8ae006f2734ee7608d59ed661419f087521edbfc2149c3932e9c14808c", size = 567747, upload-time = "2025-09-08T23:09:52.698Z" }, - { url = "https://files.pythonhosted.org/packages/a1/cf/f2b3784d536250ffd4be70e049f3b60981235d70c6e8ce7e3ef21e1adb25/pyzmq-27.1.0-pp311-pypy311_pp73-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f605d884e7c8be8fe1aa94e0a783bf3f591b84c24e4bc4f3e7564c82ac25e271", size = 747371, upload-time = "2025-09-08T23:09:54.563Z" }, - { url = "https://files.pythonhosted.org/packages/01/1b/5dbe84eefc86f48473947e2f41711aded97eecef1231f4558f1f02713c12/pyzmq-27.1.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:c9f7f6e13dff2e44a6afeaf2cf54cee5929ad64afaf4d40b50f93c58fc687355", size = 544862, upload-time = "2025-09-08T23:09:56.509Z" }, ] [[package]] @@ -1395,21 +1276,6 @@ version = "0.30.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/20/af/3f2f423103f1113b36230496629986e0ef7e199d2aa8392452b484b38ced/rpds_py-0.30.0.tar.gz", hash = "sha256:dd8ff7cf90014af0c0f787eea34794ebf6415242ee1d6fa91eaba725cc441e84", size = 69469, upload-time = "2025-11-30T20:24:38.837Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/4d/6e/f964e88b3d2abee2a82c1ac8366da848fce1c6d834dc2132c3fda3970290/rpds_py-0.30.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:a2bffea6a4ca9f01b3f8e548302470306689684e61602aa3d141e34da06cf425", size = 370157, upload-time = "2025-11-30T20:21:53.789Z" }, - { url = "https://files.pythonhosted.org/packages/94/ba/24e5ebb7c1c82e74c4e4f33b2112a5573ddc703915b13a073737b59b86e0/rpds_py-0.30.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dc4f992dfe1e2bc3ebc7444f6c7051b4bc13cd8e33e43511e8ffd13bf407010d", size = 359676, upload-time = "2025-11-30T20:21:55.475Z" }, - { url = "https://files.pythonhosted.org/packages/84/86/04dbba1b087227747d64d80c3b74df946b986c57af0a9f0c98726d4d7a3b/rpds_py-0.30.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:422c3cb9856d80b09d30d2eb255d0754b23e090034e1deb4083f8004bd0761e4", size = 389938, upload-time = "2025-11-30T20:21:57.079Z" }, - { url = "https://files.pythonhosted.org/packages/42/bb/1463f0b1722b7f45431bdd468301991d1328b16cffe0b1c2918eba2c4eee/rpds_py-0.30.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:07ae8a593e1c3c6b82ca3292efbe73c30b61332fd612e05abee07c79359f292f", size = 402932, upload-time = "2025-11-30T20:21:58.47Z" }, - { url = "https://files.pythonhosted.org/packages/99/ee/2520700a5c1f2d76631f948b0736cdf9b0acb25abd0ca8e889b5c62ac2e3/rpds_py-0.30.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:12f90dd7557b6bd57f40abe7747e81e0c0b119bef015ea7726e69fe550e394a4", size = 525830, upload-time = "2025-11-30T20:21:59.699Z" }, - { url = "https://files.pythonhosted.org/packages/e0/ad/bd0331f740f5705cc555a5e17fdf334671262160270962e69a2bdef3bf76/rpds_py-0.30.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:99b47d6ad9a6da00bec6aabe5a6279ecd3c06a329d4aa4771034a21e335c3a97", size = 412033, upload-time = "2025-11-30T20:22:00.991Z" }, - { url = "https://files.pythonhosted.org/packages/f8/1e/372195d326549bb51f0ba0f2ecb9874579906b97e08880e7a65c3bef1a99/rpds_py-0.30.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:33f559f3104504506a44bb666b93a33f5d33133765b0c216a5bf2f1e1503af89", size = 390828, upload-time = "2025-11-30T20:22:02.723Z" }, - { url = "https://files.pythonhosted.org/packages/ab/2b/d88bb33294e3e0c76bc8f351a3721212713629ffca1700fa94979cb3eae8/rpds_py-0.30.0-cp311-cp311-manylinux_2_31_riscv64.whl", hash = "sha256:946fe926af6e44f3697abbc305ea168c2c31d3e3ef1058cf68f379bf0335a78d", size = 404683, upload-time = "2025-11-30T20:22:04.367Z" }, - { url = "https://files.pythonhosted.org/packages/50/32/c759a8d42bcb5289c1fac697cd92f6fe01a018dd937e62ae77e0e7f15702/rpds_py-0.30.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:495aeca4b93d465efde585977365187149e75383ad2684f81519f504f5c13038", size = 421583, upload-time = "2025-11-30T20:22:05.814Z" }, - { url = "https://files.pythonhosted.org/packages/2b/81/e729761dbd55ddf5d84ec4ff1f47857f4374b0f19bdabfcf929164da3e24/rpds_py-0.30.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d9a0ca5da0386dee0655b4ccdf46119df60e0f10da268d04fe7cc87886872ba7", size = 572496, upload-time = "2025-11-30T20:22:07.713Z" }, - { url = "https://files.pythonhosted.org/packages/14/f6/69066a924c3557c9c30baa6ec3a0aa07526305684c6f86c696b08860726c/rpds_py-0.30.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8d6d1cc13664ec13c1b84241204ff3b12f9bb82464b8ad6e7a5d3486975c2eed", size = 598669, upload-time = "2025-11-30T20:22:09.312Z" }, - { url = "https://files.pythonhosted.org/packages/5f/48/905896b1eb8a05630d20333d1d8ffd162394127b74ce0b0784ae04498d32/rpds_py-0.30.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3896fa1be39912cf0757753826bc8bdc8ca331a28a7c4ae46b7a21280b06bb85", size = 561011, upload-time = "2025-11-30T20:22:11.309Z" }, - { url = "https://files.pythonhosted.org/packages/22/16/cd3027c7e279d22e5eb431dd3c0fbc677bed58797fe7581e148f3f68818b/rpds_py-0.30.0-cp311-cp311-win32.whl", hash = "sha256:55f66022632205940f1827effeff17c4fa7ae1953d2b74a8581baaefb7d16f8c", size = 221406, upload-time = "2025-11-30T20:22:13.101Z" }, - { url = "https://files.pythonhosted.org/packages/fa/5b/e7b7aa136f28462b344e652ee010d4de26ee9fd16f1bfd5811f5153ccf89/rpds_py-0.30.0-cp311-cp311-win_amd64.whl", hash = "sha256:a51033ff701fca756439d641c0ad09a41d9242fa69121c7d8769604a0a629825", size = 236024, upload-time = "2025-11-30T20:22:14.853Z" }, - { url = "https://files.pythonhosted.org/packages/14/a6/364bba985e4c13658edb156640608f2c9e1d3ea3c81b27aa9d889fff0e31/rpds_py-0.30.0-cp311-cp311-win_arm64.whl", hash = "sha256:47b0ef6231c58f506ef0b74d44e330405caa8428e770fec25329ed2cb971a229", size = 229069, upload-time = "2025-11-30T20:22:16.577Z" }, { url = "https://files.pythonhosted.org/packages/03/e7/98a2f4ac921d82f33e03f3835f5bf3a4a40aa1bfdc57975e74a97b2b4bdd/rpds_py-0.30.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:a161f20d9a43006833cd7068375a94d035714d73a172b681d8881820600abfad", size = 375086, upload-time = "2025-11-30T20:22:17.93Z" }, { url = "https://files.pythonhosted.org/packages/4d/a1/bca7fd3d452b272e13335db8d6b0b3ecde0f90ad6f16f3328c6fb150c889/rpds_py-0.30.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6abc8880d9d036ecaafe709079969f56e876fcf107f7a8e9920ba6d5a3878d05", size = 359053, upload-time = "2025-11-30T20:22:19.297Z" }, { url = "https://files.pythonhosted.org/packages/65/1c/ae157e83a6357eceff62ba7e52113e3ec4834a84cfe07fa4b0757a7d105f/rpds_py-0.30.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca28829ae5f5d569bb62a79512c842a03a12576375d5ece7d2cadf8abe96ec28", size = 390763, upload-time = "2025-11-30T20:22:21.661Z" }, @@ -1483,18 +1349,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/85/70/92482ccffb96f5441aab93e26c4d66489eb599efdcf96fad90c14bbfb976/rpds_py-0.30.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:dbd936cde57abfee19ab3213cf9c26be06d60750e60a8e4dd85d1ab12c8b1f40", size = 556030, upload-time = "2025-11-30T20:24:10.956Z" }, { url = "https://files.pythonhosted.org/packages/20/53/7c7e784abfa500a2b6b583b147ee4bb5a2b3747a9166bab52fec4b5b5e7d/rpds_py-0.30.0-cp314-cp314t-win32.whl", hash = "sha256:dc824125c72246d924f7f796b4f63c1e9dc810c7d9e2355864b3c3a73d59ade0", size = 211570, upload-time = "2025-11-30T20:24:12.735Z" }, { url = "https://files.pythonhosted.org/packages/d0/02/fa464cdfbe6b26e0600b62c528b72d8608f5cc49f96b8d6e38c95d60c676/rpds_py-0.30.0-cp314-cp314t-win_amd64.whl", hash = "sha256:27f4b0e92de5bfbc6f86e43959e6edd1425c33b5e69aab0984a72047f2bcf1e3", size = 226532, upload-time = "2025-11-30T20:24:14.634Z" }, - { url = "https://files.pythonhosted.org/packages/69/71/3f34339ee70521864411f8b6992e7ab13ac30d8e4e3309e07c7361767d91/rpds_py-0.30.0-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:c2262bdba0ad4fc6fb5545660673925c2d2a5d9e2e0fb603aad545427be0fc58", size = 372292, upload-time = "2025-11-30T20:24:16.537Z" }, - { url = "https://files.pythonhosted.org/packages/57/09/f183df9b8f2d66720d2ef71075c59f7e1b336bec7ee4c48f0a2b06857653/rpds_py-0.30.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:ee6af14263f25eedc3bb918a3c04245106a42dfd4f5c2285ea6f997b1fc3f89a", size = 362128, upload-time = "2025-11-30T20:24:18.086Z" }, - { url = "https://files.pythonhosted.org/packages/7a/68/5c2594e937253457342e078f0cc1ded3dd7b2ad59afdbf2d354869110a02/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3adbb8179ce342d235c31ab8ec511e66c73faa27a47e076ccc92421add53e2bb", size = 391542, upload-time = "2025-11-30T20:24:20.092Z" }, - { url = "https://files.pythonhosted.org/packages/49/5c/31ef1afd70b4b4fbdb2800249f34c57c64beb687495b10aec0365f53dfc4/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:250fa00e9543ac9b97ac258bd37367ff5256666122c2d0f2bc97577c60a1818c", size = 404004, upload-time = "2025-11-30T20:24:22.231Z" }, - { url = "https://files.pythonhosted.org/packages/e3/63/0cfbea38d05756f3440ce6534d51a491d26176ac045e2707adc99bb6e60a/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9854cf4f488b3d57b9aaeb105f06d78e5529d3145b1e4a41750167e8c213c6d3", size = 527063, upload-time = "2025-11-30T20:24:24.302Z" }, - { url = "https://files.pythonhosted.org/packages/42/e6/01e1f72a2456678b0f618fc9a1a13f882061690893c192fcad9f2926553a/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:993914b8e560023bc0a8bf742c5f303551992dcb85e247b1e5c7f4a7d145bda5", size = 413099, upload-time = "2025-11-30T20:24:25.916Z" }, - { url = "https://files.pythonhosted.org/packages/b8/25/8df56677f209003dcbb180765520c544525e3ef21ea72279c98b9aa7c7fb/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:58edca431fb9b29950807e301826586e5bbf24163677732429770a697ffe6738", size = 392177, upload-time = "2025-11-30T20:24:27.834Z" }, - { url = "https://files.pythonhosted.org/packages/4a/b4/0a771378c5f16f8115f796d1f437950158679bcd2a7c68cf251cfb00ed5b/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_31_riscv64.whl", hash = "sha256:dea5b552272a944763b34394d04577cf0f9bd013207bc32323b5a89a53cf9c2f", size = 406015, upload-time = "2025-11-30T20:24:29.457Z" }, - { url = "https://files.pythonhosted.org/packages/36/d8/456dbba0af75049dc6f63ff295a2f92766b9d521fa00de67a2bd6427d57a/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ba3af48635eb83d03f6c9735dfb21785303e73d22ad03d489e88adae6eab8877", size = 423736, upload-time = "2025-11-30T20:24:31.22Z" }, - { url = "https://files.pythonhosted.org/packages/13/64/b4d76f227d5c45a7e0b796c674fd81b0a6c4fbd48dc29271857d8219571c/rpds_py-0.30.0-pp311-pypy311_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:dff13836529b921e22f15cb099751209a60009731a68519630a24d61f0b1b30a", size = 573981, upload-time = "2025-11-30T20:24:32.934Z" }, - { url = "https://files.pythonhosted.org/packages/20/91/092bacadeda3edf92bf743cc96a7be133e13a39cdbfd7b5082e7ab638406/rpds_py-0.30.0-pp311-pypy311_pp73-musllinux_1_2_i686.whl", hash = "sha256:1b151685b23929ab7beec71080a8889d4d6d9fa9a983d213f07121205d48e2c4", size = 599782, upload-time = "2025-11-30T20:24:35.169Z" }, - { url = "https://files.pythonhosted.org/packages/d1/b7/b95708304cd49b7b6f82fdd039f1748b66ec2b21d6a45180910802f1abf1/rpds_py-0.30.0-pp311-pypy311_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:ac37f9f516c51e5753f27dfdef11a88330f04de2d564be3991384b2f3535d02e", size = 562191, upload-time = "2025-11-30T20:24:36.853Z" }, ] [[package]] @@ -1531,16 +1385,6 @@ dependencies = [ ] sdist = { url = "https://files.pythonhosted.org/packages/56/3e/9cca699f3486ce6bc12ff46dc2031f1ec8eb9ccc9a320fdaf925f1417426/scipy-1.17.0.tar.gz", hash = "sha256:2591060c8e648d8b96439e111ac41fd8342fdeff1876be2e19dea3fe8930454e", size = 30396830, upload-time = "2026-01-10T21:34:23.009Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/1e/4b/c89c131aa87cad2b77a54eb0fb94d633a842420fa7e919dc2f922037c3d8/scipy-1.17.0-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:2abd71643797bd8a106dff97894ff7869eeeb0af0f7a5ce02e4227c6a2e9d6fd", size = 31381316, upload-time = "2026-01-10T21:24:33.42Z" }, - { url = "https://files.pythonhosted.org/packages/5e/5f/a6b38f79a07d74989224d5f11b55267714707582908a5f1ae854cf9a9b84/scipy-1.17.0-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:ef28d815f4d2686503e5f4f00edc387ae58dfd7a2f42e348bb53359538f01558", size = 27966760, upload-time = "2026-01-10T21:24:38.911Z" }, - { url = "https://files.pythonhosted.org/packages/c1/20/095ad24e031ee8ed3c5975954d816b8e7e2abd731e04f8be573de8740885/scipy-1.17.0-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:272a9f16d6bb4667e8b50d25d71eddcc2158a214df1b566319298de0939d2ab7", size = 20138701, upload-time = "2026-01-10T21:24:43.249Z" }, - { url = "https://files.pythonhosted.org/packages/89/11/4aad2b3858d0337756f3323f8960755704e530b27eb2a94386c970c32cbe/scipy-1.17.0-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:7204fddcbec2fe6598f1c5fdf027e9f259106d05202a959a9f1aecf036adc9f6", size = 22480574, upload-time = "2026-01-10T21:24:47.266Z" }, - { url = "https://files.pythonhosted.org/packages/85/bd/f5af70c28c6da2227e510875cadf64879855193a687fb19951f0f44cfd6b/scipy-1.17.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fc02c37a5639ee67d8fb646ffded6d793c06c5622d36b35cfa8fe5ececb8f042", size = 32862414, upload-time = "2026-01-10T21:24:52.566Z" }, - { url = "https://files.pythonhosted.org/packages/ef/df/df1457c4df3826e908879fe3d76bc5b6e60aae45f4ee42539512438cfd5d/scipy-1.17.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:dac97a27520d66c12a34fd90a4fe65f43766c18c0d6e1c0a80f114d2260080e4", size = 35112380, upload-time = "2026-01-10T21:24:58.433Z" }, - { url = "https://files.pythonhosted.org/packages/5f/bb/88e2c16bd1dd4de19d80d7c5e238387182993c2fb13b4b8111e3927ad422/scipy-1.17.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ebb7446a39b3ae0fe8f416a9a3fdc6fba3f11c634f680f16a239c5187bc487c0", size = 34922676, upload-time = "2026-01-10T21:25:04.287Z" }, - { url = "https://files.pythonhosted.org/packages/02/ba/5120242cc735f71fc002cff0303d536af4405eb265f7c60742851e7ccfe9/scipy-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:474da16199f6af66601a01546144922ce402cb17362e07d82f5a6cf8f963e449", size = 37507599, upload-time = "2026-01-10T21:25:09.851Z" }, - { url = "https://files.pythonhosted.org/packages/52/c8/08629657ac6c0da198487ce8cd3de78e02cfde42b7f34117d56a3fe249dc/scipy-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:255c0da161bd7b32a6c898e7891509e8a9289f0b1c6c7d96142ee0d2b114c2ea", size = 36380284, upload-time = "2026-01-10T21:25:15.632Z" }, - { url = "https://files.pythonhosted.org/packages/6c/4a/465f96d42c6f33ad324a40049dfd63269891db9324aa66c4a1c108c6f994/scipy-1.17.0-cp311-cp311-win_arm64.whl", hash = "sha256:85b0ac3ad17fa3be50abd7e69d583d98792d7edc08367e01445a1e2076005379", size = 24370427, upload-time = "2026-01-10T21:25:20.514Z" }, { url = "https://files.pythonhosted.org/packages/0b/11/7241a63e73ba5a516f1930ac8d5b44cbbfabd35ac73a2d08ca206df007c4/scipy-1.17.0-cp312-cp312-macosx_10_14_x86_64.whl", hash = "sha256:0d5018a57c24cb1dd828bcf51d7b10e65986d549f52ef5adb6b4d1ded3e32a57", size = 31364580, upload-time = "2026-01-10T21:25:25.717Z" }, { url = "https://files.pythonhosted.org/packages/ed/1d/5057f812d4f6adc91a20a2d6f2ebcdb517fdbc87ae3acc5633c9b97c8ba5/scipy-1.17.0-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:88c22af9e5d5a4f9e027e26772cc7b5922fab8bcc839edb3ae33de404feebd9e", size = 27969012, upload-time = "2026-01-10T21:25:30.921Z" }, { url = "https://files.pythonhosted.org/packages/e3/21/f6ec556c1e3b6ec4e088da667d9987bb77cc3ab3026511f427dc8451187d/scipy-1.17.0-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:f3cd947f20fe17013d401b64e857c6b2da83cae567adbb75b9dcba865abc66d8", size = 20140691, upload-time = "2026-01-10T21:25:34.802Z" }, @@ -1620,62 +1464,28 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/46/2c/1462b1d0a634697ae9e55b3cecdcb64788e8b7d63f54d923fcd0bb140aed/soupsieve-2.8.3-py3-none-any.whl", hash = "sha256:ed64f2ba4eebeab06cc4962affce381647455978ffc1e36bb79a545b91f45a95", size = 37016, upload-time = "2026-01-20T04:27:01.012Z" }, ] -[[package]] -name = "sphinx" -version = "9.0.4" -source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version < '3.12'", -] -dependencies = [ - { name = "alabaster", marker = "python_full_version < '3.12'" }, - { name = "babel", marker = "python_full_version < '3.12'" }, - { name = "colorama", marker = "python_full_version < '3.12' and sys_platform == 'win32'" }, - { name = "docutils", marker = "python_full_version < '3.12'" }, - { name = "imagesize", marker = "python_full_version < '3.12'" }, - { name = "jinja2", marker = "python_full_version < '3.12'" }, - { name = "packaging", marker = "python_full_version < '3.12'" }, - { name = "pygments", marker = "python_full_version < '3.12'" }, - { name = "requests", marker = "python_full_version < '3.12'" }, - { name = "roman-numerals", marker = "python_full_version < '3.12'" }, - { name = "snowballstemmer", marker = "python_full_version < '3.12'" }, - { name = "sphinxcontrib-applehelp", marker = "python_full_version < '3.12'" }, - { name = "sphinxcontrib-devhelp", marker = "python_full_version < '3.12'" }, - { name = "sphinxcontrib-htmlhelp", marker = "python_full_version < '3.12'" }, - { name = "sphinxcontrib-jsmath", marker = "python_full_version < '3.12'" }, - { name = "sphinxcontrib-qthelp", marker = "python_full_version < '3.12'" }, - { name = "sphinxcontrib-serializinghtml", marker = "python_full_version < '3.12'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/42/50/a8c6ccc36d5eacdfd7913ddccd15a9cee03ecafc5ee2bc40e1f168d85022/sphinx-9.0.4.tar.gz", hash = "sha256:594ef59d042972abbc581d8baa577404abe4e6c3b04ef61bd7fc2acbd51f3fa3", size = 8710502, upload-time = "2025-12-04T07:45:27.343Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/c6/3f/4bbd76424c393caead2e1eb89777f575dee5c8653e2d4b6afd7a564f5974/sphinx-9.0.4-py3-none-any.whl", hash = "sha256:5bebc595a5e943ea248b99c13814c1c5e10b3ece718976824ffa7959ff95fffb", size = 3917713, upload-time = "2025-12-04T07:45:24.944Z" }, -] - [[package]] name = "sphinx" version = "9.1.0" source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version >= '3.12'", -] dependencies = [ - { name = "alabaster", marker = "python_full_version >= '3.12'" }, - { name = "babel", marker = "python_full_version >= '3.12'" }, - { name = "colorama", marker = "python_full_version >= '3.12' and sys_platform == 'win32'" }, - { name = "docutils", marker = "python_full_version >= '3.12'" }, - { name = "imagesize", marker = "python_full_version >= '3.12'" }, - { name = "jinja2", marker = "python_full_version >= '3.12'" }, - { name = "packaging", marker = "python_full_version >= '3.12'" }, - { name = "pygments", marker = "python_full_version >= '3.12'" }, - { name = "requests", marker = "python_full_version >= '3.12'" }, - { name = "roman-numerals", marker = "python_full_version >= '3.12'" }, - { name = "snowballstemmer", marker = "python_full_version >= '3.12'" }, - { name = "sphinxcontrib-applehelp", marker = "python_full_version >= '3.12'" }, - { name = "sphinxcontrib-devhelp", marker = "python_full_version >= '3.12'" }, - { name = "sphinxcontrib-htmlhelp", marker = "python_full_version >= '3.12'" }, - { name = "sphinxcontrib-jsmath", marker = "python_full_version >= '3.12'" }, - { name = "sphinxcontrib-qthelp", marker = "python_full_version >= '3.12'" }, - { name = "sphinxcontrib-serializinghtml", marker = "python_full_version >= '3.12'" }, + { name = "alabaster" }, + { name = "babel" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "docutils" }, + { name = "imagesize" }, + { name = "jinja2" }, + { name = "packaging" }, + { name = "pygments" }, + { name = "requests" }, + { name = "roman-numerals" }, + { name = "snowballstemmer" }, + { name = "sphinxcontrib-applehelp" }, + { name = "sphinxcontrib-devhelp" }, + { name = "sphinxcontrib-htmlhelp" }, + { name = "sphinxcontrib-jsmath" }, + { name = "sphinxcontrib-qthelp" }, + { name = "sphinxcontrib-serializinghtml" }, ] sdist = { url = "https://files.pythonhosted.org/packages/cd/bd/f08eb0f4eed5c83f1ba2a3bd18f7745a2b1525fad70660a1c00224ec468a/sphinx-9.1.0.tar.gz", hash = "sha256:7741722357dd75f8190766926071fed3bdc211c74dd2d7d4df5404da95930ddb", size = 8718324, upload-time = "2025-12-31T15:09:27.646Z" } wheels = [ @@ -1769,60 +1579,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/44/6f/7120676b6d73228c96e17f1f794d8ab046fc910d781c8d151120c3f1569e/toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b", size = 16588, upload-time = "2020-11-01T01:40:20.672Z" }, ] -[[package]] -name = "tomli" -version = "2.4.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/82/30/31573e9457673ab10aa432461bee537ce6cef177667deca369efb79df071/tomli-2.4.0.tar.gz", hash = "sha256:aa89c3f6c277dd275d8e243ad24f3b5e701491a860d5121f2cdd399fbb31fc9c", size = 17477, upload-time = "2026-01-11T11:22:38.165Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/3c/d9/3dc2289e1f3b32eb19b9785b6a006b28ee99acb37d1d47f78d4c10e28bf8/tomli-2.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b5ef256a3fd497d4973c11bf142e9ed78b150d36f5773f1ca6088c230ffc5867", size = 153663, upload-time = "2026-01-11T11:21:45.27Z" }, - { url = "https://files.pythonhosted.org/packages/51/32/ef9f6845e6b9ca392cd3f64f9ec185cc6f09f0a2df3db08cbe8809d1d435/tomli-2.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5572e41282d5268eb09a697c89a7bee84fae66511f87533a6f88bd2f7b652da9", size = 148469, upload-time = "2026-01-11T11:21:46.873Z" }, - { url = "https://files.pythonhosted.org/packages/d6/c2/506e44cce89a8b1b1e047d64bd495c22c9f71f21e05f380f1a950dd9c217/tomli-2.4.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:551e321c6ba03b55676970b47cb1b73f14a0a4dce6a3e1a9458fd6d921d72e95", size = 236039, upload-time = "2026-01-11T11:21:48.503Z" }, - { url = "https://files.pythonhosted.org/packages/b3/40/e1b65986dbc861b7e986e8ec394598187fa8aee85b1650b01dd925ca0be8/tomli-2.4.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5e3f639a7a8f10069d0e15408c0b96a2a828cfdec6fca05296ebcdcc28ca7c76", size = 243007, upload-time = "2026-01-11T11:21:49.456Z" }, - { url = "https://files.pythonhosted.org/packages/9c/6f/6e39ce66b58a5b7ae572a0f4352ff40c71e8573633deda43f6a379d56b3e/tomli-2.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1b168f2731796b045128c45982d3a4874057626da0e2ef1fdd722848b741361d", size = 240875, upload-time = "2026-01-11T11:21:50.755Z" }, - { url = "https://files.pythonhosted.org/packages/aa/ad/cb089cb190487caa80204d503c7fd0f4d443f90b95cf4ef5cf5aa0f439b0/tomli-2.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:133e93646ec4300d651839d382d63edff11d8978be23da4cc106f5a18b7d0576", size = 246271, upload-time = "2026-01-11T11:21:51.81Z" }, - { url = "https://files.pythonhosted.org/packages/0b/63/69125220e47fd7a3a27fd0de0c6398c89432fec41bc739823bcc66506af6/tomli-2.4.0-cp311-cp311-win32.whl", hash = "sha256:b6c78bdf37764092d369722d9946cb65b8767bfa4110f902a1b2542d8d173c8a", size = 96770, upload-time = "2026-01-11T11:21:52.647Z" }, - { url = "https://files.pythonhosted.org/packages/1e/0d/a22bb6c83f83386b0008425a6cd1fa1c14b5f3dd4bad05e98cf3dbbf4a64/tomli-2.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:d3d1654e11d724760cdb37a3d7691f0be9db5fbdaef59c9f532aabf87006dbaa", size = 107626, upload-time = "2026-01-11T11:21:53.459Z" }, - { url = "https://files.pythonhosted.org/packages/2f/6d/77be674a3485e75cacbf2ddba2b146911477bd887dda9d8c9dfb2f15e871/tomli-2.4.0-cp311-cp311-win_arm64.whl", hash = "sha256:cae9c19ed12d4e8f3ebf46d1a75090e4c0dc16271c5bce1c833ac168f08fb614", size = 94842, upload-time = "2026-01-11T11:21:54.831Z" }, - { url = "https://files.pythonhosted.org/packages/3c/43/7389a1869f2f26dba52404e1ef13b4784b6b37dac93bac53457e3ff24ca3/tomli-2.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:920b1de295e72887bafa3ad9f7a792f811847d57ea6b1215154030cf131f16b1", size = 154894, upload-time = "2026-01-11T11:21:56.07Z" }, - { url = "https://files.pythonhosted.org/packages/e9/05/2f9bf110b5294132b2edf13fe6ca6ae456204f3d749f623307cbb7a946f2/tomli-2.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7d6d9a4aee98fac3eab4952ad1d73aee87359452d1c086b5ceb43ed02ddb16b8", size = 149053, upload-time = "2026-01-11T11:21:57.467Z" }, - { url = "https://files.pythonhosted.org/packages/e8/41/1eda3ca1abc6f6154a8db4d714a4d35c4ad90adc0bcf700657291593fbf3/tomli-2.4.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:36b9d05b51e65b254ea6c2585b59d2c4cb91c8a3d91d0ed0f17591a29aaea54a", size = 243481, upload-time = "2026-01-11T11:21:58.661Z" }, - { url = "https://files.pythonhosted.org/packages/d2/6d/02ff5ab6c8868b41e7d4b987ce2b5f6a51d3335a70aa144edd999e055a01/tomli-2.4.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1c8a885b370751837c029ef9bc014f27d80840e48bac415f3412e6593bbc18c1", size = 251720, upload-time = "2026-01-11T11:22:00.178Z" }, - { url = "https://files.pythonhosted.org/packages/7b/57/0405c59a909c45d5b6f146107c6d997825aa87568b042042f7a9c0afed34/tomli-2.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8768715ffc41f0008abe25d808c20c3d990f42b6e2e58305d5da280ae7d1fa3b", size = 247014, upload-time = "2026-01-11T11:22:01.238Z" }, - { url = "https://files.pythonhosted.org/packages/2c/0e/2e37568edd944b4165735687cbaf2fe3648129e440c26d02223672ee0630/tomli-2.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:7b438885858efd5be02a9a133caf5812b8776ee0c969fea02c45e8e3f296ba51", size = 251820, upload-time = "2026-01-11T11:22:02.727Z" }, - { url = "https://files.pythonhosted.org/packages/5a/1c/ee3b707fdac82aeeb92d1a113f803cf6d0f37bdca0849cb489553e1f417a/tomli-2.4.0-cp312-cp312-win32.whl", hash = "sha256:0408e3de5ec77cc7f81960c362543cbbd91ef883e3138e81b729fc3eea5b9729", size = 97712, upload-time = "2026-01-11T11:22:03.777Z" }, - { url = "https://files.pythonhosted.org/packages/69/13/c07a9177d0b3bab7913299b9278845fc6eaaca14a02667c6be0b0a2270c8/tomli-2.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:685306e2cc7da35be4ee914fd34ab801a6acacb061b6a7abca922aaf9ad368da", size = 108296, upload-time = "2026-01-11T11:22:04.86Z" }, - { url = "https://files.pythonhosted.org/packages/18/27/e267a60bbeeee343bcc279bb9e8fbed0cbe224bc7b2a3dc2975f22809a09/tomli-2.4.0-cp312-cp312-win_arm64.whl", hash = "sha256:5aa48d7c2356055feef06a43611fc401a07337d5b006be13a30f6c58f869e3c3", size = 94553, upload-time = "2026-01-11T11:22:05.854Z" }, - { url = "https://files.pythonhosted.org/packages/34/91/7f65f9809f2936e1f4ce6268ae1903074563603b2a2bd969ebbda802744f/tomli-2.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:84d081fbc252d1b6a982e1870660e7330fb8f90f676f6e78b052ad4e64714bf0", size = 154915, upload-time = "2026-01-11T11:22:06.703Z" }, - { url = "https://files.pythonhosted.org/packages/20/aa/64dd73a5a849c2e8f216b755599c511badde80e91e9bc2271baa7b2cdbb1/tomli-2.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9a08144fa4cba33db5255f9b74f0b89888622109bd2776148f2597447f92a94e", size = 149038, upload-time = "2026-01-11T11:22:07.56Z" }, - { url = "https://files.pythonhosted.org/packages/9e/8a/6d38870bd3d52c8d1505ce054469a73f73a0fe62c0eaf5dddf61447e32fa/tomli-2.4.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c73add4bb52a206fd0c0723432db123c0c75c280cbd67174dd9d2db228ebb1b4", size = 242245, upload-time = "2026-01-11T11:22:08.344Z" }, - { url = "https://files.pythonhosted.org/packages/59/bb/8002fadefb64ab2669e5b977df3f5e444febea60e717e755b38bb7c41029/tomli-2.4.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1fb2945cbe303b1419e2706e711b7113da57b7db31ee378d08712d678a34e51e", size = 250335, upload-time = "2026-01-11T11:22:09.951Z" }, - { url = "https://files.pythonhosted.org/packages/a5/3d/4cdb6f791682b2ea916af2de96121b3cb1284d7c203d97d92d6003e91c8d/tomli-2.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bbb1b10aa643d973366dc2cb1ad94f99c1726a02343d43cbc011edbfac579e7c", size = 245962, upload-time = "2026-01-11T11:22:11.27Z" }, - { url = "https://files.pythonhosted.org/packages/f2/4a/5f25789f9a460bd858ba9756ff52d0830d825b458e13f754952dd15fb7bb/tomli-2.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4cbcb367d44a1f0c2be408758b43e1ffb5308abe0ea222897d6bfc8e8281ef2f", size = 250396, upload-time = "2026-01-11T11:22:12.325Z" }, - { url = "https://files.pythonhosted.org/packages/aa/2f/b73a36fea58dfa08e8b3a268750e6853a6aac2a349241a905ebd86f3047a/tomli-2.4.0-cp313-cp313-win32.whl", hash = "sha256:7d49c66a7d5e56ac959cb6fc583aff0651094ec071ba9ad43df785abc2320d86", size = 97530, upload-time = "2026-01-11T11:22:13.865Z" }, - { url = "https://files.pythonhosted.org/packages/3b/af/ca18c134b5d75de7e8dc551c5234eaba2e8e951f6b30139599b53de9c187/tomli-2.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:3cf226acb51d8f1c394c1b310e0e0e61fecdd7adcb78d01e294ac297dd2e7f87", size = 108227, upload-time = "2026-01-11T11:22:15.224Z" }, - { url = "https://files.pythonhosted.org/packages/22/c3/b386b832f209fee8073c8138ec50f27b4460db2fdae9ffe022df89a57f9b/tomli-2.4.0-cp313-cp313-win_arm64.whl", hash = "sha256:d20b797a5c1ad80c516e41bc1fb0443ddb5006e9aaa7bda2d71978346aeb9132", size = 94748, upload-time = "2026-01-11T11:22:16.009Z" }, - { url = "https://files.pythonhosted.org/packages/f3/c4/84047a97eb1004418bc10bdbcfebda209fca6338002eba2dc27cc6d13563/tomli-2.4.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:26ab906a1eb794cd4e103691daa23d95c6919cc2fa9160000ac02370cc9dd3f6", size = 154725, upload-time = "2026-01-11T11:22:17.269Z" }, - { url = "https://files.pythonhosted.org/packages/a8/5d/d39038e646060b9d76274078cddf146ced86dc2b9e8bbf737ad5983609a0/tomli-2.4.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:20cedb4ee43278bc4f2fee6cb50daec836959aadaf948db5172e776dd3d993fc", size = 148901, upload-time = "2026-01-11T11:22:18.287Z" }, - { url = "https://files.pythonhosted.org/packages/73/e5/383be1724cb30f4ce44983d249645684a48c435e1cd4f8b5cded8a816d3c/tomli-2.4.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:39b0b5d1b6dd03684b3fb276407ebed7090bbec989fa55838c98560c01113b66", size = 243375, upload-time = "2026-01-11T11:22:19.154Z" }, - { url = "https://files.pythonhosted.org/packages/31/f0/bea80c17971c8d16d3cc109dc3585b0f2ce1036b5f4a8a183789023574f2/tomli-2.4.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a26d7ff68dfdb9f87a016ecfd1e1c2bacbe3108f4e0f8bcd2228ef9a766c787d", size = 250639, upload-time = "2026-01-11T11:22:20.168Z" }, - { url = "https://files.pythonhosted.org/packages/2c/8f/2853c36abbb7608e3f945d8a74e32ed3a74ee3a1f468f1ffc7d1cb3abba6/tomli-2.4.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:20ffd184fb1df76a66e34bd1b36b4a4641bd2b82954befa32fe8163e79f1a702", size = 246897, upload-time = "2026-01-11T11:22:21.544Z" }, - { url = "https://files.pythonhosted.org/packages/49/f0/6c05e3196ed5337b9fe7ea003e95fd3819a840b7a0f2bf5a408ef1dad8ed/tomli-2.4.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:75c2f8bbddf170e8effc98f5e9084a8751f8174ea6ccf4fca5398436e0320bc8", size = 254697, upload-time = "2026-01-11T11:22:23.058Z" }, - { url = "https://files.pythonhosted.org/packages/f3/f5/2922ef29c9f2951883525def7429967fc4d8208494e5ab524234f06b688b/tomli-2.4.0-cp314-cp314-win32.whl", hash = "sha256:31d556d079d72db7c584c0627ff3a24c5d3fb4f730221d3444f3efb1b2514776", size = 98567, upload-time = "2026-01-11T11:22:24.033Z" }, - { url = "https://files.pythonhosted.org/packages/7b/31/22b52e2e06dd2a5fdbc3ee73226d763b184ff21fc24e20316a44ccc4d96b/tomli-2.4.0-cp314-cp314-win_amd64.whl", hash = "sha256:43e685b9b2341681907759cf3a04e14d7104b3580f808cfde1dfdb60ada85475", size = 108556, upload-time = "2026-01-11T11:22:25.378Z" }, - { url = "https://files.pythonhosted.org/packages/48/3d/5058dff3255a3d01b705413f64f4306a141a8fd7a251e5a495e3f192a998/tomli-2.4.0-cp314-cp314-win_arm64.whl", hash = "sha256:3d895d56bd3f82ddd6faaff993c275efc2ff38e52322ea264122d72729dca2b2", size = 96014, upload-time = "2026-01-11T11:22:26.138Z" }, - { url = "https://files.pythonhosted.org/packages/b8/4e/75dab8586e268424202d3a1997ef6014919c941b50642a1682df43204c22/tomli-2.4.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:5b5807f3999fb66776dbce568cc9a828544244a8eb84b84b9bafc080c99597b9", size = 163339, upload-time = "2026-01-11T11:22:27.143Z" }, - { url = "https://files.pythonhosted.org/packages/06/e3/b904d9ab1016829a776d97f163f183a48be6a4deb87304d1e0116a349519/tomli-2.4.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c084ad935abe686bd9c898e62a02a19abfc9760b5a79bc29644463eaf2840cb0", size = 159490, upload-time = "2026-01-11T11:22:28.399Z" }, - { url = "https://files.pythonhosted.org/packages/e3/5a/fc3622c8b1ad823e8ea98a35e3c632ee316d48f66f80f9708ceb4f2a0322/tomli-2.4.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0f2e3955efea4d1cfbcb87bc321e00dc08d2bcb737fd1d5e398af111d86db5df", size = 269398, upload-time = "2026-01-11T11:22:29.345Z" }, - { url = "https://files.pythonhosted.org/packages/fd/33/62bd6152c8bdd4c305ad9faca48f51d3acb2df1f8791b1477d46ff86e7f8/tomli-2.4.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0e0fe8a0b8312acf3a88077a0802565cb09ee34107813bba1c7cd591fa6cfc8d", size = 276515, upload-time = "2026-01-11T11:22:30.327Z" }, - { url = "https://files.pythonhosted.org/packages/4b/ff/ae53619499f5235ee4211e62a8d7982ba9e439a0fb4f2f351a93d67c1dd2/tomli-2.4.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:413540dce94673591859c4c6f794dfeaa845e98bf35d72ed59636f869ef9f86f", size = 273806, upload-time = "2026-01-11T11:22:32.56Z" }, - { url = "https://files.pythonhosted.org/packages/47/71/cbca7787fa68d4d0a9f7072821980b39fbb1b6faeb5f5cf02f4a5559fa28/tomli-2.4.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:0dc56fef0e2c1c470aeac5b6ca8cc7b640bb93e92d9803ddaf9ea03e198f5b0b", size = 281340, upload-time = "2026-01-11T11:22:33.505Z" }, - { url = "https://files.pythonhosted.org/packages/f5/00/d595c120963ad42474cf6ee7771ad0d0e8a49d0f01e29576ee9195d9ecdf/tomli-2.4.0-cp314-cp314t-win32.whl", hash = "sha256:d878f2a6707cc9d53a1be1414bbb419e629c3d6e67f69230217bb663e76b5087", size = 108106, upload-time = "2026-01-11T11:22:34.451Z" }, - { url = "https://files.pythonhosted.org/packages/de/69/9aa0c6a505c2f80e519b43764f8b4ba93b5a0bbd2d9a9de6e2b24271b9a5/tomli-2.4.0-cp314-cp314t-win_amd64.whl", hash = "sha256:2add28aacc7425117ff6364fe9e06a183bb0251b03f986df0e78e974047571fd", size = 120504, upload-time = "2026-01-11T11:22:35.764Z" }, - { url = "https://files.pythonhosted.org/packages/b3/9f/f1668c281c58cfae01482f7114a4b88d345e4c140386241a1a24dcc9e7bc/tomli-2.4.0-cp314-cp314t-win_arm64.whl", hash = "sha256:2b1e3b80e1d5e52e40e9b924ec43d81570f0e7d09d11081b797bc4692765a3d4", size = 99561, upload-time = "2026-01-11T11:22:36.624Z" }, - { url = "https://files.pythonhosted.org/packages/23/d1/136eb2cb77520a31e1f64cbae9d33ec6df0d78bdf4160398e86eec8a8754/tomli-2.4.0-py3-none-any.whl", hash = "sha256:1f776e7d669ebceb01dee46484485f43a4048746235e683bcdffacdf1fb4785a", size = 14477, upload-time = "2026-01-11T11:22:37.446Z" }, -] - [[package]] name = "tornado" version = "6.5.4" From 994017ac426cb42ca64eadbbc6af09a91a154bd8 Mon Sep 17 00:00:00 2001 From: Steven Murray Date: Sun, 22 Feb 2026 17:19:32 +0200 Subject: [PATCH 15/18] fix: avoid unnecessary warnings --- tests/test_framework.py | 5 ++++- tests/test_mdef.py | 7 ++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/tests/test_framework.py b/tests/test_framework.py index d80ff69a..ca27adaf 100644 --- a/tests/test_framework.py +++ b/tests/test_framework.py @@ -109,5 +109,8 @@ def test_validate_inputs(): m.Mmin = 8 # Ensure that validation still runs. - with pytest.raises(AssertionError, match="Mmin > Mmax: 8, 7"): + with ( + pytest.warns(UserWarning, match="You are setting Mmax directly."), + pytest.raises(AssertionError, match="Mmin > Mmax: 8, 7"), + ): m.Mmax = 7 diff --git a/tests/test_mdef.py b/tests/test_mdef.py index a938c9ee..ad0f88e8 100644 --- a/tests/test_mdef.py +++ b/tests/test_mdef.py @@ -98,7 +98,12 @@ def test_change_dndm(colossus_cosmo): UserWarning, match=r"Your input mass definition 'SOVirial' does not match the mass definition", ): - h = MassFunction(mdef_model="SOVirial", hmf_model="Warren", disable_mass_conversion=False) + h = MassFunction( + mdef_model="SOVirial", + hmf_model="Warren", + disable_mass_conversion=False, + extrapolate_with_eh=True, + ) dndm = h.dndm From bd17ed91f560e72e9e497ae84242cb64b48232b0 Mon Sep 17 00:00:00 2001 From: Steven Murray Date: Sun, 22 Feb 2026 17:41:18 +0200 Subject: [PATCH 16/18] fix: set extrap with eh --- tests/test_mdef.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_mdef.py b/tests/test_mdef.py index ad0f88e8..74d4e74e 100644 --- a/tests/test_mdef.py +++ b/tests/test_mdef.py @@ -102,7 +102,7 @@ def test_change_dndm(colossus_cosmo): mdef_model="SOVirial", hmf_model="Warren", disable_mass_conversion=False, - extrapolate_with_eh=True, + transfer_params={"extrapolate_with_eh": True}, ) dndm = h.dndm From 5e5b1c17230a9ed6103dca95de2c04422e3cc23d Mon Sep 17 00:00:00 2001 From: Steven Murray Date: Sun, 22 Feb 2026 18:47:47 +0200 Subject: [PATCH 17/18] test: increase test coverage for fitting functions and cache --- coverage.txt | 373 +++++++++++++++++++++ src/hmf/mass_function/fitting_functions.py | 2 +- tests/test_cache.py | 267 +++++++++++++++ tests/test_fitting_functions_extra.py | 289 ++++++++++++++++ tests/test_sample.py | 38 ++- tests/test_utils.py | 47 +++ 6 files changed, 1014 insertions(+), 2 deletions(-) create mode 100644 coverage.txt create mode 100644 tests/test_cache.py create mode 100644 tests/test_fitting_functions_extra.py create mode 100644 tests/test_utils.py diff --git a/coverage.txt b/coverage.txt new file mode 100644 index 00000000..bea2207f --- /dev/null +++ b/coverage.txt @@ -0,0 +1,373 @@ +============================= test session starts ============================== +platform linux -- Python 3.13.11, pytest-9.0.2, pluggy-1.6.0 -- /home/steven/Documents/work/halos/hmf/.venv/bin/python3 +cachedir: .pytest_cache +rootdir: /home/steven/Documents/work/halos/hmf +configfile: pyproject.toml +testpaths: tests +plugins: cov-7.0.0 +collecting ... collected 329 items + +tests/test_cache.py::test_hidden_loc_underscores PASSED [ 0%] +tests/test_cache.py::test_obj_eq_numpy PASSED [ 0%] +tests/test_cache.py::test_obj_eq_dictlike_keys PASSED [ 0%] +tests/test_cache.py::test_parameter_docstring_trim PASSED [ 1%] +tests/test_cache.py::test_parameter_requires_dict_for_params PASSED [ 1%] +tests/test_cache.py::test_parameter_dict_update PASSED [ 1%] +tests/test_cache.py::test_parameter_validate_warning PASSED [ 2%] +tests/test_cache.py::test_parameter_switch_reindexes PASSED [ 2%] +tests/test_cache.py::test_parameter_recalc_updates PASSED [ 2%] +tests/test_cache.py::test_cached_quantity_del_warnings PASSED [ 3%] +tests/test_cache.py::test_cached_quantity_del_without_value PASSED [ 3%] +tests/test_cache.py::test_cached_quantity_keyerror_missing_prpa PASSED [ 3%] +tests/test_cache.py::test_subframework_copy_and_recalc PASSED [ 3%] +tests/test_cache.py::test_subframework_delete_without_instance PASSED [ 4%] +tests/test_cli.py::test_no_config_or_args PASSED [ 4%] +tests/test_cli.py::test_with_config PASSED [ 4%] +tests/test_cli.py::test_config_vs_cli PASSED [ 5%] +tests/test_cli.py::test_list_of_parameters PASSED [ 5%] +tests/test_cli.py::test_roundtrip_cfg PASSED [ 5%] +tests/test_cosmo.py::test_string_cosmo PASSED [ 6%] +tests/test_cosmo.py::test_cosmo_model PASSED [ 6%] +tests/test_cosmo.py::test_cosmo_params PASSED [ 6%] +tests/test_cosmo.py::test_cosmo_to_colossus PASSED [ 6%] +tests/test_fcoll.py::test_fcoll[PS] PASSED [ 7%] +tests/test_fcoll.py::test_fcoll[Peacock] PASSED [ 7%] +tests/test_fcoll.py::TestCumulants::test_ranges_cut[9-14] PASSED [ 7%] +tests/test_fcoll.py::TestCumulants::test_ranges_cut[9-15] PASSED [ 8%] +tests/test_fcoll.py::TestCumulants::test_ranges_cut[9-16] PASSED [ 8%] +tests/test_fcoll.py::TestCumulants::test_ranges_cut[9-18] PASSED [ 8%] +tests/test_fcoll.py::TestCumulants::test_ranges_cut[9-19] PASSED [ 9%] +tests/test_fcoll.py::TestCumulants::test_ranges_cut[10-14] PASSED [ 9%] +tests/test_fcoll.py::TestCumulants::test_ranges_cut[10-15] PASSED [ 9%] +tests/test_fcoll.py::TestCumulants::test_ranges_cut[10-16] PASSED [ 10%] +tests/test_fcoll.py::TestCumulants::test_ranges_cut[10-18] PASSED [ 10%] +tests/test_fcoll.py::TestCumulants::test_ranges_cut[10-19] PASSED [ 10%] +tests/test_fcoll.py::TestCumulants::test_ranges_cut[11-14] PASSED [ 10%] +tests/test_fcoll.py::TestCumulants::test_ranges_cut[11-15] PASSED [ 11%] +tests/test_fcoll.py::TestCumulants::test_ranges_cut[11-16] PASSED [ 11%] +tests/test_fcoll.py::TestCumulants::test_ranges_cut[11-18] PASSED [ 11%] +tests/test_fcoll.py::TestCumulants::test_ranges_cut[11-19] PASSED [ 12%] +tests/test_fcoll.py::TestCumulants::test_mgtm[14] PASSED [ 12%] +tests/test_fcoll.py::TestCumulants::test_mgtm[15] PASSED [ 12%] +tests/test_fcoll.py::TestCumulants::test_mgtm[16] PASSED [ 13%] +tests/test_fcoll.py::TestCumulants::test_mgtm[18] PASSED [ 13%] +tests/test_fcoll.py::TestCumulants::test_mgtm[19] PASSED [ 13%] +tests/test_fcoll.py::TestCumulants::test_mltm[14] PASSED [ 13%] +tests/test_fcoll.py::TestCumulants::test_mltm[15] PASSED [ 14%] +tests/test_fcoll.py::TestCumulants::test_mltm[16] PASSED [ 14%] +tests/test_fcoll.py::TestCumulants::test_mltm[18] PASSED [ 14%] +tests/test_fcoll.py::TestCumulants::test_mltm[19] PASSED [ 15%] +tests/test_filters.py::TestTopHat::test_sigma PASSED [ 15%] +tests/test_filters.py::TestTopHat::test_sigma1 PASSED [ 15%] +tests/test_filters.py::TestTopHat::test_dwdlnkr PASSED [ 16%] +tests/test_filters.py::TestTopHat::test_dlnssdlnr PASSED [ 16%] +tests/test_filters.py::TestSharpK::test_sigma PASSED [ 16%] +tests/test_filters.py::TestSharpK::test_sigma1 PASSED [ 17%] +tests/test_filters.py::TestSharpK::test_dlnssdlnr PASSED [ 17%] +tests/test_filters.py::TestSharpK::test_sigma_R3 PASSED [ 17%] +tests/test_filters.py::TestSharpK::test_sigma1_R3 PASSED [ 17%] +tests/test_filters.py::TestSharpK::test_dlnssdlnr_R3 PASSED [ 18%] +tests/test_filters.py::TestSharpK::test_sigma_Rhalf PASSED [ 18%] +tests/test_filters.py::TestSharpK::test_sigma1_Rhalf PASSED [ 18%] +tests/test_filters.py::TestSharpK::test_dlnssdlnr_Rhalf PASSED [ 19%] +tests/test_filters.py::TestGaussian::test_sigma PASSED [ 19%] +tests/test_filters.py::TestGaussian::test_sigma1 PASSED [ 19%] +tests/test_filters.py::TestGaussian::test_dlnssdlnr PASSED [ 20%] +tests/test_fits.py::test_allfits[0.0-Angulo] PASSED [ 20%] +tests/test_fits.py::test_allfits[0.0-AnguloBound] PASSED [ 20%] +tests/test_fits.py::test_allfits[0.0-Behroozi] PASSED [ 20%] +tests/test_fits.py::test_allfits[0.0-Bhattacharya] PASSED [ 21%] +tests/test_fits.py::test_allfits[0.0-Bocquet200cDMOnly] PASSED [ 21%] +tests/test_fits.py::test_allfits[0.0-Bocquet200cHydro] PASSED [ 21%] +tests/test_fits.py::test_allfits[0.0-Bocquet200mDMOnly] PASSED [ 22%] +tests/test_fits.py::test_allfits[0.0-Bocquet200mHydro] PASSED [ 22%] +tests/test_fits.py::test_allfits[0.0-Bocquet500cDMOnly] PASSED [ 22%] +tests/test_fits.py::test_allfits[0.0-Bocquet500cHydro] PASSED [ 23%] +tests/test_fits.py::test_allfits[0.0-Courtin] PASSED [ 23%] +tests/test_fits.py::test_allfits[0.0-Crocce] PASSED [ 23%] +tests/test_fits.py::test_allfits[0.0-Ishiyama] PASSED [ 24%] +tests/test_fits.py::test_allfits[0.0-Jenkins] PASSED [ 24%] +tests/test_fits.py::test_allfits[0.0-Manera] PASSED [ 24%] +tests/test_fits.py::test_allfits[0.0-Peacock] PASSED [ 24%] +tests/test_fits.py::test_allfits[0.0-Pillepich] PASSED [ 25%] +tests/test_fits.py::test_allfits[0.0-Reed03] PASSED [ 25%] +tests/test_fits.py::test_allfits[0.0-Reed07] PASSED [ 25%] +tests/test_fits.py::test_allfits[0.0-SMT] PASSED [ 26%] +tests/test_fits.py::test_allfits[0.0-ST] PASSED [ 26%] +tests/test_fits.py::test_allfits[0.0-Tinker08] PASSED [ 26%] +tests/test_fits.py::test_allfits[0.0-Tinker10] PASSED [ 27%] +tests/test_fits.py::test_allfits[0.0-Warren] PASSED [ 27%] +tests/test_fits.py::test_allfits[0.0-Watson] PASSED [ 27%] +tests/test_fits.py::test_allfits[0.0-Watson_FoF] PASSED [ 27%] +tests/test_fits.py::test_allfits[2.0-Angulo] PASSED [ 28%] +tests/test_fits.py::test_allfits[2.0-AnguloBound] PASSED [ 28%] +tests/test_fits.py::test_allfits[2.0-Behroozi] PASSED [ 28%] +tests/test_fits.py::test_allfits[2.0-Bhattacharya] PASSED [ 29%] +tests/test_fits.py::test_allfits[2.0-Bocquet200cDMOnly] PASSED [ 29%] +tests/test_fits.py::test_allfits[2.0-Bocquet200cHydro] PASSED [ 29%] +tests/test_fits.py::test_allfits[2.0-Bocquet200mDMOnly] PASSED [ 30%] +tests/test_fits.py::test_allfits[2.0-Bocquet200mHydro] PASSED [ 30%] +tests/test_fits.py::test_allfits[2.0-Bocquet500cDMOnly] PASSED [ 30%] +tests/test_fits.py::test_allfits[2.0-Bocquet500cHydro] PASSED [ 31%] +tests/test_fits.py::test_allfits[2.0-Courtin] PASSED [ 31%] +tests/test_fits.py::test_allfits[2.0-Crocce] PASSED [ 31%] +tests/test_fits.py::test_allfits[2.0-Ishiyama] PASSED [ 31%] +tests/test_fits.py::test_allfits[2.0-Jenkins] PASSED [ 32%] +tests/test_fits.py::test_allfits[2.0-Manera] PASSED [ 32%] +tests/test_fits.py::test_allfits[2.0-Peacock] PASSED [ 32%] +tests/test_fits.py::test_allfits[2.0-Pillepich] PASSED [ 33%] +tests/test_fits.py::test_allfits[2.0-Reed03] PASSED [ 33%] +tests/test_fits.py::test_allfits[2.0-Reed07] PASSED [ 33%] +tests/test_fits.py::test_allfits[2.0-SMT] PASSED [ 34%] +tests/test_fits.py::test_allfits[2.0-ST] PASSED [ 34%] +tests/test_fits.py::test_allfits[2.0-Tinker08] PASSED [ 34%] +tests/test_fits.py::test_allfits[2.0-Tinker10] PASSED [ 34%] +tests/test_fits.py::test_allfits[2.0-Warren] PASSED [ 35%] +tests/test_fits.py::test_allfits[2.0-Watson] PASSED [ 35%] +tests/test_fits.py::test_allfits[2.0-Watson_FoF] PASSED [ 35%] +tests/test_fits.py::test_tinker08_dh PASSED [ 36%] +tests/test_fits.py::test_tinker10_dh PASSED [ 36%] +tests/test_fits.py::test_tinker10_neg_gam PASSED [ 36%] +tests/test_fits.py::test_tinker10_neg_eta PASSED [ 37%] +tests/test_fits.py::test_tinker10_neg_etaphi PASSED [ 37%] +tests/test_fits.py::test_tinker10_neg_beta PASSED [ 37%] +tests/test_fitting_functions_extra.py::test_fittingfunction_requires_mass PASSED [ 37%] +tests/test_fitting_functions_extra.py::test_fittingfunction_requires_neff PASSED [ 38%] +tests/test_fitting_functions_extra.py::test_fittingfunction_sets_measured_mdef PASSED [ 38%] +tests/test_fitting_functions_extra.py::test_get_measured_mdef_unrecognized_overdensity_warns PASSED [ 38%] +tests/test_fitting_functions_extra.py::test_get_measured_mdef_unknown_halo_finder_warns PASSED [ 39%] +tests/test_fitting_functions_extra.py::test_base_cutmask_all_true PASSED [ 39%] +tests/test_fitting_functions_extra.py::test_smt_validation_p PASSED [ 39%] +tests/test_fitting_functions_extra.py::test_smt_validation_a PASSED [ 40%] +tests/test_fitting_functions_extra.py::test_jenkins_cutmask_shape PASSED [ 40%] +tests/test_fitting_functions_extra.py::test_bhattacharya_q_validation PASSED [ 40%] +tests/test_fitting_functions_extra.py::test_bhattacharya_pq_validation PASSED [ 41%] +tests/test_fitting_functions_extra.py::test_bhattacharya_cutmask PASSED [ 41%] +tests/test_fitting_functions_extra.py::test_bhattacharya_norm_returns_existing_a PASSED [ 41%] +tests/test_fitting_functions_extra.py::test_bhattacharya_normed_uses_norm PASSED [ 41%] +tests/test_fitting_functions_extra.py::test_tinker10_non_so_raises PASSED [ 42%] +tests/test_fitting_functions_extra.py::test_tinker10_interpolates_params PASSED [ 42%] +tests/test_fitting_functions_extra.py::test_tinker10_non_terminate_clamps PASSED [ 42%] +tests/test_fitting_functions_extra.py::test_tinker10_normalise_alpha_at_z0 PASSED [ 43%] +tests/test_fitting_functions_extra.py::test_mass_cutmasks[Warren-m0-expected0] PASSED [ 43%] +tests/test_fitting_functions_extra.py::test_mass_cutmasks[Angulo-m1-expected1] PASSED [ 43%] +tests/test_fitting_functions_extra.py::test_mass_cutmasks[Crocce-m2-expected2] PASSED [ 44%] +tests/test_fitting_functions_extra.py::test_mass_cutmasks[Ishiyama-m3-expected3] PASSED [ 44%] +tests/test_fitting_functions_extra.py::test_lnsigma_cutmasks[Reed03-nu20-expected0] PASSED [ 44%] +tests/test_fitting_functions_extra.py::test_lnsigma_cutmasks[Reed07-nu21-expected1] PASSED [ 44%] +tests/test_fitting_functions_extra.py::test_lnsigma_cutmasks[Courtin-nu22-expected2] PASSED [ 45%] +tests/test_fitting_functions_extra.py::test_lnsigma_cutmasks[Watson_FoF-nu23-expected3] PASSED [ 45%] +tests/test_fitting_functions_extra.py::test_peacock_cutmask_all_false PASSED [ 45%] +tests/test_fitting_functions_extra.py::test_tinker08_non_so_raises PASSED [ 46%] +tests/test_fitting_functions_extra.py::test_tinker08_cutmask_z_positive PASSED [ 46%] +tests/test_fitting_functions_extra.py::test_tinker08_cutmask_z_zero PASSED [ 46%] +tests/test_fitting_functions_extra.py::test_tinker10_eta_phi_validation PASSED [ 47%] +tests/test_fitting_functions_extra.py::test_tinker10_cutmask_z_zero PASSED [ 47%] +tests/test_fitting_functions_extra.py::test_tinker10_cutmask_z_positive PASSED [ 47%] +tests/test_fitting_functions_extra.py::test_watson_gamma_and_fsigma_branches PASSED [ 48%] +tests/test_fitting_functions_extra.py::test_watson_gamma_non_so_raises PASSED [ 48%] +tests/test_fitting_functions_extra.py::test_watson_cutmask PASSED [ 48%] +tests/test_fitting_functions_extra.py::test_behroozi_modify_dndm_handles_nan PASSED [ 48%] +tests/test_framework.py::test_incorrect_argument PASSED [ 49%] +tests/test_framework.py::test_incorrect_update_arg PASSED [ 49%] +tests/test_framework.py::test_parameter_names PASSED [ 49%] +tests/test_framework.py::test_parameter_defaults PASSED [ 50%] +tests/test_framework.py::test_parameter_default_rec PASSED [ 50%] +tests/test_framework.py::test_param_values PASSED [ 50%] +tests/test_framework.py::test_qnt_avail PASSED [ 51%] +tests/test_framework.py::test_parameter_info PASSED [ 51%] +tests/test_framework.py::test_pluggable PASSED [ 51%] +tests/test_framework.py::test_get_base_components PASSED [ 51%] +tests/test_framework.py::test_get_base_component PASSED [ 52%] +tests/test_framework.py::test_get_model PASSED [ 52%] +tests/test_framework.py::test_growth_plugins PASSED [ 52%] +tests/test_framework.py::test_validate_inputs PASSED [ 53%] +tests/test_functional.py::test_order PASSED [ 53%] +tests/test_genmf.py::TestGenMF::test_sigmas[0.0-sigma] PASSED [ 53%] +tests/test_genmf.py::TestGenMF::test_sigmas[0.0-lnsigma] PASSED [ 54%] +tests/test_genmf.py::TestGenMF::test_sigmas[0.0-n_eff] PASSED [ 54%] +tests/test_genmf.py::TestGenMF::test_sigmas[2.0-sigma] PASSED [ 54%] +tests/test_genmf.py::TestGenMF::test_sigmas[2.0-lnsigma] PASSED [ 55%] +tests/test_genmf.py::TestGenMF::test_sigmas[2.0-n_eff] PASSED [ 55%] +tests/test_genmf.py::TestGenMF::test_fits[0.0-ST-dndlog10m] PASSED [ 55%] +tests/test_genmf.py::TestGenMF::test_fits[0.0-ST-ngtm] PASSED [ 55%] +tests/test_genmf.py::TestGenMF::test_fits[0.0-ST-fsigma] PASSED [ 56%] +tests/test_genmf.py::TestGenMF::test_fits[0.0-PS-dndlog10m] PASSED [ 56%] +tests/test_genmf.py::TestGenMF::test_fits[0.0-PS-ngtm] PASSED [ 56%] +tests/test_genmf.py::TestGenMF::test_fits[0.0-PS-fsigma] PASSED [ 57%] +tests/test_genmf.py::TestGenMF::test_fits[0.0-Reed03-dndlog10m] PASSED [ 57%] +tests/test_genmf.py::TestGenMF::test_fits[0.0-Reed03-ngtm] PASSED [ 57%] +tests/test_genmf.py::TestGenMF::test_fits[0.0-Reed03-fsigma] PASSED [ 58%] +tests/test_genmf.py::TestGenMF::test_fits[0.0-Warren-dndlog10m] PASSED [ 58%] +tests/test_genmf.py::TestGenMF::test_fits[0.0-Warren-ngtm] PASSED [ 58%] +tests/test_genmf.py::TestGenMF::test_fits[0.0-Warren-fsigma] PASSED [ 58%] +tests/test_genmf.py::TestGenMF::test_fits[0.0-Jenkins-dndlog10m] PASSED [ 59%] +tests/test_genmf.py::TestGenMF::test_fits[0.0-Jenkins-ngtm] PASSED [ 59%] +tests/test_genmf.py::TestGenMF::test_fits[0.0-Jenkins-fsigma] PASSED [ 59%] +tests/test_genmf.py::TestGenMF::test_fits[0.0-Reed07-dndlog10m] PASSED [ 60%] +tests/test_genmf.py::TestGenMF::test_fits[0.0-Reed07-ngtm] PASSED [ 60%] +tests/test_genmf.py::TestGenMF::test_fits[0.0-Reed07-fsigma] PASSED [ 60%] +tests/test_genmf.py::TestGenMF::test_fits[2.0-ST-dndlog10m] PASSED [ 61%] +tests/test_genmf.py::TestGenMF::test_fits[2.0-ST-ngtm] PASSED [ 61%] +tests/test_genmf.py::TestGenMF::test_fits[2.0-ST-fsigma] PASSED [ 61%] +tests/test_genmf.py::TestGenMF::test_fits[2.0-PS-dndlog10m] PASSED [ 62%] +tests/test_genmf.py::TestGenMF::test_fits[2.0-PS-ngtm] PASSED [ 62%] +tests/test_genmf.py::TestGenMF::test_fits[2.0-PS-fsigma] PASSED [ 62%] +tests/test_genmf.py::TestGenMF::test_fits[2.0-Reed03-dndlog10m] PASSED [ 62%] +tests/test_genmf.py::TestGenMF::test_fits[2.0-Reed03-ngtm] PASSED [ 63%] +tests/test_genmf.py::TestGenMF::test_fits[2.0-Reed03-fsigma] PASSED [ 63%] +tests/test_genmf.py::TestGenMF::test_fits[2.0-Warren-dndlog10m] PASSED [ 63%] +tests/test_genmf.py::TestGenMF::test_fits[2.0-Warren-ngtm] PASSED [ 64%] +tests/test_genmf.py::TestGenMF::test_fits[2.0-Warren-fsigma] PASSED [ 64%] +tests/test_genmf.py::TestGenMF::test_fits[2.0-Jenkins-dndlog10m] PASSED [ 64%] +tests/test_genmf.py::TestGenMF::test_fits[2.0-Jenkins-ngtm] PASSED [ 65%] +tests/test_genmf.py::TestGenMF::test_fits[2.0-Jenkins-fsigma] PASSED [ 65%] +tests/test_genmf.py::TestGenMF::test_fits[2.0-Reed07-dndlog10m] PASSED [ 65%] +tests/test_genmf.py::TestGenMF::test_fits[2.0-Reed07-ngtm] PASSED [ 65%] +tests/test_genmf.py::TestGenMF::test_fits[2.0-Reed07-fsigma] PASSED [ 66%] +tests/test_growth.py::test_gf[0.0] PASSED [ 66%] +tests/test_growth.py::test_gf[0.5] PASSED [ 66%] +tests/test_growth.py::test_gf[1.0] PASSED [ 67%] +tests/test_growth.py::test_gf[1.5] PASSED [ 67%] +tests/test_growth.py::test_gf[2.0] PASSED [ 67%] +tests/test_growth.py::test_gf[2.5] PASSED [ 68%] +tests/test_growth.py::test_gf[3.0] PASSED [ 68%] +tests/test_growth.py::test_gf[3.5] PASSED [ 68%] +tests/test_growth.py::test_gf[4.0] PASSED [ 68%] +tests/test_growth.py::test_gf[4.5] PASSED [ 69%] +tests/test_growth.py::test_gf[5.0] PASSED [ 69%] +tests/test_growth.py::test_gf[5.5] PASSED [ 69%] +tests/test_growth.py::test_gf[6.0] PASSED [ 70%] +tests/test_growth.py::test_gf[6.5] PASSED [ 70%] +tests/test_growth.py::test_gf[7.0] PASSED [ 70%] +tests/test_growth.py::test_gf[7.5] PASSED [ 71%] +tests/test_growth.py::test_gr[0.0] PASSED [ 71%] +tests/test_growth.py::test_gr[0.5] PASSED [ 71%] +tests/test_growth.py::test_gr[1.0] PASSED [ 72%] +tests/test_growth.py::test_gr[1.5] PASSED [ 72%] +tests/test_growth.py::test_gr[2.0] PASSED [ 72%] +tests/test_growth.py::test_gr[2.5] PASSED [ 72%] +tests/test_growth.py::test_gr[3.0] PASSED [ 73%] +tests/test_growth.py::test_gr[3.5] PASSED [ 73%] +tests/test_growth.py::test_gr[4.0] PASSED [ 73%] +tests/test_growth.py::test_gr[4.5] PASSED [ 74%] +tests/test_growth.py::test_gr[5.0] PASSED [ 74%] +tests/test_growth.py::test_gr[5.5] PASSED [ 74%] +tests/test_growth.py::test_gr[6.0] PASSED [ 75%] +tests/test_growth.py::test_gr[6.5] PASSED [ 75%] +tests/test_growth.py::test_gr[7.0] PASSED [ 75%] +tests/test_growth.py::test_gr[7.5] PASSED [ 75%] +tests/test_growth.py::test_gfunc PASSED [ 76%] +tests/test_growth.py::test_gr_func PASSED [ 76%] +tests/test_growth.py::test_inverse PASSED [ 76%] +tests/test_growth.py::test_unsupported_cosmo PASSED [ 77%] +tests/test_growth.py::test_carroll PASSED [ 77%] +tests/test_growth.py::test_pickleability_of_cambgrowth PASSED [ 77%] +tests/test_growth.py::test_from_file PASSED [ 78%] +tests/test_growth.py::test_from_array PASSED [ 78%] +tests/test_halofit.py::test_takahashi PASSED [ 78%] +tests/test_halofit.py::test_takahashi_hiz PASSED [ 79%] +tests/test_halofit.py::test_halofit_high_s8 PASSED [ 79%] +tests/test_hmf.py::test_wrong_filter PASSED [ 79%] +tests/test_hmf.py::test_string_dc PASSED [ 79%] +tests/test_hmf.py::test_neg_dc PASSED [ 80%] +tests/test_hmf.py::test_big_dc PASSED [ 80%] +tests/test_hmf.py::test_wrong_fit PASSED [ 80%] +tests/test_hmf.py::test_wrong_mf_par PASSED [ 81%] +tests/test_hmf.py::test_str_filter PASSED [ 81%] +tests/test_hmf.py::test_mass_nonlinear_outside_range PASSED [ 81%] +tests/test_hmf.py::test_nu PASSED [ 82%] +tests/test_hmf.py::test_sigma8z PASSED [ 82%] +tests/test_hmf.py::test_neff_at_collapse PASSED [ 82%] +tests/test_integrate_hmf.py::TestAnalyticIntegral::test_high_z PASSED [ 82%] +tests/test_integrate_hmf.py::TestAnalyticIntegral::test_low_mmax_high_z PASSED [ 83%] +tests/test_mdef.py::test_mean_to_mean_nfw PASSED [ 83%] +tests/test_mdef.py::test_mean_to_crit_nfw PASSED [ 83%] +tests/test_mdef.py::test_mean_to_crit_z1_nfw PASSED [ 84%] +tests/test_mdef.py::test_mean_to_vir_nfw PASSED [ 84%] +tests/test_mdef.py::test_colossus_name PASSED [ 84%] +tests/test_mdef.py::test_from_colossus_name PASSED [ 85%] +tests/test_mdef.py::test_change_dndm PASSED [ 85%] +tests/test_mdef.py::test_change_dndm_bocquet PASSED [ 85%] +tests/test_sample.py::test_circular PASSED [ 86%] +tests/test_sample.py::test_mmax_big PASSED [ 86%] +tests/test_sample.py::test_sample_mf_sort_descending PASSED [ 86%] +tests/test_sample.py::test_choose_halo_masses_default_rng PASSED [ 86%] +tests/test_sample.py::test_dndm_from_sample_nan_edges PASSED [ 87%] +tests/test_sample.py::test_dndm_from_sample_empty PASSED [ 87%] +tests/test_transfer.py::test_updates[z-0.1] PASSED [ 87%] +tests/test_transfer.py::test_updates[sigma_8-0.82] PASSED [ 88%] +tests/test_transfer.py::test_updates[n-0.95] PASSED [ 88%] +tests/test_transfer.py::test_updates[cosmo_params-val3] PASSED [ 88%] +tests/test_transfer.py::test_updates_from_file_array PASSED [ 89%] +tests/test_transfer.py::test_halofit PASSED [ 89%] +tests/test_transfer.py::test_ehnobao PASSED [ 89%] +tests/test_transfer.py::test_bondefs PASSED [ 89%] +tests/test_transfer.py::test_data SKIPPED (Too slow and needs to be ...) [ 90%] +tests/test_transfer.py::test_camb_extrapolation PASSED [ 90%] +tests/test_transfer.py::test_camb_neutrinos PASSED [ 90%] +tests/test_transfer.py::test_setting_kmax PASSED [ 91%] +tests/test_transfer.py::test_camb_w0wa PASSED [ 91%] +tests/test_transfer.py::test_camb_wcdm PASSED [ 91%] +tests/test_transfer.py::test_camb_unset_params PASSED [ 92%] +tests/test_transfer.py::test_bbks_sugiyama PASSED [ 92%] +tests/test_utils.py::test_inherit_docstrings_sets_missing PASSED [ 92%] +tests/test_utils.py::test_inherit_docstrings_preserves_existing PASSED [ 93%] +tests/test_utils.py::test_inherit_docstrings_skips_dunder PASSED [ 93%] +tests/test_wcdm.py::test_defaults PASSED [ 93%] +tests/test_wcdm.py::test_trivial PASSED [ 93%] +tests/test_wcdm.py::test_divergence PASSED [ 94%] +tests/test_wdm.py::test_null PASSED [ 94%] +tests/test_wdm.py::TestViel::test_lowk_transfer PASSED [ 94%] +tests/test_wdm.py::TestViel::test_lam_eff PASSED [ 95%] +tests/test_wdm.py::TestViel::test_m_eff PASSED [ 95%] +tests/test_wdm.py::TestViel::test_lam_hm PASSED [ 95%] +tests/test_wdm.py::TestViel::test_m_hm PASSED [ 96%] +tests/test_wdm.py::TestBode::test_lowk_transfer PASSED [ 96%] +tests/test_wdm.py::TestBode::test_lam_eff PASSED [ 96%] +tests/test_wdm.py::TestBode::test_m_eff PASSED [ 96%] +tests/test_wdm.py::TestBode::test_lam_hm PASSED [ 97%] +tests/test_wdm.py::TestBode::test_m_hm PASSED [ 97%] +tests/test_wdm.py::TestSchneider12_vCDM::test_high_m PASSED [ 97%] +tests/test_wdm.py::TestSchneider12::test_high_m PASSED [ 98%] +tests/test_wdm.py::TestLovell14::test_high_m PASSED [ 98%] +tests/test_wdm.py::TestTransfer::test_wdm_model PASSED [ 98%] +tests/test_wdm.py::TestTransfer::test_wrong_model_type PASSED [ 99%] +tests/test_wdm.py::TestTransfer::test_power PASSED [ 99%] +tests/test_wdm.py::TestMassFunction::test_dndm PASSED [ 99%] +tests/test_wdm.py::TestMassFunctionAlter::test_dndm PASSED [100%] + +================================ tests coverage ================================ +_______________ coverage: platform linux, python 3.13.11-final-0 _______________ + +Name Stmts Miss Cover Missing +-------------------------------------------------------------------------- +src/hmf/__init__.py 12 0 100% +src/hmf/_cli.py 106 5 95% 53-55, 60-62 +src/hmf/_internals/__init__.py 4 0 100% +src/hmf/_internals/_cache.py 171 0 100% +src/hmf/_internals/_framework.py 150 22 85% 34, 68, 72, 79-80, 123-144, 186, 230, 310-318, 337, 354 +src/hmf/_internals/_utils.py 11 0 100% +src/hmf/alternatives/__init__.py 2 0 100% +src/hmf/alternatives/wdm.py 109 3 97% 326-327, 330 +src/hmf/cosmology/__init__.py 4 0 100% +src/hmf/cosmology/cosmo.py 36 2 94% 97, 155 +src/hmf/cosmology/growth_factor.py 172 15 91% 116, 118, 288, 290, 317, 365, 368, 375-377, 405, 409, 458, 463, 516 +src/hmf/density_field/__init__.py 6 0 100% +src/hmf/density_field/filters.py 159 40 75% 267, 301-302, 356, 364, 368, 414-415, 419, 423, 433, 437, 487-489, 493, 497, 501, 505, 509-512, 520, 524-528, 536-538, 542-545, 549-552 +src/hmf/density_field/halofit.py 80 3 96% 60, 110, 113 +src/hmf/density_field/transfer.py 131 8 94% 126, 146, 159, 211-212, 215, 278, 284 +src/hmf/density_field/transfer_models.py 219 28 87% 106-107, 134, 176, 266, 291-376, 380-382, 425, 427, 430, 518 +src/hmf/halos/__init__.py 3 0 100% +src/hmf/halos/mass_definitions.py 157 24 85% 49, 54, 62, 80-81, 99-100, 136, 138, 140, 142, 151-152, 157-162, 174, 203, 218, 352-353, 363-365, 368 +src/hmf/helpers/__init__.py 3 0 100% +src/hmf/helpers/cfg_utils.py 35 2 94% 51-52 +src/hmf/helpers/functional.py 84 11 87% 62, 178, 185, 192, 205, 220-221, 232, 258-259, 267 +src/hmf/helpers/sample.py 39 0 100% +src/hmf/mass_function/__init__.py 4 0 100% +src/hmf/mass_function/fitting_functions.py 585 0 100% +src/hmf/mass_function/hmf.py 212 14 93% 221, 257, 277, 288, 338, 343, 436-439, 482-485, 509, 620 +src/hmf/mass_function/integrate_hmf.py 24 1 96% 60 +-------------------------------------------------------------------------- +TOTAL 2518 178 93% +======================= 328 passed, 1 skipped in 17.08s ======================== diff --git a/src/hmf/mass_function/fitting_functions.py b/src/hmf/mass_function/fitting_functions.py index 0c9f3fe7..9dd61426 100644 --- a/src/hmf/mass_function/fitting_functions.py +++ b/src/hmf/mass_function/fitting_functions.py @@ -1077,7 +1077,7 @@ def cutmask(self): @override def _norm(self): - if self.params["A"] is not None: + if self.params.get("A") is not None: return self.params["A"] p, q = self.params["p"], self.params["q"] diff --git a/tests/test_cache.py b/tests/test_cache.py new file mode 100644 index 00000000..0cb9344d --- /dev/null +++ b/tests/test_cache.py @@ -0,0 +1,267 @@ +import numpy as np +import pytest + +import hmf._internals._cache as cache +from hmf._internals._cache import cached_quantity, hidden_loc, obj_eq, parameter, subframework + + +class _CacheBase: + def __init__(self): + self._validate = False + self.validate_calls = 0 + self.a = 1 + self.flag = False + self.opts_params = {"a": 1} + self._validate = True + + def validate(self): + self.validate_calls += 1 + + @parameter("param") + def a(self, val): + return val + + @parameter("switch") + def flag(self, val): + return val + + @parameter("param") + def opts_params(self, val): + return val + + @cached_quantity + def q(self): + return self.a + (1 if self.flag else 0) + + @cached_quantity + def qchild(self): + return self.q + 1 + + +class _Child: + def __init__(self): + self._validate = False + self.a = 2 + + @parameter("param") + def a(self, val): + return val + + @cached_quantity + def child_q(self): + return self.a + 1 + + +class _Parent: + def __init__(self): + self._validate = False + self.p = 3 + self._counter = 0 + + @parameter("param") + def p(self, val): + return val + + @subframework + def sub(self): + return _Child() + + @cached_quantity + def q(self): + self._counter += 1 + return self.p + self.sub.child_q + + +class _DictLike: + def __init__(self, data): + self._data = data + + def __eq__(self, other): + raise ValueError("no bool") + + def __array__(self, *args, **kwargs): + raise ValueError("no array") + + def keys(self): + return self._data.keys() + + def __getitem__(self, key): + return self._data[key] + + def __iter__(self): + return iter(self._data) + + +class _DocStr: + def __init__(self, value): + self.value = value + + def strip(self): + return self.value + + def __bool__(self): + return True + + +def _doc_param(self, val): + return val + + +_doc_param.__doc__ = _DocStr("\nDoc with leading newline.") + + +class _DocParam: + def __init__(self): + self._validate = False + self.doc = 1 + + doc = parameter("param")(_doc_param) + + +def test_hidden_loc_underscores(): + obj = _CacheBase() + + assert hidden_loc(obj, "_x") == "__CacheBase__x" + + +def test_obj_eq_numpy(): + assert obj_eq(np.array([1, 2]), np.array([1, 2])) + + +def test_obj_eq_dictlike_keys(monkeypatch): + def fake_array_equal(a, b): + if isinstance(a, _DictLike) or isinstance(b, _DictLike): + raise ValueError("boom") + return np.array_equal(a, b) + + monkeypatch.setattr(cache, "array_equal", fake_array_equal) + + left = _DictLike({"a": np.array([1, 2])}) + right = _DictLike({"b": np.array([1, 2])}) + assert cache.obj_eq(left, right) is False + + left = _DictLike({"a": np.array([1, 2])}) + right = _DictLike({"a": np.array([1, 2])}) + assert cache.obj_eq(left, right) is True + + +def test_parameter_docstring_trim(): + assert _DocParam.doc.__doc__.startswith("**Parameter**: Doc with leading") + + +def test_parameter_requires_dict_for_params(): + obj = _CacheBase() + + with pytest.raises(ValueError, match="opts_params must be a dictionary"): + obj.opts_params = 3 + + +def test_parameter_dict_update(): + obj = _CacheBase() + + with pytest.warns(UserWarning, match="setting opts_params"): + obj.opts_params = {"b": 2} + + assert obj.opts_params == {"a": 1, "b": 2} + + +def test_parameter_validate_warning(): + obj = _CacheBase() + + with pytest.warns(UserWarning, match="You are setting a directly"): + obj.a = 2 + + assert obj.validate_calls == 1 + + +def test_parameter_switch_reindexes(): + obj = _CacheBase() + assert obj.q == 1 + + recalc = getattr(obj, hidden_loc(obj, "recalc")) + assert "q" in recalc + + with pytest.warns(UserWarning, match="setting flag"): + obj.flag = True + + recalc = getattr(obj, hidden_loc(obj, "recalc")) + assert "q" not in recalc + assert obj.q == 2 + + +def test_parameter_recalc_updates(): + obj = _CacheBase() + _ = obj.q + + recalc = getattr(obj, hidden_loc(obj, "recalc")) + assert recalc["q"] is False + + obj._validate = False + obj.a = 5 + + assert recalc["q"] is True + + +def test_cached_quantity_del_warnings(): + obj = _CacheBase() + _ = obj.q + + recalc = getattr(obj, hidden_loc(obj, "recalc")) + recalc_prpa = getattr(obj, hidden_loc(obj, "recalc_prop_par")) + del recalc["q"] + del recalc_prpa["q"] + + with pytest.warns(UserWarning) as record: + del obj.q + + assert len(record) == 2 + + +def test_cached_quantity_del_without_value(): + obj = _CacheBase() + + with pytest.warns(UserWarning) as record: + del obj.q + + assert len(record) == 2 + + +def test_cached_quantity_keyerror_missing_prpa(): + obj = _CacheBase() + recalc = getattr(obj, hidden_loc(obj, "recalc")) + _ = obj.q + activeq = getattr(obj, hidden_loc(obj, "active_q")) + activeq.add("qchild") + recalc["q"] = True + + with pytest.raises(KeyError, match="couldn't find qchild"): + _ = obj.q + + +def test_subframework_copy_and_recalc(): + obj = _Parent() + + _ = obj.sub + _ = obj.sub + + value = obj.q + assert value == 6 + assert obj._counter == 1 + + child = obj.sub + child_recalc = getattr(child, hidden_loc(child, "recalc")) + child_activeq = getattr(child, hidden_loc(child, "active_q")) + assert ":q" not in child_activeq + child_recalc[":q"] = True + + _ = obj.q + assert obj._counter == 2 + + child_papr = getattr(child, hidden_loc(child, "recalc_par_prop")) + assert ":q" in child_papr["a"] + + +def test_subframework_delete_without_instance(): + obj = _Parent() + + del obj.sub diff --git a/tests/test_fitting_functions_extra.py b/tests/test_fitting_functions_extra.py new file mode 100644 index 00000000..d559bbe7 --- /dev/null +++ b/tests/test_fitting_functions_extra.py @@ -0,0 +1,289 @@ +import numpy as np +import pytest + +from hmf.halos import mass_definitions as md +from hmf.mass_function import fitting_functions as ff + + +def test_fittingfunction_requires_mass(): + with pytest.raises(ValueError): + ff.Warren(nu2=np.array([1.0])) + + +def test_fittingfunction_requires_neff(): + with pytest.raises(ValueError): + ff.Reed07(nu2=np.array([1.0])) + + +def test_fittingfunction_sets_measured_mdef(): + fit = ff.SMT(nu2=np.array([1.0, 2.0])) + + assert isinstance(fit.mass_definition, md.SOVirial) + + +def test_get_measured_mdef_unrecognized_overdensity_warns(): + class _BadSO(ff.FittingFunction): + sim_definition = ff.SimDetails( + L=1, + N=1, + halo_finder_type="SO", + omegam=0.3, + sigma_8=0.8, + halo_overdensity="bad", + ) + + with pytest.warns(UserWarning, match="Unrecognized overdensity criterion format"): + assert _BadSO.get_measured_mdef() is None + + +def test_get_measured_mdef_unknown_halo_finder_warns(): + class _BadFinder(ff.FittingFunction): + sim_definition = ff.SimDetails( + L=1, + N=1, + halo_finder_type="??", + omegam=0.3, + sigma_8=0.8, + halo_overdensity=200, + ) + + with pytest.warns(UserWarning, match="Unknown halo finder type"): + assert _BadFinder.get_measured_mdef() is None + + +def test_base_cutmask_all_true(): + fit = ff.PS(nu2=np.array([1.0, 2.0, 3.0])) + mask = fit.cutmask + + assert mask.dtype == bool + assert mask.shape == (3,) + assert np.all(mask) + + +def test_smt_validation_p(): + with pytest.raises(ValueError): + ff.SMT(nu2=np.array([1.0]), p=0.6) + + +def test_smt_validation_a(): + with pytest.raises(ValueError): + ff.SMT(nu2=np.array([1.0]), a=-1.0) + + +def test_jenkins_cutmask_shape(): + fit = ff.Jenkins(nu2=np.array([0.5, 1.0, 2.0])) + mask = fit.cutmask + + assert mask.shape == (3,) + + +def test_bhattacharya_q_validation(): + with pytest.raises(ValueError): + ff.Bhattacharya(nu2=np.array([1.0]), m=np.array([1e12]), q=0) + + +def test_bhattacharya_pq_validation(): + with pytest.raises(ValueError): + ff.Bhattacharya(nu2=np.array([1.0]), m=np.array([1e12]), p=1.0, q=1.0) + + +def test_bhattacharya_cutmask(): + fit = ff.Bhattacharya(nu2=np.array([1.0, 2.0]), m=np.array([1e12, 1e16])) + mask = fit.cutmask + + assert mask.shape == (2,) + assert np.array_equal(mask, np.array([True, False])) + + +def test_bhattacharya_norm_returns_existing_a(): + fit = ff.Bhattacharya(nu2=np.array([1.0]), m=np.array([1e12])) + + assert fit._norm() == fit.params["A"] + + +def test_bhattacharya_normed_uses_norm(): + fit = ff.Bhattacharya(nu2=np.array([1.0]), m=np.array([1e12]), normed=True) + + assert np.isfinite(fit.params["A"]) + + +def test_tinker10_non_so_raises(): + with pytest.raises(ValueError): + ff.Tinker10(nu2=np.array([1.0]), mass_definition=md.FOF(linking_length=0.2)) + + +def test_tinker10_interpolates_params(): + fit = ff.Tinker10(nu2=np.array([1.0]), mass_definition=md.SOMean(overdensity=250)) + + assert fit.delta_halo == 250 + assert np.isfinite(fit.beta) + + +def test_tinker10_non_terminate_clamps(): + class _Tinker10NoTerminate(ff.Tinker10): + sim_definition = None + terminate = False + + fit = _Tinker10NoTerminate( + nu2=np.array([1.0]), + gamma_200=-1.0, + eta_200=-1.0, + phi_200=1.0, + beta_200=-1.0, + ) + + assert fit.gamma == pytest.approx(1e-3) + assert fit.eta == pytest.approx(-0.499) + assert fit.phi == pytest.approx(fit.eta + 0.499) + assert fit.beta == pytest.approx(1e-3) + + +def test_tinker10_normalise_alpha_at_z0(): + class _Tinker10NoSim(ff.Tinker10): + sim_definition = None + + fit = _Tinker10NoSim(nu2=np.array([1.0])) + + assert fit._normalise == fit.params["alpha_200"] + + +@pytest.mark.parametrize( + ("fit_cls", "m", "expected"), + [ + (ff.Warren, np.array([1e9, 1e12, 1e16]), np.array([False, True, False])), + (ff.Angulo, np.array([1e7, 1e10, 1e17]), np.array([False, True, False])), + (ff.Crocce, np.array([1e10, 1e12, 1e16]), np.array([False, True, False])), + (ff.Ishiyama, np.array([1e7, 1e9, 1e17]), np.array([False, True, False])), + ], +) +def test_mass_cutmasks(fit_cls, m, expected): + fit = fit_cls(nu2=np.ones_like(m), m=m, z=0.5) + + assert np.array_equal(fit.cutmask, expected) + + +@pytest.mark.parametrize( + ("fit_cls", "nu2", "expected"), + [ + (ff.Reed03, np.array([1e-6, 1.0, 1e6]), np.array([False, True, False])), + (ff.Reed07, np.array([1e-6, 2.0, 1e6]), np.array([False, True, False])), + (ff.Courtin, np.array([1e-6, 1.0, 1e6]), np.array([False, True, False])), + (ff.Watson_FoF, np.array([1e-6, 1.0, 1e6]), np.array([False, True, False])), + ], +) +def test_lnsigma_cutmasks(fit_cls, nu2, expected): + kwargs = {} + if fit_cls is ff.Reed07: + kwargs["n_eff"] = np.zeros_like(nu2) + + fit = fit_cls(nu2=nu2, **kwargs) + + assert np.array_equal(fit.cutmask, expected) + + +def test_peacock_cutmask_all_false(): + m = np.array([1e8, 1e12, 1e16]) + fit = ff.Peacock(nu2=np.ones_like(m), m=m) + + assert np.all(~fit.cutmask) + + +def test_tinker08_non_so_raises(): + with pytest.raises(ValueError): + ff.Tinker08( + nu2=np.array([1.0]), + mass_definition=md.FOF(linking_length=0.2), + ) + + +def test_tinker08_cutmask_z_positive(): + fit = ff.Tinker08( + nu2=np.array([1.0, 2.0, 10.0]), + z=1.0, + mass_definition=md.SOMean(overdensity=200), + ) + + assert np.array_equal(fit.cutmask, np.array([False, True, True])) + + +def test_tinker08_cutmask_z_zero(): + fit = ff.Tinker08( + nu2=np.array([0.01, 1.0, 100.0]), + z=0.0, + mass_definition=md.SOMean(overdensity=200), + ) + + assert np.array_equal(fit.cutmask, np.array([False, True, False])) + + +def test_tinker10_eta_phi_validation(): + class _Tinker10NoSim(ff.Tinker10): + sim_definition = None + + with pytest.raises(ValueError): + _Tinker10NoSim(nu2=np.array([1.0]), eta_200=0.0, phi_200=1.0) + + +def test_tinker10_cutmask_z_zero(): + class _Tinker10NoSim(ff.Tinker10): + sim_definition = None + + fit = _Tinker10NoSim(nu2=np.array([1.0, 2.0, 10.0]), z=0.0) + + assert np.array_equal(fit.cutmask, np.array([True, True, True])) + + +def test_tinker10_cutmask_z_positive(): + class _Tinker10NoSim(ff.Tinker10): + sim_definition = None + + fit = _Tinker10NoSim(nu2=np.array([1.0, 2.0, 10.0]), z=1.0) + + assert np.array_equal(fit.cutmask, np.array([False, True, True])) + + +def test_watson_gamma_and_fsigma_branches(): + class _WatsonNoSim(ff.Watson): + sim_definition = None + + fit_z0 = _WatsonNoSim(nu2=np.array([1.0, 2.0]), z=0.0) + fit_zhi = _WatsonNoSim(nu2=np.array([1.0, 2.0]), z=7.0) + + assert np.isfinite(fit_z0.gamma()).all() + assert np.isfinite(fit_z0.fsigma).all() + assert np.isfinite(fit_zhi.fsigma).all() + + +def test_watson_gamma_non_so_raises(): + class _WatsonNoSim(ff.Watson): + sim_definition = None + + fit = _WatsonNoSim(nu2=np.array([1.0]), mass_definition=md.FOF(linking_length=0.2)) + + with pytest.raises(ValueError): + fit.gamma() + + +def test_watson_cutmask(): + class _WatsonNoSim(ff.Watson): + sim_definition = None + + fit = _WatsonNoSim(nu2=np.array([1e-6, 1.0, 1e6])) + + assert np.array_equal(fit.cutmask, np.array([False, True, False])) + + +def test_behroozi_modify_dndm_handles_nan(): + fit = ff.Behroozi( + nu2=np.array([1.0, 2.0]), + mass_definition=md.SOMean(overdensity=200), + ) + m = np.array([-1e11, 1e12]) + dndm = np.array([1.0, 1.0]) + ngtm = np.array([1.0, 1.0]) + + with pytest.warns(RuntimeWarning): + res = fit._modify_dndm(m, dndm, z=1.0, ngtm_tinker=ngtm) + + assert res[0] == 0 + assert np.isfinite(res[1]) diff --git a/tests/test_sample.py b/tests/test_sample.py index 70ac24f2..f4475c88 100644 --- a/tests/test_sample.py +++ b/tests/test_sample.py @@ -1,7 +1,7 @@ import numpy as np from scipy.interpolate import InterpolatedUnivariateSpline as Spline -from hmf.helpers.sample import dndm_from_sample, sample_mf +from hmf.helpers.sample import _choose_halo_masses_num, dndm_from_sample, sample_mf def test_circular(): @@ -20,3 +20,39 @@ def test_mmax_big(): m, h = sample_mf(1e5, 11, transfer_model="EH", Mmax=18, rng=rng) dndm_from_sample(m, 1e5 / h.ngtm[0]) + + +def test_sample_mf_sort_descending(): + rng = np.random.default_rng(4) + m, _ = sample_mf(20, 11, transfer_model="EH", sort=True, rng=rng) + + assert np.all(np.diff(m) <= 0) + + +def test_choose_halo_masses_default_rng(): + def icdf(x): + return np.zeros_like(x) + 1.0 + + m = _choose_halo_masses_num(5, icdf, xmin=0.2, rng=None) + + assert m.shape == (5,) + assert np.allclose(m, 10.0) + + +def test_dndm_from_sample_nan_edges(): + m = np.array([10**2.5]) + bins = np.array([1.0, 2.0, 3.0, 4.0]) + + _, hist = dndm_from_sample(m, 1.0, bins=bins) + + assert np.isnan(hist[1]) + assert hist[0] == 0 + assert hist[-1] == 0 + + +def test_dndm_from_sample_empty(): + m = np.array([]) + + _, hist = dndm_from_sample(m, 1.0, bins=3) + + assert np.all(hist == 0) diff --git a/tests/test_utils.py b/tests/test_utils.py new file mode 100644 index 00000000..3558ccf1 --- /dev/null +++ b/tests/test_utils.py @@ -0,0 +1,47 @@ +from hmf._internals._utils import inherit_docstrings + + +@inherit_docstrings +class _Base: + @classmethod + def foo(cls): + """Base foo.""" + return "base" + + @classmethod + def bar(cls): + """Base bar.""" + return "base bar" + + @classmethod + def __str__(cls): + """Base str.""" + return "base str" + + +@inherit_docstrings +class _Child(_Base): + @classmethod + def foo(cls): + return "child" + + @classmethod + def bar(cls): + """Child bar.""" + return "child bar" + + @classmethod + def __str__(cls): + return "child str" + + +def test_inherit_docstrings_sets_missing(): + assert _Child.foo.__doc__ == "base foo" + + +def test_inherit_docstrings_preserves_existing(): + assert _Child.bar.__doc__ == "child bar" + + +def test_inherit_docstrings_skips_dunder(): + assert _Child.__str__.__doc__ is None From 7dba465b6834ea1ea4fbb61406357b061a1fdfff Mon Sep 17 00:00:00 2001 From: Steven Murray Date: Sun, 22 Feb 2026 19:20:55 +0200 Subject: [PATCH 18/18] test: increase coverage for mdef and frameworks --- coverage.txt | 531 ++++++++++++++++++---------------- tests/test_filters.py | 106 +++++++ tests/test_framework.py | 238 ++++++++++++++- tests/test_mdef.py | 134 +++++++++ tests/test_transfer_models.py | 99 +++++++ tests/test_utils.py | 4 +- 6 files changed, 865 insertions(+), 247 deletions(-) create mode 100644 tests/test_transfer_models.py diff --git a/coverage.txt b/coverage.txt index bea2207f..97d17e6d 100644 --- a/coverage.txt +++ b/coverage.txt @@ -5,7 +5,7 @@ rootdir: /home/steven/Documents/work/halos/hmf configfile: pyproject.toml testpaths: tests plugins: cov-7.0.0 -collecting ... collected 329 items +collecting ... collected 372 items tests/test_cache.py::test_hidden_loc_underscores PASSED [ 0%] tests/test_cache.py::test_obj_eq_numpy PASSED [ 0%] @@ -13,194 +13,220 @@ tests/test_cache.py::test_obj_eq_dictlike_keys PASSED [ 0%] tests/test_cache.py::test_parameter_docstring_trim PASSED [ 1%] tests/test_cache.py::test_parameter_requires_dict_for_params PASSED [ 1%] tests/test_cache.py::test_parameter_dict_update PASSED [ 1%] -tests/test_cache.py::test_parameter_validate_warning PASSED [ 2%] +tests/test_cache.py::test_parameter_validate_warning PASSED [ 1%] tests/test_cache.py::test_parameter_switch_reindexes PASSED [ 2%] tests/test_cache.py::test_parameter_recalc_updates PASSED [ 2%] -tests/test_cache.py::test_cached_quantity_del_warnings PASSED [ 3%] -tests/test_cache.py::test_cached_quantity_del_without_value PASSED [ 3%] +tests/test_cache.py::test_cached_quantity_del_warnings PASSED [ 2%] +tests/test_cache.py::test_cached_quantity_del_without_value PASSED [ 2%] tests/test_cache.py::test_cached_quantity_keyerror_missing_prpa PASSED [ 3%] tests/test_cache.py::test_subframework_copy_and_recalc PASSED [ 3%] -tests/test_cache.py::test_subframework_delete_without_instance PASSED [ 4%] +tests/test_cache.py::test_subframework_delete_without_instance PASSED [ 3%] tests/test_cli.py::test_no_config_or_args PASSED [ 4%] tests/test_cli.py::test_with_config PASSED [ 4%] -tests/test_cli.py::test_config_vs_cli PASSED [ 5%] -tests/test_cli.py::test_list_of_parameters PASSED [ 5%] +tests/test_cli.py::test_config_vs_cli PASSED [ 4%] +tests/test_cli.py::test_list_of_parameters PASSED [ 4%] tests/test_cli.py::test_roundtrip_cfg PASSED [ 5%] -tests/test_cosmo.py::test_string_cosmo PASSED [ 6%] -tests/test_cosmo.py::test_cosmo_model PASSED [ 6%] -tests/test_cosmo.py::test_cosmo_params PASSED [ 6%] +tests/test_cosmo.py::test_string_cosmo PASSED [ 5%] +tests/test_cosmo.py::test_cosmo_model PASSED [ 5%] +tests/test_cosmo.py::test_cosmo_params PASSED [ 5%] tests/test_cosmo.py::test_cosmo_to_colossus PASSED [ 6%] -tests/test_fcoll.py::test_fcoll[PS] PASSED [ 7%] -tests/test_fcoll.py::test_fcoll[Peacock] PASSED [ 7%] -tests/test_fcoll.py::TestCumulants::test_ranges_cut[9-14] PASSED [ 7%] -tests/test_fcoll.py::TestCumulants::test_ranges_cut[9-15] PASSED [ 8%] -tests/test_fcoll.py::TestCumulants::test_ranges_cut[9-16] PASSED [ 8%] -tests/test_fcoll.py::TestCumulants::test_ranges_cut[9-18] PASSED [ 8%] -tests/test_fcoll.py::TestCumulants::test_ranges_cut[9-19] PASSED [ 9%] -tests/test_fcoll.py::TestCumulants::test_ranges_cut[10-14] PASSED [ 9%] -tests/test_fcoll.py::TestCumulants::test_ranges_cut[10-15] PASSED [ 9%] -tests/test_fcoll.py::TestCumulants::test_ranges_cut[10-16] PASSED [ 10%] -tests/test_fcoll.py::TestCumulants::test_ranges_cut[10-18] PASSED [ 10%] -tests/test_fcoll.py::TestCumulants::test_ranges_cut[10-19] PASSED [ 10%] -tests/test_fcoll.py::TestCumulants::test_ranges_cut[11-14] PASSED [ 10%] -tests/test_fcoll.py::TestCumulants::test_ranges_cut[11-15] PASSED [ 11%] -tests/test_fcoll.py::TestCumulants::test_ranges_cut[11-16] PASSED [ 11%] -tests/test_fcoll.py::TestCumulants::test_ranges_cut[11-18] PASSED [ 11%] -tests/test_fcoll.py::TestCumulants::test_ranges_cut[11-19] PASSED [ 12%] -tests/test_fcoll.py::TestCumulants::test_mgtm[14] PASSED [ 12%] -tests/test_fcoll.py::TestCumulants::test_mgtm[15] PASSED [ 12%] -tests/test_fcoll.py::TestCumulants::test_mgtm[16] PASSED [ 13%] -tests/test_fcoll.py::TestCumulants::test_mgtm[18] PASSED [ 13%] -tests/test_fcoll.py::TestCumulants::test_mgtm[19] PASSED [ 13%] -tests/test_fcoll.py::TestCumulants::test_mltm[14] PASSED [ 13%] -tests/test_fcoll.py::TestCumulants::test_mltm[15] PASSED [ 14%] -tests/test_fcoll.py::TestCumulants::test_mltm[16] PASSED [ 14%] -tests/test_fcoll.py::TestCumulants::test_mltm[18] PASSED [ 14%] -tests/test_fcoll.py::TestCumulants::test_mltm[19] PASSED [ 15%] -tests/test_filters.py::TestTopHat::test_sigma PASSED [ 15%] -tests/test_filters.py::TestTopHat::test_sigma1 PASSED [ 15%] -tests/test_filters.py::TestTopHat::test_dwdlnkr PASSED [ 16%] -tests/test_filters.py::TestTopHat::test_dlnssdlnr PASSED [ 16%] +tests/test_fcoll.py::test_fcoll[PS] PASSED [ 6%] +tests/test_fcoll.py::test_fcoll[Peacock] PASSED [ 6%] +tests/test_fcoll.py::TestCumulants::test_ranges_cut[9-14] PASSED [ 6%] +tests/test_fcoll.py::TestCumulants::test_ranges_cut[9-15] PASSED [ 7%] +tests/test_fcoll.py::TestCumulants::test_ranges_cut[9-16] PASSED [ 7%] +tests/test_fcoll.py::TestCumulants::test_ranges_cut[9-18] PASSED [ 7%] +tests/test_fcoll.py::TestCumulants::test_ranges_cut[9-19] PASSED [ 8%] +tests/test_fcoll.py::TestCumulants::test_ranges_cut[10-14] PASSED [ 8%] +tests/test_fcoll.py::TestCumulants::test_ranges_cut[10-15] PASSED [ 8%] +tests/test_fcoll.py::TestCumulants::test_ranges_cut[10-16] PASSED [ 8%] +tests/test_fcoll.py::TestCumulants::test_ranges_cut[10-18] PASSED [ 9%] +tests/test_fcoll.py::TestCumulants::test_ranges_cut[10-19] PASSED [ 9%] +tests/test_fcoll.py::TestCumulants::test_ranges_cut[11-14] PASSED [ 9%] +tests/test_fcoll.py::TestCumulants::test_ranges_cut[11-15] PASSED [ 9%] +tests/test_fcoll.py::TestCumulants::test_ranges_cut[11-16] PASSED [ 10%] +tests/test_fcoll.py::TestCumulants::test_ranges_cut[11-18] PASSED [ 10%] +tests/test_fcoll.py::TestCumulants::test_ranges_cut[11-19] PASSED [ 10%] +tests/test_fcoll.py::TestCumulants::test_mgtm[14] PASSED [ 11%] +tests/test_fcoll.py::TestCumulants::test_mgtm[15] PASSED [ 11%] +tests/test_fcoll.py::TestCumulants::test_mgtm[16] PASSED [ 11%] +tests/test_fcoll.py::TestCumulants::test_mgtm[18] PASSED [ 11%] +tests/test_fcoll.py::TestCumulants::test_mgtm[19] PASSED [ 12%] +tests/test_fcoll.py::TestCumulants::test_mltm[14] PASSED [ 12%] +tests/test_fcoll.py::TestCumulants::test_mltm[15] PASSED [ 12%] +tests/test_fcoll.py::TestCumulants::test_mltm[16] PASSED [ 12%] +tests/test_fcoll.py::TestCumulants::test_mltm[18] PASSED [ 13%] +tests/test_fcoll.py::TestCumulants::test_mltm[19] PASSED [ 13%] +tests/test_filters.py::TestTopHat::test_sigma PASSED [ 13%] +tests/test_filters.py::TestTopHat::test_sigma1 PASSED [ 13%] +tests/test_filters.py::TestTopHat::test_dwdlnkr PASSED [ 14%] +tests/test_filters.py::TestTopHat::test_dlnssdlnr PASSED [ 14%] +tests/test_filters.py::TestTopHat::test_real_space_edges PASSED [ 14%] +tests/test_filters.py::TestTopHat::test_k_space_small PASSED [ 15%] +tests/test_filters.py::TestTopHat::test_nu PASSED [ 15%] +tests/test_filters.py::TestTopHat::test_mass_radius_roundtrip PASSED [ 15%] +tests/test_filters.py::TestTopHat::test_dlnr_dlnm PASSED [ 15%] tests/test_filters.py::TestSharpK::test_sigma PASSED [ 16%] -tests/test_filters.py::TestSharpK::test_sigma1 PASSED [ 17%] -tests/test_filters.py::TestSharpK::test_dlnssdlnr PASSED [ 17%] -tests/test_filters.py::TestSharpK::test_sigma_R3 PASSED [ 17%] +tests/test_filters.py::TestSharpK::test_sigma1 PASSED [ 16%] +tests/test_filters.py::TestSharpK::test_dlnssdlnr PASSED [ 16%] +tests/test_filters.py::TestSharpK::test_sigma_R3 PASSED [ 16%] tests/test_filters.py::TestSharpK::test_sigma1_R3 PASSED [ 17%] -tests/test_filters.py::TestSharpK::test_dlnssdlnr_R3 PASSED [ 18%] -tests/test_filters.py::TestSharpK::test_sigma_Rhalf PASSED [ 18%] +tests/test_filters.py::TestSharpK::test_dlnssdlnr_R3 PASSED [ 17%] +tests/test_filters.py::TestSharpK::test_sigma_Rhalf PASSED [ 17%] tests/test_filters.py::TestSharpK::test_sigma1_Rhalf PASSED [ 18%] -tests/test_filters.py::TestSharpK::test_dlnssdlnr_Rhalf PASSED [ 19%] +tests/test_filters.py::TestSharpK::test_dlnssdlnr_Rhalf PASSED [ 18%] +tests/test_filters.py::TestSharpK::test_k_space_edges PASSED [ 18%] +tests/test_filters.py::TestSharpK::test_real_space_and_dw PASSED [ 18%] +tests/test_filters.py::TestSharpK::test_mass_radius_roundtrip PASSED [ 19%] tests/test_filters.py::TestGaussian::test_sigma PASSED [ 19%] tests/test_filters.py::TestGaussian::test_sigma1 PASSED [ 19%] -tests/test_filters.py::TestGaussian::test_dlnssdlnr PASSED [ 20%] -tests/test_fits.py::test_allfits[0.0-Angulo] PASSED [ 20%] -tests/test_fits.py::test_allfits[0.0-AnguloBound] PASSED [ 20%] -tests/test_fits.py::test_allfits[0.0-Behroozi] PASSED [ 20%] -tests/test_fits.py::test_allfits[0.0-Bhattacharya] PASSED [ 21%] -tests/test_fits.py::test_allfits[0.0-Bocquet200cDMOnly] PASSED [ 21%] -tests/test_fits.py::test_allfits[0.0-Bocquet200cHydro] PASSED [ 21%] -tests/test_fits.py::test_allfits[0.0-Bocquet200mDMOnly] PASSED [ 22%] -tests/test_fits.py::test_allfits[0.0-Bocquet200mHydro] PASSED [ 22%] -tests/test_fits.py::test_allfits[0.0-Bocquet500cDMOnly] PASSED [ 22%] +tests/test_filters.py::TestGaussian::test_dlnssdlnr PASSED [ 19%] +tests/test_filters.py::TestGaussian::test_real_space_and_k_space PASSED [ 20%] +tests/test_filters.py::TestGaussian::test_mass_radius_roundtrip PASSED [ 20%] +tests/test_filters.py::TestSharpKEllipsoid::test_shape_helpers PASSED [ 20%] +tests/test_filters.py::TestSharpKEllipsoid::test_gamma_xi_a3 PASSED [ 20%] +tests/test_filters.py::TestSharpKEllipsoid::test_r_a3_and_derivatives PASSED [ 21%] +tests/test_fits.py::test_allfits[0.0-Angulo] PASSED [ 21%] +tests/test_fits.py::test_allfits[0.0-AnguloBound] PASSED [ 21%] +tests/test_fits.py::test_allfits[0.0-Behroozi] PASSED [ 22%] +tests/test_fits.py::test_allfits[0.0-Bhattacharya] PASSED [ 22%] +tests/test_fits.py::test_allfits[0.0-Bocquet200cDMOnly] PASSED [ 22%] +tests/test_fits.py::test_allfits[0.0-Bocquet200cHydro] PASSED [ 22%] +tests/test_fits.py::test_allfits[0.0-Bocquet200mDMOnly] PASSED [ 23%] +tests/test_fits.py::test_allfits[0.0-Bocquet200mHydro] PASSED [ 23%] +tests/test_fits.py::test_allfits[0.0-Bocquet500cDMOnly] PASSED [ 23%] tests/test_fits.py::test_allfits[0.0-Bocquet500cHydro] PASSED [ 23%] -tests/test_fits.py::test_allfits[0.0-Courtin] PASSED [ 23%] -tests/test_fits.py::test_allfits[0.0-Crocce] PASSED [ 23%] +tests/test_fits.py::test_allfits[0.0-Courtin] PASSED [ 24%] +tests/test_fits.py::test_allfits[0.0-Crocce] PASSED [ 24%] tests/test_fits.py::test_allfits[0.0-Ishiyama] PASSED [ 24%] -tests/test_fits.py::test_allfits[0.0-Jenkins] PASSED [ 24%] -tests/test_fits.py::test_allfits[0.0-Manera] PASSED [ 24%] -tests/test_fits.py::test_allfits[0.0-Peacock] PASSED [ 24%] +tests/test_fits.py::test_allfits[0.0-Jenkins] PASSED [ 25%] +tests/test_fits.py::test_allfits[0.0-Manera] PASSED [ 25%] +tests/test_fits.py::test_allfits[0.0-Peacock] PASSED [ 25%] tests/test_fits.py::test_allfits[0.0-Pillepich] PASSED [ 25%] -tests/test_fits.py::test_allfits[0.0-Reed03] PASSED [ 25%] -tests/test_fits.py::test_allfits[0.0-Reed07] PASSED [ 25%] +tests/test_fits.py::test_allfits[0.0-Reed03] PASSED [ 26%] +tests/test_fits.py::test_allfits[0.0-Reed07] PASSED [ 26%] tests/test_fits.py::test_allfits[0.0-SMT] PASSED [ 26%] tests/test_fits.py::test_allfits[0.0-ST] PASSED [ 26%] -tests/test_fits.py::test_allfits[0.0-Tinker08] PASSED [ 26%] +tests/test_fits.py::test_allfits[0.0-Tinker08] PASSED [ 27%] tests/test_fits.py::test_allfits[0.0-Tinker10] PASSED [ 27%] tests/test_fits.py::test_allfits[0.0-Warren] PASSED [ 27%] tests/test_fits.py::test_allfits[0.0-Watson] PASSED [ 27%] -tests/test_fits.py::test_allfits[0.0-Watson_FoF] PASSED [ 27%] +tests/test_fits.py::test_allfits[0.0-Watson_FoF] PASSED [ 28%] tests/test_fits.py::test_allfits[2.0-Angulo] PASSED [ 28%] tests/test_fits.py::test_allfits[2.0-AnguloBound] PASSED [ 28%] -tests/test_fits.py::test_allfits[2.0-Behroozi] PASSED [ 28%] +tests/test_fits.py::test_allfits[2.0-Behroozi] PASSED [ 29%] tests/test_fits.py::test_allfits[2.0-Bhattacharya] PASSED [ 29%] tests/test_fits.py::test_allfits[2.0-Bocquet200cDMOnly] PASSED [ 29%] tests/test_fits.py::test_allfits[2.0-Bocquet200cHydro] PASSED [ 29%] tests/test_fits.py::test_allfits[2.0-Bocquet200mDMOnly] PASSED [ 30%] tests/test_fits.py::test_allfits[2.0-Bocquet200mHydro] PASSED [ 30%] tests/test_fits.py::test_allfits[2.0-Bocquet500cDMOnly] PASSED [ 30%] -tests/test_fits.py::test_allfits[2.0-Bocquet500cHydro] PASSED [ 31%] +tests/test_fits.py::test_allfits[2.0-Bocquet500cHydro] PASSED [ 30%] tests/test_fits.py::test_allfits[2.0-Courtin] PASSED [ 31%] tests/test_fits.py::test_allfits[2.0-Crocce] PASSED [ 31%] tests/test_fits.py::test_allfits[2.0-Ishiyama] PASSED [ 31%] -tests/test_fits.py::test_allfits[2.0-Jenkins] PASSED [ 32%] +tests/test_fits.py::test_allfits[2.0-Jenkins] PASSED [ 31%] tests/test_fits.py::test_allfits[2.0-Manera] PASSED [ 32%] tests/test_fits.py::test_allfits[2.0-Peacock] PASSED [ 32%] -tests/test_fits.py::test_allfits[2.0-Pillepich] PASSED [ 33%] +tests/test_fits.py::test_allfits[2.0-Pillepich] PASSED [ 32%] tests/test_fits.py::test_allfits[2.0-Reed03] PASSED [ 33%] tests/test_fits.py::test_allfits[2.0-Reed07] PASSED [ 33%] -tests/test_fits.py::test_allfits[2.0-SMT] PASSED [ 34%] -tests/test_fits.py::test_allfits[2.0-ST] PASSED [ 34%] +tests/test_fits.py::test_allfits[2.0-SMT] PASSED [ 33%] +tests/test_fits.py::test_allfits[2.0-ST] PASSED [ 33%] tests/test_fits.py::test_allfits[2.0-Tinker08] PASSED [ 34%] tests/test_fits.py::test_allfits[2.0-Tinker10] PASSED [ 34%] -tests/test_fits.py::test_allfits[2.0-Warren] PASSED [ 35%] -tests/test_fits.py::test_allfits[2.0-Watson] PASSED [ 35%] +tests/test_fits.py::test_allfits[2.0-Warren] PASSED [ 34%] +tests/test_fits.py::test_allfits[2.0-Watson] PASSED [ 34%] tests/test_fits.py::test_allfits[2.0-Watson_FoF] PASSED [ 35%] -tests/test_fits.py::test_tinker08_dh PASSED [ 36%] -tests/test_fits.py::test_tinker10_dh PASSED [ 36%] +tests/test_fits.py::test_tinker08_dh PASSED [ 35%] +tests/test_fits.py::test_tinker10_dh PASSED [ 35%] tests/test_fits.py::test_tinker10_neg_gam PASSED [ 36%] -tests/test_fits.py::test_tinker10_neg_eta PASSED [ 37%] -tests/test_fits.py::test_tinker10_neg_etaphi PASSED [ 37%] -tests/test_fits.py::test_tinker10_neg_beta PASSED [ 37%] +tests/test_fits.py::test_tinker10_neg_eta PASSED [ 36%] +tests/test_fits.py::test_tinker10_neg_etaphi PASSED [ 36%] +tests/test_fits.py::test_tinker10_neg_beta PASSED [ 36%] tests/test_fitting_functions_extra.py::test_fittingfunction_requires_mass PASSED [ 37%] -tests/test_fitting_functions_extra.py::test_fittingfunction_requires_neff PASSED [ 38%] -tests/test_fitting_functions_extra.py::test_fittingfunction_sets_measured_mdef PASSED [ 38%] -tests/test_fitting_functions_extra.py::test_get_measured_mdef_unrecognized_overdensity_warns PASSED [ 38%] -tests/test_fitting_functions_extra.py::test_get_measured_mdef_unknown_halo_finder_warns PASSED [ 39%] -tests/test_fitting_functions_extra.py::test_base_cutmask_all_true PASSED [ 39%] -tests/test_fitting_functions_extra.py::test_smt_validation_p PASSED [ 39%] -tests/test_fitting_functions_extra.py::test_smt_validation_a PASSED [ 40%] -tests/test_fitting_functions_extra.py::test_jenkins_cutmask_shape PASSED [ 40%] -tests/test_fitting_functions_extra.py::test_bhattacharya_q_validation PASSED [ 40%] -tests/test_fitting_functions_extra.py::test_bhattacharya_pq_validation PASSED [ 41%] -tests/test_fitting_functions_extra.py::test_bhattacharya_cutmask PASSED [ 41%] -tests/test_fitting_functions_extra.py::test_bhattacharya_norm_returns_existing_a PASSED [ 41%] -tests/test_fitting_functions_extra.py::test_bhattacharya_normed_uses_norm PASSED [ 41%] -tests/test_fitting_functions_extra.py::test_tinker10_non_so_raises PASSED [ 42%] -tests/test_fitting_functions_extra.py::test_tinker10_interpolates_params PASSED [ 42%] -tests/test_fitting_functions_extra.py::test_tinker10_non_terminate_clamps PASSED [ 42%] -tests/test_fitting_functions_extra.py::test_tinker10_normalise_alpha_at_z0 PASSED [ 43%] -tests/test_fitting_functions_extra.py::test_mass_cutmasks[Warren-m0-expected0] PASSED [ 43%] -tests/test_fitting_functions_extra.py::test_mass_cutmasks[Angulo-m1-expected1] PASSED [ 43%] -tests/test_fitting_functions_extra.py::test_mass_cutmasks[Crocce-m2-expected2] PASSED [ 44%] -tests/test_fitting_functions_extra.py::test_mass_cutmasks[Ishiyama-m3-expected3] PASSED [ 44%] -tests/test_fitting_functions_extra.py::test_lnsigma_cutmasks[Reed03-nu20-expected0] PASSED [ 44%] -tests/test_fitting_functions_extra.py::test_lnsigma_cutmasks[Reed07-nu21-expected1] PASSED [ 44%] -tests/test_fitting_functions_extra.py::test_lnsigma_cutmasks[Courtin-nu22-expected2] PASSED [ 45%] -tests/test_fitting_functions_extra.py::test_lnsigma_cutmasks[Watson_FoF-nu23-expected3] PASSED [ 45%] -tests/test_fitting_functions_extra.py::test_peacock_cutmask_all_false PASSED [ 45%] -tests/test_fitting_functions_extra.py::test_tinker08_non_so_raises PASSED [ 46%] -tests/test_fitting_functions_extra.py::test_tinker08_cutmask_z_positive PASSED [ 46%] -tests/test_fitting_functions_extra.py::test_tinker08_cutmask_z_zero PASSED [ 46%] -tests/test_fitting_functions_extra.py::test_tinker10_eta_phi_validation PASSED [ 47%] -tests/test_fitting_functions_extra.py::test_tinker10_cutmask_z_zero PASSED [ 47%] -tests/test_fitting_functions_extra.py::test_tinker10_cutmask_z_positive PASSED [ 47%] -tests/test_fitting_functions_extra.py::test_watson_gamma_and_fsigma_branches PASSED [ 48%] -tests/test_fitting_functions_extra.py::test_watson_gamma_non_so_raises PASSED [ 48%] -tests/test_fitting_functions_extra.py::test_watson_cutmask PASSED [ 48%] -tests/test_fitting_functions_extra.py::test_behroozi_modify_dndm_handles_nan PASSED [ 48%] -tests/test_framework.py::test_incorrect_argument PASSED [ 49%] -tests/test_framework.py::test_incorrect_update_arg PASSED [ 49%] -tests/test_framework.py::test_parameter_names PASSED [ 49%] -tests/test_framework.py::test_parameter_defaults PASSED [ 50%] -tests/test_framework.py::test_parameter_default_rec PASSED [ 50%] -tests/test_framework.py::test_param_values PASSED [ 50%] -tests/test_framework.py::test_qnt_avail PASSED [ 51%] -tests/test_framework.py::test_parameter_info PASSED [ 51%] -tests/test_framework.py::test_pluggable PASSED [ 51%] -tests/test_framework.py::test_get_base_components PASSED [ 51%] -tests/test_framework.py::test_get_base_component PASSED [ 52%] -tests/test_framework.py::test_get_model PASSED [ 52%] -tests/test_framework.py::test_growth_plugins PASSED [ 52%] -tests/test_framework.py::test_validate_inputs PASSED [ 53%] -tests/test_functional.py::test_order PASSED [ 53%] -tests/test_genmf.py::TestGenMF::test_sigmas[0.0-sigma] PASSED [ 53%] +tests/test_fitting_functions_extra.py::test_fittingfunction_requires_neff PASSED [ 37%] +tests/test_fitting_functions_extra.py::test_fittingfunction_sets_measured_mdef PASSED [ 37%] +tests/test_fitting_functions_extra.py::test_get_measured_mdef_unrecognized_overdensity_warns PASSED [ 37%] +tests/test_fitting_functions_extra.py::test_get_measured_mdef_unknown_halo_finder_warns PASSED [ 38%] +tests/test_fitting_functions_extra.py::test_base_cutmask_all_true PASSED [ 38%] +tests/test_fitting_functions_extra.py::test_smt_validation_p PASSED [ 38%] +tests/test_fitting_functions_extra.py::test_smt_validation_a PASSED [ 38%] +tests/test_fitting_functions_extra.py::test_jenkins_cutmask_shape PASSED [ 39%] +tests/test_fitting_functions_extra.py::test_bhattacharya_q_validation PASSED [ 39%] +tests/test_fitting_functions_extra.py::test_bhattacharya_pq_validation PASSED [ 39%] +tests/test_fitting_functions_extra.py::test_bhattacharya_cutmask PASSED [ 40%] +tests/test_fitting_functions_extra.py::test_bhattacharya_norm_returns_existing_a PASSED [ 40%] +tests/test_fitting_functions_extra.py::test_bhattacharya_normed_uses_norm PASSED [ 40%] +tests/test_fitting_functions_extra.py::test_tinker10_non_so_raises PASSED [ 40%] +tests/test_fitting_functions_extra.py::test_tinker10_interpolates_params PASSED [ 41%] +tests/test_fitting_functions_extra.py::test_tinker10_non_terminate_clamps PASSED [ 41%] +tests/test_fitting_functions_extra.py::test_tinker10_normalise_alpha_at_z0 PASSED [ 41%] +tests/test_fitting_functions_extra.py::test_mass_cutmasks[Warren-m0-expected0] PASSED [ 41%] +tests/test_fitting_functions_extra.py::test_mass_cutmasks[Angulo-m1-expected1] PASSED [ 42%] +tests/test_fitting_functions_extra.py::test_mass_cutmasks[Crocce-m2-expected2] PASSED [ 42%] +tests/test_fitting_functions_extra.py::test_mass_cutmasks[Ishiyama-m3-expected3] PASSED [ 42%] +tests/test_fitting_functions_extra.py::test_lnsigma_cutmasks[Reed03-nu20-expected0] PASSED [ 43%] +tests/test_fitting_functions_extra.py::test_lnsigma_cutmasks[Reed07-nu21-expected1] PASSED [ 43%] +tests/test_fitting_functions_extra.py::test_lnsigma_cutmasks[Courtin-nu22-expected2] PASSED [ 43%] +tests/test_fitting_functions_extra.py::test_lnsigma_cutmasks[Watson_FoF-nu23-expected3] PASSED [ 43%] +tests/test_fitting_functions_extra.py::test_peacock_cutmask_all_false PASSED [ 44%] +tests/test_fitting_functions_extra.py::test_tinker08_non_so_raises PASSED [ 44%] +tests/test_fitting_functions_extra.py::test_tinker08_cutmask_z_positive PASSED [ 44%] +tests/test_fitting_functions_extra.py::test_tinker08_cutmask_z_zero PASSED [ 44%] +tests/test_fitting_functions_extra.py::test_tinker10_eta_phi_validation PASSED [ 45%] +tests/test_fitting_functions_extra.py::test_tinker10_cutmask_z_zero PASSED [ 45%] +tests/test_fitting_functions_extra.py::test_tinker10_cutmask_z_positive PASSED [ 45%] +tests/test_fitting_functions_extra.py::test_watson_gamma_and_fsigma_branches PASSED [ 45%] +tests/test_fitting_functions_extra.py::test_watson_gamma_non_so_raises PASSED [ 46%] +tests/test_fitting_functions_extra.py::test_watson_cutmask PASSED [ 46%] +tests/test_fitting_functions_extra.py::test_behroozi_modify_dndm_handles_nan PASSED [ 46%] +tests/test_framework.py::test_incorrect_argument PASSED [ 47%] +tests/test_framework.py::test_incorrect_update_arg PASSED [ 47%] +tests/test_framework.py::test_parameter_names PASSED [ 47%] +tests/test_framework.py::test_parameter_defaults PASSED [ 47%] +tests/test_framework.py::test_parameter_default_rec PASSED [ 48%] +tests/test_framework.py::test_param_values PASSED [ 48%] +tests/test_framework.py::test_qnt_avail PASSED [ 48%] +tests/test_framework.py::test_parameter_info PASSED [ 48%] +tests/test_framework.py::test_pluggable PASSED [ 49%] +tests/test_framework.py::test_get_base_components PASSED [ 49%] +tests/test_framework.py::test_get_base_component PASSED [ 49%] +tests/test_framework.py::test_get_model PASSED [ 50%] +tests/test_framework.py::test_growth_plugins PASSED [ 50%] +tests/test_framework.py::test_validate_inputs PASSED [ 50%] +tests/test_framework.py::test_component_invalid_param PASSED [ 50%] +tests/test_framework.py::test_get_base_component_missing PASSED [ 51%] +tests/test_framework.py::test_get_base_component_multiple_warns PASSED [ 51%] +tests/test_framework.py::test_get_base_component_bad_type PASSED [ 51%] +tests/test_framework.py::test_get_mdl_kind_lookup_and_error PASSED [ 51%] +tests/test_framework.py::test_get_mdl_ambiguous_and_missing PASSED [ 52%] +tests/test_framework.py::test_get_mdl_invalid_class PASSED [ 52%] +tests/test_framework.py::test_get_model_deprecated PASSED [ 52%] +tests/test_framework.py::test_component_get_models PASSED [ 52%] +tests/test_framework.py::test_validator_calls_validate PASSED [ 53%] +tests/test_framework.py::test_framework_update_and_defaults PASSED [ 53%] +tests/test_framework.py::test_get_dependencies_and_parameter_info PASSED [ 53%] +tests/test_framework.py::test_parameter_info_empty_doc PASSED [ 54%] +tests/test_functional.py::test_order PASSED [ 54%] +tests/test_genmf.py::TestGenMF::test_sigmas[0.0-sigma] PASSED [ 54%] tests/test_genmf.py::TestGenMF::test_sigmas[0.0-lnsigma] PASSED [ 54%] -tests/test_genmf.py::TestGenMF::test_sigmas[0.0-n_eff] PASSED [ 54%] -tests/test_genmf.py::TestGenMF::test_sigmas[2.0-sigma] PASSED [ 54%] +tests/test_genmf.py::TestGenMF::test_sigmas[0.0-n_eff] PASSED [ 55%] +tests/test_genmf.py::TestGenMF::test_sigmas[2.0-sigma] PASSED [ 55%] tests/test_genmf.py::TestGenMF::test_sigmas[2.0-lnsigma] PASSED [ 55%] tests/test_genmf.py::TestGenMF::test_sigmas[2.0-n_eff] PASSED [ 55%] -tests/test_genmf.py::TestGenMF::test_fits[0.0-ST-dndlog10m] PASSED [ 55%] -tests/test_genmf.py::TestGenMF::test_fits[0.0-ST-ngtm] PASSED [ 55%] +tests/test_genmf.py::TestGenMF::test_fits[0.0-ST-dndlog10m] PASSED [ 56%] +tests/test_genmf.py::TestGenMF::test_fits[0.0-ST-ngtm] PASSED [ 56%] tests/test_genmf.py::TestGenMF::test_fits[0.0-ST-fsigma] PASSED [ 56%] tests/test_genmf.py::TestGenMF::test_fits[0.0-PS-dndlog10m] PASSED [ 56%] -tests/test_genmf.py::TestGenMF::test_fits[0.0-PS-ngtm] PASSED [ 56%] +tests/test_genmf.py::TestGenMF::test_fits[0.0-PS-ngtm] PASSED [ 57%] tests/test_genmf.py::TestGenMF::test_fits[0.0-PS-fsigma] PASSED [ 57%] tests/test_genmf.py::TestGenMF::test_fits[0.0-Reed03-dndlog10m] PASSED [ 57%] -tests/test_genmf.py::TestGenMF::test_fits[0.0-Reed03-ngtm] PASSED [ 57%] +tests/test_genmf.py::TestGenMF::test_fits[0.0-Reed03-ngtm] PASSED [ 58%] tests/test_genmf.py::TestGenMF::test_fits[0.0-Reed03-fsigma] PASSED [ 58%] tests/test_genmf.py::TestGenMF::test_fits[0.0-Warren-dndlog10m] PASSED [ 58%] tests/test_genmf.py::TestGenMF::test_fits[0.0-Warren-ngtm] PASSED [ 58%] -tests/test_genmf.py::TestGenMF::test_fits[0.0-Warren-fsigma] PASSED [ 58%] +tests/test_genmf.py::TestGenMF::test_fits[0.0-Warren-fsigma] PASSED [ 59%] tests/test_genmf.py::TestGenMF::test_fits[0.0-Jenkins-dndlog10m] PASSED [ 59%] tests/test_genmf.py::TestGenMF::test_fits[0.0-Jenkins-ngtm] PASSED [ 59%] tests/test_genmf.py::TestGenMF::test_fits[0.0-Jenkins-fsigma] PASSED [ 59%] @@ -210,125 +236,142 @@ tests/test_genmf.py::TestGenMF::test_fits[0.0-Reed07-fsigma] PASSED [ 60%] tests/test_genmf.py::TestGenMF::test_fits[2.0-ST-dndlog10m] PASSED [ 61%] tests/test_genmf.py::TestGenMF::test_fits[2.0-ST-ngtm] PASSED [ 61%] tests/test_genmf.py::TestGenMF::test_fits[2.0-ST-fsigma] PASSED [ 61%] -tests/test_genmf.py::TestGenMF::test_fits[2.0-PS-dndlog10m] PASSED [ 62%] +tests/test_genmf.py::TestGenMF::test_fits[2.0-PS-dndlog10m] PASSED [ 61%] tests/test_genmf.py::TestGenMF::test_fits[2.0-PS-ngtm] PASSED [ 62%] tests/test_genmf.py::TestGenMF::test_fits[2.0-PS-fsigma] PASSED [ 62%] tests/test_genmf.py::TestGenMF::test_fits[2.0-Reed03-dndlog10m] PASSED [ 62%] -tests/test_genmf.py::TestGenMF::test_fits[2.0-Reed03-ngtm] PASSED [ 63%] +tests/test_genmf.py::TestGenMF::test_fits[2.0-Reed03-ngtm] PASSED [ 62%] tests/test_genmf.py::TestGenMF::test_fits[2.0-Reed03-fsigma] PASSED [ 63%] tests/test_genmf.py::TestGenMF::test_fits[2.0-Warren-dndlog10m] PASSED [ 63%] -tests/test_genmf.py::TestGenMF::test_fits[2.0-Warren-ngtm] PASSED [ 64%] -tests/test_genmf.py::TestGenMF::test_fits[2.0-Warren-fsigma] PASSED [ 64%] +tests/test_genmf.py::TestGenMF::test_fits[2.0-Warren-ngtm] PASSED [ 63%] +tests/test_genmf.py::TestGenMF::test_fits[2.0-Warren-fsigma] PASSED [ 63%] tests/test_genmf.py::TestGenMF::test_fits[2.0-Jenkins-dndlog10m] PASSED [ 64%] -tests/test_genmf.py::TestGenMF::test_fits[2.0-Jenkins-ngtm] PASSED [ 65%] -tests/test_genmf.py::TestGenMF::test_fits[2.0-Jenkins-fsigma] PASSED [ 65%] +tests/test_genmf.py::TestGenMF::test_fits[2.0-Jenkins-ngtm] PASSED [ 64%] +tests/test_genmf.py::TestGenMF::test_fits[2.0-Jenkins-fsigma] PASSED [ 64%] tests/test_genmf.py::TestGenMF::test_fits[2.0-Reed07-dndlog10m] PASSED [ 65%] tests/test_genmf.py::TestGenMF::test_fits[2.0-Reed07-ngtm] PASSED [ 65%] -tests/test_genmf.py::TestGenMF::test_fits[2.0-Reed07-fsigma] PASSED [ 66%] -tests/test_growth.py::test_gf[0.0] PASSED [ 66%] +tests/test_genmf.py::TestGenMF::test_fits[2.0-Reed07-fsigma] PASSED [ 65%] +tests/test_growth.py::test_gf[0.0] PASSED [ 65%] tests/test_growth.py::test_gf[0.5] PASSED [ 66%] -tests/test_growth.py::test_gf[1.0] PASSED [ 67%] -tests/test_growth.py::test_gf[1.5] PASSED [ 67%] -tests/test_growth.py::test_gf[2.0] PASSED [ 67%] -tests/test_growth.py::test_gf[2.5] PASSED [ 68%] -tests/test_growth.py::test_gf[3.0] PASSED [ 68%] -tests/test_growth.py::test_gf[3.5] PASSED [ 68%] +tests/test_growth.py::test_gf[1.0] PASSED [ 66%] +tests/test_growth.py::test_gf[1.5] PASSED [ 66%] +tests/test_growth.py::test_gf[2.0] PASSED [ 66%] +tests/test_growth.py::test_gf[2.5] PASSED [ 67%] +tests/test_growth.py::test_gf[3.0] PASSED [ 67%] +tests/test_growth.py::test_gf[3.5] PASSED [ 67%] tests/test_growth.py::test_gf[4.0] PASSED [ 68%] -tests/test_growth.py::test_gf[4.5] PASSED [ 69%] -tests/test_growth.py::test_gf[5.0] PASSED [ 69%] -tests/test_growth.py::test_gf[5.5] PASSED [ 69%] -tests/test_growth.py::test_gf[6.0] PASSED [ 70%] -tests/test_growth.py::test_gf[6.5] PASSED [ 70%] -tests/test_growth.py::test_gf[7.0] PASSED [ 70%] -tests/test_growth.py::test_gf[7.5] PASSED [ 71%] -tests/test_growth.py::test_gr[0.0] PASSED [ 71%] -tests/test_growth.py::test_gr[0.5] PASSED [ 71%] -tests/test_growth.py::test_gr[1.0] PASSED [ 72%] -tests/test_growth.py::test_gr[1.5] PASSED [ 72%] -tests/test_growth.py::test_gr[2.0] PASSED [ 72%] -tests/test_growth.py::test_gr[2.5] PASSED [ 72%] -tests/test_growth.py::test_gr[3.0] PASSED [ 73%] -tests/test_growth.py::test_gr[3.5] PASSED [ 73%] -tests/test_growth.py::test_gr[4.0] PASSED [ 73%] -tests/test_growth.py::test_gr[4.5] PASSED [ 74%] -tests/test_growth.py::test_gr[5.0] PASSED [ 74%] -tests/test_growth.py::test_gr[5.5] PASSED [ 74%] -tests/test_growth.py::test_gr[6.0] PASSED [ 75%] -tests/test_growth.py::test_gr[6.5] PASSED [ 75%] -tests/test_growth.py::test_gr[7.0] PASSED [ 75%] -tests/test_growth.py::test_gr[7.5] PASSED [ 75%] -tests/test_growth.py::test_gfunc PASSED [ 76%] -tests/test_growth.py::test_gr_func PASSED [ 76%] -tests/test_growth.py::test_inverse PASSED [ 76%] -tests/test_growth.py::test_unsupported_cosmo PASSED [ 77%] -tests/test_growth.py::test_carroll PASSED [ 77%] -tests/test_growth.py::test_pickleability_of_cambgrowth PASSED [ 77%] -tests/test_growth.py::test_from_file PASSED [ 78%] -tests/test_growth.py::test_from_array PASSED [ 78%] -tests/test_halofit.py::test_takahashi PASSED [ 78%] -tests/test_halofit.py::test_takahashi_hiz PASSED [ 79%] -tests/test_halofit.py::test_halofit_high_s8 PASSED [ 79%] -tests/test_hmf.py::test_wrong_filter PASSED [ 79%] -tests/test_hmf.py::test_string_dc PASSED [ 79%] -tests/test_hmf.py::test_neg_dc PASSED [ 80%] -tests/test_hmf.py::test_big_dc PASSED [ 80%] -tests/test_hmf.py::test_wrong_fit PASSED [ 80%] -tests/test_hmf.py::test_wrong_mf_par PASSED [ 81%] -tests/test_hmf.py::test_str_filter PASSED [ 81%] -tests/test_hmf.py::test_mass_nonlinear_outside_range PASSED [ 81%] -tests/test_hmf.py::test_nu PASSED [ 82%] -tests/test_hmf.py::test_sigma8z PASSED [ 82%] -tests/test_hmf.py::test_neff_at_collapse PASSED [ 82%] -tests/test_integrate_hmf.py::TestAnalyticIntegral::test_high_z PASSED [ 82%] -tests/test_integrate_hmf.py::TestAnalyticIntegral::test_low_mmax_high_z PASSED [ 83%] -tests/test_mdef.py::test_mean_to_mean_nfw PASSED [ 83%] -tests/test_mdef.py::test_mean_to_crit_nfw PASSED [ 83%] -tests/test_mdef.py::test_mean_to_crit_z1_nfw PASSED [ 84%] -tests/test_mdef.py::test_mean_to_vir_nfw PASSED [ 84%] -tests/test_mdef.py::test_colossus_name PASSED [ 84%] -tests/test_mdef.py::test_from_colossus_name PASSED [ 85%] -tests/test_mdef.py::test_change_dndm PASSED [ 85%] -tests/test_mdef.py::test_change_dndm_bocquet PASSED [ 85%] -tests/test_sample.py::test_circular PASSED [ 86%] -tests/test_sample.py::test_mmax_big PASSED [ 86%] -tests/test_sample.py::test_sample_mf_sort_descending PASSED [ 86%] +tests/test_growth.py::test_gf[4.5] PASSED [ 68%] +tests/test_growth.py::test_gf[5.0] PASSED [ 68%] +tests/test_growth.py::test_gf[5.5] PASSED [ 68%] +tests/test_growth.py::test_gf[6.0] PASSED [ 69%] +tests/test_growth.py::test_gf[6.5] PASSED [ 69%] +tests/test_growth.py::test_gf[7.0] PASSED [ 69%] +tests/test_growth.py::test_gf[7.5] PASSED [ 69%] +tests/test_growth.py::test_gr[0.0] PASSED [ 70%] +tests/test_growth.py::test_gr[0.5] PASSED [ 70%] +tests/test_growth.py::test_gr[1.0] PASSED [ 70%] +tests/test_growth.py::test_gr[1.5] PASSED [ 70%] +tests/test_growth.py::test_gr[2.0] PASSED [ 71%] +tests/test_growth.py::test_gr[2.5] PASSED [ 71%] +tests/test_growth.py::test_gr[3.0] PASSED [ 71%] +tests/test_growth.py::test_gr[3.5] PASSED [ 72%] +tests/test_growth.py::test_gr[4.0] PASSED [ 72%] +tests/test_growth.py::test_gr[4.5] PASSED [ 72%] +tests/test_growth.py::test_gr[5.0] PASSED [ 72%] +tests/test_growth.py::test_gr[5.5] PASSED [ 73%] +tests/test_growth.py::test_gr[6.0] PASSED [ 73%] +tests/test_growth.py::test_gr[6.5] PASSED [ 73%] +tests/test_growth.py::test_gr[7.0] PASSED [ 73%] +tests/test_growth.py::test_gr[7.5] PASSED [ 74%] +tests/test_growth.py::test_gfunc PASSED [ 74%] +tests/test_growth.py::test_gr_func PASSED [ 74%] +tests/test_growth.py::test_inverse PASSED [ 75%] +tests/test_growth.py::test_unsupported_cosmo PASSED [ 75%] +tests/test_growth.py::test_carroll PASSED [ 75%] +tests/test_growth.py::test_pickleability_of_cambgrowth PASSED [ 75%] +tests/test_growth.py::test_from_file PASSED [ 76%] +tests/test_growth.py::test_from_array PASSED [ 76%] +tests/test_halofit.py::test_takahashi PASSED [ 76%] +tests/test_halofit.py::test_takahashi_hiz PASSED [ 76%] +tests/test_halofit.py::test_halofit_high_s8 PASSED [ 77%] +tests/test_hmf.py::test_wrong_filter PASSED [ 77%] +tests/test_hmf.py::test_string_dc PASSED [ 77%] +tests/test_hmf.py::test_neg_dc PASSED [ 77%] +tests/test_hmf.py::test_big_dc PASSED [ 78%] +tests/test_hmf.py::test_wrong_fit PASSED [ 78%] +tests/test_hmf.py::test_wrong_mf_par PASSED [ 78%] +tests/test_hmf.py::test_str_filter PASSED [ 79%] +tests/test_hmf.py::test_mass_nonlinear_outside_range PASSED [ 79%] +tests/test_hmf.py::test_nu PASSED [ 79%] +tests/test_hmf.py::test_sigma8z PASSED [ 79%] +tests/test_hmf.py::test_neff_at_collapse PASSED [ 80%] +tests/test_integrate_hmf.py::TestAnalyticIntegral::test_high_z PASSED [ 80%] +tests/test_integrate_hmf.py::TestAnalyticIntegral::test_low_mmax_high_z PASSED [ 80%] +tests/test_mdef.py::test_mean_to_mean_nfw PASSED [ 80%] +tests/test_mdef.py::test_mean_to_crit_nfw PASSED [ 81%] +tests/test_mdef.py::test_mean_to_crit_z1_nfw PASSED [ 81%] +tests/test_mdef.py::test_mean_to_vir_nfw PASSED [ 81%] +tests/test_mdef.py::test_colossus_name PASSED [ 81%] +tests/test_mdef.py::test_from_colossus_name PASSED [ 82%] +tests/test_mdef.py::test_change_dndm PASSED [ 82%] +tests/test_mdef.py::test_change_dndm_bocquet PASSED [ 82%] +tests/test_mdef.py::test_mass_definition_base_errors PASSED [ 83%] +tests/test_mdef.py::test_mass_definition_overdensity_helpers PASSED [ 83%] +tests/test_mdef.py::test_so_str_and_sogeneric PASSED [ 83%] +tests/test_mdef.py::test_change_definition_requires_halomod PASSED [ 83%] +tests/test_mdef.py::test_change_definition_m_c_length_mismatch PASSED [ 84%] +tests/test_mdef.py::test_change_definition_broadcasts_and_warns PASSED [ 84%] +tests/test_mdef.py::test_find_new_concentration_default_h PASSED [ 84%] +tests/test_mdef.py::test_find_new_concentration_failure_warns PASSED [ 84%] +tests/test_sample.py::test_circular PASSED [ 85%] +tests/test_sample.py::test_mmax_big PASSED [ 85%] +tests/test_sample.py::test_sample_mf_sort_descending PASSED [ 85%] tests/test_sample.py::test_choose_halo_masses_default_rng PASSED [ 86%] -tests/test_sample.py::test_dndm_from_sample_nan_edges PASSED [ 87%] -tests/test_sample.py::test_dndm_from_sample_empty PASSED [ 87%] -tests/test_transfer.py::test_updates[z-0.1] PASSED [ 87%] -tests/test_transfer.py::test_updates[sigma_8-0.82] PASSED [ 88%] -tests/test_transfer.py::test_updates[n-0.95] PASSED [ 88%] -tests/test_transfer.py::test_updates[cosmo_params-val3] PASSED [ 88%] -tests/test_transfer.py::test_updates_from_file_array PASSED [ 89%] -tests/test_transfer.py::test_halofit PASSED [ 89%] -tests/test_transfer.py::test_ehnobao PASSED [ 89%] -tests/test_transfer.py::test_bondefs PASSED [ 89%] -tests/test_transfer.py::test_data SKIPPED (Too slow and needs to be ...) [ 90%] -tests/test_transfer.py::test_camb_extrapolation PASSED [ 90%] -tests/test_transfer.py::test_camb_neutrinos PASSED [ 90%] -tests/test_transfer.py::test_setting_kmax PASSED [ 91%] -tests/test_transfer.py::test_camb_w0wa PASSED [ 91%] -tests/test_transfer.py::test_camb_wcdm PASSED [ 91%] -tests/test_transfer.py::test_camb_unset_params PASSED [ 92%] -tests/test_transfer.py::test_bbks_sugiyama PASSED [ 92%] -tests/test_utils.py::test_inherit_docstrings_sets_missing PASSED [ 92%] +tests/test_sample.py::test_dndm_from_sample_nan_edges PASSED [ 86%] +tests/test_sample.py::test_dndm_from_sample_empty PASSED [ 86%] +tests/test_transfer.py::test_updates[z-0.1] PASSED [ 86%] +tests/test_transfer.py::test_updates[sigma_8-0.82] PASSED [ 87%] +tests/test_transfer.py::test_updates[n-0.95] PASSED [ 87%] +tests/test_transfer.py::test_updates[cosmo_params-val3] PASSED [ 87%] +tests/test_transfer.py::test_updates_from_file_array PASSED [ 87%] +tests/test_transfer.py::test_halofit PASSED [ 88%] +tests/test_transfer.py::test_ehnobao PASSED [ 88%] +tests/test_transfer.py::test_bondefs PASSED [ 88%] +tests/test_transfer.py::test_data SKIPPED (Too slow and needs to be ...) [ 88%] +tests/test_transfer.py::test_camb_extrapolation PASSED [ 89%] +tests/test_transfer.py::test_camb_neutrinos PASSED [ 89%] +tests/test_transfer.py::test_setting_kmax PASSED [ 89%] +tests/test_transfer.py::test_camb_w0wa PASSED [ 90%] +tests/test_transfer.py::test_camb_wcdm PASSED [ 90%] +tests/test_transfer.py::test_camb_unset_params PASSED [ 90%] +tests/test_transfer.py::test_bbks_sugiyama PASSED [ 90%] +tests/test_transfer_models.py::test_fromfile_low_k_branch PASSED [ 91%] +tests/test_transfer_models.py::test_fromarray_validation[None-None-must supply an array] PASSED [ 91%] +tests/test_transfer_models.py::test_fromarray_validation[k1-t1-must have same length] PASSED [ 91%] +tests/test_transfer_models.py::test_fromarray_low_k_branch PASSED [ 91%] +tests/test_transfer_models.py::test_eh_bao_k_peak_property PASSED [ 92%] +tests/test_transfer_models.py::test_camb_rejects_non_lcdm_cosmology PASSED [ 92%] +tests/test_transfer_models.py::test_camb_no_extrapolation_branch PASSED [ 92%] +tests/test_transfer_models.py::test_camb_getstate_and_setstate PASSED [ 93%] +tests/test_transfer_models.py::test_camb_getstate_warns_for_missing_and_unpickleable PASSED [ 93%] +tests/test_utils.py::test_inherit_docstrings_sets_missing PASSED [ 93%] tests/test_utils.py::test_inherit_docstrings_preserves_existing PASSED [ 93%] -tests/test_utils.py::test_inherit_docstrings_skips_dunder PASSED [ 93%] -tests/test_wcdm.py::test_defaults PASSED [ 93%] -tests/test_wcdm.py::test_trivial PASSED [ 93%] +tests/test_utils.py::test_inherit_docstrings_skips_dunder PASSED [ 94%] +tests/test_wcdm.py::test_defaults PASSED [ 94%] +tests/test_wcdm.py::test_trivial PASSED [ 94%] tests/test_wcdm.py::test_divergence PASSED [ 94%] -tests/test_wdm.py::test_null PASSED [ 94%] -tests/test_wdm.py::TestViel::test_lowk_transfer PASSED [ 94%] +tests/test_wdm.py::test_null PASSED [ 95%] +tests/test_wdm.py::TestViel::test_lowk_transfer PASSED [ 95%] tests/test_wdm.py::TestViel::test_lam_eff PASSED [ 95%] tests/test_wdm.py::TestViel::test_m_eff PASSED [ 95%] -tests/test_wdm.py::TestViel::test_lam_hm PASSED [ 95%] +tests/test_wdm.py::TestViel::test_lam_hm PASSED [ 96%] tests/test_wdm.py::TestViel::test_m_hm PASSED [ 96%] tests/test_wdm.py::TestBode::test_lowk_transfer PASSED [ 96%] -tests/test_wdm.py::TestBode::test_lam_eff PASSED [ 96%] -tests/test_wdm.py::TestBode::test_m_eff PASSED [ 96%] +tests/test_wdm.py::TestBode::test_lam_eff PASSED [ 97%] +tests/test_wdm.py::TestBode::test_m_eff PASSED [ 97%] tests/test_wdm.py::TestBode::test_lam_hm PASSED [ 97%] tests/test_wdm.py::TestBode::test_m_hm PASSED [ 97%] -tests/test_wdm.py::TestSchneider12_vCDM::test_high_m PASSED [ 97%] +tests/test_wdm.py::TestSchneider12_vCDM::test_high_m PASSED [ 98%] tests/test_wdm.py::TestSchneider12::test_high_m PASSED [ 98%] tests/test_wdm.py::TestLovell14::test_high_m PASSED [ 98%] tests/test_wdm.py::TestTransfer::test_wdm_model PASSED [ 98%] @@ -346,7 +389,7 @@ src/hmf/__init__.py 12 0 100% src/hmf/_cli.py 106 5 95% 53-55, 60-62 src/hmf/_internals/__init__.py 4 0 100% src/hmf/_internals/_cache.py 171 0 100% -src/hmf/_internals/_framework.py 150 22 85% 34, 68, 72, 79-80, 123-144, 186, 230, 310-318, 337, 354 +src/hmf/_internals/_framework.py 150 1 99% 354 src/hmf/_internals/_utils.py 11 0 100% src/hmf/alternatives/__init__.py 2 0 100% src/hmf/alternatives/wdm.py 109 3 97% 326-327, 330 @@ -354,12 +397,12 @@ src/hmf/cosmology/__init__.py 4 0 100% src/hmf/cosmology/cosmo.py 36 2 94% 97, 155 src/hmf/cosmology/growth_factor.py 172 15 91% 116, 118, 288, 290, 317, 365, 368, 375-377, 405, 409, 458, 463, 516 src/hmf/density_field/__init__.py 6 0 100% -src/hmf/density_field/filters.py 159 40 75% 267, 301-302, 356, 364, 368, 414-415, 419, 423, 433, 437, 487-489, 493, 497, 501, 505, 509-512, 520, 524-528, 536-538, 542-545, 549-552 +src/hmf/density_field/filters.py 159 0 100% src/hmf/density_field/halofit.py 80 3 96% 60, 110, 113 src/hmf/density_field/transfer.py 131 8 94% 126, 146, 159, 211-212, 215, 278, 284 -src/hmf/density_field/transfer_models.py 219 28 87% 106-107, 134, 176, 266, 291-376, 380-382, 425, 427, 430, 518 +src/hmf/density_field/transfer_models.py 219 2 99% 365-366 src/hmf/halos/__init__.py 3 0 100% -src/hmf/halos/mass_definitions.py 157 24 85% 49, 54, 62, 80-81, 99-100, 136, 138, 140, 142, 151-152, 157-162, 174, 203, 218, 352-353, 363-365, 368 +src/hmf/halos/mass_definitions.py 157 0 100% src/hmf/helpers/__init__.py 3 0 100% src/hmf/helpers/cfg_utils.py 35 2 94% 51-52 src/hmf/helpers/functional.py 84 11 87% 62, 178, 185, 192, 205, 220-221, 232, 258-259, 267 @@ -369,5 +412,5 @@ src/hmf/mass_function/fitting_functions.py 585 0 100% src/hmf/mass_function/hmf.py 212 14 93% 221, 257, 277, 288, 338, 343, 436-439, 482-485, 509, 620 src/hmf/mass_function/integrate_hmf.py 24 1 96% 60 -------------------------------------------------------------------------- -TOTAL 2518 178 93% -======================= 328 passed, 1 skipped in 17.08s ======================== +TOTAL 2518 67 97% +======================= 371 passed, 1 skipped in 15.03s ======================== diff --git a/tests/test_filters.py b/tests/test_filters.py index 8b9cbde0..781a37a9 100644 --- a/tests/test_filters.py +++ b/tests/test_filters.py @@ -77,6 +77,38 @@ def test_dlnssdlnr(self, cls): print(true, cls.dlnss_dlnr(R)) assert np.isclose(cls.dlnss_dlnr(R), true) + def test_real_space_edges(self, cls): + R = 1.0 + r = np.array([0.5, 1.0, 1.5]) + + assert np.array_equal(cls.real_space(R, r), np.array([1.0, 0.5, 0.0])) + + def test_k_space_small(self, cls): + kr = np.array([1e-8, 1e-7, 1e-2]) + w = cls.k_space(kr) + + assert np.allclose(w[:2], 1.0) + assert np.isfinite(w[2]) + + def test_nu(self, cls): + R = 1.0 + nu = cls.nu(R) + + assert np.isfinite(nu).all() + + def test_mass_radius_roundtrip(self, cls): + rho = 2.0 + m = 1.0e12 + r = cls.mass_to_radius(m, rho) + + assert np.isclose(cls.radius_to_mass(r, rho), m) + + def test_dlnr_dlnm(self, cls): + r = np.array([0.5, 1.0]) + + assert np.allclose(cls.dlnr_dlnm(r), 1.0 / 3.0) + assert np.allclose(cls.dlnss_dlnm(r), cls.dlnss_dlnr(r) / 3.0) + class TestSharpK: @pytest.fixture(scope="class") @@ -167,6 +199,25 @@ def test_dlnssdlnr_Rhalf(self, cls): print(true, cls.dlnss_dlnr(R)) assert np.isclose(cls.dlnss_dlnr(R), true) + def test_k_space_edges(self, cls): + kr = np.array([0.5, 1.0, 1.5]) + + assert np.array_equal(cls.k_space(kr), np.array([1.0, 0.5, 0.0])) + + def test_real_space_and_dw(self, cls): + R = 2.0 + r = np.array([1.0, 2.0]) + + assert np.isfinite(cls.real_space(R, r)).all() + assert np.array_equal(cls.dw_dlnkr(np.array([1.0, 2.0])), np.array([1.0, 0.0])) + + def test_mass_radius_roundtrip(self, cls): + rho = 2.5 + m = 1.0e12 + r = cls.mass_to_radius(m, rho) + + assert np.isclose(cls.radius_to_mass(r, rho), m) + class TestGaussian: @pytest.fixture(scope="class") @@ -195,3 +246,58 @@ def test_dlnssdlnr(self, cls): print(true, cls.dlnss_dlnr(R)) assert np.isclose(cls.dlnss_dlnr(R), true) + + def test_real_space_and_k_space(self, cls): + R = 2.0 + r = np.array([1.0, 2.0]) + kr = np.array([0.0, 1.0]) + + assert np.isfinite(cls.real_space(R, r)).all() + assert np.allclose(cls.k_space(kr), np.exp(-(kr**2) / 2.0)) + + def test_mass_radius_roundtrip(self, cls): + rho = 1.5 + m = 3.0e11 + r = cls.mass_to_radius(m, rho) + + assert np.isclose(cls.radius_to_mass(r, rho), m) + + +class TestSharpKEllipsoid: + @pytest.fixture(scope="class") + def cls(self): + k = np.logspace(-3, 1, 200) + pk = np.ones_like(k) + return filters.SharpKEllipsoid(k, pk) + + def test_shape_helpers(self, cls): + g = 0.5 + v = 1.2 + xm = cls.xm(g, v) + em = cls.em(xm) + pm = cls.pm(xm) + + assert np.isfinite(xm) + assert np.isfinite(em) + assert np.isfinite(pm) + assert np.isfinite(cls.a3a1(em, pm)) + assert np.isfinite(cls.a3a2(em, pm)) + + def test_gamma_xi_a3(self, cls): + r = np.array([0.5]) + g = cls.gamma(r) + xm = cls.xm(g, cls.nu(r)) + em = cls.em(xm) + pm = cls.pm(xm) + + assert np.isfinite(cls.xi(pm, em)).all() + assert np.isfinite(cls.a3(r)).all() + + def test_r_a3_and_derivatives(self, cls): + spline = cls.r_a3(0.2, 1.0) + r = np.array([0.4, 0.5, 0.6, 0.7]) + + a3 = cls.a3(r) + assert np.isfinite(spline(a3)).all() + assert np.isfinite(cls.dlnss_dlnr(r)).all() + assert np.isfinite(cls.dlnr_dlnm(r)).all() diff --git a/tests/test_framework.py b/tests/test_framework.py index ca27adaf..8ea0885f 100644 --- a/tests/test_framework.py +++ b/tests/test_framework.py @@ -1,10 +1,14 @@ +import sys +import typing + import pytest from deprecation import fail_if_not_removed import hmf from hmf import GrowthFactor, MassFunction from hmf._internals import get_base_component, get_base_components, pluggable -from hmf._internals._framework import get_model_ +from hmf._internals._cache import cached_quantity, parameter +from hmf._internals._framework import Component, Framework, get_mdl, get_model, get_model_ from hmf.density_field.transfer_models import TransferComponent @@ -114,3 +118,235 @@ def test_validate_inputs(): pytest.raises(AssertionError, match="Mmin > Mmax: 8, 7"), ): m.Mmax = 7 + + +def test_component_invalid_param(): + @pluggable + class Dummy(Component): + _defaults: typing.ClassVar = {"a": 1} + + with pytest.raises(ValueError, match="not a valid argument"): + Dummy(b=1) + + +def test_get_base_component_missing(): + with pytest.raises(ValueError, match="There are no components called"): + get_base_component("DoesNotExist") + + +def test_get_base_component_multiple_warns(): + @pluggable + class DupComponent(Component): + pass + + def construct(): + @pluggable + class DupComponent(Component): + pass + + return DupComponent + + construct() + + with pytest.warns(UserWarning, match="More than one component called"): + get_base_component("DupComponent") + + +def test_get_base_component_bad_type(): + with pytest.raises(ValueError, match="must be str or a Component subclass"): + get_base_component(123) + + +def test_get_mdl_kind_lookup_and_error(): + @pluggable + class DummyBase(Component): + pass + + class DummyModel(DummyBase): + pass + + assert get_mdl("DummyModel", DummyBase) is DummyModel + + with pytest.raises(ValueError, match="not a defined"): + get_mdl("MissingModel", DummyBase) + + +def test_get_mdl_ambiguous_and_missing(monkeypatch): + @pluggable + class BaseA(Component): + pass + + @pluggable + class BaseB(Component): + pass + + type("SharedModel", (BaseA,), {}) + SharedB = type("SharedModel", (BaseB,), {}) + + monkeypatch.setattr( + sys.modules["hmf._internals._framework"], + "get_base_components", + lambda: [BaseA, BaseB], + ) + + with pytest.warns(UserWarning, match="More than one model was found"): + model = get_mdl("SharedModel") + assert model is SharedB + + with pytest.raises(ValueError, match="No model found"): + get_mdl("NoModelFound") + + +def test_get_mdl_invalid_class(): + with pytest.raises(ValueError, match="must be str or Component subclass"): + get_mdl(object(), Component) + + +def test_get_model_deprecated(): + with pytest.deprecated_call(): + inst = get_model("Component", "hmf._internals._framework") + + assert isinstance(inst, Component) + + +def test_component_get_models(): + @pluggable + class ModelBase(Component): + pass + + class ModelImpl(ModelBase): + pass + + models = ModelBase.get_models() + assert models["ModelImpl"] is ModelImpl + + +def test_validator_calls_validate(): + class Validated(Framework): + def __init__(self): + self._validate = False + self.validated = 0 + self.x = 1 + self._validate = True + + @parameter("param") + def x(self, val): + return val + + def validate(self): + self.validated += 1 + + obj = Validated() + assert obj.validated == 1 + + +def test_framework_update_and_defaults(): + class Child(Framework): + def __init__(self, y=1): + self._validate = False + self.validated = 0 + self.y = y + self._validate = True + + @parameter("param") + def y(self, val): + return val + + def validate(self): + self.validated += 1 + + class ChildModel: + _defaults: typing.ClassVar = {"y": 2} + + class Parent(Framework): + def __init__(self, x=1, child=None): + self._validate = False + self.validated = 0 + self.x = x + self.child = child or Child() + self.other_params = {} + self.missing_params = {} + self._validate = True + + @parameter("param") + def x(self, val): + return val + + @parameter("param") + def missing_params(self, val): + return val + + @parameter("param") + def other_params(self, val): + return val + + @property + def other_model(self): + return ChildModel + + @cached_quantity + def q(self): + return self.x + self.child.y + + def validate(self): + self.validated += 1 + + parent = Parent() + parent.update(x=3, child_params={"y": 4}) + + assert parent.x == 3 + assert parent.child.y == 4 + assert parent.validated >= 1 + + defaults = Parent.get_all_parameter_defaults(recursive=True) + assert defaults["other_params"] == {"y": 2} + assert defaults["missing_params"] == {} + + with pytest.raises(ValueError, match="Invalid arguments"): + parent.update(bad=1) + + clone = parent.clone(x=5) + assert clone.x == 5 + assert parent.x == 3 + + +def test_get_dependencies_and_parameter_info(capsys): + class Simple(Framework): + def __init__(self): + self._validate = False + self.x = 2 + self._validate = True + + @parameter("param") + def x(self, val): + r"""Value for x.""" + return val + + @cached_quantity + def q(self): + return self.x + 1 + + obj = Simple() + setattr(obj, "_" + obj.__class__.__name__ + "__recalc_prop_par_static", {"q": {"x"}}) + + assert obj.get_dependencies("q") == {"x"} + + assert Simple.parameter_info() is None + output = capsys.readouterr().out + assert "x" in output + + +def test_parameter_info_empty_doc(capsys): + class EmptyDoc(Framework): + def __init__(self): + self._validate = False + self.empty = 1 + self._validate = True + + @parameter("param") + def empty(self, val): + return val + + assert EmptyDoc.parameter_info() is None + output = capsys.readouterr().out + assert "empty" in output diff --git a/tests/test_mdef.py b/tests/test_mdef.py index 74d4e74e..34fc5b75 100644 --- a/tests/test_mdef.py +++ b/tests/test_mdef.py @@ -1,3 +1,5 @@ +import builtins + import numpy as np import pytest from colossus.cosmology.cosmology import setCosmology @@ -127,3 +129,135 @@ def test_change_dndm_bocquet(): ) np.testing.assert_allclose(h200m.fsigma / h200c.fsigma, h200m.dndm / h200c.dndm) + + +def test_mass_definition_base_errors(): + base = md.MassDefinition() + + with pytest.raises(AttributeError, match="halo_density does not exist"): + base.halo_density() + + assert base.colossus_name is None + + with pytest.raises(AttributeError, match="cannot convert mass to radius"): + base.m_to_r(1.0) + + with pytest.raises(AttributeError, match="cannot convert radius to mass"): + base.r_to_m(1.0) + + +def test_mass_definition_overdensity_helpers(): + class Dummy(md.MassDefinition): + def halo_density(self, z=0, cosmo=md.Planck15): + return 10.0 + + dummy = Dummy() + + assert np.isclose( + dummy.halo_overdensity_mean(), + dummy.halo_density() / dummy.mean_density(), + ) + assert np.isclose( + dummy.halo_overdensity_crit(), + dummy.halo_density() / dummy.critical_density(), + ) + + +def test_so_str_and_sogeneric(): + assert str(md.SOMean()) == "SOMean(200)" + assert str(md.SOCritical(overdensity=500)) == "SOCritical(500)" + assert str(md.SOVirial()) == "SOVirial" + assert str(md.FOF()) == "FoF(l=0.2)" + + generic = md.SOGeneric() + assert str(generic) == "SOGeneric" + assert generic == md.SOMean() + + +def test_change_definition_requires_halomod(monkeypatch): + original_import = builtins.__import__ + + def fake_import(name, globals=None, locals=None, fromlist=(), level=0): # noqa: A002 + if name.startswith("halomod"): + raise ImportError("No module named 'halomod'") + return original_import(name, globals, locals, fromlist, level) + + monkeypatch.setattr(builtins, "__import__", fake_import) + + base = md.SOMean() + with pytest.raises(ImportError, match="without halomod installed"): + base.change_definition(1e12, md.SOCritical()) + + +def test_change_definition_m_c_length_mismatch(monkeypatch): + class DummyProfile: + z = 0 + _h = None + + def cm_relation(self, m): + return 5.0 + + def _rho_s(self, c): + return 1.0 + + monkeypatch.setattr(md, "_find_new_concentration", lambda *args, **kwargs: 1.0) + + base = md.SOMean() + other = md.SOCritical() + profile = DummyProfile() + + with pytest.raises(ValueError, match="same length"): + base.change_definition(np.array([1.0, 2.0]), other, profile=profile, c=np.array([1.0])) + + +def test_change_definition_broadcasts_and_warns(monkeypatch): + class DummyProfile: + def __init__(self, z): + self.z = z + self._h = None + + def cm_relation(self, m): + return 5.0 + + def _rho_s(self, c): + c_arr = np.atleast_1d(c) + return np.ones_like(c_arr, dtype=float) + + monkeypatch.setattr(md, "_find_new_concentration", lambda *args, **kwargs: 2.0) + + base = md.SOMean() + other = md.SOCritical() + profile = DummyProfile(z=2) + + with pytest.warns(UserWarning, match="Redshift of given profile"): + base.change_definition(np.array([1.0, 2.0]), other, profile=profile, c=3.0, z=0) + + with pytest.warns(UserWarning, match="Redshift of given profile"): + base.change_definition(1.0, other, profile=DummyProfile(z=2), c=np.array([3.0, 4.0]), z=0) + + with pytest.warns(UserWarning, match="Redshift of given profile"): + base.change_definition(1.0, other, profile=DummyProfile(z=2), c=None, z=0) + + +def test_find_new_concentration_default_h(monkeypatch): + def fake_brentq(fnc, xmin, xmax): + fnc(1.0) + return 1.0 + + monkeypatch.setattr(md.sp.optimize, "brentq", fake_brentq) + + out = md._find_new_concentration(rho_s=1.0, halo_density=0.1, h=None, x_guess=5.0) + assert out == 1.0 + + +def test_find_new_concentration_failure_warns(): + with ( + pytest.warns(UserWarning, match="raised following error"), + pytest.raises(md.OptimizationError, match="Could not determine x"), + ): + md._find_new_concentration( + rho_s=1.0, + halo_density=100.0, + h=lambda x: 0.0, + x_guess=5.0, + ) diff --git a/tests/test_transfer_models.py b/tests/test_transfer_models.py new file mode 100644 index 00000000..c01894df --- /dev/null +++ b/tests/test_transfer_models.py @@ -0,0 +1,99 @@ +import camb +import numpy as np +import pytest +from astropy.cosmology import LambdaCDM + +from hmf.density_field.transfer_models import CAMB, EH_BAO, FromArray, FromFile + + +@pytest.fixture +def base_cosmo(): + return LambdaCDM(Om0=0.3, Ode0=0.7, H0=70.0, Ob0=0.05, Tcmb0=2.7) + + +def test_fromfile_low_k_branch(tmp_path, base_cosmo): + data = np.array( + [ + [1.0, 1.0], + [2.0, 1.0], + [3.0, 1.0], + [4.0, 1.0], + ] + ) + fname = tmp_path / "transfer.dat" + np.savetxt(fname, data) + + model = FromFile(base_cosmo, fname=str(fname)) + lnk = np.log(np.array([0.1, 0.5, 1.0])) + out = model.lnt(lnk) + + assert out.shape == lnk.shape + + +@pytest.mark.parametrize( + ("k", "t", "match"), + [ + (None, None, "must supply an array"), + (np.array([1.0, 2.0]), np.array([1.0]), "must have same length"), + ], +) +def test_fromarray_validation(base_cosmo, k, t, match): + model = FromArray(base_cosmo, k=k, T=t) + with pytest.raises(ValueError, match=match): + model.lnt(np.log(np.array([0.5, 1.0]))) + + +def test_fromarray_low_k_branch(base_cosmo): + k = np.array([1.0, 2.0, 3.0]) + t = np.array([1.0, 1.0, 1.0]) + model = FromArray(base_cosmo, k=k, T=t) + lnk = np.log(np.array([0.1, 1.0, 2.0])) + + out = model.lnt(lnk) + + assert out.shape == lnk.shape + + +def test_eh_bao_k_peak_property(base_cosmo): + model = EH_BAO(base_cosmo) + + assert np.isfinite(model.k_peak) + + +def test_camb_rejects_non_lcdm_cosmology(): + with pytest.raises(ValueError, match="CAMB will only work with LCDM or wCDM"): + CAMB(object(), extrapolate_with_eh=False) + + +def test_camb_no_extrapolation_branch(base_cosmo): + model = CAMB(base_cosmo, extrapolate_with_eh=False) + lnk = np.log(np.logspace(-3, -2, 4)) + + out = model.lnt(lnk) + + assert out.shape == lnk.shape + + +def test_camb_getstate_and_setstate(base_cosmo): + model = CAMB(base_cosmo, extrapolate_with_eh=False) + state = model.__getstate__() + + restored = CAMB.__new__(CAMB) + restored.__setstate__(state) + + assert isinstance(restored.params["camb_params"], camb.CAMBparams) + + +def test_camb_getstate_warns_for_missing_and_unpickleable(base_cosmo): + class DummyCambParams: + def __init__(self): + self.WantCls = lambda: None + + def __getattr__(self, name): + raise AttributeError(name) + + model = CAMB(base_cosmo, extrapolate_with_eh=False) + model.params["camb_params"] = DummyCambParams() + + with pytest.warns(UserWarning, match="CAMB key"): + model.__getstate__() diff --git a/tests/test_utils.py b/tests/test_utils.py index 3558ccf1..a67d1266 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -36,11 +36,11 @@ def __str__(cls): def test_inherit_docstrings_sets_missing(): - assert _Child.foo.__doc__ == "base foo" + assert _Child.foo.__doc__ == "Base foo." def test_inherit_docstrings_preserves_existing(): - assert _Child.bar.__doc__ == "child bar" + assert _Child.bar.__doc__ == "Child bar." def test_inherit_docstrings_skips_dunder():