diff --git a/nomad/config/models/common.py b/nomad/config/models/common.py index fa89af6ae44887d291c64ab9dd84872b0f4d52ea..4c004e8023cb9ba3ea3e8e1cb6ec1f1ff99a6eea 100644 --- a/nomad/config/models/common.py +++ b/nomad/config/models/common.py @@ -65,7 +65,9 @@ class ConfigBaseModel(BaseModel, extra=Extra.ignore): return ', '.join([f'"{x}"' for x in items]) if extra_fields: - logger = logging.getLogger(__name__) + from structlog import get_logger + + logger = get_logger() logger.warning( f'The following unsupported keys were found in your configuration, ' f'e.g. nomad.yaml: {list_items(extra_fields)}.' diff --git a/pyproject.toml b/pyproject.toml index d57fbcbe43586ed000581140d8c17a89de2f0e0c..00fcb8cbfa0312e50c67650ef5bcc90439c2945a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -127,10 +127,10 @@ dev = [ 'names==0.3.0', 'uv', 'pycodestyle', - 'pytest-cov==2.7.1', - 'pytest-timeout==1.4.2', + 'pytest-cov>=2.7.1', + 'pytest-timeout>=1.4.2', 'pytest-xdist>=1.30.0', - 'pytest>= 5.3.0, < 6.0.0', + 'pytest>= 5.3.0, <8', 'python-gitlab==2.10.1', 'rope==0.21.0', 'ruamel.yaml', diff --git a/requirements-dev.txt b/requirements-dev.txt index e9841e78c294d82ef783f41e389717e4441425f5..9bd5b8fc085b76d3e3e67532aff795356641e0cd 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,5 +1,5 @@ # This file was autogenerated by uv via the following command: -# uv pip compile --annotation-style=line --extra=dev --extra=infrastructure --extra=parsing --output-file=requirements-dev.txt requirements.txt pyproject.toml +# uv pip compile -p 3.9 --annotation-style=line --extra=dev --extra=infrastructure --extra=parsing --output-file=requirements-dev.txt requirements.txt pyproject.toml aiosmtpd==1.4.6 # via nomad-lab (pyproject.toml) alabaster==0.7.16 # via sphinx, -r requirements.txt alembic==1.13.1 # via jupyterhub, -r requirements.txt @@ -20,9 +20,9 @@ asttokens==2.4.1 # via devtools, stack-data, -r requirements.txt async-generator==1.10 # via jupyterhub, -r requirements.txt async-lru==2.0.4 # via jupyterlab, -r requirements.txt atpublic==4.1.0 # via aiosmtpd -attrs==23.2.0 # via aiosmtpd, jsonschema, pytest, -r requirements.txt +attrs==23.2.0 # via aiosmtpd, jsonschema, -r requirements.txt babel==2.15.0 # via jupyterlab-server, mkdocs-git-revision-date-localized-plugin, mkdocs-material, sphinx, -r requirements.txt -backports-tarfile==1.1.1 # via jaraco-context +backports-tarfile==1.2.0 # via jaraco-context bagit==1.8.1 # via -r requirements.txt, nomad-lab (pyproject.toml) basicauth==0.4.1 # via -r requirements.txt, nomad-lab (pyproject.toml) beautifulsoup4==4.12.3 # via nbconvert, -r requirements.txt, nomad-lab (pyproject.toml) @@ -50,7 +50,7 @@ colorama==0.4.6 # via mkdocs-material, twine comm==0.2.2 # via ipykernel, ipywidgets, -r requirements.txt commonmark==0.9.1 # via recommonmark, -r requirements.txt contourpy==1.2.1 # via matplotlib, -r requirements.txt -coverage==7.5.2 # via pytest-cov +coverage==7.5.3 # via pytest-cov cryptography==42.0.7 # via jwcrypto, pyjwt, pyopenssl, rfc3161ng, secretstorage, -r requirements.txt cycler==0.12.1 # via matplotlib, -r requirements.txt dask==2024.5.1 # via hyperspy, kikuchipy, orix, pyxem, rosettasciio, -r requirements.txt @@ -74,7 +74,7 @@ entrypoints==0.4 # via ipyparallel, -r requirements.txt escapism==1.0.1 # via dockerspawner, -r requirements.txt essential-generators==1.0 # via nomad-lab (pyproject.toml) et-xmlfile==1.1.0 # via openpyxl, -r requirements.txt -exceptiongroup==1.2.1 # via anyio, ipython, -r requirements.txt +exceptiongroup==1.2.1 # via anyio, ipython, pytest, -r requirements.txt execnet==2.1.1 # via pytest-xdist executing==2.0.1 # via devtools, stack-data, -r requirements.txt f90wrap==0.2.14 # via quippy-ase, -r requirements.txt @@ -86,7 +86,7 @@ filelock==3.3.1 # via -r requirements.txt, nomad-lab (pyproject.toml) findiff==0.10.0 # via pynxtools-stm, -r requirements.txt flask==3.0.3 # via asr, -r requirements.txt flatdict==4.0.1 # via ifes-apt-tc-data-modeling, pynxtools-em, -r requirements.txt -fonttools==4.52.1 # via matplotlib, -r requirements.txt +fonttools==4.52.4 # via matplotlib, -r requirements.txt fqdn==1.5.1 # via jsonschema, -r requirements.txt fsspec==2024.5.0 # via dask, hyperspy, -r requirements.txt future==1.0.0 # via uncertainties, -r requirements.txt @@ -95,7 +95,7 @@ gitdb==4.0.11 # via gitpython, -r requirements.txt gitpython==3.1.43 # via mkdocs-git-revision-date-localized-plugin, -r requirements.txt, nomad-lab (pyproject.toml) greenlet==3.0.3 # via sqlalchemy, -r requirements.txt griddataformats==1.0.2 # via mdanalysis, -r requirements.txt -gsd==3.2.1 # via mdanalysis, -r requirements.txt +gsd==3.3.0 # via mdanalysis, -r requirements.txt gunicorn==21.2.0 # via -r requirements.txt, nomad-lab (pyproject.toml) h11==0.14.0 # via httpcore, uvicorn, -r requirements.txt h5grove==1.3.0 # via jupyterlab-h5web, -r requirements.txt, nomad-lab (pyproject.toml) @@ -115,10 +115,11 @@ imagesize==1.4.1 # via sphinx, -r requirements.txt importlib-metadata==7.1.0 # via build, dask, flask, hyperspy, jupyter-client, jupyter-lsp, jupyterhub, jupyterlab, jupyterlab-server, keyring, markdown, mkdocs, mkdocs-get-deps, nbconvert, pynxtools, sphinx, twine, -r requirements.txt, nomad-lab (pyproject.toml) importlib-resources==6.4.0 # via matplotlib, spglib, -r requirements.txt inflection==0.5.1 # via -r requirements.txt, nomad-lab (pyproject.toml) +iniconfig==2.0.0 # via pytest ipykernel==6.29.4 # via ipyparallel, jupyter, jupyter-console, jupyterlab, qtconsole, -r requirements.txt ipyparallel==8.8.0 # via hyperspy, -r requirements.txt ipython==8.18.1 # via hyperspy, ipykernel, ipyparallel, ipywidgets, jupyter-console, pynxtools-xrd, -r requirements.txt -ipywidgets==8.1.2 # via jupyter, -r requirements.txt +ipywidgets==8.1.3 # via jupyter, -r requirements.txt isodate==0.6.1 # via rdflib, -r requirements.txt isoduration==20.11.0 # via jsonschema, -r requirements.txt itsdangerous==2.2.0 # via flask, -r requirements.txt, nomad-lab (pyproject.toml) @@ -147,7 +148,7 @@ jupyterlab==4.1.6 # via ifes-apt-tc-data-modeling, notebook, -r requirem jupyterlab-h5web==11.1.0 # via ifes-apt-tc-data-modeling, -r requirements.txt jupyterlab-pygments==0.3.0 # via nbconvert, -r requirements.txt jupyterlab-server==2.24.0 # via jupyterlab, notebook, -r requirements.txt -jupyterlab-widgets==3.0.10 # via ipywidgets, -r requirements.txt +jupyterlab-widgets==3.0.11 # via ipywidgets, -r requirements.txt jwcrypto==1.5.6 # via python-keycloak, -r requirements.txt keyring==25.2.1 # via twine kikuchipy==0.9.0 # via pynxtools-em, -r requirements.txt @@ -185,7 +186,7 @@ mmtf-python==1.1.3 # via mdanalysis, -r requirements.txt mongoengine==0.28.2 # via -r requirements.txt, nomad-lab (pyproject.toml) mongomock==4.1.2 # via optimade, -r requirements.txt monty==2024.5.24 # via pymatgen, -r requirements.txt -more-itertools==10.2.0 # via jaraco-classes, jaraco-functools, pytest +more-itertools==10.2.0 # via jaraco-classes, jaraco-functools mpmath==1.3.0 # via sympy, -r requirements.txt mrcfile==1.5.0 # via griddataformats, -r requirements.txt msgpack==1.0.8 # via blosc2, mmtf-python, -r requirements.txt, nomad-lab (pyproject.toml) @@ -216,7 +217,7 @@ numpy==1.22.4 # via ase, biopython, blosc2, cftime, contourpy, dask, numpy-quaternion==2023.0.3 # via orix, -r requirements.txt oauthenticator==15.1.0 # via -r requirements.txt, nomad-lab (pyproject.toml) oauthlib==3.2.2 # via jupyterhub, -r requirements.txt -openpyxl==3.1.2 # via -r requirements.txt, nomad-lab (pyproject.toml) +openpyxl==3.1.3 # via -r requirements.txt, nomad-lab (pyproject.toml) optimade==0.22.1 # via -r requirements.txt, nomad-lab (pyproject.toml) orix==0.12.1.post0 # via diffsims, kikuchipy, pyxem, -r requirements.txt orjson==3.10.3 # via h5grove, -r requirements.txt, nomad-lab (pyproject.toml) @@ -238,16 +239,15 @@ pint==0.17 # via hyperspy, pynxtools-xps, rosettasciio, -r requir pkginfo==1.10.0 # via twine platformdirs==4.2.2 # via jupyter-core, mkdocs-get-deps, pooch, xraydb, -r requirements.txt plotly==5.22.0 # via asr, pymatgen, -r requirements.txt -pluggy==0.13.1 # via pytest +pluggy==1.5.0 # via pytest ply==3.11 # via pycifrw, -r requirements.txt pooch==1.8.1 # via kikuchipy, orix, -r requirements.txt prettytable==3.10.0 # via hyperspy, -r requirements.txt prometheus-client==0.20.0 # via jupyter-server, jupyterhub, -r requirements.txt -prompt-toolkit==3.0.43 # via click-repl, ipython, jupyter-console, -r requirements.txt +prompt-toolkit==3.0.45 # via click-repl, ipython, jupyter-console, -r requirements.txt psutil==5.9.8 # via diffsims, ipykernel, ipyparallel, pyxem, -r requirements.txt ptyprocess==0.7.0 # via pexpect, terminado, -r requirements.txt pure-eval==0.2.2 # via stack-data, -r requirements.txt -py==1.11.0 # via pytest, pytest-forked py-cpuinfo==9.0.0 # via blosc2, tables, -r requirements.txt pyasn1==0.6.0 # via pyasn1-modules, rfc3161ng, -r requirements.txt pyasn1-modules==0.4.0 # via rfc3161ng, -r requirements.txt @@ -276,11 +276,10 @@ pyopenssl==24.1.0 # via certipy, -r requirements.txt pyparsing==3.1.2 # via matplotlib, rdflib, -r requirements.txt pyproject-hooks==1.1.0 # via build pyrsistent==0.20.0 # via jsonschema, -r requirements.txt -pytest==5.4.3 # via pytest-cov, pytest-forked, pytest-timeout, pytest-xdist, nomad-lab (pyproject.toml) -pytest-cov==2.7.1 # via nomad-lab (pyproject.toml) -pytest-forked==1.6.0 # via pytest-xdist -pytest-timeout==1.4.2 # via nomad-lab (pyproject.toml) -pytest-xdist==1.34.0 # via nomad-lab (pyproject.toml) +pytest==7.4.4 # via pytest-cov, pytest-timeout, pytest-xdist, nomad-lab (pyproject.toml) +pytest-cov==5.0.0 # via nomad-lab (pyproject.toml) +pytest-timeout==2.3.1 # via nomad-lab (pyproject.toml) +pytest-xdist==3.6.1 # via nomad-lab (pyproject.toml) python-box==6.1.0 # via rosettasciio, -r requirements.txt python-dateutil==2.9.0.post0 # via arrow, celery, elasticsearch-dsl, ghp-import, hyperspy, ipyparallel, jupyter-client, jupyterhub, matplotlib, mkdocs-macros-plugin, pandas, pybis, rfc3161ng, rosettasciio, -r requirements.txt python-dotenv==1.0.1 # via uvicorn, -r requirements.txt @@ -317,7 +316,7 @@ rope==0.21.0 # via nomad-lab (pyproject.toml) rosettasciio==0.4 # via pynxtools-em, -r requirements.txt ruamel-yaml==0.18.6 # via jupyter-telemetry, oauthenticator, pymatgen, -r requirements.txt, nomad-lab (pyproject.toml) ruamel-yaml-clib==0.2.8 # via ruamel-yaml, -r requirements.txt -ruff==0.4.5 # via nomad-lab (pyproject.toml) +ruff==0.4.6 # via nomad-lab (pyproject.toml) runstats==2.0.0 # via -r requirements.txt, nomad-lab (pyproject.toml) scikit-image==0.19.3 # via hyperspy, kikuchipy, pyxem, -r requirements.txt scikit-learn==1.5.0 # via kikuchipy, matid, pyxem, -r requirements.txt, nomad-lab (pyproject.toml) @@ -327,7 +326,7 @@ send2trash==1.8.3 # via jupyter-server, -r requirements.txt sentinels==1.0.0 # via mongomock, -r requirements.txt setuptools==70.0.0 # via radioactivedecay, -r requirements.txt silx==2.1.0 # via pyfai, -r requirements.txt -six==1.16.0 # via anytree, asttokens, basicauth, bleach, diffpy-structure, elasticsearch-dsl, html5lib, isodate, pybtex, pytest-xdist, python-dateutil, rdflib, rfc3339-validator, validators, -r requirements.txt +six==1.16.0 # via anytree, asttokens, basicauth, bleach, diffpy-structure, elasticsearch-dsl, html5lib, isodate, pybtex, python-dateutil, rdflib, rfc3339-validator, validators, -r requirements.txt smmap==5.0.1 # via gitdb, -r requirements.txt sniffio==1.3.1 # via anyio, httpx, -r requirements.txt snowballstemmer==2.2.0 # via sphinx, -r requirements.txt @@ -344,8 +343,8 @@ sphinxcontrib-serializinghtml==1.1.10 # via sphinx, -r requirements.txt sqlalchemy==2.0.30 # via alembic, jupyterhub, xraydb, -r requirements.txt stack-data==0.6.3 # via ipython, -r requirements.txt starlette==0.27.0 # via fastapi, -r requirements.txt -structlog==24.1.0 # via -r requirements.txt, nomad-lab (pyproject.toml) -sympy==1.12 # via findiff, hyperspy, pymatgen, radioactivedecay, -r requirements.txt +structlog==24.2.0 # via -r requirements.txt, nomad-lab (pyproject.toml) +sympy==1.12.1 # via findiff, hyperspy, pymatgen, radioactivedecay, -r requirements.txt tables==3.9.2 # via ifes-apt-tc-data-modeling, -r requirements.txt tabulate==0.8.9 # via pybis, pymatgen, -r requirements.txt, nomad-lab (pyproject.toml) tenacity==8.3.0 # via plotly, -r requirements.txt @@ -355,7 +354,7 @@ texttable==1.7.0 # via pybis, -r requirements.txt threadpoolctl==3.5.0 # via mdanalysis, scikit-learn, -r requirements.txt tifffile==2024.5.22 # via h5grove, hyperspy, scikit-image, -r requirements.txt tinycss2==1.3.0 # via nbconvert, -r requirements.txt -tomli==2.0.1 # via build, jupyterlab, mypy, sphinx, -r requirements.txt +tomli==2.0.1 # via build, coverage, jupyterlab, mypy, pytest, sphinx, -r requirements.txt toolz==0.12.1 # via dask, hyperspy, partd, -r requirements.txt toposort==1.10 # via -r requirements.txt, nomad-lab (pyproject.toml) tornado==6.4 # via ipykernel, ipyparallel, jupyter-client, jupyter-server, jupyterhub, jupyterlab, notebook, terminado, -r requirements.txt @@ -374,20 +373,20 @@ uncertainties==3.1.7 # via lmfit, pymatgen, -r requirements.txt unidecode==1.3.2 # via -r requirements.txt, nomad-lab (pyproject.toml) uri-template==1.3.0 # via jsonschema, -r requirements.txt urllib3==1.26.18 # via docker, elasticsearch, pybis, requests, -r requirements.txt -uv==0.2.4 # via nomad-lab (pyproject.toml) -uvicorn==0.29.0 # via h5grove, -r requirements.txt, nomad-lab (pyproject.toml) +uv==0.2.5 # via nomad-lab (pyproject.toml) +uvicorn==0.30.0 # via h5grove, -r requirements.txt, nomad-lab (pyproject.toml) uvloop==0.19.0 # via uvicorn, -r requirements.txt validators==0.18.2 # via -r requirements.txt, nomad-lab (pyproject.toml) vine==5.1.0 # via amqp, celery, kombu, -r requirements.txt watchdog==4.0.1 # via mkdocs watchfiles==0.22.0 # via uvicorn, -r requirements.txt -wcwidth==0.2.13 # via prettytable, prompt-toolkit, pytest, -r requirements.txt +wcwidth==0.2.13 # via prettytable, prompt-toolkit, -r requirements.txt webcolors==1.13 # via jsonschema, -r requirements.txt webencodings==0.5.1 # via bleach, html5lib, tinycss2, -r requirements.txt websocket-client==1.8.0 # via jupyter-server, -r requirements.txt websockets==12.0 # via uvicorn, -r requirements.txt werkzeug==3.0.3 # via flask, -r requirements.txt -widgetsnbextension==4.0.10 # via ipywidgets, -r requirements.txt +widgetsnbextension==4.0.11 # via ipywidgets, -r requirements.txt wrapt==1.16.0 # via -r requirements.txt, nomad-lab (pyproject.toml) xarray==2023.12.0 # via pynxtools, pynxtools-mpes, pynxtools-xps, -r requirements.txt, nomad-lab (pyproject.toml) xmltodict==0.13.0 # via ifes-apt-tc-data-modeling, pynxtools-em, -r requirements.txt diff --git a/requirements.txt b/requirements.txt index edf2fa30f00b713925909bb0aae0a044c15861a7..30decbfbf9e0b77ca01b40fd906026b41e43d452 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ # This file was autogenerated by uv via the following command: -# uv pip compile --annotation-style=line --extra=infrastructure --extra=parsing --output-file=requirements.txt dependencies/nomad-dos-fingerprints/pyproject.toml dependencies/parsers/eelsdb/pyproject.toml pyproject.toml +# uv pip compile -p 3.9 --annotation-style=line --extra=infrastructure --extra=parsing --output-file=requirements.txt dependencies/nomad-dos-fingerprints/pyproject.toml dependencies/parsers/eelsdb/pyproject.toml pyproject.toml alabaster==0.7.16 # via sphinx alembic==1.13.1 # via jupyterhub amqp==5.2.0 # via kombu @@ -76,7 +76,7 @@ filelock==3.3.1 # via nomad-lab (pyproject.toml) findiff==0.10.0 # via pynxtools-stm flask==3.0.3 # via asr flatdict==4.0.1 # via ifes-apt-tc-data-modeling, pynxtools-em -fonttools==4.52.1 # via matplotlib +fonttools==4.52.4 # via matplotlib fqdn==1.5.1 # via jsonschema fsspec==2024.5.0 # via dask, hyperspy future==1.0.0 # via uncertainties @@ -84,7 +84,7 @@ gitdb==4.0.11 # via gitpython gitpython==3.1.43 # via nomad-lab (pyproject.toml) greenlet==3.0.3 # via sqlalchemy griddataformats==1.0.2 # via mdanalysis -gsd==3.2.1 # via mdanalysis +gsd==3.3.0 # via mdanalysis gunicorn==21.2.0 # via nomad-lab (pyproject.toml) h11==0.14.0 # via httpcore, uvicorn h5grove==1.3.0 # via jupyterlab-h5web, nomad-lab (pyproject.toml) @@ -107,7 +107,7 @@ inflection==0.5.1 # via nomad-lab (pyproject.toml) ipykernel==6.29.4 # via ipyparallel, jupyter, jupyter-console, jupyterlab, qtconsole ipyparallel==8.8.0 # via hyperspy ipython==8.18.1 # via hyperspy, ipykernel, ipyparallel, ipywidgets, jupyter-console, pynxtools-xrd -ipywidgets==8.1.2 # via jupyter +ipywidgets==8.1.3 # via jupyter isodate==0.6.1 # via rdflib isoduration==20.11.0 # via jsonschema itsdangerous==2.2.0 # via flask, nomad-lab (pyproject.toml) @@ -132,7 +132,7 @@ jupyterlab==4.1.6 # via ifes-apt-tc-data-modeling, notebook jupyterlab-h5web==11.1.0 # via ifes-apt-tc-data-modeling jupyterlab-pygments==0.3.0 # via nbconvert jupyterlab-server==2.24.0 # via jupyterlab, notebook -jupyterlab-widgets==3.0.10 # via ipywidgets +jupyterlab-widgets==3.0.11 # via ipywidgets jwcrypto==1.5.6 # via python-keycloak kikuchipy==0.9.0 # via pynxtools-em kiwisolver==1.4.5 # via matplotlib @@ -185,7 +185,7 @@ numpy==1.22.4 # via ase, biopython, blosc2, cftime, contourpy, dask, numpy-quaternion==2023.0.3 # via orix oauthenticator==15.1.0 # via nomad-lab (pyproject.toml) oauthlib==3.2.2 # via jupyterhub -openpyxl==3.1.2 # via nomad-lab (pyproject.toml) +openpyxl==3.1.3 # via nomad-lab (pyproject.toml) optimade==0.22.1 # via nomad-lab (pyproject.toml) orix==0.12.1.post0 # via diffsims, kikuchipy, pyxem orjson==3.10.3 # via h5grove, nomad-lab (pyproject.toml) @@ -208,7 +208,7 @@ ply==3.11 # via pycifrw pooch==1.8.1 # via kikuchipy, orix prettytable==3.10.0 # via hyperspy prometheus-client==0.20.0 # via jupyter-server, jupyterhub -prompt-toolkit==3.0.43 # via click-repl, ipython, jupyter-console +prompt-toolkit==3.0.45 # via click-repl, ipython, jupyter-console psutil==5.9.8 # via diffsims, ipykernel, ipyparallel, pyxem ptyprocess==0.7.0 # via pexpect, terminado pure-eval==0.2.2 # via stack-data @@ -258,7 +258,7 @@ radioactivedecay==0.5.0 # via ifes-apt-tc-data-modeling rdflib==5.0.0 # via nomad-lab (pyproject.toml) rdkit==2023.9.5 # via nomad-lab (pyproject.toml) recommonmark==0.7.1 # via nomad-lab (pyproject.toml) -requests==2.32.2 # via docker, hyperspy, jupyterhub, jupyterlab-server, oauthenticator, optimade, pooch, pybis, pymatgen, python-keycloak, requests-toolbelt, rfc3161ng, sphinx, eelsdbconverter (dependencies/parsers/eelsdb/pyproject.toml), nomad-lab (pyproject.toml) +requests==2.31.0 # via docker, hyperspy, jupyterhub, jupyterlab-server, oauthenticator, optimade, pooch, pybis, pymatgen, python-keycloak, requests-toolbelt, rfc3161ng, sphinx, eelsdbconverter (dependencies/parsers/eelsdb/pyproject.toml), nomad-lab (pyproject.toml) requests-toolbelt==1.0.0 # via python-keycloak rfc3161ng==2.1.3 # via nomad-lab (pyproject.toml) rfc3339-validator==0.1.4 # via jsonschema @@ -292,8 +292,8 @@ sphinxcontrib-serializinghtml==1.1.10 # via sphinx sqlalchemy==2.0.30 # via alembic, jupyterhub, xraydb stack-data==0.6.3 # via ipython starlette==0.27.0 # via fastapi -structlog==24.1.0 # via nomad-lab (pyproject.toml) -sympy==1.12 # via findiff, hyperspy, pymatgen, radioactivedecay +structlog==24.2.0 # via nomad-lab (pyproject.toml) +sympy==1.12.1 # via findiff, hyperspy, pymatgen, radioactivedecay tables==3.9.2 # via ifes-apt-tc-data-modeling tabulate==0.8.9 # via pybis, pymatgen, nomad-lab (pyproject.toml) tenacity==8.3.0 # via plotly @@ -319,7 +319,7 @@ uncertainties==3.1.7 # via lmfit, pymatgen unidecode==1.3.2 # via nomad-lab (pyproject.toml) uri-template==1.3.0 # via jsonschema urllib3==1.26.18 # via docker, elasticsearch, pybis, requests -uvicorn==0.29.0 # via h5grove, nomad-lab (pyproject.toml) +uvicorn==0.30.0 # via h5grove, nomad-lab (pyproject.toml) uvloop==0.19.0 # via uvicorn validators==0.18.2 # via nomad-lab (pyproject.toml) vine==5.1.0 # via amqp, celery, kombu @@ -330,7 +330,7 @@ webencodings==0.5.1 # via bleach, html5lib, tinycss2 websocket-client==1.8.0 # via jupyter-server websockets==12.0 # via uvicorn werkzeug==3.0.3 # via flask -widgetsnbextension==4.0.10 # via ipywidgets +widgetsnbextension==4.0.11 # via ipywidgets wrapt==1.16.0 # via nomad-lab (pyproject.toml) xarray==2023.12.0 # via pynxtools, pynxtools-mpes, pynxtools-xps, nomad-lab (pyproject.toml) xmltodict==0.13.0 # via ifes-apt-tc-data-modeling, pynxtools-em diff --git a/scripts/generate_python_dependencies.sh b/scripts/generate_python_dependencies.sh index 02890282fd762c6f6c305a2a7ce0e90f8cdf48a2..a08c88fdb9e7eb849a84b967a896a7fb1b382c75 100755 --- a/scripts/generate_python_dependencies.sh +++ b/scripts/generate_python_dependencies.sh @@ -15,14 +15,14 @@ project_dir=$(dirname $(dirname $(realpath $0))) cd $project_dir -uv pip compile -U --annotation-style=line \ +uv pip compile -U -p 3.9 --annotation-style=line \ --extra=infrastructure --extra=parsing \ --output-file=requirements.txt \ dependencies/nomad-dos-fingerprints/pyproject.toml \ dependencies/parsers/eelsdb/pyproject.toml \ pyproject.toml -uv pip compile -U --annotation-style=line \ +uv pip compile -U -p 3.9 --annotation-style=line \ --extra=dev --extra=infrastructure --extra=parsing \ --output-file=requirements-dev.txt \ requirements.txt \ diff --git a/tests/conftest.py b/tests/conftest.py index 5c6579ce029f814a57bb95c00d393804548f20d7..97b280296e0c35c8839283b9ab5daeb32f38c411 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -70,6 +70,31 @@ pytest_plugins = ( ) +from structlog.testing import LogCapture +import structlog + + +@pytest.fixture(scope='function') +def log_output(): + cap = LogCapture() + # Modify `_Configuration.default_processors` set via `configure` but always + # keep the list instance intact to not break references held by bound + # loggers. + processors = structlog.get_config()['processors'] + old_processors = processors.copy() + try: + # clear processors list and use LogCapture for testing + processors.clear() + processors.append(cap) + structlog.configure(processors=processors) + yield cap + finally: + # remove LogCapture and restore original processors + processors.clear() + processors.extend(old_processors) + structlog.configure(processors=processors) + + def pytest_addoption(parser): help = 'Set this < 1.0 to speed up worker cleanup. May leave tasks running.' parser.addoption('--celery-inspect-timeout', type=float, default=1.0, help=help) @@ -141,35 +166,30 @@ def nomad_logging(monkeysession): @pytest.fixture(scope='function') -def no_warn(caplog): - caplog.handler.formatter = structlogging.ConsoleFormatter() - yield caplog - for record in caplog.get_records(when='call'): - if record.levelname in ['WARNING', 'ERROR', 'CRITICAL']: - try: - msg = structlogging.ConsoleFormatter.serialize(json.loads(record.msg)) - except Exception: - msg = record.msg - assert False, msg +def no_warn(log_output): + yield log_output + for record in log_output.entries: + if record['log_level'] in ['error', 'critical', 'warning']: + assert False, record @pytest.fixture(scope='function') -def with_error(caplog): - yield caplog +def with_error(log_output): + yield log_output count = 0 - for record in caplog.get_records(when='call'): - if record.levelname in ['ERROR', 'CRITICAL']: + for record in log_output.entries: + if record['log_level'] in ['error', 'critical']: count += 1 assert count > 0 @pytest.fixture(scope='function') -def with_warn(caplog): - yield caplog +def with_warn(log_output): + yield log_output count = 0 - for record in caplog.get_records(when='call'): - if record.levelname in ['WARNING']: + for record in log_output.entries: + if record['log_level'] in ['warning']: count += 1 assert count > 0 diff --git a/tests/datamodel/test_schema.py b/tests/datamodel/test_schema.py index 4cffe1ec40eef917373d8b8149a87de86d960ac1..e8710fe3e0431df304df9456ec8593f937135ae5 100644 --- a/tests/datamodel/test_schema.py +++ b/tests/datamodel/test_schema.py @@ -55,7 +55,7 @@ def test_schema_processing(raw_files_function, no_warn): assert test_archive.metadata.entry_type == 'Schema' -def test_eln_annotation_validation_parsing(raw_files_function, caplog): +def test_eln_annotation_validation_parsing(raw_files_function, log_output): mainfile = os.path.join( os.path.dirname(__file__), '../data/datamodel/eln.archive.yaml' ) @@ -67,8 +67,8 @@ def test_eln_annotation_validation_parsing(raw_files_function, caplog): parser.parse(mainfile, test_archive, get_logger(__name__)) has_error = False - for record in caplog.get_records(when='call'): - if record.levelname == 'ERROR': + for record in log_output.entries: + if record['log_level'] == 'error': has_error = True assert has_error diff --git a/tests/fixtures/group_uploads.py b/tests/fixtures/group_uploads.py index 9d0e7d3734ab02b5dc3d38497fd8dde4f39e9eb5..9b03ae9e69db4eab8df5d639c96cb4cd848a252c 100644 --- a/tests/fixtures/group_uploads.py +++ b/tests/fixtures/group_uploads.py @@ -16,7 +16,7 @@ import pytest from nomad.utils.exampledata import ExampleData -@pytest.fixture('session') +@pytest.fixture(scope='session') def group_upload_molds( convert_user_labels_to_ids, convert_group_labels_to_ids, user1, user2 ): @@ -59,7 +59,7 @@ def group_upload_molds( return molds -@pytest.fixture('session') +@pytest.fixture(scope='session') def create_group_uploads_from_molds(group_upload_molds): """Returned function creates and returns uploads with given labels. diff --git a/tests/metainfo/test_metainfo.py b/tests/metainfo/test_metainfo.py index 565c46944116f5de058ef429d4705f6f8bbd2e05..a4f780ed1d234246ed16a2a43b55cbb8ca91db49 100644 --- a/tests/metainfo/test_metainfo.py +++ b/tests/metainfo/test_metainfo.py @@ -848,7 +848,7 @@ class TestM1: section.f32 = -200 section.f64 = -200 - def test_np_allow_wrong_shape(self, caplog): + def test_np_allow_wrong_shape(self, log_output): class MyContext(Context): def warning(self, event, **kwargs): utils.get_logger(__name__).warn(event, **kwargs) @@ -856,7 +856,7 @@ class TestM1: scc = SCC(m_context=MyContext()) scc.energy_total_0 = np.array([1.0, 1.0, 1.0]) scc.m_to_dict() - test_utils.assert_log(caplog, 'WARNING', 'numpy quantity has wrong shape') + test_utils.assert_log(log_output, 'WARNING', 'numpy quantity has wrong shape') def test_copy(self): run = Run() diff --git a/tests/parsing/test_parsing.py b/tests/parsing/test_parsing.py index db25370daac7be412687ffbb1d391bf45d5e5302..3f339d622377d9f58597844da57f3698f2a9bcf6 100644 --- a/tests/parsing/test_parsing.py +++ b/tests/parsing/test_parsing.py @@ -112,16 +112,16 @@ def create_reference(data, pretty): @pytest.fixture(scope='function') -def assert_parser_result(caplog): +def assert_parser_result(log_output): def _assert( entry_archive: EntryArchive, has_errors: bool = False, has_warnings: bool = None ): errors_exist = False warnings_exist = False - for record in caplog.get_records(when='call'): - if record.levelname in ['ERROR', 'CRITICAL']: + for record in log_output.entries: + if record['log_level'] in ['error', 'critical']: errors_exist = True - if record.levelname in ['WARNING']: + if record['log_level'] in ['warning']: warnings_exist = True assert has_errors == errors_exist if has_warnings is not None: diff --git a/tests/processing/test_base.py b/tests/processing/test_base.py index 664845942043ea7ae64cac96e2d59a5bfc1d5cac..03d8c6bb1bbd80aadf471c073422c32df57917c8 100644 --- a/tests/processing/test_base.py +++ b/tests/processing/test_base.py @@ -138,10 +138,10 @@ def test_failing_process(worker, mongo_function, with_error): assert_proc(p, process, ProcessStatus.FAILURE, errors=1) has_log = False - for record in with_error.get_records(when='call'): - if record.levelname == 'ERROR': + for record in with_error.entries: + if record['log_level'] == 'error': has_log = True - assert json.loads(record.msg)['event'] == event + assert record['event'] == event assert has_log diff --git a/tests/test_config.py b/tests/test_config.py index e6103fc7b63b1f2baeed93993d4764214bcda197..8938afe3b0624849a2cf2316499174a808201172 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -111,12 +111,20 @@ def test_config_success(config_dict, format, mockopen, monkeypatch): ) @pytest.mark.parametrize('format', ['yaml', 'env']) def test_config_warning( - config_dict, format, warning, formats_with_warning, caplog, mockopen, monkeypatch + config_dict, + format, + warning, + formats_with_warning, + log_output, + mockopen, + monkeypatch, ): """Tests that extra fields create a warning message.""" conf_yaml, conf_env = load_format(config_dict, format) load_test_config(conf_yaml, conf_env, mockopen, monkeypatch) - assert_log(caplog, 'WARNING', warning, negate=format not in formats_with_warning) + assert_log( + log_output, 'WARNING', warning, negate=format not in formats_with_warning + ) @pytest.mark.parametrize( diff --git a/tests/test_utils.py b/tests/test_utils.py index 9d14b43ae5b7eb9d2696506c4fa094f5103bb80f..91ca1f2c6aca9cbef408007c0045507c052f8d23 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -43,11 +43,11 @@ def test_decode_handle_id(): utils.decode_handle_id('zz') -def test_timer(caplog): +def test_timer(log_output): with utils.timer(utils.get_logger('test_logger'), 'test measure'): time.sleep(0.1) - assert json.loads(caplog.record_tuples[0][2])['event'] == 'test measure' + assert log_output.entries[0]['event'] == 'test measure' def test_sleep_timer(): @@ -75,11 +75,10 @@ def test_logging(no_warn): utils.get_logger(__name__).info('test msg') received_test_event = False - for record in no_warn.get_records(when='call'): - assert record.levelname == 'INFO' - data = json.loads(record.msg) - assert 'event' in data - assert data['event'] == 'test msg' + for record in no_warn.entries: + assert record['log_level'] == 'info' + assert 'event' in record + assert record['event'] == 'test msg' received_test_event = True assert received_test_event diff --git a/tests/utils.py b/tests/utils.py index 4a4b347d90980bd79452c3612eb1a0ec4557a4e9..4ae5c223df4abd17cb377c0825046a1012656c49 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -24,17 +24,19 @@ import urllib.parse import zipfile from logging import LogRecord from typing import Any, Dict, List, Union - +from structlog import get_logger import pytest -def assert_log(caplog, level: str, event_part: str, negate: bool = False) -> LogRecord: +def assert_log( + log_output, level: str, event_part: str, negate: bool = False +) -> LogRecord: """ Assert whether a log message exists in the logs of the tests at a certain level. Parameters ---------- - caplog : pytest fixture + log_output : pytest fixture This informs pytest that we want to access the logs from a pytest test. level : str The level of type of log for which we will search (e.g. 'WARN', @@ -45,14 +47,9 @@ def assert_log(caplog, level: str, event_part: str, negate: bool = False) -> Log negate: Instead asserting that the log exist, assert that it does not exist. """ match = None - for record in caplog.get_records(when='call'): - if record.levelname == level: - try: - event_data = json.loads(record.msg) - present = event_part in event_data['event'] - except Exception: - present = event_part in record.msg - + for record in log_output.entries: + if record['log_level'] == level.lower(): + present = event_part in record['event'] if present: match = record # No need to look for more matches since we aren't counting matches.