Skip to content

Commit

Permalink
fix import, tests, etc
Browse files Browse the repository at this point in the history
  • Loading branch information
loriab committed Sep 9, 2024
1 parent ded5edb commit 8f2d8b5
Show file tree
Hide file tree
Showing 19 changed files with 118 additions and 183 deletions.
5 changes: 5 additions & 0 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,18 @@ Changelog
Breaking Changes
++++++++++++++++
* The very old model names `ResultInput`, `Result`, `ResultProperties`, `Optimization` deprecated in 2019 are now only available through `qcelelemental.models.v1`
* ``models.v2`` do not support AutoDoc. The AutoDoc routines have been left at pydantic v1 syntax. Use autodoc-pydantic for Sphinx instead.

New Features
++++++++++++
* Downstream code should ``from qcelemental.models.v1 import Molecule, AtomicResult`` etc. to assure medium-term availability of existing models.
* New pydantic v2 models available as ``from qcelemental.models.v2 import Molecule, AtomicResult`` etc.

Enhancements
++++++++++++
* The ``models.v2`` have had their `schema_version` bumped for ``BasisSet``, ``AtomicInput``, ``OptimizationInput`` (implicit for ``AtomicResult`` and ``OptimizationResult``), ``TorsionDriveInput`` , and ``TorsionDriveResult``.
* The ``models.v2`` ``AtomicResultProperties`` has been given a ``schema_name`` and ``schema_version`` (2) for the first time.
* Note that ``models.v2`` ``QCInputSpecification`` and ``OptimizationSpecification`` have *not* had schema_version bumped.

Bug Fixes
+++++++++
Expand Down
9 changes: 9 additions & 0 deletions qcelemental/models/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,10 @@
try:
import pydantic
except ImportError: # pragma: no cover
raise ImportError(
"Python module pydantic not found. Solve by installing it: "
"`conda install pydantic -c conda-forge` or `pip install pydantic`"
)

from . import v1, v2
from .v1 import *
8 changes: 0 additions & 8 deletions qcelemental/models/v1/__init__.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,3 @@
try:
import pydantic
except ImportError: # pragma: no cover
raise ImportError(
"Python module pydantic not found. Solve by installing it: "
"`conda install pydantic -c conda-forge` or `pip install pydantic`"
)

from . import types
from .align import AlignmentMill
from .basemodels import AutodocBaseSettings # remove when QCFractal merges `next`
Expand Down
6 changes: 1 addition & 5 deletions qcelemental/models/v1/align.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
from typing import Optional

import numpy as np

try:
from pydantic.v1 import Field, validator
except ImportError: # Will also trap ModuleNotFoundError
from pydantic import Field, validator
from pydantic.v1 import Field, validator

from ...util import blockwise_contract, blockwise_expand
from .basemodels import ProtoModel
Expand Down
9 changes: 2 additions & 7 deletions qcelemental/models/v1/basemodels.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,8 @@
from typing import Any, Dict, Optional, Set, Union

import numpy as np

try:
from pydantic.v1 import BaseSettings # remove when QCFractal merges `next`
from pydantic.v1 import BaseModel
except ImportError: # Will also trap ModuleNotFoundError
from pydantic import BaseSettings # remove when QCFractal merges `next`
from pydantic import BaseModel
from pydantic.v1 import BaseSettings # remove when QCFractal merges `next`
from pydantic.v1 import BaseModel

from qcelemental.util import deserialize, serialize
from qcelemental.util.autodocs import AutoPydanticDocGenerator # remove when QCFractal merges `next`
Expand Down
5 changes: 1 addition & 4 deletions qcelemental/models/v1/basis.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
from enum import Enum
from typing import Dict, List, Optional

try:
from pydantic.v1 import ConstrainedInt, Field, constr, validator
except ImportError: # Will also trap ModuleNotFoundError
from pydantic import ConstrainedInt, Field, constr, validator
from pydantic.v1 import ConstrainedInt, Field, constr, validator

from ...exceptions import ValidationError
from .basemodels import ProtoModel, qcschema_draft
Expand Down
11 changes: 2 additions & 9 deletions qcelemental/models/v1/common_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,13 @@
from typing import TYPE_CHECKING, Any, Dict, Optional, Union

import numpy as np

try:
from pydantic.v1 import Field
except ImportError: # Will also trap ModuleNotFoundError
from pydantic import Field
from pydantic.v1 import Field

from .basemodels import ProtoModel, qcschema_draft
from .basis import BasisSet

if TYPE_CHECKING:
try:
from pydantic.v1.typing import ReprArgs
except ImportError: # Will also trap ModuleNotFoundError
from pydantic.typing import ReprArgs
from pydantic.v1.typing import ReprArgs


# Encoders, to be deprecated
Expand Down
11 changes: 2 additions & 9 deletions qcelemental/models/v1/molecule.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,7 @@
from typing import TYPE_CHECKING, Any, Dict, Iterable, List, Optional, Tuple, Union, cast

import numpy as np

try:
from pydantic.v1 import ConstrainedFloat, ConstrainedInt, Field, constr, validator
except ImportError: # Will also trap ModuleNotFoundError
from pydantic import ConstrainedFloat, ConstrainedInt, Field, constr, validator
from pydantic.v1 import ConstrainedFloat, ConstrainedInt, Field, constr, validator

# molparse imports separated b/c https://github.com/python/mypy/issues/7203
from ...molparse.from_arrays import from_arrays
Expand All @@ -31,10 +27,7 @@
from .types import Array

if TYPE_CHECKING:
try:
from pydantic.v1.typing import ReprArgs
except ImportError: # Will also trap ModuleNotFoundError
from pydantic.typing import ReprArgs
from pydantic.v1.typing import ReprArgs

# Rounding quantities for hashing
GEOMETRY_NOISE = 8
Expand Down
10 changes: 2 additions & 8 deletions qcelemental/models/v1/procedures.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
from enum import Enum
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Tuple

try:
from pydantic.v1 import Field, conlist, constr, validator
except ImportError: # Will also trap ModuleNotFoundError
from pydantic import Field, conlist, constr, validator
from pydantic.v1 import Field, conlist, constr, validator

from ...util import provenance_stamp
from .basemodels import ProtoModel
Expand All @@ -23,10 +20,7 @@
from .results import AtomicResult

if TYPE_CHECKING:
try:
from pydantic.v1.typing import ReprArgs
except ImportError: # Will also trap ModuleNotFoundError
from pydantic.typing import ReprArgs
from pydantic.v1.typing import ReprArgs


class TrajectoryProtocolEnum(str, Enum):
Expand Down
11 changes: 2 additions & 9 deletions qcelemental/models/v1/results.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,7 @@
from typing import TYPE_CHECKING, Any, Dict, Optional, Set, Union

import numpy as np

try:
from pydantic.v1 import Field, constr, validator
except ImportError: # Will also trap ModuleNotFoundError
from pydantic import Field, constr, validator
from pydantic.v1 import Field, constr, validator

from ...util import provenance_stamp
from .basemodels import ProtoModel, qcschema_draft
Expand All @@ -17,10 +13,7 @@
from .types import Array

if TYPE_CHECKING:
try:
from pydantic.v1.typing import ReprArgs
except ImportError: # Will also trap ModuleNotFoundError
from pydantic.typing import ReprArgs
from pydantic.v1.typing import ReprArgs


class AtomicResultProperties(ProtoModel):
Expand Down
19 changes: 19 additions & 0 deletions qcelemental/models/v2/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
from . import types
from .align import AlignmentMill
from .basemodels import ProtoModel
from .basis import BasisSet
from .common_models import ComputeError, DriverEnum, FailedOperation, Provenance
from .molecule import Molecule
from .procedures import OptimizationInput, OptimizationResult
from .results import AtomicInput, AtomicResult, AtomicResultProperties


def qcschema_models():
return [
AtomicInput,
AtomicResult,
AtomicResultProperties,
BasisSet,
Molecule,
Provenance,
]
8 changes: 0 additions & 8 deletions qcelemental/models/v2/basemodels.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,8 @@

import numpy as np
from pydantic import BaseModel, ConfigDict, model_serializer
from pydantic_settings import BaseSettings # remove when QCFractal merges `next`

from qcelemental.util import deserialize, serialize
from qcelemental.util.autodocs import AutoPydanticDocGenerator # remove when QCFractal merges `next`


def _repr(self) -> str:
Expand Down Expand Up @@ -279,10 +277,4 @@ def _merge_config_with(cls, *args, **kwargs):
return ExtendedConfigDict(**output_dict)


# remove when QCFractal merges `next`
class AutodocBaseSettings(BaseSettings):
def __init_subclass__(cls) -> None:
cls.__doc__ = AutoPydanticDocGenerator(cls, always_apply=True)


qcschema_draft = "http://json-schema.org/draft-04/schema#"
2 changes: 1 addition & 1 deletion qcelemental/models/v2/basis.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ class BasisSet(ProtoModel):
description=f"The QCSchema specification to which this model conforms. Explicitly fixed as qcschema_basis.",
)
schema_version: int = Field( # type: ignore
1,
2,
description="The version number of :attr:`~qcelemental.models.BasisSet.schema_name` "
"to which this model conforms.",
)
Expand Down
21 changes: 3 additions & 18 deletions qcelemental/models/v2/procedures.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ class OptimizationInput(ProtoModel):
schema_name: constr( # type: ignore
strip_whitespace=True, pattern=qcschema_optimization_input_default
) = qcschema_optimization_input_default
schema_version: int = 1
schema_version: int = 2

keywords: Dict[str, Any] = Field({}, description="The optimization specific keywords to be used.")
extras: Dict[str, Any] = Field({}, description="Extra fields that are not part of the schema.")
Expand Down Expand Up @@ -205,7 +205,7 @@ class TorsionDriveInput(ProtoModel):
schema_name: constr(
strip_whitespace=True, pattern=qcschema_torsion_drive_input_default
) = qcschema_torsion_drive_input_default # type: ignore
schema_version: int = 1
schema_version: int = 2

keywords: TDKeywords = Field(..., description="The torsion drive specific keywords to be used.")
extras: Dict[str, Any] = Field({}, description="Extra fields that are not part of the schema.")
Expand Down Expand Up @@ -239,7 +239,7 @@ class TorsionDriveResult(TorsionDriveInput):
schema_name: constr(
strip_whitespace=True, pattern=qcschema_torsion_drive_output_default
) = qcschema_torsion_drive_output_default # type: ignore
schema_version: int = 1
schema_version: int = 2

final_energies: Dict[str, float] = Field(
..., description="The final energy at each angle of the TorsionDrive scan."
Expand All @@ -261,18 +261,3 @@ class TorsionDriveResult(TorsionDriveInput):
)
error: Optional[ComputeError] = Field(None, description=str(ComputeError.__doc__))
provenance: Provenance = Field(..., description=str(Provenance.__doc__))


def Optimization(*args, **kwargs):
"""QC Optimization Results Schema.
.. deprecated:: 0.12
Use :py:func:`qcelemental.models.OptimizationResult` instead.
"""
from warnings import warn

warn(
"Optimization has been renamed to OptimizationResult and will be removed as soon as v0.13.0", DeprecationWarning
)
return OptimizationResult(*args, **kwargs)
85 changes: 18 additions & 67 deletions qcelemental/models/v2/results.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@
from functools import partial
from typing import TYPE_CHECKING, Any, Dict, Optional, Set, Union

try:
from typing import Literal
except ImportError:
# remove when minimum py38
from typing_extensions import Literal

import numpy as np
from pydantic import Field, constr, field_validator

Expand All @@ -26,6 +32,17 @@ class AtomicResultProperties(ProtoModel):
* nmo: number of molecular orbitals = :attr:`~qcelemental.models.AtomicResultProperties.calcinfo_nmo`
"""

schema_name: Literal["qcschema_atomicproperties"] = Field(
"qcschema_atomicproperties",
description=(
f"The QCSchema specification this model conforms to. Explicitly fixed as qcschema_atomicproperties."
),
)
schema_version: int = Field(
2,
description="The version number of :attr:`~qcelemental.models.AtomicResultProperties.schema_name` to which this model conforms.",
)

# Calcinfo
calcinfo_nbasis: Optional[int] = Field(None, description="The number of basis functions for the computation.")
calcinfo_nmo: Optional[int] = Field(None, description="The number of molecular orbitals for the computation.")
Expand Down Expand Up @@ -642,7 +659,7 @@ class AtomicInput(ProtoModel):
),
)
schema_version: int = Field(
1,
2,
description="The version number of :attr:`~qcelemental.models.AtomicInput.schema_name` to which this model conforms.",
)

Expand Down Expand Up @@ -831,69 +848,3 @@ def _native_file_protocol(cls, value, info):
for rk in return_keep:
ret[rk] = files.get(rk, None)
return ret


class ResultProperties(AtomicResultProperties):
"""QC Result Properties Schema.
.. deprecated:: 0.12
Use :py:func:`qcelemental.models.AtomicResultProperties` instead.
"""

def __init__(self, *args, **kwargs):
from warnings import warn

warn(
"ResultProperties has been renamed to AtomicResultProperties and will be removed as soon as v0.13.0",
DeprecationWarning,
)
super().__init__(*args, **kwargs)


class ResultProtocols(AtomicResultProtocols):
"""QC Result Protocols Schema.
.. deprecated:: 0.12
Use :py:func:`qcelemental.models.AtomicResultProtocols` instead.
"""

def __init__(self, *args, **kwargs):
from warnings import warn

warn(
"ResultProtocols has been renamed to AtomicResultProtocols and will be removed as soon as v0.13.0",
DeprecationWarning,
)
super().__init__(*args, **kwargs)


class ResultInput(AtomicInput):
"""QC Input Schema.
.. deprecated:: 0.12
Use :py:func:`qcelemental.models.AtomicInput` instead.
"""

def __init__(self, *args, **kwargs):
from warnings import warn

warn("ResultInput has been renamed to AtomicInput and will be removed as soon as v0.13.0", DeprecationWarning)
super().__init__(*args, **kwargs)


class Result(AtomicResult):
"""QC Result Schema.
.. deprecated:: 0.12
Use :py:func:`qcelemental.models.AtomicResult` instead.
"""

def __init__(self, *args, **kwargs):
from warnings import warn

warn("Result has been renamed to AtomicResult and will be removed as soon as v0.13.0", DeprecationWarning)
super().__init__(*args, **kwargs)
Loading

0 comments on commit 8f2d8b5

Please sign in to comment.