-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #58 from snok/sondrelg/pydantic-support
Add Pydantic support
- Loading branch information
Showing
9 changed files
with
173 additions
and
28 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
""" | ||
This file tests pydantic support. | ||
See https://github.com/snok/flake8-type-checking/issues/52 | ||
for discussion on the implementation. | ||
""" | ||
|
||
import textwrap | ||
|
||
import pytest | ||
|
||
from flake8_type_checking.codes import TC002 | ||
from tests import _get_error | ||
|
||
|
||
@pytest.mark.parametrize( | ||
'enabled, expected', | ||
( | ||
[True, {'2:0 ' + TC002.format(module='decimal.Decimal')}], | ||
[False, {'2:0 ' + TC002.format(module='decimal.Decimal')}], | ||
), | ||
) | ||
def test_non_pydantic_model(enabled, expected): | ||
""" | ||
A class cannot be a pydantic model if it doesn't have a base class, | ||
so we should raise the same error here in both cases. | ||
""" | ||
example = textwrap.dedent( | ||
''' | ||
from decimal import Decimal | ||
class X: | ||
x: Decimal | ||
''' | ||
) | ||
assert _get_error(example, error_code_filter='TC001,TC002', type_checking_pydantic_enabled=enabled) == expected | ||
|
||
|
||
def test_class_with_base_class(): | ||
""" | ||
Whenever a class inherits from anything, we need | ||
to assume it might be a pydantic model, for which | ||
we need to register annotations as uses. | ||
""" | ||
example = textwrap.dedent( | ||
''' | ||
from decimal import Decimal | ||
class X(Y): | ||
x: Decimal | ||
''' | ||
) | ||
assert _get_error(example, error_code_filter='TC001,TC002', type_checking_pydantic_enabled=True) == set() | ||
|
||
|
||
def test_complex_pydantic_model(): | ||
""" | ||
Test actual Pydantic models, with different annotation types. | ||
""" | ||
example = textwrap.dedent( | ||
''' | ||
from __future__ import annotations | ||
from datetime import datetime | ||
from decimal import Decimal | ||
from typing import TYPE_CHECKING | ||
from pydantic import BaseModel, condecimal, validator | ||
if TYPE_CHECKING: | ||
from datetime import date | ||
from typing import Union | ||
def format_datetime(value: Union[str, datetime]) -> datetime: | ||
if isinstance(value, str): | ||
value = datetime.strptime(value, '%Y-%m-%dT%H:%M:%S.%f%z') | ||
assert isinstance(value, datetime) | ||
return value | ||
class ModelBase(BaseModel): | ||
id: int | ||
created_at: datetime | ||
updated_at: datetime | ||
_format_datetime = validator('created_at', 'updated_at', pre=True, allow_reuse=True)(format_datetime) | ||
class NestedModel(ModelBase): | ||
z: Decimal | ||
x: int | ||
y: str | ||
class FinalModel(ModelBase): | ||
a: str | ||
b: int | ||
c: float | ||
d: bool | ||
e: date | ||
f: NestedModel | ||
g: condecimal(ge=Decimal(0)) = Decimal(0) | ||
''' | ||
) | ||
assert _get_error(example, error_code_filter='TC001,TC002', type_checking_pydantic_enabled=True) == set() |