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

Pydantic v1/v2 compatibility #232

Merged
merged 16 commits into from
Jan 19, 2024
Merged
Show file tree
Hide file tree
Changes from 14 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
11 changes: 9 additions & 2 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,19 @@ defaults:
jobs:
test:

name: ${{ matrix.cfg.os }}, 🐍=${{ matrix.python-version }}, program=${{ matrix.cfg.conda-env }}
name: ${{ matrix.cfg.os }}, 🐍=${{ matrix.python-version }}, program=${{ matrix.cfg.conda-env }}, pydantic=${{ matrix.pydantic-version }}
runs-on: ${{ matrix.cfg.os }}

strategy:
fail-fast: false
matrix:
python-version:
- "3.9"
- "3.10"
mattwthompson marked this conversation as resolved.
Show resolved Hide resolved
- "3.11"
pydantic-version:
- "1"
- "2"
cfg:
- os: ubuntu-latest
conda-env: basic
Expand All @@ -46,7 +51,9 @@ jobs:

with:
environment-file: devtools/conda-envs/${{ matrix.cfg.conda-env }}.yaml
create-args: python=${{ matrix.python-version }}
create-args: >-
python=${{ matrix.python-version }}
pydantic=${{ matrix.pydantic-version }}

- name: License OpenEye

Expand Down
13 changes: 5 additions & 8 deletions .github/workflows/Lint.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,17 @@ jobs:
steps:

- uses: actions/checkout@v4
- uses: actions/setup-python@v5.0.0
- uses: actions/setup-python@v5
with:
python-version: '3.8'
python-version: '3.10'
- name: Install the package
run: python -m pip install .

- name: Install isort / black
run: |
pip install isort black
run: pip install isort black

- name: Run isort
run: |
isort --recursive --check-only openff
run: isort --check-only openff

- name: Run black
run: |
black openff --check
run: black openff --check
9 changes: 5 additions & 4 deletions devtools/conda-envs/basic.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,16 @@ dependencies:
# Testing
- pytest
- pytest-cov
- pytest-randomly
- pytest-xdist
- pytest-randomly
- requests-mock

- qcengine >=0.25
- qcelemental >=0.25.1
- qcfractal>0.49
- qcarchivetesting>0.49
- qcportal>=0.49
- qcfractal >=0.52
- qcarchivetesting
- qcportal

- postgresql

Expand All @@ -35,7 +36,7 @@ dependencies:

- openff-toolkit >= 0.14.0
- openff-units >=0.2.1
- pydantic =1
- pydantic
- pyyaml
- torsiondrive
- basis_set_exchange
Expand Down
4 changes: 2 additions & 2 deletions devtools/conda-envs/docs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ dependencies:

- openff-toolkit-base =0.14.0
- rdkit
- pydantic =1
- pydantic
- pyyaml
- qcportal >=0.15
- qcportal >=0.52
- torsiondrive
- basis_set_exchange
- typing-extensions
Expand Down
11 changes: 6 additions & 5 deletions devtools/conda-envs/psi4.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,15 @@ dependencies:
# Testing
- pytest
- pytest-cov
- codecov
- pytest-randomly
- pytest-xdist
- requests-mock

- qcengine >=0.25
- qcelemental >=0.25.1
- qcfractal>0.49
- qcarchivetesting>0.49
- qcportal>=0.49
- qcfractal >=0.52
- qcarchivetesting
- qcportal

- openeye-toolkits

Expand All @@ -32,7 +33,7 @@ dependencies:
- openff-toolkit-base >= 0.14.0
- openff-units >=0.2.1
- rdkit
- pydantic =1
- pydantic
- pyyaml
- torsiondrive
- basis_set_exchange
Expand Down
21 changes: 21 additions & 0 deletions openff/qcsubmit/_pydantic.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
"""Centralized shim for Pydantic v1/v2 compatible import."""
try:
from pydantic.v1 import (
BaseModel,
Field,
PrivateAttr,
ValidationError,
constr,
root_validator,
validator,
)
except ImportError:
from pydantic import (
BaseModel,
Field,
PrivateAttr,
ValidationError,
constr,
root_validator,
validator,
)
2 changes: 1 addition & 1 deletion openff/qcsubmit/_tests/results/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@
import numpy
from openff.toolkit.topology import Molecule
from openff.units import unit
from pydantic import BaseModel
from qcelemental.models import DriverEnum
from qcelemental.models.procedures import TDKeywords
from qcportal.optimization import OptimizationRecord, OptimizationSpecification
from qcportal.record_models import RecordStatusEnum
from qcportal.singlepoint import QCSpecification, SinglepointRecord
from qcportal.torsiondrive import TorsiondriveRecord, TorsiondriveSpecification

from openff.qcsubmit._pydantic import BaseModel
from openff.qcsubmit.results import (
BasicResult,
BasicResultCollection,
Expand Down
2 changes: 1 addition & 1 deletion openff/qcsubmit/_tests/results/test_filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
import pytest
from openff.toolkit.topology import Molecule
from openff.units import unit
from pydantic import ValidationError
from qcelemental.models import DriverEnum
from qcportal.singlepoint import QCSpecification

from openff.qcsubmit._pydantic import ValidationError
from openff.qcsubmit._tests.results import mock_optimization_result_collection
from openff.qcsubmit.results import (
BasicResult,
Expand Down
2 changes: 1 addition & 1 deletion openff/qcsubmit/_tests/results/test_results.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@
import pytest
from openff.toolkit.topology import Molecule
from openff.toolkit.typing.engines.smirnoff import ForceField
from pydantic import ValidationError
from qcelemental.models import DriverEnum
from qcportal.torsiondrive import (
TorsiondriveKeywords,
TorsiondriveRecord,
TorsiondriveSpecification,
)

from openff.qcsubmit._pydantic import ValidationError
from openff.qcsubmit._tests import does_not_raise
from openff.qcsubmit.common_structures import QCSpec
from openff.qcsubmit.exceptions import RecordTypeError
Expand Down
2 changes: 1 addition & 1 deletion openff/qcsubmit/_tests/test_datasets.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
from openff.toolkit.topology import Molecule
from openff.toolkit.typing.engines.smirnoff import ForceField
from openff.units import unit
from pydantic import ValidationError
from qcelemental.models.procedures import OptimizationProtocols

from openff.qcsubmit._pydantic import ValidationError
from openff.qcsubmit.common_structures import MoleculeAttributes, QCSpec
from openff.qcsubmit.constraints import Constraints, PositionConstraintSet
from openff.qcsubmit.datasets import (
Expand Down
2 changes: 1 addition & 1 deletion openff/qcsubmit/_tests/test_factories.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@

import pytest
from openff.toolkit.topology import Molecule
from pydantic import ValidationError

from openff.qcsubmit import workflow_components
from openff.qcsubmit._pydantic import ValidationError
from openff.qcsubmit.datasets import BasicDataset, OptimizationDataset
from openff.qcsubmit.exceptions import DriverError, InvalidWorkflowComponentError
from openff.qcsubmit.factories import (
Expand Down
2 changes: 1 addition & 1 deletion openff/qcsubmit/_tests/test_workflow_components.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@
RDKitToolkitWrapper,
ToolkitRegistry,
)
from pydantic import ValidationError
from typing_extensions import Literal

from openff.qcsubmit import workflow_components
from openff.qcsubmit._pydantic import ValidationError
from openff.qcsubmit.common_structures import ComponentProperties
from openff.qcsubmit.exceptions import (
ComponentRegisterError,
Expand Down
39 changes: 27 additions & 12 deletions openff/qcsubmit/common_structures.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,6 @@

import numpy as np
from openff.toolkit.topology import Molecule
from pydantic import (
BaseModel,
Field,
HttpUrl,
PositiveInt,
StrictBool,
StrictFloat,
StrictInt,
StrictStr,
constr,
validator,
)
from qcelemental import constants
from qcelemental.models.common_models import Model
from qcelemental.models.results import WavefunctionProtocolEnum
Expand All @@ -46,6 +34,33 @@
)
from openff.qcsubmit.utils.smirnoff import split_openff_molecule

try:
from pydantic.v1 import (
BaseModel,
Field,
HttpUrl,
PositiveInt,
StrictBool,
StrictFloat,
StrictInt,
StrictStr,
constr,
validator,
)
except ImportError:
from pydantic import (
BaseModel,
Field,
HttpUrl,
PositiveInt,
StrictBool,
StrictFloat,
StrictInt,
StrictStr,
constr,
validator,
)

if TYPE_CHECKING:
DictStrAny = Dict[str, Any]
IntStr = Union[int, str]
Expand Down
2 changes: 1 addition & 1 deletion openff/qcsubmit/constraints.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
"""
from typing import List, Tuple, Union

from pydantic import Field, ValidationError, validator
from typing_extensions import Literal

from openff.qcsubmit._pydantic import Field, ValidationError, validator
from openff.qcsubmit.common_structures import ResultsConfig
from openff.qcsubmit.exceptions import ConstraintError

Expand Down
2 changes: 1 addition & 1 deletion openff/qcsubmit/datasets/datasets.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
import qcelemental as qcel
import qcportal as ptl
from openff.toolkit import topology as off
from pydantic import Field, constr, validator
from qcelemental.models import AtomicInput, OptimizationInput
from qcelemental.models.procedures import OptimizationProtocols, QCInputSpecification
from qcportal import PortalClient, PortalRequestError
Expand All @@ -31,6 +30,7 @@
from qcportal.torsiondrive import TorsiondriveDatasetNewEntry, TorsiondriveSpecification
from typing_extensions import Literal

from openff.qcsubmit._pydantic import Field, constr, validator
from openff.qcsubmit.common_structures import CommonBase, Metadata, MoleculeAttributes
from openff.qcsubmit.constraints import Constraints
from openff.qcsubmit.datasets.entries import (
Expand Down
2 changes: 1 addition & 1 deletion openff/qcsubmit/datasets/entries.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@
import qcelemental as qcel
import qcelemental.models
from openff.units import unit
from pydantic import Field, validator
from typing_extensions import Literal

from openff.qcsubmit._pydantic import Field, validator
from openff.qcsubmit.common_structures import (
DatasetConfig,
MoleculeAttributes,
Expand Down
2 changes: 1 addition & 1 deletion openff/qcsubmit/factories.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
import tqdm
from openff.toolkit import topology as off
from openff.toolkit.utils import GLOBAL_TOOLKIT_REGISTRY, ToolkitRegistry
from pydantic import Field, validator
from qcportal.singlepoint import SinglepointDriver
from typing_extensions import Literal

from openff.qcsubmit._pydantic import Field, validator
from openff.qcsubmit.common_structures import CommonBase, Metadata
from openff.qcsubmit.datasets import (
BasicDataset,
Expand Down
2 changes: 1 addition & 1 deletion openff/qcsubmit/procedures.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@

from typing import Any, Dict

from pydantic import BaseModel, Field, validator
from qcportal.optimization import OptimizationSpecification
from typing_extensions import Literal

from openff.qcsubmit._pydantic import BaseModel, Field, validator
from openff.qcsubmit.validators import literal_lower, literal_upper


Expand Down
8 changes: 7 additions & 1 deletion openff/qcsubmit/results/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,19 @@
)
from openff.units import unit
from openff.utilities import requires_package
from pydantic import BaseModel, Field, PrivateAttr, root_validator, validator
from qcelemental.molutil import guess_connectivity
from qcportal.optimization import OptimizationRecord
from qcportal.record_models import BaseRecord, RecordStatusEnum
from qcportal.singlepoint import SinglepointRecord
from typing_extensions import Literal

from openff.qcsubmit._pydantic import (
BaseModel,
Field,
PrivateAttr,
root_validator,
validator,
)
from openff.qcsubmit.results.results import (
TorsionDriveResultCollection,
_BaseResult,
Expand Down
2 changes: 1 addition & 1 deletion openff/qcsubmit/results/results.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
from openff.toolkit.topology import Molecule
from openff.toolkit.typing.engines.smirnoff import ForceField
from openff.units import unit
from pydantic import BaseModel, Field, validator
from qcportal import PortalClient
from qcportal.dataset_models import BaseDataset as QCPDataset
from qcportal.optimization import OptimizationDataset, OptimizationRecord
Expand All @@ -38,6 +37,7 @@
from qcportal.torsiondrive import TorsiondriveDataset, TorsiondriveRecord
from typing_extensions import Literal

from openff.qcsubmit._pydantic import BaseModel, Field, validator
from openff.qcsubmit.common_structures import Metadata, MoleculeAttributes, QCSpec
from openff.qcsubmit.datasets import BasicDataset
from openff.qcsubmit.exceptions import RecordTypeError
Expand Down
2 changes: 1 addition & 1 deletion openff/qcsubmit/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
from typing import IO, Dict, Optional, Tuple, Union

import yaml
from pydantic import BaseModel
from typing_extensions import Literal

from openff.qcsubmit._pydantic import BaseModel
from openff.qcsubmit.exceptions import UnsupportedFiletypeError

__all__ = [
Expand Down
Loading