Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Single source of truth for optional deps in pyproject.toml #1036

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ default_language_version:
exclude: ^(.github/|tests/test_data/abinit/)
repos:
- repo: https://github.com/charliermarsh/ruff-pre-commit
rev: v0.6.9
rev: v0.7.1
hooks:
- id: ruff
args: [--fix]
Expand All @@ -17,7 +17,7 @@ repos:
- id: end-of-file-fixer
- id: trailing-whitespace
- repo: https://github.com/asottile/blacken-docs
rev: 1.18.0
rev: 1.19.1
hooks:
- id: blacken-docs
additional_dependencies: [black]
Expand All @@ -30,7 +30,7 @@ repos:
- id: rst-directive-colons
- id: rst-inline-touching-normal
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.11.2
rev: v1.13.0
hooks:
- id: mypy
files: ^src/
Expand Down
52 changes: 14 additions & 38 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ dependencies = [
[project.optional-dependencies]
abinit = ["abipy>=0.9.3"]
amset = ["amset>=0.4.15", "pydash"]
cclib = ["cclib"]
cclib = ["cclib>=1.8.1"]
mp = ["mp-api>=0.37.5"]
phonons = ["phonopy>=1.10.8", "seekpath"]
lobster = ["ijson>=3.2.2", "lobsterpy>=0.4.0"]
Expand All @@ -51,16 +51,26 @@ defects = [
]
forcefields = [
"ase>=3.23.0",
"calorine<=2.2.1",
"calorine>=3.0",
"chgnet>=0.2.2",
"mace-torch>=0.3.3",
"torchdata<=0.7.1",
"matgl>=1.1.3",
"torchdata<=0.7.1",
# quippy-ase support for py3.12 tracked in https://github.com/libAtoms/QUIP/issues/645
"quippy-ase>=0.9.14; python_version < '3.12'",
"sevenn>=0.9.3",
"torchdata<=0.7.1", # TODO: remove when issue fixed
]
strict-forcefields = [
"calorine==3.0",
"chgnet==0.4.0",
"mace-torch==0.3.6",
"matgl==1.1.3",
"quippy-ase==0.9.14; python_version < '3.12'",
"sevenn==0.10.0",
"torch==2.5.0",
"torchdata==0.7.1", # TODO: remove when issue fixed
]
ase = ["ase>=3.23.0"]
# tblite py3.12 support tracked in https://github.com/tblite/tblite/issues/198
ase-ext = ["tblite>=0.3.0; python_version < '3.12'"]
Expand Down Expand Up @@ -92,41 +102,7 @@ tests = [
"pytest==8.3.3",
]
strict = [
"PyYAML==6.0.2",
"ase==3.23.0",
"cclib==1.8.1",
"click==8.1.7",
"custodian==2024.10.16",
"dscribe==2.1.1",
"emmet-core==0.84.2",
"ijson==3.3.0",
"jobflow==0.1.18",
"lobsterpy==0.4.9",
"mdanalysis==2.7.0",
"monty==2024.7.30",
"mp-api==0.42.2",
"numpy",
"openmm-mdanalysis-reporter==0.1.0",
"openmm==8.1.1",
"phonopy==2.27.0",
"pydantic-settings==2.6.0",
"pydantic==2.9.2",
"pymatgen-analysis-defects==2024.7.19",
"pymatgen==2024.10.3",
"python-ulid==3.0.0",
"seekpath==2.1.0",
"tblite==0.3.0; python_version < '3.12'",
"typing-extensions==4.12.2",
]
strict-forcefields = [
"calorine==3.0",
"chgnet==0.4.0",
"mace-torch>=0.3.6",
"matgl==1.1.3",
"quippy-ase==0.9.14; python_version < '3.12'",
"sevenn==0.10.0",
"torch==2.5.0",
"torchdata==0.7.1", # TODO: remove when issue fixed
"atomate2[forcefields, docs, cclib, phonons, lobster, openmm, mp, defects, ase, ase-ext]",
]

[project.scripts]
Expand Down
4 changes: 2 additions & 2 deletions src/atomate2/ase/jobs.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from __future__ import annotations

import logging
from abc import ABCMeta, abstractmethod
from abc import ABC, abstractmethod
from dataclasses import dataclass, field
from typing import TYPE_CHECKING

Expand All @@ -29,7 +29,7 @@


@dataclass
class AseMaker(Maker, metaclass=ABCMeta):
class AseMaker(Maker, ABC):
"""
Define basic template of ASE-based jobs.

Expand Down
4 changes: 2 additions & 2 deletions src/atomate2/ase/md.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import os
import sys
import time
from abc import ABCMeta, abstractmethod
from abc import ABC, abstractmethod
from collections.abc import Sequence
from dataclasses import dataclass, field
from enum import Enum
Expand Down Expand Up @@ -79,7 +79,7 @@ class DynamicsPresets(Enum):


@dataclass
class AseMDMaker(AseMaker, metaclass=ABCMeta):
class AseMDMaker(AseMaker, ABC):
"""
Perform MD with the Atomic Simulation Environment (ASE).

Expand Down
2 changes: 1 addition & 1 deletion src/atomate2/ase/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ class AseBaseModel(BaseModel):
)
molecule: Optional[Molecule] = Field(None, description="The molecule at this step.")

def model_post_init(self, __context: Any) -> None:
def model_post_init(self, context: Any, /) -> None:
"""Establish alias to structure and molecule fields."""
if self.structure is None and isinstance(self.mol_or_struct, Structure):
self.structure = self.mol_or_struct
Expand Down
11 changes: 5 additions & 6 deletions src/atomate2/common/flows/mpmorph.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

from __future__ import annotations

from abc import ABCMeta, abstractmethod
from abc import ABC, abstractmethod
from dataclasses import dataclass, field
from typing import TYPE_CHECKING, Literal

Expand Down Expand Up @@ -165,9 +165,8 @@ def make(
structure=deformed_structures[index].final_structure,
prev_dir=None,
)
md_job.name = (
f"{self.name} {md_job.name} {len(working_outputs['relax']['volume'])+1}"
)
n_volumes = len(working_outputs["relax"]["volume"]) + 1
md_job.name = f"{self.name} {md_job.name} {n_volumes}"

working_outputs["relax"]["energies"].append(md_job.output.output.energy)
working_outputs["relax"]["volume"].append(md_job.output.structure.volume)
Expand All @@ -186,7 +185,7 @@ def make(


@dataclass
class MPMorphMDMaker(Maker, metaclass=ABCMeta):
class MPMorphMDMaker(Maker, ABC):
"""Base MPMorph flow for amorphous solid equilibration.

This flow uses NVT molecular dynamics to:
Expand Down Expand Up @@ -399,7 +398,7 @@ def make(


@dataclass
class SlowQuenchMaker(Maker, metaclass=ABCMeta):
class SlowQuenchMaker(Maker, ABC):
"""Slow quench from high to low temperature structures.

Quenches a provided structure with a molecular dynamics
Expand Down
4 changes: 2 additions & 2 deletions src/atomate2/common/jobs/eos.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from __future__ import annotations

from abc import ABCMeta, abstractmethod
from abc import ABC, abstractmethod
from typing import TYPE_CHECKING

import numpy as np
Expand All @@ -23,7 +23,7 @@
from pymatgen.core import Structure


class EOSPostProcessor(MSONable, metaclass=ABCMeta):
class EOSPostProcessor(MSONable, ABC):
"""
Fit data to an EOS.

Expand Down
2 changes: 1 addition & 1 deletion src/atomate2/common/jobs/mpmorph.py
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ def get_entry_from_dict(chem_env: str) -> dict | None:
for ielt in range(2, len(composition)):
for combo in combinations(composition, ielt):
chem_env_key = _get_chem_env_key_from_composition(
Composition({spec: 1 for spec in combo}),
Composition(dict.fromkeys(combo, 1)),
ignore_oxi_states=ignore_oxi_states,
)

Expand Down
2 changes: 1 addition & 1 deletion src/atomate2/forcefields/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class ForcefieldResult(AseResult):
None, description="The structure in the final trajectory frame."
)

def model_post_init(self, __context: Any) -> None:
def model_post_init(self, context: Any, /) -> None:
"""Populate final_structure attr."""
self.final_structure = getattr(
self, "final_structure", self.final_mol_or_struct
Expand Down
3 changes: 1 addition & 2 deletions src/atomate2/vasp/flows/ferroelectric.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,7 @@ def make(
add_interp_flow.output,
)

jobs.append(add_interp_flow)
jobs.append(pol_analysis)
jobs += (add_interp_flow, pol_analysis)

return Flow(
jobs=jobs,
Expand Down
2 changes: 1 addition & 1 deletion tests/forcefields/flows/test_mpmorph.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ def test_mpmorph_mlff_maker(ff_name, si_structure, test_dir, clean_dir):
)
task_docs = {}
for uuid, job_name in uuids.items():
for _i, mp_job_name in enumerate(main_mp_morph_job_names):
for mp_job_name in main_mp_morph_job_names:
if mp_job_name in job_name:
task_docs[mp_job_name] = response[uuid][1].output
break
Expand Down
4 changes: 2 additions & 2 deletions tests/vasp/flows/test_mpmorph.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ def test_vasp_mpmorph(
assert all(
task_docs[
"MP Morph VASP Equilibrium Volume Maker "
f"Convergence MPMorph VASP MD Maker {1+idx}"
f"Convergence MPMorph VASP MD Maker {1 + idx}"
].output.energy
== pytest.approx(ref_eos["energy"][idx])
for idx in range(3)
Expand All @@ -156,7 +156,7 @@ def test_vasp_mpmorph(
assert all(
task_docs[
"MP Morph VASP Equilibrium Volume Maker "
f"Convergence MPMorph VASP MD Maker {1+idx}"
f"Convergence MPMorph VASP MD Maker {1 + idx}"
].output.structure.volume
== pytest.approx(ref_eos["volume"][idx])
for idx in range(3)
Expand Down
10 changes: 5 additions & 5 deletions tests/vasp/test_sets.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,13 +83,13 @@ def test_user_incar_settings():
static_set_generator = StaticSetGenerator(user_incar_settings=uis)
incar = static_set_generator.get_input_set(structure, potcar_spec=True)["INCAR"]

for key in uis:
for key, val in uis.items():
if isinstance(incar[key], str):
assert incar[key].lower() == uis[key].lower()
elif isinstance(uis[key], dict):
assert incar[key] == [uis[key][str(site.specie)] for site in structure]
assert incar[key].lower() == val.lower()
elif isinstance(val, dict):
assert incar[key] == [val[str(site.specie)] for site in structure]
else:
assert incar[key] == uis[key]
assert incar[key] == val


@pytest.mark.parametrize(
Expand Down
Loading