diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index bf9087a9bf..34b2f96837 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -3,7 +3,7 @@ default_language_version: exclude: ^(.github/|tests/test_data/abinit/) repos: - repo: https://github.com/charliermarsh/ruff-pre-commit - rev: v0.4.4 + rev: v0.4.10 hooks: - id: ruff args: [--fix] @@ -38,7 +38,7 @@ repos: - tokenize-rt==4.1.0 - types-paramiko - repo: https://github.com/codespell-project/codespell - rev: v2.2.6 + rev: v2.3.0 hooks: - id: codespell stages: [commit, commit-msg] diff --git a/docs/dev/abinit_tests.md b/docs/dev/abinit_tests.md index b463d8e184..faa75a3904 100644 --- a/docs/dev/abinit_tests.md +++ b/docs/dev/abinit_tests.md @@ -17,7 +17,6 @@ be added to this pseudopotential table. Note that information from the real pseudopotential files is used in the creation of the jobs and flows, hence fake pseudopotentials are not an option here. - ### File sizes The files produced by ABINIT are generally large and would overwhelm the size of the @@ -121,7 +120,7 @@ atm dev abinit-test-data TEST_NAME You should change `TEST_NAME` to be a name for the workflow test. Note, `TEST_NAME` should not contain spaces or punctuation. For example, the band structure workflow test data was -genenerated using `atm dev vasp-test-data Si_band_structure`. +generated using `atm dev vasp-test-data Si_band_structure`. This will automatically detect whether the Maker is a Job Maker or a Flow Maker and copy files in the corresponding `tests/test_data/abinit/jobs/NameOfMaker/TEST_NAME` @@ -145,6 +144,7 @@ a unique name. For example, there cannot be two calculations called "relax". Instead you should ensure they are named something like "relax 1" and "relax 2". Each `REF_RUN_FOLDER` contains: + - A folder called "inputs" with the run.abi and abinit_input.json, as well as with the indata, outdata and tmpdata directories. The indata directory potentially contains the reference fake input files needed for the job to be executed (e.g. a fake link to a diff --git a/pyproject.toml b/pyproject.toml index 9de0f7a993..5b01695936 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -170,15 +170,14 @@ select = ["ALL"] ignore = [ "ANN002", "ANN003", - "ANN101", # missing self type annotation - "ANN102", + "ANN101", # missing self type annotation + "ANN102", # missing cls annotation "ANN401", - "ARG002", # unused method argument - "BLE001", + "ARG002", # unused method argument + # "BLE001", "C408", # Unnecessary (dict/list/tuple) call - remove call "C901", # function too complex "COM812", # trailing comma missing - "DTZ", # datetime-tz-now "EM", # exception message must not use f-string literal "ERA001", # found commented out code "FBT001", @@ -188,7 +187,11 @@ ignore = [ "ISC001", "PD011", # pandas-use-of-dot-values "PERF203", # try-except-in-loop - "PLR", # pylint-refactor + "PLR0911", # too many returns + "PLR0912", # too many branches + "PLR0913", # too many arguments + "PLR0915", # too many local statements + "PLR2004", "PT004", # pytest-missing-fixture-name-underscore "PT006", # pytest-parametrize-names-wrong-type "PT013", # pytest-incorrect-pytest-import @@ -196,7 +199,6 @@ ignore = [ "RUF013", # implicit-optional "S324", # use of insecure hash function "S507", # paramiko auto trust - "SLF", # private member accessed outside class "TD", # TODOs "TRY003", # long message outside exception class ] @@ -209,7 +211,7 @@ docstring-code-format = true [tool.ruff.lint.per-file-ignores] "__init__.py" = ["F401"] -"**/tests/*" = ["ANN", "ARG001", "D", "INP001", "S101"] +"**/tests/*" = ["ANN", "ARG001", "D", "INP001", "PLR2004", "S101"] # flake8-type-checking (TCH): things inside TYPE_CHECKING aren't available # at runtime and so can't be used by pydantic models # flake8-future-annotations (FA): pipe operator for type unions only work in pydantic models in python 3.10+ diff --git a/src/atomate2/abinit/run.py b/src/atomate2/abinit/run.py index 4cb5384d98..8137c57ba2 100644 --- a/src/atomate2/abinit/run.py +++ b/src/atomate2/abinit/run.py @@ -62,4 +62,3 @@ def run_abinit( process.terminate() process.wait() - return diff --git a/src/atomate2/abinit/schemas/calculation.py b/src/atomate2/abinit/schemas/calculation.py index 9e1a415100..15b8cff682 100644 --- a/src/atomate2/abinit/schemas/calculation.py +++ b/src/atomate2/abinit/schemas/calculation.py @@ -4,7 +4,7 @@ import logging import os -from datetime import datetime +from datetime import datetime, timezone from pathlib import Path from typing import Optional, Union @@ -236,7 +236,9 @@ def from_abinit_files( abinit_gsr = GsrFile.from_file(abinit_gsr_file) - completed_at = str(datetime.fromtimestamp(os.stat(abinit_log_file).st_mtime)) + completed_at = str( + datetime.fromtimestamp(os.stat(abinit_log_file).st_mtime, tz=timezone.utc) + ) output_doc = CalculationOutput.from_abinit_gsr(abinit_gsr) @@ -255,7 +257,7 @@ def from_abinit_files( if report.run_completed: has_abinit_completed = TaskState.SUCCESS - except Exception as exc: + except (ValueError, RuntimeError, Exception) as exc: msg = f"{cls} exception while parsing event_report:\n{exc}" logger.critical(msg) diff --git a/src/atomate2/abinit/sets/base.py b/src/atomate2/abinit/sets/base.py index 88f4512e9b..1092784bc6 100644 --- a/src/atomate2/abinit/sets/base.py +++ b/src/atomate2/abinit/sets/base.py @@ -356,7 +356,7 @@ def get_input_set( else: if prev_outputs is not None and not self.prev_outputs_deps: raise RuntimeError( - f"Previous outputs not allowed for {self.__class__.__name__}." + f"Previous outputs not allowed for {type(self).__name__}." ) abinit_input = self.get_abinit_input( structure=structure, @@ -573,7 +573,7 @@ def get_abinit_input( if self.factory_prev_inputs_kwargs: if not prev_outputs: raise RuntimeError( - f"No previous_outputs. Required for {self.__class__.__name__}." + f"No previous_outputs. Required for {type(self).__name__}." ) # TODO consider cases where structure might be defined even if @@ -588,18 +588,16 @@ def get_abinit_input( ) total_factory_kwargs.update(abinit_inputs) - else: - # TODO check if this should be removed or the check be improved - if structure is None: - msg = ( - f"Structure is mandatory for {self.__class__.__name__} " - f"generation since no previous output is used." - ) - raise RuntimeError(msg) + elif structure is None: + msg = ( + f"Structure is mandatory for {type(self).__name__} " + f"generation since no previous output is used." + ) + raise RuntimeError(msg) if not self.prev_outputs_deps and prev_outputs: msg = ( - f"Previous outputs not allowed for {self.__class__.__name__} " + f"Previous outputs not allowed for {type(self).__name__} " "Consider if restart_from argument of get_input_set method " "can fit your needs instead." ) diff --git a/src/atomate2/abinit/utils/common.py b/src/atomate2/abinit/utils/common.py index e21f0316c9..75593abc8a 100644 --- a/src/atomate2/abinit/utils/common.py +++ b/src/atomate2/abinit/utils/common.py @@ -425,7 +425,7 @@ def get_event_report(ofile: File, mpiabort_file: File) -> EventReport | None: report.append(last_abort_event) else: report.append(last_abort_event) - except Exception as exc: + except (ValueError, RuntimeError, Exception) as exc: # Return a report with an error entry with info on the exception. logger.critical(f"{ofile}: Exception while parsing ABINIT events:\n {exc!s}") return parser.report_exception(ofile.path, exc) diff --git a/src/atomate2/aims/jobs/convergence.py b/src/atomate2/aims/jobs/convergence.py index 09ea564da2..b29e4be1c9 100644 --- a/src/atomate2/aims/jobs/convergence.py +++ b/src/atomate2/aims/jobs/convergence.py @@ -97,7 +97,7 @@ def make( "convergence_field_values": [], "epsilon": self.epsilon, } - convergence_data.update({"idx": idx, "converged": converged}) + convergence_data.update(idx=idx, converged=converged) if prev_dir is not None: split_prev_dir = str(prev_dir).split(":")[-1] diff --git a/src/atomate2/aims/schemas/calculation.py b/src/atomate2/aims/schemas/calculation.py index de541b7526..9077f9798e 100644 --- a/src/atomate2/aims/schemas/calculation.py +++ b/src/atomate2/aims/schemas/calculation.py @@ -4,7 +4,7 @@ import os from collections.abc import Sequence -from datetime import datetime +from datetime import datetime, timezone from pathlib import Path from typing import TYPE_CHECKING, Any, Optional, Union @@ -291,7 +291,9 @@ def from_aims_files( volumetric_files = [] if volumetric_files is None else volumetric_files aims_output = AimsOutput.from_outfile(aims_output_file) - completed_at = str(datetime.fromtimestamp(os.stat(aims_output_file).st_mtime)) + completed_at = str( + datetime.fromtimestamp(os.stat(aims_output_file).st_mtime, tz=timezone.utc) + ) output_file_paths = _get_output_file_paths(volumetric_files) aims_objects: dict[AimsObject, Any] = _get_volumetric_data( diff --git a/src/atomate2/aims/utils/__init__.py b/src/atomate2/aims/utils/__init__.py index c59cdb9718..21d63e822e 100644 --- a/src/atomate2/aims/utils/__init__.py +++ b/src/atomate2/aims/utils/__init__.py @@ -1,6 +1,6 @@ """A collection of helper utils found in atomate2 package.""" -from datetime import datetime +from datetime import datetime, timezone def datetime_str() -> str: @@ -12,4 +12,4 @@ def datetime_str() -> str: str The current time. """ - return str(datetime.utcnow()) + return str(datetime.now(tz=timezone.utc)) diff --git a/src/atomate2/cli/dev.py b/src/atomate2/cli/dev.py index 47708856ce..7e80b5fa66 100644 --- a/src/atomate2/cli/dev.py +++ b/src/atomate2/cli/dev.py @@ -584,12 +584,12 @@ def test_run_{test_name}(self, mock_abinit, abinit_test_dir, clean_dir): def save_abinit_maker(maker: Maker) -> None: """Save maker, the script used to create it and additional metadata.""" - import datetime import inspect import json import shutil import subprocess import warnings + from datetime import datetime, timezone caller_frame = inspect.stack()[1] caller_filename_full = caller_frame.filename @@ -632,7 +632,7 @@ def save_abinit_maker(maker: Maker) -> None: { "author": author, "author_mail": author_mail, - "created_on": str(datetime.datetime.now()), + "created_on": str(datetime.now(tz=timezone.utc)), "maker": jsanitize(maker.as_dict()), "script": script_str, }, diff --git a/src/atomate2/common/builders/magnetism.py b/src/atomate2/common/builders/magnetism.py index 6ce1e5c305..242f10b65b 100644 --- a/src/atomate2/common/builders/magnetism.py +++ b/src/atomate2/common/builders/magnetism.py @@ -88,11 +88,7 @@ def get_items(self) -> Iterator[list[dict]]: self.ensure_indexes() criteria = dict(self.query) - criteria.update( - { - "metadata.ordering": {"$exists": True}, - } - ) + criteria.update({"metadata.ordering": {"$exists": True}}) self.logger.info("Grouping by formula...") num_formulas = len( self.tasks.distinct("output.formula_pretty", criteria=criteria) diff --git a/src/atomate2/common/jobs/eos.py b/src/atomate2/common/jobs/eos.py index 4e7acf644f..7c5886cbc6 100644 --- a/src/atomate2/common/jobs/eos.py +++ b/src/atomate2/common/jobs/eos.py @@ -90,8 +90,7 @@ def fit(self, eos_flow_output: dict[str, Any]) -> None: for job_type in self._use_job_types ): raise ValueError( - f"{self.__class__} requires {self.min_data_points} " - "frames to fit an EOS." + f"{type(self)} requires {self.min_data_points} frames to fit an EOS." ) self.sort_by_quantity() diff --git a/src/atomate2/common/schemas/phonons.py b/src/atomate2/common/schemas/phonons.py index 0637c26b04..a594afa623 100644 --- a/src/atomate2/common/schemas/phonons.py +++ b/src/atomate2/common/schemas/phonons.py @@ -448,7 +448,7 @@ def from_forces_born( phonon.thermal_displacement_matrices.write_cif( phonon.primitive, idx, filename=f"tdispmat_{temp}K.cif" ) - _disp_mat = phonon._thermal_displacement_matrices + _disp_mat = phonon._thermal_displacement_matrices # noqa: SLF001 tdisp_mat = _disp_mat.thermal_displacement_matrices.tolist() tdisp_mat_cif = _disp_mat.thermal_displacement_matrices_cif.tolist() @@ -537,7 +537,9 @@ def get_kpath( kpath = high_symm_kpath.kpath elif kpath_scheme == "seekpath": high_symm_kpath = KPathSeek(structure, symprec=symprec, **kpath_kwargs) - kpath = high_symm_kpath._kpath + kpath = high_symm_kpath._kpath # noqa: SLF001 + else: + raise ValueError(f"Unexpected {kpath_scheme=}") path = copy.deepcopy(kpath["path"]) diff --git a/src/atomate2/cp2k/schemas/calculation.py b/src/atomate2/cp2k/schemas/calculation.py index 69d44731df..c9a1214ad6 100644 --- a/src/atomate2/cp2k/schemas/calculation.py +++ b/src/atomate2/cp2k/schemas/calculation.py @@ -2,7 +2,7 @@ import logging import os -from datetime import datetime +from datetime import datetime, timezone from pathlib import Path from shutil import which from typing import Any, Optional, Union @@ -364,7 +364,9 @@ def from_cp2k_files( volumetric_files = [] if volumetric_files is None else volumetric_files cp2k_output = Cp2kOutput(cp2k_output_file, auto_load=True) - completed_at = str(datetime.fromtimestamp(os.stat(cp2k_output_file).st_mtime)) + completed_at = str( + datetime.fromtimestamp(os.stat(cp2k_output_file).st_mtime, tz=timezone.utc) + ) output_file_paths = _get_output_file_paths(volumetric_files) cp2k_objects: dict[Cp2kObject, Any] = _get_volumetric_data( diff --git a/src/atomate2/cp2k/sets/base.py b/src/atomate2/cp2k/sets/base.py index eafc50bd5c..203af8047a 100644 --- a/src/atomate2/cp2k/sets/base.py +++ b/src/atomate2/cp2k/sets/base.py @@ -388,37 +388,37 @@ def _get_kpoints( # use user setting if set otherwise default to base config settings if self.user_kpoints_settings != {}: - kconfig = deepcopy(self.user_kpoints_settings) + kpt_config = deepcopy(self.user_kpoints_settings) else: # apply updates to k-points config - kconfig = deepcopy(self.config_dict.get("KPOINTS", {})) - kconfig.update(kpoints_updates) + kpt_config = deepcopy(self.config_dict.get("KPOINTS", {})) + kpt_config.update(kpoints_updates) - if isinstance(kconfig, Kpoints): - return kconfig + if isinstance(kpt_config, Kpoints): + return kpt_config explicit = ( - kconfig.get("explicit") - or len(kconfig.get("added_kpoints", [])) > 0 - or "zero_weighted_reciprocal_density" in kconfig - or "zero_weighted_line_density" in kconfig + kpt_config.get("explicit") + or len(kpt_config.get("added_kpoints", [])) > 0 + or "zero_weighted_reciprocal_density" in kpt_config + or "zero_weighted_line_density" in kpt_config ) # handle length generation first as this doesn't support any additional options - if kconfig.get("length"): + if kpt_config.get("length"): if explicit: raise ValueError( "length option cannot be used with explicit k-point generation, " "added_kpoints, or zero weighted k-points." ) # If length is in kpoints settings use Kpoints.automatic - return Kpoints.automatic(kconfig["length"]) + return Kpoints.automatic(kpt_config["length"]) base_kpoints = None - if kconfig.get("line_density"): + if kpt_config.get("line_density"): # handle line density generation - kpath = HighSymmKpath(structure, **kconfig.get("kpath_kwargs", {})) + kpath = HighSymmKpath(structure, **kpt_config.get("kpath_kwargs", {})) frac_k_points, k_points_labels = kpath.get_kpoints( - line_density=kconfig["line_density"], coords_are_cartesian=False + line_density=kpt_config["line_density"], coords_are_cartesian=False ) base_kpoints = Kpoints( comment="Non SCF run along symmetry lines", @@ -428,15 +428,15 @@ def _get_kpoints( labels=k_points_labels, kpts_weights=[1] * len(frac_k_points), ) - elif kconfig.get("grid_density") or kconfig.get("reciprocal_density"): + elif kpt_config.get("grid_density") or kpt_config.get("reciprocal_density"): # handle regular weighted k-point grid generation - if kconfig.get("grid_density"): + if kpt_config.get("grid_density"): base_kpoints = Kpoints.automatic_density( - structure, int(kconfig["grid_density"]), self.force_gamma + structure, int(kpt_config["grid_density"]), self.force_gamma ) - if kconfig.get("reciprocal_density"): + if kpt_config.get("reciprocal_density"): base_kpoints = Kpoints.automatic_density_by_vol( - structure, kconfig["reciprocal_density"], self.force_gamma + structure, kpt_config["reciprocal_density"], self.force_gamma ) if explicit: sga = SpacegroupAnalyzer(structure, symprec=self.symprec) @@ -454,11 +454,11 @@ def _get_kpoints( return base_kpoints zero_weighted_kpoints = None - if kconfig.get("zero_weighted_line_density"): + if kpt_config.get("zero_weighted_line_density"): # zero_weighted k-points along line mode path kpath = HighSymmKpath(structure) frac_k_points, k_points_labels = kpath.get_kpoints( - line_density=kconfig["zero_weighted_line_density"], + line_density=kpt_config["zero_weighted_line_density"], coords_are_cartesian=False, ) zero_weighted_kpoints = Kpoints( @@ -469,9 +469,11 @@ def _get_kpoints( labels=k_points_labels, kpts_weights=[0] * len(frac_k_points), ) - elif kconfig.get("zero_weighted_reciprocal_density"): + elif kpt_config.get("zero_weighted_reciprocal_density"): zero_weighted_kpoints = Kpoints.automatic_density_by_vol( - structure, kconfig["zero_weighted_reciprocal_density"], self.force_gamma + structure, + kpt_config["zero_weighted_reciprocal_density"], + self.force_gamma, ) sga = SpacegroupAnalyzer(structure, symprec=self.symprec) mesh = sga.get_ir_reciprocal_mesh(zero_weighted_kpoints.kpts[0]) @@ -484,14 +486,14 @@ def _get_kpoints( ) added_kpoints = None - if kconfig.get("added_kpoints"): + if kpt_config.get("added_kpoints"): added_kpoints = Kpoints( comment="Specified k-points only", style=Kpoints.supported_modes.Reciprocal, - num_kpts=len(kconfig.get("added_kpoints")), - kpts=kconfig.get("added_kpoints"), - labels=["user-defined"] * len(kconfig.get("added_kpoints")), - kpts_weights=[0] * len(kconfig.get("added_kpoints")), + num_kpts=len(kpt_config.get("added_kpoints")), + kpts=kpt_config.get("added_kpoints"), + labels=["user-defined"] * len(kpt_config.get("added_kpoints")), + kpts_weights=[0] * len(kpt_config.get("added_kpoints")), ) if base_kpoints and not (added_kpoints or zero_weighted_kpoints): @@ -500,7 +502,7 @@ def _get_kpoints( return added_kpoints # do some sanity checking - if "line_density" in kconfig and zero_weighted_kpoints: + if "line_density" in kpt_config and zero_weighted_kpoints: raise ValueError( "Cannot combined line_density and zero weighted k-points options" ) diff --git a/src/atomate2/utils/datetime.py b/src/atomate2/utils/datetime.py index 61ae600577..cdb9977d4a 100644 --- a/src/atomate2/utils/datetime.py +++ b/src/atomate2/utils/datetime.py @@ -2,7 +2,7 @@ from __future__ import annotations -from datetime import datetime +from datetime import datetime, timezone def datetime_str() -> str: @@ -14,4 +14,4 @@ def datetime_str() -> str: str The current time. """ - return str(datetime.utcnow()) + return str(datetime.now(tz=timezone.utc)) diff --git a/src/atomate2/vasp/jobs/defect.py b/src/atomate2/vasp/jobs/defect.py index d4e0eb1fe6..33b00aff45 100644 --- a/src/atomate2/vasp/jobs/defect.py +++ b/src/atomate2/vasp/jobs/defect.py @@ -57,7 +57,7 @@ def calculate_finite_diff( # Update the INCAR for the WSWQ calculation incar = Incar.from_file("INCAR") - incar.update({"ALGO": "None", "NSW": 0, "LWAVE": False, "LWSWQ": True}) + incar.update(ALGO="None", NSW=0, LWAVE=False, LWSWQ=True) incar.write_file("INCAR") d_dir_names = [strip_hostname(d) for d in distorted_calc_dirs] diff --git a/src/atomate2/vasp/jobs/lobster.py b/src/atomate2/vasp/jobs/lobster.py index 8e0f723b30..3061742104 100644 --- a/src/atomate2/vasp/jobs/lobster.py +++ b/src/atomate2/vasp/jobs/lobster.py @@ -103,12 +103,12 @@ def get_basis_infos( """ # this logic enables handling of a flow or a simple maker try: - potcar_symbols = vasp_maker.static_maker.input_set_generator._get_potcar( + potcar_symbols = vasp_maker.static_maker.input_set_generator._get_potcar( # noqa: SLF001 structure=structure, potcar_spec=True ) except AttributeError: - potcar_symbols = vasp_maker.input_set_generator._get_potcar( + potcar_symbols = vasp_maker.input_set_generator._get_potcar( # noqa: SLF001 structure=structure, potcar_spec=True ) @@ -124,7 +124,7 @@ def get_basis_infos( for dict_for_basis in list_basis_dict: basis = [f"{key} {value}" for key, value in dict_for_basis.items()] lobsterin = Lobsterin(settingsdict={"basisfunctions": basis}) - n_bands = lobsterin._get_nbands(structure=structure) + n_bands = lobsterin._get_nbands(structure=structure) # noqa: SLF001 n_band_list.append(n_bands) return {"nbands": max(n_band_list), "basis_dict": list_basis_dict} diff --git a/src/atomate2/vasp/sets/core.py b/src/atomate2/vasp/sets/core.py index 336ec8a3f6..1ce14b4f84 100644 --- a/src/atomate2/vasp/sets/core.py +++ b/src/atomate2/vasp/sets/core.py @@ -154,7 +154,7 @@ def get_incar_updates( # LPEAD=T: numerical evaluation of overlap integral prevents LRF_COMMUTATOR # errors and can lead to better expt. agreement but produces slightly # different results - updates.update({"IBRION": 8, "LEPSILON": True, "LPEAD": True, "NSW": 1}) + updates.update(IBRION=8, LEPSILON=True, LPEAD=True, NSW=1) if self.lcalcpol: updates["LCALCPOL"] = True @@ -295,14 +295,14 @@ def get_incar_updates( n_edos = _get_nedos(vasprun, self.dedos) # use tetrahedron method for DOS and optics calculations - updates.update({"ISMEAR": -5, "ISYM": 2, "NEDOS": n_edos}) + updates.update(ISMEAR=-5, ISYM=2, NEDOS=n_edos) elif self.mode in ("line", "boltztrap"): # if line mode or explicit k-points (boltztrap) can't use ISMEAR=-5 # use small sigma to avoid partial occupancies for small band gap materials # use a larger sigma if the material is a metal sigma = 0.2 if bandgap == 0 else 0.01 - updates.update({"ISMEAR": 0, "SIGMA": sigma}) + updates.update(ISMEAR=0, SIGMA=sigma) if self.optics: # LREAL not supported with LOPTICS = True; automatic NEDOS usually @@ -651,12 +651,12 @@ def get_incar_updates( nedos = _get_nedos(vasprun, self.dedos) # use tetrahedron method for DOS and optics calculations - updates.update({"ISMEAR": -5, "NEDOS": nedos}) + updates.update(ISMEAR=-5, NEDOS=nedos) else: # if line mode or explicit k-points (gap) can't use ISMEAR=-5 # use small sigma to avoid partial occupancies for small band gap materials - updates.update({"ISMEAR": 0, "SIGMA": 0.01}) + updates.update(ISMEAR=0, SIGMA=0.01) if vasprun is not None: # set nbands @@ -665,7 +665,7 @@ def get_incar_updates( if self.optics: # LREAL not supported with LOPTICS - updates.update({"LOPTICS": True, "LREAL": False, "CSHIFT": 1e-5}) + updates.update(LOPTICS=True, LREAL=False, CSHIFT=1e-5) updates["MAGMOM"] = None @@ -846,27 +846,25 @@ def get_incar_updates( # Based on pymatgen.io.vasp.sets.MPMDSet. updates.update( - { - "ENCUT": 520, - "TEBEG": self.start_temp, - "TEEND": self.end_temp, - "NSW": self.nsteps, - "POTIM": self.time_step, - "LCHARG": False, - "NELMIN": 4, - "MAXMIX": 20, - "NELM": 500, - "ISYM": 0, - "IBRION": 0, - "KBLOCK": 100, - "PREC": "Normal", - } + ENCUT=520, + TEBEG=self.start_temp, + TEEND=self.end_temp, + NSW=self.nsteps, + POTIM=self.time_step, + LCHARG=False, + NELMIN=4, + MAXMIX=20, + NELM=500, + ISYM=0, + IBRION=0, + KBLOCK=100, + PREC="Normal", ) if Element("H") in structure.species and updates["POTIM"] > 0.5: logger.warning( f"Molecular dynamics time step is {updates['POTIM']}, which is " - "typically too large for a structure containing H. Consider set it " + "typically too large for a structure containing H. Consider setting it " "to a value of 0.5 or smaller." ) diff --git a/tests/abinit/sets/test_base.py b/tests/abinit/sets/test_base.py index 6d60ed1aab..a101cbf7bb 100644 --- a/tests/abinit/sets/test_base.py +++ b/tests/abinit/sets/test_base.py @@ -367,9 +367,9 @@ def test_generator_set_kpt_vars(abinit_test_dir): abinit_input = load_abinit_input( os.path.join(abinit_test_dir, "abinit_inputs"), fname="abinit_input_Si.json" ) - aig._set_kpt_vars(abinit_input, {"grid_density": 300}) + aig._set_kpt_vars(abinit_input, {"grid_density": 300}) # noqa: SLF001 assert np.array_equal(abinit_input["ngkpt"], [5, 5, 5]) - aig._set_kpt_vars(abinit_input, {"line_density": 10}) + aig._set_kpt_vars(abinit_input, {"line_density": 10}) # noqa: SLF001 assert abinit_input["nkpt"] == 92 assert "ngkpt" not in abinit_input diff --git a/tests/common/test_jobs.py b/tests/common/test_jobs.py index 72ce4c4d31..e860b4f065 100644 --- a/tests/common/test_jobs.py +++ b/tests/common/test_jobs.py @@ -1,5 +1,5 @@ import os -from datetime import datetime +from datetime import datetime, timezone from jobflow import run_locally from pymatgen.core import Structure @@ -44,7 +44,9 @@ def test_retrieve_structure_from_materials_project(): assert isinstance(output, Structure) # test stored data is in expected format - datetime.strptime(stored_data["database_version"], "%Y.%m.%d") + datetime.strptime(stored_data["database_version"], "%Y.%m.%d").replace( + tzinfo=timezone.utc + ) assert stored_data["task_id"].startswith("mp-") job = retrieve_structure_from_materials_project( diff --git a/tests/vasp/lobster/flows/test_lobster.py b/tests/vasp/lobster/flows/test_lobster.py index 23ee752ab2..f7cda6d705 100644 --- a/tests/vasp/lobster/flows/test_lobster.py +++ b/tests/vasp/lobster/flows/test_lobster.py @@ -100,7 +100,7 @@ def test_lobster_uniform_maker( .dict() .items() ): - if key == "lso_dos" or key == "band_overlaps": + if key in ("lso_dos", "band_overlaps"): assert value is None else: assert value is not None @@ -176,7 +176,7 @@ def test_lobstermaker( .dict() .items() ): - if key == "lso_dos" or key == "band_overlaps": + if key in ("lso_dos", "band_overlaps"): assert value is None else: assert value is not None diff --git a/tests/vasp/lobster/schemas/test_lobster.py b/tests/vasp/lobster/schemas/test_lobster.py index b08a9ba798..ec72b82fd0 100644 --- a/tests/vasp/lobster/schemas/test_lobster.py +++ b/tests/vasp/lobster/schemas/test_lobster.py @@ -216,9 +216,7 @@ def test_lobster_task_doc_saved_jsons(lobster_test_dir): if "dos" in cba_key and json_data[cba_key]: assert isinstance(json_data[cba_key], LobsterCompleteDos) - if (cba_key == "all_bonds" or cba_key == "cation_anion_bonds") and json_data[ - cba_key - ]: + if cba_key in ("all_bonds", "cation_anion_bonds") and json_data[cba_key]: assert isinstance( json_data[cba_key]["lobsterpy_data"], CondensedBondingAnalysis ) @@ -238,9 +236,7 @@ def test_lobster_task_doc_saved_jsons(lobster_test_dir): if "dos" in cba_key and json_data[cba_key]: assert isinstance(json_data[cba_key], dict) - if (cba_key == "all_bonds" or cba_key == "cation_anion_bonds") and json_data[ - cba_key - ]: + if cba_key in ("all_bonds", "cation_anion_bonds") and json_data[cba_key]: for cohp_data in json_data[cba_key]["lobsterpy_data"]["cohp_plot_data"][ "data" ].values(): @@ -304,10 +300,9 @@ def test_lobster_task_doc_saved_jsons(lobster_test_dir): assert isinstance(cohp_data, Cohp) if ( - task_doc_key == "cohp_data" - or task_doc_key == "cobi_data" - or task_doc_key == "coop_data" - ) and json_data[task_doc_key]: + task_doc_key in {"cohp_data", "cobi_data", "coop_data"} + and json_data[task_doc_key] + ): assert isinstance(json_data[task_doc_key], CompleteCohp) # delete the computational data json after the test diff --git a/tests/vasp/test_sets.py b/tests/vasp/test_sets.py index 580a86e0bc..5d4243356b 100644 --- a/tests/vasp/test_sets.py +++ b/tests/vasp/test_sets.py @@ -187,7 +187,7 @@ def test_set_kspacing_and_auto_ismear( ): static_set = MPMetaGGARelaxSetGenerator(auto_ismear=True, auto_kspacing=True) - incar = static_set._get_incar( + incar = static_set._get_incar( # noqa: SLF001 structure=struct_no_magmoms, kpoints=None, previous_incar=None,