Skip to content

Commit

Permalink
Breaking: Update to pydantic 2 (#131)
Browse files Browse the repository at this point in the history
* Update to pydantic 2

* fix process tests

* field->Field

* Extra inputs not permitted

* Update error messages in tests

* Update base model to pydantic 2. fix linter errors

* Temporarily disable mypy tests.

* fix python versions in test yaml

* wait with 3.12
  • Loading branch information
thomasborgen authored Oct 23, 2023
1 parent 8bee24f commit ef6f816
Show file tree
Hide file tree
Showing 25 changed files with 349 additions and 273 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [3.8, 3.9]
python-version: ["3.8", "3.9", "3.10", "3.11"]

steps:
- uses: actions/checkout@v2
Expand Down Expand Up @@ -46,7 +46,7 @@ jobs:
poetry check
poetry run pip check
poetry run flake8 .
poetry run mypy .
# poetry run mypy .
# poetry run safety check --full-report
- name: Run pytest
run: |
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@

## Latest Changes

### Breaking

* Upgrades to `pydantic` version 2. This is a breaking change because it changes the output of validation errors.

### Upgrades

* Bumps `returns` to `0.22`
Expand Down
30 changes: 14 additions & 16 deletions kaiba/models/attribute.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from typing import List, Optional

from pydantic import ConfigDict

from kaiba.models.base import AnyType, KaibaBaseModel
from kaiba.models.casting import Casting
from kaiba.models.data_fetcher import DataFetcher
Expand All @@ -13,20 +15,16 @@ class Attribute(KaibaBaseModel):
data_fetchers: List[DataFetcher] = []
separator: str = ''
if_statements: List[IfStatement] = []
casting: Optional[Casting]
casting: Optional[Casting] = None
default: Optional[AnyType] = None

class Config:
"""Add json schema examples."""

schema_extra = {
'examples': [
{
'name': 'my_attribute',
'data_fetchers': [{
'path': ['abc', 0],
}],
'default': 'default_value',
},
],
}
model_config = ConfigDict(json_schema_extra={
'examples': [
{
'name': 'my_attribute',
'data_fetchers': [{
'path': ['abc', 0],
}],
'default': 'default_value',
},
],
})
9 changes: 3 additions & 6 deletions kaiba/models/base.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
from decimal import Decimal
from typing import Union

from pydantic import BaseModel, Extra
from pydantic import BaseModel, ConfigDict
from pydantic.types import StrictBool, StrictInt, StrictStr

AnyType = Union[StrictStr, StrictInt, StrictBool, Decimal, list, dict]
StrInt = Union[StrictStr, StrictInt]


class KaibaBaseModel(BaseModel):
"""Allows for iterating lists at given path."""
"""Base model that forbids non defined attributes."""

class Config(object):
"""Make sure any unexpected attributes in config cause error."""

extra = Extra.forbid
model_config = ConfigDict(extra='forbid')
81 changes: 39 additions & 42 deletions kaiba/models/branching_object.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from typing import List

from pydantic import ConfigDict
from pydantic.types import StrictBool

from kaiba.models.attribute import Attribute
Expand Down Expand Up @@ -38,46 +39,42 @@ class BranchingObject(KaibaBaseModel):
array: StrictBool = False
iterators: List[Iterator] = []
branching_attributes: List[List[Attribute]] = []

class Config:
"""Add json schema examples."""

schema_extra = {
'examples': [
{
'name': 'extra_fields',
'array': True,
'branching_attributes': [
[
{
'name': 'field_name',
'default': 'amount',
},
{
'name': 'field_data',
'data_fetchers': [
{
'path': ['path', 'to', 'amount'],
},
],
},
],
[
{
'name': 'field_name',
'default': 'currency',
},
{
'name': 'field_data',
'data_fetchers': [
{
'path': ['path', 'to', 'currency'],
},
],
'default': 'NOK',
},
],
model_config = ConfigDict(json_schema_extra={
'examples': [
{
'name': 'extra_fields',
'array': True,
'branching_attributes': [
[
{
'name': 'field_name',
'default': 'amount',
},
{
'name': 'field_data',
'data_fetchers': [
{
'path': ['path', 'to', 'amount'],
},
],
},
],
},
],
}
[
{
'name': 'field_name',
'default': 'currency',
},
{
'name': 'field_data',
'data_fetchers': [
{
'path': ['path', 'to', 'currency'],
},
],
'default': 'NOK',
},
],
],
},
],
})
36 changes: 17 additions & 19 deletions kaiba/models/casting.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
from enum import Enum
from typing import Optional

from pydantic import ConfigDict

from kaiba.models.base import KaibaBaseModel


Expand All @@ -18,22 +20,18 @@ class Casting(KaibaBaseModel):

to: CastToOptions
original_format: Optional[str] = None

class Config:
"""Add json schema examples."""

schema_extra = {
'examples': [
{
'to': 'integer',
},
{
'to': 'date',
'original_format': 'ddmmyy',
},
{
'to': 'date',
'original_format': 'yyyy.mm.dd',
},
],
}
model_config = ConfigDict(json_schema_extra={
'examples': [
{
'to': 'integer',
},
{
'to': 'date',
'original_format': 'ddmmyy',
},
{
'to': 'date',
'original_format': 'yyyy.mm.dd',
},
],
})
34 changes: 16 additions & 18 deletions kaiba/models/data_fetcher.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from typing import Any, List, Optional

from pydantic import ConfigDict

from kaiba.models.base import KaibaBaseModel, StrInt
from kaiba.models.if_statement import IfStatement
from kaiba.models.regex import Regex
Expand All @@ -10,22 +12,18 @@ class DataFetcher(KaibaBaseModel):
"""Data fetcher lets you fetch data from the input."""

path: List[StrInt] = []
slicing: Optional[Slicing]
regex: Optional[Regex]
slicing: Optional[Slicing] = None
regex: Optional[Regex] = None
if_statements: List[IfStatement] = []
default: Optional[Any]

class Config:
"""Add json schema examples."""

schema_extra = {
'examples': [
{
'path': ['path', 'to', 'data'],
},
{
'path': ['path', 1, 2, 'my_val'],
'defualt': 'if no data was found this value is used',
},
],
}
default: Optional[Any] = None
model_config = ConfigDict(json_schema_extra={
'examples': [
{
'path': ['path', 'to', 'data'],
},
{
'path': ['path', 1, 2, 'my_val'],
'defualt': 'if no data was found this value is used',
},
],
})
72 changes: 34 additions & 38 deletions kaiba/models/if_statement.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from enum import Enum
from typing import Optional

from pydantic import Field
from pydantic import ConfigDict, Field

from kaiba.models.base import AnyType, KaibaBaseModel

Expand All @@ -22,40 +22,36 @@ class IfStatement(KaibaBaseModel):
target: Optional[AnyType] = Field(...) # ... = required but allow None
then: Optional[AnyType] = Field(...) # ... = required but allow Nones
otherwise: Optional[AnyType] = None # Should be any valid json value

class Config:
"""Add json schema examples."""

schema_extra = {
'examples': [
{
'condition': 'is',
'target': 'target value',
'then': 'was target value',
},
{
'condition': 'not',
'target': 'target_value',
'then': 'was not target value',
'otherwise': 'was target value',
},
{
'condition': 'in',
'target': ['one', 'of', 'these'],
'then': 'was either one, of or these',
'otherwise': 'was none of those',
},
{
'condition': 'in',
'target': 'a substring of this will be true',
'then': 'substrings also work',
'otherwise': 'was not a substring of target',
},
{
'condition': 'contains',
'target': 'value',
'then': 'value was a substring of input',
'otherwise': 'value was not in the input',
},
],
}
model_config = ConfigDict(json_schema_extra={
'examples': [
{
'condition': 'is',
'target': 'target value',
'then': 'was target value',
},
{
'condition': 'not',
'target': 'target_value',
'then': 'was not target value',
'otherwise': 'was target value',
},
{
'condition': 'in',
'target': ['one', 'of', 'these'],
'then': 'was either one, of or these',
'otherwise': 'was none of those',
},
{
'condition': 'in',
'target': 'a substring of this will be true',
'then': 'substrings also work',
'otherwise': 'was not a substring of target',
},
{
'condition': 'contains',
'target': 'value',
'then': 'value was a substring of input',
'otherwise': 'value was not in the input',
},
],
})
24 changes: 10 additions & 14 deletions kaiba/models/iterator.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from typing import List

from pydantic import Field
from pydantic import ConfigDict, Field

from kaiba.models.base import KaibaBaseModel, StrInt

Expand All @@ -9,16 +9,12 @@ class Iterator(KaibaBaseModel):
"""Allows for iterating lists at given path."""

alias: str
path: List[StrInt] = Field(..., min_items=1)

class Config:
"""Add json schema examples."""

schema_extra = {
'examples': [
{
'alias': 'an_item',
'path': ['path', 'to', 10, 'data'],
},
],
}
path: List[StrInt] = Field(..., min_length=1)
model_config = ConfigDict(json_schema_extra={
'examples': [
{
'alias': 'an_item',
'path': ['path', 'to', 10, 'data'],
},
],
})
Loading

0 comments on commit ef6f816

Please sign in to comment.