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

Begin supporting Pydantic 2 (without dropping support for Pydantic 1) #238

Merged
merged 5 commits into from
Jan 3, 2024
Merged
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: 6 additions & 0 deletions .changes/unreleased/Dependencies-20231221-130418.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
kind: Dependencies
body: Add support for pydantic 2 (and continue support for pydantic 1)
time: 2023-12-21T13:04:18.792592-08:00
custom:
Author: QMalcolm bernardcooke53 esciara
PR: "134"
3 changes: 3 additions & 0 deletions .github/workflows/ci-pre-commit.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,8 @@ jobs:
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/setup-python-env
# This step is necessary so long as we're allowing Pydantic 1 and Pydantic 2 via shimming
- name: Force Pydantic 1
run: hatch run dev-env:pip install "pydantic~=1.10"
- name: Run Pre-commit Hooks
run: hatch run dev-env:pre-commit run --show-diff-on-failure --color=always --all-files
5 changes: 4 additions & 1 deletion .github/workflows/ci-pytest.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,12 @@ on:

jobs:
pytest:
name: Run Tests / Python ${{ matrix.python-version }}
name: Run Tests / Python ${{ matrix.python-version }} / Pydantic ~= ${{ matrix.pydantic-version }}

strategy:
matrix:
python-version: ["3.8", "3.9", "3.10", "3.11"]
pydantic-version: ["1.10", "2.0"]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
Expand All @@ -26,5 +27,7 @@ jobs:
- name: Install Hatch
shell: bash
run: pip3 install hatch
- name: Set pydantic Version ~= ${{ matrix.pydantic-version }}
run: hatch run dev-env:pip install "pydantic~=${{ matrix.pydantic-version }}"
- name: Run Python Tests
run: hatch run dev-env:pytest tests
5 changes: 2 additions & 3 deletions dbt_semantic_interfaces/dataclass_serialization.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,10 @@
get_type_hints,
)

import pydantic
from pydantic import BaseModel
from typing_extensions import TypeAlias

from dbt_semantic_interfaces.pretty_print import pformat_big_objects
from pydantic_shim import BaseModel, create_model

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -347,7 +346,7 @@ def _convert_dataclass_type_to_pydantic_type(
logger.debug(
f"Creating Pydantic model {class_name} with fields:\n{pformat_big_objects(fields_for_pydantic_model)}"
)
pydantic_model = pydantic.create_model(class_name, **fields_for_pydantic_model) # type: ignore
pydantic_model = create_model(class_name, **fields_for_pydantic_model) # type: ignore
logger.debug(f"Finished creating Pydantic model {class_name}")
logger.debug(f"Finished converting {dataclass_type.__name__} to a pydantic class")
return pydantic_model
Expand Down
3 changes: 1 addition & 2 deletions dbt_semantic_interfaces/implementations/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,12 @@
from abc import ABC, abstractmethod
from typing import Any, Callable, ClassVar, Generator, Generic, Type, TypeVar

from pydantic import BaseModel, root_validator

from dbt_semantic_interfaces.errors import ParsingException
from dbt_semantic_interfaces.parsing.yaml_loader import (
PARSING_CONTEXT_KEY,
ParsingContext,
)
from pydantic_shim import BaseModel, root_validator

# Type alias for the implicit "Any" type used as input and output for Pydantic's parsing API
PydanticParseableValueType = Any # type: ignore[misc]
Expand Down
2 changes: 1 addition & 1 deletion dbt_semantic_interfaces/implementations/export.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

from typing import Optional

from pydantic import Field
from typing_extensions import override

from dbt_semantic_interfaces.implementations.base import HashableBaseModel
Expand All @@ -11,6 +10,7 @@
from dbt_semantic_interfaces.type_enums.export_destination_type import (
ExportDestinationType,
)
from pydantic_shim import Field


class PydanticExportConfig(HashableBaseModel, ProtocolHint[ExportConfig]):
Expand Down
3 changes: 1 addition & 2 deletions dbt_semantic_interfaces/implementations/metric.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

from typing import List, Optional, Sequence

from pydantic import Field

from dbt_semantic_interfaces.enum_extension import assert_values_exhausted
from dbt_semantic_interfaces.errors import ParsingException
from dbt_semantic_interfaces.implementations.base import (
Expand All @@ -22,6 +20,7 @@
MetricType,
TimeGranularity,
)
from pydantic_shim import Field


class PydanticMetricInputMeasure(PydanticCustomInputParser, HashableBaseModel):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
from typing import List, Optional

from importlib_metadata import version
from pydantic import validator
from typing_extensions import override

from dbt_semantic_interfaces.implementations.base import (
Expand All @@ -20,6 +19,7 @@
)
from dbt_semantic_interfaces.protocols import ProtocolHint
from dbt_semantic_interfaces.protocols.project_configuration import ProjectConfiguration
from pydantic_shim import validator


class PydanticProjectConfiguration(HashableBaseModel, ModelWithMetadataParsing, ProtocolHint[ProjectConfiguration]):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

from typing import Any, List, Optional, Sequence

from pydantic import validator
from typing_extensions import override

from dbt_semantic_interfaces.implementations.base import (
Expand All @@ -25,6 +24,7 @@
SemanticModelReference,
TimeDimensionReference,
)
from pydantic_shim import validator


class NodeRelation(HashableBaseModel):
Expand Down
2 changes: 1 addition & 1 deletion dbt_semantic_interfaces/validations/validator_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
)

import click
from pydantic import BaseModel, Extra

from dbt_semantic_interfaces.implementations.base import FrozenBaseModel
from dbt_semantic_interfaces.protocols import Metadata, SemanticManifestT, SemanticModel
Expand All @@ -30,6 +29,7 @@
SemanticModelReference,
)
from dbt_semantic_interfaces.type_enums import DimensionType
from pydantic_shim import BaseModel, Extra

VALIDATE_SAFELY_ERROR_STR_TMPLT = ". Issue occurred in method `{method_name}` called with {arguments_str}"
ValidationContextJSON = Dict[str, Union[str, int, None]]
Expand Down
26 changes: 26 additions & 0 deletions pydantic_shim.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
from importlib.metadata import version

pydantic_version = version("pydantic")
# Pydantic uses semantic versioning, i.e. <major>.<minor>.<patch>, and we need to know the major
pydantic_major = pydantic_version.split(".")[0]

if pydantic_major == "1":
from pydantic import ( # type: ignore # noqa
BaseModel,
Extra,
Field,
create_model,
root_validator,
validator,
)
elif pydantic_major == "2":
from pydantic.v1 import ( # type: ignore # noqa
BaseModel,
Extra,
Field,
create_model,
root_validator,
validator,
)
else:
raise RuntimeError(f"Currently only pydantic 1 and 2 are supported, found pydantic {pydantic_version}")
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ classifiers = [
"Programming Language :: Python :: Implementation :: PyPy",
]
dependencies = [
"pydantic~=1.10",
"pydantic>=1.10,<3",
"jsonschema~=4.0",
"PyYAML~=6.0",
"more-itertools>=8.0,<11.0",
Expand Down
Loading