diff --git a/pyproject.toml b/pyproject.toml index f7ac6e6dc..0f30bed9b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -28,7 +28,7 @@ dependencies = [ 'importlib_resources', 'jsonschema', 'numpy', - 'pydantic~=1.10,>=1.10.8', + 'pydantic~=2.0', 'packaging', 'qe-tools~=2.0', 'xmlschema~=1.2,>=1.2.5' diff --git a/src/aiida_quantumespresso/common/hubbard.py b/src/aiida_quantumespresso/common/hubbard.py index 99ddca3eb..6bc131a49 100644 --- a/src/aiida_quantumespresso/common/hubbard.py +++ b/src/aiida_quantumespresso/common/hubbard.py @@ -3,7 +3,7 @@ # pylint: disable=no-name-in-module, invalid-name from typing import List, Literal, Tuple -from pydantic import BaseModel, conint, constr, validator +from pydantic import BaseModel, conint, constr, field_validator __all__ = ('HubbardParameters', 'Hubbard') @@ -39,7 +39,7 @@ class HubbardParameters(BaseModel): hubbard_type: Literal['Ueff', 'U', 'V', 'J', 'B', 'E2', 'E3'] """Type of the Hubbard parameters used (`Ueff`, `U`, `V`, `J`, `B`, `E2`, `E3`).""" - @validator('atom_manifold', 'neighbour_manifold') # cls is mandatory to use + @field_validator('atom_manifold', 'neighbour_manifold') # cls is mandatory to use def check_manifolds(cls, value): # pylint: disable=no-self-argument, no-self-use """Check the validity of the manifold input. diff --git a/src/aiida_quantumespresso/data/hubbard_structure.py b/src/aiida_quantumespresso/data/hubbard_structure.py index 041aac199..78d0862b4 100644 --- a/src/aiida_quantumespresso/data/hubbard_structure.py +++ b/src/aiida_quantumespresso/data/hubbard_structure.py @@ -59,7 +59,7 @@ def hubbard(self) -> Hubbard: :returns: a :class:`~aiida_quantumespresso.common.hubbard.Hubbard` instance. """ with self.base.repository.open(self._hubbard_filename, mode='rb') as handle: - return Hubbard.parse_raw(json.load(handle)) + return Hubbard.model_validate_json(json.load(handle)) @hubbard.setter def hubbard(self, hubbard: Hubbard): @@ -67,7 +67,7 @@ def hubbard(self, hubbard: Hubbard): if not isinstance(hubbard, Hubbard): raise ValueError('the input is not of type `Hubbard`') - serialized = json.dumps(hubbard.json()) + serialized = json.dumps(hubbard.model_dump_json()) self.base.repository.put_object_from_bytes(serialized.encode('utf-8'), self._hubbard_filename) @staticmethod diff --git a/src/aiida_quantumespresso/utils/hubbard.py b/src/aiida_quantumespresso/utils/hubbard.py index 046488fd5..65565191b 100644 --- a/src/aiida_quantumespresso/utils/hubbard.py +++ b/src/aiida_quantumespresso/utils/hubbard.py @@ -181,7 +181,7 @@ def reorder_atoms(self): reordered = structure.clone() # to be set at the end reordered.clear_kinds() - hubbard = structure.hubbard.copy() + hubbard = structure.hubbard.model_copy() parameters = hubbard.to_list() sites = structure.sites diff --git a/tests/common/test_hubbard.py b/tests/common/test_hubbard.py index d9b612ea8..5b10b1850 100644 --- a/tests/common/test_hubbard.py +++ b/tests/common/test_hubbard.py @@ -30,6 +30,8 @@ def _get_hubbard_parameters(overrides=None): if overrides: inputs.update(overrides) + print('INPUTS', inputs) + return HubbardParameters(**inputs) return _get_hubbard_parameters @@ -50,7 +52,7 @@ def _get_hubbard(): def test_safe_hubbard_parameters(get_hubbard_parameters): """Test valid inputs are stored correctly for py:meth:`HubbardParameters`.""" - params = get_hubbard_parameters().dict() + params = get_hubbard_parameters().model_dump() assert params == VALID_PARAMETERS @@ -60,7 +62,7 @@ def test_from_to_list_parameters(get_hubbard_parameters): hp_tuple = (0, '3d', 1, '2p', 5.0, (0, 0, 0), 'U') assert param.to_tuple() == hp_tuple param = HubbardParameters.from_tuple(hp_tuple) - assert param.dict() == VALID_PARAMETERS + assert param.model_dump() == VALID_PARAMETERS @pytest.mark.parametrize( @@ -76,7 +78,7 @@ def test_from_to_list_parameters(get_hubbard_parameters): ) def test_valid_hubbard_parameters(get_hubbard_parameters, overrides): """Test valid inputs for py:meth:`HubbardParameters`.""" - hp_dict = get_hubbard_parameters(overrides=overrides).dict() + hp_dict = get_hubbard_parameters(overrides=overrides).model_dump() new_dict = deepcopy(VALID_PARAMETERS) new_dict.update(overrides) assert hp_dict == new_dict @@ -85,12 +87,12 @@ def test_valid_hubbard_parameters(get_hubbard_parameters, overrides): @pytest.mark.parametrize(('overrides', 'match'), ( ({ 'atom_index': -1 - }, r'ensure this value is greater than or equal to 0'), + }, r'Input should be greater than or equal to 0'), ( { 'atom_index': 0.5 }, - r'value is not a valid integer', + r'Input should be a valid integer', ), ( { @@ -108,31 +110,31 @@ def test_valid_hubbard_parameters(get_hubbard_parameters, overrides): { 'atom_manifold': '3d-3p-2s' }, - r'ensure this value has at most 5 characters', + r'String should have at most 5 characters', ), ( { 'translation': (0, 0) }, - r'wrong tuple length 2, expected 3', + r'translation\.2\n\s+Field required', ), ( { 'translation': (0, 0, 0, 0) }, - r'wrong tuple length 4, expected 3', + r'Tuple should have at most 3 items after validation, not 4', ), ( { 'translation': (0, 0, -1.5) }, - r'value is not a valid integer', + r'Input should be a valid integer', ), ( { 'hubbard_type': 'L' }, - r"permitted: 'Ueff', 'U', 'V', 'J', 'B', 'E2', 'E3'", + r"Input should be 'Ueff', 'U', 'V', 'J', 'B', 'E2' or 'E3'", ), )) def test_invalid_hubbard_parameters(get_hubbard_parameters, overrides, match): @@ -150,7 +152,7 @@ def test_from_to_list_hubbard(get_hubbard): assert hubbard.to_list() == hubbard_list hubbard = Hubbard.from_list(hubbard_list) - assert hubbard.dict() == { + assert hubbard.model_dump() == { 'parameters': [VALID_PARAMETERS, VALID_PARAMETERS], 'projectors': 'ortho-atomic', 'formulation': 'dudarev',