Skip to content

Commit

Permalink
Merge pull request #240 from dbt-labs/backport-238-to-0.4.latest
Browse files Browse the repository at this point in the history
[BACKPORT] #238 to 0.4.latest (Pydantic 2 Support)
  • Loading branch information
QMalcolm authored Jan 3, 2024
2 parents ccb2031 + f183092 commit 653a177
Show file tree
Hide file tree
Showing 12 changed files with 48 additions and 13 deletions.
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
2 changes: 1 addition & 1 deletion dbt_semantic_interfaces/implementations/semantic_model.py
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

0 comments on commit 653a177

Please sign in to comment.