From ec2dc9db27999eb414b74bd6cab5a1b2b7debe6d Mon Sep 17 00:00:00 2001 From: "Lori A. Burns" Date: Wed, 18 Sep 2024 15:55:51 -0400 Subject: [PATCH] internal classes to pyd v2 api --- qcengine/compute.py | 5 +-- qcengine/config.py | 37 ++++++++++------------ qcengine/procedures/berny.py | 4 +-- qcengine/procedures/geometric.py | 7 ++-- qcengine/procedures/model.py | 12 +++---- qcengine/procedures/nwchem_opt/__init__.py | 7 ++-- qcengine/procedures/optking.py | 7 ++-- qcengine/procedures/torsiondrive.py | 7 ++-- qcengine/programs/adcc.py | 7 ++-- qcengine/programs/cfour/runner.py | 3 -- qcengine/programs/dftd3.py | 3 -- qcengine/programs/dftd_ng.py | 6 ---- qcengine/programs/gamess/runner.py | 3 -- qcengine/programs/gcp.py | 3 -- qcengine/programs/model.py | 19 +++++------ qcengine/programs/molpro.py | 7 ++-- qcengine/programs/mopac.py | 3 -- qcengine/programs/mp2d.py | 3 -- qcengine/programs/mrchem.py | 3 -- qcengine/programs/nwchem/runner.py | 3 -- qcengine/programs/openmm.py | 3 -- qcengine/programs/psi4.py | 3 -- qcengine/programs/qchem.py | 4 +-- qcengine/programs/qcore.py | 9 ++---- qcengine/programs/rdkit.py | 3 -- qcengine/programs/terachem.py | 3 -- qcengine/programs/terachem_frontend.py | 4 +-- qcengine/programs/terachem_pbs.py | 17 ++++------ qcengine/programs/torchani.py | 3 -- qcengine/programs/xtb.py | 3 -- qcengine/testing.py | 6 ++-- qcengine/tests/test_config.py | 5 +-- qcengine/tests/test_utils.py | 1 + qcengine/util.py | 8 ++--- 34 files changed, 67 insertions(+), 154 deletions(-) diff --git a/qcengine/compute.py b/qcengine/compute.py index 00e94a329..af4754bf4 100644 --- a/qcengine/compute.py +++ b/qcengine/compute.py @@ -13,10 +13,7 @@ from .util import compute_wrapper, environ_context, handle_output_metadata, model_wrapper if TYPE_CHECKING: - try: - from pydantic.v1.main import BaseModel - except ImportError: - from pydantic.main import BaseModel + from pydantic.main import BaseModel from qcelemental.models import AtomicResult diff --git a/qcengine/config.py b/qcengine/config.py index a836ddbe9..d17df557d 100644 --- a/qcengine/config.py +++ b/qcengine/config.py @@ -9,10 +9,8 @@ import socket from typing import Any, Dict, Optional, Union -try: - import pydantic.v1 as pydantic -except ImportError: - import pydantic +from pydantic import BaseModel, Field +from pydantic_settings import BaseSettings, SettingsConfigDict from .extras import get_information @@ -69,7 +67,7 @@ def get_global(key: Optional[str] = None) -> Union[str, Dict[str, Any]]: return _global_values[key] -class NodeDescriptor(pydantic.BaseModel): +class NodeDescriptor(BaseModel): """ Description of an individual node """ @@ -83,7 +81,7 @@ class NodeDescriptor(pydantic.BaseModel): memory_safety_factor: int = 10 # Percentage of memory as a safety factor # Specifications - ncores: Optional[int] = pydantic.Field( + ncores: Optional[int] = Field( None, description="""Number of cores accessible to each task on this node @@ -93,7 +91,7 @@ class NodeDescriptor(pydantic.BaseModel): retries: int = 0 # Cluster options - is_batch_node: bool = pydantic.Field( + is_batch_node: bool = Field( False, help="""Whether the node running QCEngine is a batch node @@ -108,7 +106,7 @@ class NodeDescriptor(pydantic.BaseModel): ``mpiexec_command`` must always be used even for serial jobs (e.g., getting the version number) """, ) - mpiexec_command: Optional[str] = pydantic.Field( + mpiexec_command: Optional[str] = Field( None, description="""Invocation for launching node-parallel tasks with MPI @@ -149,27 +147,24 @@ class Config: extra = "forbid" -class TaskConfig(pydantic.BaseSettings): +class TaskConfig(BaseSettings): """Description of the configuration used to launch a task.""" # Specifications - ncores: int = pydantic.Field(None, description="Number cores per task on each node") - nnodes: int = pydantic.Field(None, description="Number of nodes per task") - memory: float = pydantic.Field( - None, description="Amount of memory in GiB (2^30 bytes; not GB = 10^9 bytes) per node." - ) + ncores: int = Field(None, description="Number cores per task on each node") + nnodes: int = Field(None, description="Number of nodes per task") + memory: float = Field(None, description="Amount of memory in GiB (2^30 bytes; not GB = 10^9 bytes) per node.") scratch_directory: Optional[str] # What location to use as scratch retries: int # Number of retries on random failures mpiexec_command: Optional[str] # Command used to launch MPI tasks, see NodeDescriptor use_mpiexec: bool = False # Whether it is necessary to use MPI to run an executable - cores_per_rank: int = pydantic.Field(1, description="Number of cores per MPI rank") - scratch_messy: bool = pydantic.Field( - False, description="Leave scratch directory and contents on disk after completion." - ) + cores_per_rank: int = Field(1, description="Number of cores per MPI rank") + scratch_messy: bool = Field(False, description="Leave scratch directory and contents on disk after completion.") - class Config(pydantic.BaseSettings.Config): - extra = "forbid" - env_prefix = "QCENGINE_" + model_config = SettingsConfigDict( + extra="forbid", + env_prefix="QCENGINE_", + ) def _load_defaults() -> None: diff --git a/qcengine/procedures/berny.py b/qcengine/procedures/berny.py index 332b473d6..7159f7d4a 100644 --- a/qcengine/procedures/berny.py +++ b/qcengine/procedures/berny.py @@ -2,7 +2,7 @@ import sys import traceback from io import StringIO -from typing import Any, Dict, Union +from typing import Any, ClassVar, Dict, Union import numpy as np from qcelemental.models import FailedOperation, OptimizationInput, OptimizationResult @@ -16,7 +16,7 @@ class BernyProcedure(ProcedureHarness): - _defaults = {"name": "Berny", "procedure": "optimization"} + _defaults: ClassVar[Dict[str, Any]] = {"name": "Berny", "procedure": "optimization"} def found(self, raise_error: bool = False) -> bool: return which_import( diff --git a/qcengine/procedures/geometric.py b/qcengine/procedures/geometric.py index 59bc26c86..d8b19e40a 100644 --- a/qcengine/procedures/geometric.py +++ b/qcengine/procedures/geometric.py @@ -1,4 +1,4 @@ -from typing import Any, Dict, Union +from typing import Any, ClassVar, Dict, Union from qcelemental.models import OptimizationInput, OptimizationResult from qcelemental.util import safe_version, which_import @@ -8,13 +8,10 @@ class GeometricProcedure(ProcedureHarness): - _defaults = {"name": "geomeTRIC", "procedure": "optimization"} + _defaults: ClassVar[Dict[str, Any]] = {"name": "geomeTRIC", "procedure": "optimization"} version_cache: Dict[str, str] = {} - class Config(ProcedureHarness.Config): - pass - def found(self, raise_error: bool = False) -> bool: return which_import( "geometric", diff --git a/qcengine/procedures/model.py b/qcengine/procedures/model.py index 0e540114d..e5a334ddf 100644 --- a/qcengine/procedures/model.py +++ b/qcengine/procedures/model.py @@ -1,10 +1,7 @@ import abc from typing import Any, Dict, Union -try: - from pydantic.v1 import BaseModel -except ImportError: - from pydantic import BaseModel +from pydantic import BaseModel, ConfigDict from ..util import model_wrapper @@ -14,9 +11,10 @@ class ProcedureHarness(BaseModel, abc.ABC): name: str procedure: str - class Config: - allow_mutation: False - extra: "forbid" + model_config = ConfigDict( + frozen=True, + extra="forbid", + ) def __init__(self, **kwargs): super().__init__(**{**self._defaults, **kwargs}) diff --git a/qcengine/procedures/nwchem_opt/__init__.py b/qcengine/procedures/nwchem_opt/__init__.py index f884cdc58..e11b6db23 100644 --- a/qcengine/procedures/nwchem_opt/__init__.py +++ b/qcengine/procedures/nwchem_opt/__init__.py @@ -1,4 +1,4 @@ -from typing import Any, Dict, Union +from typing import Any, ClassVar, Dict, Union from qcelemental.models import AtomicInput, OptimizationInput, OptimizationResult, Provenance @@ -12,10 +12,7 @@ class NWChemDriverProcedure(ProcedureHarness): """Structural relaxation using NWChem's optimizer""" - _defaults = {"name": "NWChemDriver", "procedure": "optimization"} - - class Config(ProcedureHarness.Config): - pass + _defaults: ClassVar[Dict[str, Any]] = {"name": "NWChemDriver", "procedure": "optimization"} def found(self, raise_error: bool = False) -> bool: nwc_harness = NWChemHarness() diff --git a/qcengine/procedures/optking.py b/qcengine/procedures/optking.py index 34139a3f3..0c078a2d1 100644 --- a/qcengine/procedures/optking.py +++ b/qcengine/procedures/optking.py @@ -1,4 +1,4 @@ -from typing import Any, Dict, Union +from typing import Any, ClassVar, Dict, Union from qcelemental.models import OptimizationInput, OptimizationResult from qcelemental.util import safe_version, which_import @@ -8,13 +8,10 @@ class OptKingProcedure(ProcedureHarness): - _defaults = {"name": "OptKing", "procedure": "optimization"} + _defaults: ClassVar[Dict[str, Any]] = {"name": "OptKing", "procedure": "optimization"} version_cache: Dict[str, str] = {} - class Config(ProcedureHarness.Config): - pass - def found(self, raise_error: bool = False) -> bool: return which_import( "optking", diff --git a/qcengine/procedures/torsiondrive.py b/qcengine/procedures/torsiondrive.py index 0fc1327d7..ad7f88059 100644 --- a/qcengine/procedures/torsiondrive.py +++ b/qcengine/procedures/torsiondrive.py @@ -1,7 +1,7 @@ import io from collections import defaultdict from contextlib import redirect_stderr, redirect_stdout -from typing import TYPE_CHECKING, Any, Dict, List, Tuple, Union +from typing import TYPE_CHECKING, Any, ClassVar, Dict, List, Tuple, Union import numpy as np from qcelemental.models import FailedOperation, Molecule @@ -16,10 +16,7 @@ class TorsionDriveProcedure(ProcedureHarness): - _defaults = {"name": "TorsionDrive", "procedure": "torsiondrive"} - - class Config(ProcedureHarness.Config): - pass + _defaults: ClassVar[Dict[str, Any]] = {"name": "TorsionDrive", "procedure": "torsiondrive"} def found(self, raise_error: bool = False) -> bool: return which_import( diff --git a/qcengine/programs/adcc.py b/qcengine/programs/adcc.py index ff641c5ef..619e4fc75 100644 --- a/qcengine/programs/adcc.py +++ b/qcengine/programs/adcc.py @@ -1,7 +1,7 @@ """ Calls adcc """ -from typing import TYPE_CHECKING, Dict +from typing import TYPE_CHECKING, Any, ClassVar, Dict from qcelemental.models import AtomicResult, BasisSet, Provenance from qcelemental.util import safe_version, which_import @@ -19,7 +19,7 @@ class AdccHarness(ProgramHarness): - _defaults = { + _defaults: ClassVar[Dict[str, Any]] = { "name": "adcc", "scratch": False, "thread_safe": False, @@ -29,9 +29,6 @@ class AdccHarness(ProgramHarness): } version_cache: Dict[str, str] = {} - class Config(ProgramHarness.Config): - pass - @staticmethod def found(raise_error: bool = False) -> bool: """Whether adcc harness is ready for operation. diff --git a/qcengine/programs/cfour/runner.py b/qcengine/programs/cfour/runner.py index 6fe67e2b6..e181f6db3 100644 --- a/qcengine/programs/cfour/runner.py +++ b/qcengine/programs/cfour/runner.py @@ -41,9 +41,6 @@ class CFOURHarness(ProgramHarness): } version_cache: Dict[str, str] = {} - class Config(ProgramHarness.Config): - pass - @staticmethod def found(raise_error: bool = False) -> bool: return which( diff --git a/qcengine/programs/dftd3.py b/qcengine/programs/dftd3.py index 2f67fcfee..1ca875651 100644 --- a/qcengine/programs/dftd3.py +++ b/qcengine/programs/dftd3.py @@ -40,9 +40,6 @@ class DFTD3Harness(ProgramHarness): } version_cache: Dict[str, str] = {} - class Config(ProgramHarness.Config): - pass - @staticmethod def found(raise_error: bool = False) -> bool: return which( diff --git a/qcengine/programs/dftd_ng.py b/qcengine/programs/dftd_ng.py index 8fe0af980..2c73d56eb 100644 --- a/qcengine/programs/dftd_ng.py +++ b/qcengine/programs/dftd_ng.py @@ -31,9 +31,6 @@ class DFTD4Harness(ProgramHarness): } version_cache: Dict[str, str] = {} - class Config(ProgramHarness.Config): - pass - @staticmethod def found(raise_error: bool = False) -> bool: """Check for the availability of the Python API of dftd4""" @@ -195,9 +192,6 @@ class SDFTD3Harness(ProgramHarness): } version_cache: Dict[str, str] = {} - class Config(ProgramHarness.Config): - pass - @staticmethod def found(raise_error: bool = False) -> bool: """Check for the availability of the Python API of dftd3""" diff --git a/qcengine/programs/gamess/runner.py b/qcengine/programs/gamess/runner.py index b456dbc4d..18a874501 100644 --- a/qcengine/programs/gamess/runner.py +++ b/qcengine/programs/gamess/runner.py @@ -42,9 +42,6 @@ class GAMESSHarness(ProgramHarness): } version_cache: Dict[str, str] = {} - class Config(ProgramHarness.Config): - pass - @staticmethod def found(raise_error: bool = False) -> bool: return which( diff --git a/qcengine/programs/gcp.py b/qcengine/programs/gcp.py index 368f82521..0f934f736 100644 --- a/qcengine/programs/gcp.py +++ b/qcengine/programs/gcp.py @@ -39,9 +39,6 @@ class GCPHarness(ProgramHarness): } version_cache: Dict[str, str] = {} - class Config(ProgramHarness.Config): - pass - @staticmethod def found(raise_error: bool = False) -> bool: return which( diff --git a/qcengine/programs/model.py b/qcengine/programs/model.py index a62f7013f..27da36341 100644 --- a/qcengine/programs/model.py +++ b/qcengine/programs/model.py @@ -1,12 +1,8 @@ import abc import logging -from typing import Any, Dict, List, Optional, Tuple, Union - -try: - from pydantic.v1 import BaseModel -except ImportError: - from pydantic import BaseModel +from typing import Any, ClassVar, Dict, List, Optional, Tuple, Union +from pydantic import BaseModel, ConfigDict from qcelemental.models import AtomicInput, AtomicResult, FailedOperation from qcengine.config import TaskConfig @@ -17,18 +13,19 @@ class ProgramHarness(BaseModel, abc.ABC): - _defaults: Dict[str, Any] = {} + _defaults: ClassVar[Dict[str, Any]] = {} name: str scratch: bool thread_safe: bool thread_parallel: bool node_parallel: bool managed_memory: bool - extras: Optional[Dict[str, Any]] + extras: Optional[Dict[str, Any]] = None - class Config: - allow_mutation: False - extra: "forbid" + model_config = ConfigDict( + frozen=True, + extra="forbid", + ) def __init__(self, **kwargs): super().__init__(**{**self._defaults, **kwargs}) diff --git a/qcengine/programs/molpro.py b/qcengine/programs/molpro.py index 0025ae0f4..09e14a369 100644 --- a/qcengine/programs/molpro.py +++ b/qcengine/programs/molpro.py @@ -3,7 +3,7 @@ """ import string -from typing import Any, Dict, List, Optional, Set, Tuple +from typing import Any, ClassVar, Dict, List, Optional, Set, Tuple from xml.etree import ElementTree as ET from qcelemental.models import AtomicResult @@ -15,7 +15,7 @@ class MolproHarness(ProgramHarness): - _defaults: Dict[str, Any] = { + _defaults: ClassVar[Dict[str, Any]] = { "name": "Molpro", "scratch": True, "thread_safe": False, @@ -63,9 +63,6 @@ class MolproHarness(ProgramHarness): # _unrestricted_post_hf_methods: Set[str] = {"UMP2", "UCCSD", "UCCSD(T)"} _post_hf_methods: Set[str] = {*_restricted_post_hf_methods} - class Config(ProgramHarness.Config): - pass - def found(self, raise_error: bool = False) -> bool: return which( "molpro", return_bool=True, raise_error=raise_error, raise_msg="Please install via https://www.molpro.net/" diff --git a/qcengine/programs/mopac.py b/qcengine/programs/mopac.py index e97a319c8..397245f26 100644 --- a/qcengine/programs/mopac.py +++ b/qcengine/programs/mopac.py @@ -24,9 +24,6 @@ class MopacHarness(ProgramHarness): } version_cache: Dict[str, str] = {} - class Config(ProgramHarness.Config): - pass - def __init__(self, **kwargs): extras = { # All units taken from within MOPAC "bohr_to_angstroms": 0.5291772083, diff --git a/qcengine/programs/mp2d.py b/qcengine/programs/mp2d.py index 2fd08c8aa..4d4153b01 100644 --- a/qcengine/programs/mp2d.py +++ b/qcengine/programs/mp2d.py @@ -31,9 +31,6 @@ class MP2DHarness(ProgramHarness): } version_cache: Dict[str, str] = {} - class Config(ProgramHarness.Config): - pass - @staticmethod def found(raise_error: bool = False) -> bool: return which( diff --git a/qcengine/programs/mrchem.py b/qcengine/programs/mrchem.py index e52c889ee..58b22a17f 100644 --- a/qcengine/programs/mrchem.py +++ b/qcengine/programs/mrchem.py @@ -39,9 +39,6 @@ class MRChemHarness(ProgramHarness): } version_cache: Dict[str, str] = {} - class Config(ProgramHarness.Config): - pass - @staticmethod def found(raise_error: bool = False) -> bool: """Whether MRChem harness is ready for operation. diff --git a/qcengine/programs/nwchem/runner.py b/qcengine/programs/nwchem/runner.py index 7c8223392..09addc1f2 100644 --- a/qcengine/programs/nwchem/runner.py +++ b/qcengine/programs/nwchem/runner.py @@ -50,9 +50,6 @@ class NWChemHarness(ErrorCorrectionProgramHarness): # ATL: OpenMP only >=6.6 and only for Phi; potential for Mac using MKL and Intel compilers version_cache: Dict[str, str] = {} - class Config(ErrorCorrectionProgramHarness.Config): - pass - @staticmethod def found(raise_error: bool = False) -> bool: """Whether NWChem harness is ready for operation, with both the QC program and any particular dependencies found. diff --git a/qcengine/programs/openmm.py b/qcengine/programs/openmm.py index bb54567b3..ca2f4c541 100644 --- a/qcengine/programs/openmm.py +++ b/qcengine/programs/openmm.py @@ -39,9 +39,6 @@ class OpenMMHarness(ProgramHarness): version_cache: Dict[str, str] = {} - class Config(ProgramHarness.Config): - pass - # def _get_off_forcefield(self, hashstring, offxml): # # from openff.toolkit.typing.engines import smirnoff diff --git a/qcengine/programs/psi4.py b/qcengine/programs/psi4.py index 1ba3d7fac..707557c9b 100644 --- a/qcengine/programs/psi4.py +++ b/qcengine/programs/psi4.py @@ -32,9 +32,6 @@ class Psi4Harness(ProgramHarness): } version_cache: Dict[str, str] = {} - class Config(ProgramHarness.Config): - pass - @staticmethod def found(raise_error: bool = False) -> bool: """Whether Psi4 harness is ready for operation. diff --git a/qcengine/programs/qchem.py b/qcengine/programs/qchem.py index 0a743e115..9945679e5 100644 --- a/qcengine/programs/qchem.py +++ b/qcengine/programs/qchem.py @@ -7,7 +7,7 @@ import tempfile import warnings from collections import defaultdict -from typing import Any, Dict, List, Optional, Tuple +from typing import Any, ClassVar, Dict, List, Optional, Tuple import numpy as np from qcelemental import constants @@ -25,7 +25,7 @@ class QChemHarness(ProgramHarness): - _defaults: Dict[str, Any] = { + _defaults: ClassVar[Dict[str, Any]] = { "name": "QChem", "scratch": True, "thread_safe": False, diff --git a/qcengine/programs/qcore.py b/qcengine/programs/qcore.py index 172f8dbb7..b8a51ebdb 100644 --- a/qcengine/programs/qcore.py +++ b/qcengine/programs/qcore.py @@ -2,7 +2,7 @@ The qcore QCEngine Harness """ -from typing import TYPE_CHECKING, Any, Dict, List, Set +from typing import TYPE_CHECKING, Any, ClassVar, Dict, List, Set import numpy as np from qcelemental.models import AtomicResult, BasisSet @@ -31,7 +31,7 @@ def qcore_ao_order_spherical(max_angular_momentum: int) -> Dict[int, List[int]]: class QcoreHarness(ProgramHarness): - _defaults: Dict[str, Any] = { + _defaults: ClassVar[Dict[str, Any]] = { "name": "Qcore", "scratch": False, "thread_safe": False, @@ -88,9 +88,6 @@ class QcoreHarness(ProgramHarness): # Entos spherical basis ordering for each angular momentum. Follows reverse order of CCA. _qcore_to_cca_ao_order = {"spherical": get_ao_conversion(cca_ao_order_spherical(10), qcore_ao_order_spherical(10))} - class Config(ProgramHarness.Config): - pass - def found(self, raise_error: bool = False) -> bool: return which_import( "qcore", @@ -250,7 +247,7 @@ def parse_output(self, output: Dict[str, Any], input_model: "AtomicInput") -> "A class EntosHarness(QcoreHarness): - _defaults: Dict[str, Any] = { + _defaults: ClassVar[Dict[str, Any]] = { "name": "Entos", "scratch": True, "thread_safe": False, diff --git a/qcengine/programs/rdkit.py b/qcengine/programs/rdkit.py index 1a01a0253..5ce291f0a 100644 --- a/qcengine/programs/rdkit.py +++ b/qcengine/programs/rdkit.py @@ -30,9 +30,6 @@ class RDKitHarness(ProgramHarness): version_cache: Dict[str, str] = {} - class Config(ProgramHarness.Config): - pass - @staticmethod def _process_molecule_rdkit(jmol): from rdkit import Chem diff --git a/qcengine/programs/terachem.py b/qcengine/programs/terachem.py index 98dfcaabe..f743145ce 100644 --- a/qcengine/programs/terachem.py +++ b/qcengine/programs/terachem.py @@ -28,9 +28,6 @@ class TeraChemHarness(ProgramHarness): } version_cache: Dict[str, str] = {} - class Config(ProgramHarness.Config): - pass - @staticmethod def found(raise_error: bool = False) -> bool: return which( diff --git a/qcengine/programs/terachem_frontend.py b/qcengine/programs/terachem_frontend.py index 09b8503a3..0ce03af15 100644 --- a/qcengine/programs/terachem_frontend.py +++ b/qcengine/programs/terachem_frontend.py @@ -1,7 +1,7 @@ """Harness for TeraChem Frontend""" import logging from os import getenv -from typing import Any, Dict +from typing import Any, ClassVar, Dict from .terachem_pbs import TeraChemPBSHarness, _pbs_defaults @@ -18,7 +18,7 @@ class TeraChemFrontEndHarness(TeraChemPBSHarness): _defaults = {**_pbs_defaults, **_fe_defaults} _tcpb_min_version = "0.9.0" _tcpb_client = "TCFrontEndClient" - _env_vars: Dict[str, Any] = { + _env_vars: ClassVar[Dict[str, Any]] = { **TeraChemPBSHarness._env_vars, **{ "frontend_host": getenv("TERACHEM_FE_HOST", "127.0.0.1"), diff --git a/qcengine/programs/terachem_pbs.py b/qcengine/programs/terachem_pbs.py index 4cee0a31e..1ca944e7e 100644 --- a/qcengine/programs/terachem_pbs.py +++ b/qcengine/programs/terachem_pbs.py @@ -4,7 +4,7 @@ import logging from importlib import import_module from os import getenv -from typing import TYPE_CHECKING, Any, Dict, Union +from typing import TYPE_CHECKING, Any, ClassVar, Dict, Union from qcelemental.models import AtomicResult, FailedOperation from qcelemental.util import which_import @@ -31,18 +31,15 @@ class TeraChemPBSHarness(ProgramHarness): """QCEngine Harness for interfacing with the TeraChem running in Protocol Buffer Server Mode""" - _defaults = _pbs_defaults - _tcpb_package: str = "tcpb" - _tcpb_min_version: str = "0.7.0" - _tcpb_client: str = "TCProtobufClient" - _env_vars: Dict[str, Any] = { + _defaults: ClassVar[Dict[str, Any]] = _pbs_defaults + _tcpb_package: ClassVar[str] = "tcpb" + _tcpb_min_version: ClassVar[str] = "0.7.0" + _tcpb_client: ClassVar[str] = "TCProtobufClient" + _env_vars: ClassVar[Dict[str, Any]] = { "host": getenv("TERACHEM_PBS_HOST", "127.0.0.1"), "port": int(getenv("TERACHEM_PBS_PORT", 11111)), } - _env_vars_external: str = "TERACHEM_PBS_HOST, TERACHEM_PBS_PORT" - - class Config(ProgramHarness.Config): - pass + _env_vars_external: ClassVar[str] = "TERACHEM_PBS_HOST, TERACHEM_PBS_PORT" @classmethod def found(cls, raise_error: bool = False) -> bool: diff --git a/qcengine/programs/torchani.py b/qcengine/programs/torchani.py index 2e81a5d9e..51e6592fe 100644 --- a/qcengine/programs/torchani.py +++ b/qcengine/programs/torchani.py @@ -31,9 +31,6 @@ class TorchANIHarness(ProgramHarness): } version_cache: Dict[str, str] = {} - class Config(ProgramHarness.Config): - pass - @staticmethod def found(raise_error: bool = False) -> bool: return which_import( diff --git a/qcengine/programs/xtb.py b/qcengine/programs/xtb.py index d9114b54d..217711a76 100644 --- a/qcengine/programs/xtb.py +++ b/qcengine/programs/xtb.py @@ -31,9 +31,6 @@ class XTBHarness(ProgramHarness): } version_cache: Dict[str, str] = {} - class Config(ProgramHarness.Config): - pass - @staticmethod def found(raise_error: bool = False) -> bool: """Check for the availability of the Python API of xtb""" diff --git a/qcengine/testing.py b/qcengine/testing.py index c7a3ecf11..4cb31d5e0 100644 --- a/qcengine/testing.py +++ b/qcengine/testing.py @@ -8,6 +8,7 @@ import pytest import qcelemental as qcel from pkg_resources import parse_version +from pydantic import ConfigDict from qcelemental.util import which, which_import import qcengine as qcng @@ -95,8 +96,9 @@ class FailEngine(qcng.programs.ProgramHarness): "managed_memory": False, } - class Config(qcng.programs.ProgramHarness.Config): - allow_mutation: True + model_config = ConfigDict( + frozen=False, + ) @staticmethod def found(raise_error: bool = False) -> bool: diff --git a/qcengine/tests/test_config.py b/qcengine/tests/test_config.py index 083a9774c..0dd4b1fa6 100644 --- a/qcengine/tests/test_config.py +++ b/qcengine/tests/test_config.py @@ -5,10 +5,7 @@ import copy import os -try: - import pydantic.v1 as pydantic -except ImportError: - import pydantic +import pydantic import pytest import qcengine as qcng diff --git a/qcengine/tests/test_utils.py b/qcengine/tests/test_utils.py index f1203da0b..6b84dfa4c 100644 --- a/qcengine/tests/test_utils.py +++ b/qcengine/tests/test_utils.py @@ -12,6 +12,7 @@ def test_model_wrapper(): with pytest.raises(InputError): +#pydantic.v1.error_wrappers.ValidationError util.model_wrapper({"bad": "yup"}, AtomicInput) diff --git a/qcengine/util.py b/qcengine/util.py index 352193885..a2931dcd0 100644 --- a/qcengine/util.py +++ b/qcengine/util.py @@ -18,10 +18,8 @@ from threading import Thread from typing import Any, BinaryIO, Dict, List, Optional, TextIO, Tuple, Union -try: - from pydantic.v1 import BaseModel, ValidationError -except ImportError: - from pydantic import BaseModel, ValidationError +import pydantic +from pydantic import BaseModel from qcelemental.models import AtomicResult, FailedOperation, OptimizationResult from qcengine.config import TaskConfig @@ -65,7 +63,7 @@ def model_wrapper(input_data: Dict[str, Any], model: BaseModel) -> BaseModel: if isinstance(input_data, dict): try: input_data = model(**input_data) - except ValidationError as exc: + except (pydantic.v1.ValidationError) as exc: raise InputError( f"Error creating '{model.__name__}', data could not be correctly parsed:\n{str(exc)}" ) from None