Skip to content

Commit

Permalink
Support Pydantic v2 (#248)
Browse files Browse the repository at this point in the history
  • Loading branch information
pilosus committed Sep 22, 2023
1 parent b8ff5da commit da0fdce
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 11 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
Changelog
---------

v1.1.0 (2023-09-22)
...................

* Added: new validator `PydanticV2Validator` to support Pydantic v2


v1.0.2 (2023-02-03)
...................

Expand Down
12 changes: 10 additions & 2 deletions docs/code/flask_integration.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
from flask import Flask
from flask.logging import default_handler
from piny import YamlLoader, StrictMatcher, PydanticValidator
from piny import YamlLoader, StrictMatcher, PydanticV2Validator
from pydantic import BaseModel, validator
from typing import Any, Dict, Optional
from werkzeug.serving import run_simple
import logging
import sys

# Watch out!
# Pydantic V2 deprecated some model's methods:
# https://docs.pydantic.dev/2.0/migration/
#
# For Pydantic v2 use `PydanticV2Validator`
# For Pydantic v1 use `PydanticValidator`


#
# Validation
#
Expand Down Expand Up @@ -78,7 +86,7 @@ def create_app(path: str) -> Flask:
config = YamlLoader(
path=path,
matcher=StrictMatcher,
validator=PydanticValidator,
validator=PydanticV2Validator,
schema=Configuration,
).load()

Expand Down
10 changes: 8 additions & 2 deletions docs/code/pydantic_validation.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
from pydantic import BaseModel
from piny import PydanticValidator, StrictMatcher, YamlLoader
from piny import PydanticV2Validator, StrictMatcher, YamlLoader

# Watch out!
# Pydantic V2 deprecated some model's methods:
# https://docs.pydantic.dev/2.0/migration/
#
# For Pydantic v2 use `PydanticV2Validator`
# For Pydantic v1 use `PydanticValidator`

class DBModel(BaseModel):
login: str
Expand All @@ -14,6 +20,6 @@ class ConfigModel(BaseModel):
config = YamlLoader(
path="database.yaml",
matcher=StrictMatcher,
validator=PydanticValidator,
validator=PydanticV2Validator,
schema=ConfigModel,
).load()
7 changes: 6 additions & 1 deletion src/piny/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
from .errors import ConfigError, LoadingError, ValidationError
from .loaders import YamlLoader, YamlStreamLoader
from .matchers import Matcher, MatcherWithDefaults, StrictMatcher
from .validators import MarshmallowValidator, PydanticValidator, TrafaretValidator
from .validators import (
MarshmallowValidator,
PydanticV2Validator,
PydanticValidator,
TrafaretValidator,
)
16 changes: 14 additions & 2 deletions src/piny/validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ def load(self, data: LoadedData, **params):
pass # pragma: no cover


class PydanticValidator(Validator):
class PydanticValidator(Validator): # pragma: no cover
"""
Validator class for Pydantic library
Validator class for Pydantic Version 1
"""

def load(self, data: LoadedData, **params):
Expand All @@ -37,6 +37,18 @@ def load(self, data: LoadedData, **params):
raise ValidationError(origin=e, reason=str(e))


class PydanticV2Validator(Validator):
"""
Validator class for Pydantic Version 2
"""

def load(self, data: LoadedData, **params):
try:
return self.schema(**data).model_dump()
except Exception as e:
raise ValidationError(origin=e, reason=str(e))


class MarshmallowValidator(Validator):
"""
Validator class for Marshmallow library
Expand Down
13 changes: 9 additions & 4 deletions tests/test_validators.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
from unittest import mock

import pydantic
import pytest
import trafaret
from marshmallow import Schema, fields
from pydantic import BaseModel
from packaging import version

from piny import (
MarshmallowValidator,
PydanticV2Validator,
PydanticValidator,
StrictMatcher,
TrafaretValidator,
Expand All @@ -17,18 +19,21 @@

from . import config_directory, config_map

if version.parse(pydantic.__version__) >= version.parse("2.0"):
PydanticValidator = PydanticV2Validator

#
# Const
#


class PydanticDB(BaseModel):
class PydanticDB(pydantic.BaseModel):
host: str
login: str
password: str


class PydanticConfig(BaseModel):
class PydanticConfig(pydantic.BaseModel):
db: PydanticDB


Expand Down Expand Up @@ -71,7 +76,7 @@ def test_pydantic_validator_success(name):

@pytest.mark.parametrize("name", ["db"])
def test_pydantic_validator_fail(name):
with pytest.raises(ValidationError, match=r"db -> password"):
with pytest.raises(ValidationError, match=r"db.*password"):
YamlLoader(
path=config_directory.joinpath("{}.yaml".format(name)),
matcher=StrictMatcher,
Expand Down

0 comments on commit da0fdce

Please sign in to comment.