-
Notifications
You must be signed in to change notification settings - Fork 6
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
Allow nullable foreign keys #12
Changes from 3 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,9 @@ | ||
import inspect | ||
import sys | ||
from enum import Enum | ||
from functools import reduce | ||
from itertools import chain | ||
from types import UnionType | ||
from typing import Any, Dict, List, Optional, no_type_check, Union | ||
from typing_extensions import get_origin, get_args | ||
|
||
|
@@ -15,6 +17,10 @@ | |
from pydantic.errors import PydanticUserError | ||
from pydantic._internal._model_construction import ModelMetaclass | ||
|
||
if sys.version_info >= (3, 10): | ||
from types import UnionType | ||
else: | ||
from typing import Union as UnionType | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @idan-david This looks ok to me. The import on line 6 needs to be removed though. Let's see if the tests pass after this. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry for the mess, removed the import on line 6 |
||
|
||
from .fields import ModelSchemaField | ||
|
||
|
@@ -136,6 +142,16 @@ def __new__(mcs, name: str, bases: tuple, namespace: dict, **kwargs): | |
return cls | ||
|
||
|
||
def _is_optional_field(annotation) -> bool: | ||
args = get_args(annotation) | ||
return ( | ||
(get_origin(annotation) is Union or get_origin(annotation) is UnionType) | ||
and type(None) in args | ||
and len(args) == 2 | ||
and any(issubclass(arg, ModelSchema) for arg in args) | ||
) | ||
|
||
|
||
class ProxyGetterNestedObj: | ||
def __init__(self, obj: Any, schema_class): | ||
self._obj = obj | ||
|
@@ -199,7 +215,17 @@ def dict(self) -> dict: | |
# Pick the underlying annotation | ||
annotation = get_args(annotation)[0] | ||
|
||
if inspect.isclass(annotation) and issubclass(annotation, ModelSchema): | ||
if _is_optional_field(annotation): | ||
value = self.get(key) | ||
if value is None: | ||
data[key] = None | ||
else: | ||
non_none_type_annotation = next( | ||
arg for arg in get_args(annotation) if arg is not type(None) | ||
) | ||
data[key] = self._get_annotation_objects(value, non_none_type_annotation) | ||
|
||
elif inspect.isclass(annotation) and issubclass(annotation, ModelSchema): | ||
data[key] = self._get_annotation_objects(self.get(key), annotation) | ||
else: | ||
key = fieldinfo.alias if fieldinfo.alias else key | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like UnionType doesn't exist in python 3.8 and 3.9 either.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are correct. After some reading, UnionType was introduced in 3.10, with the "|" annotation (e.g.
int | str
).I can make the tests compatible for python 3.8 by removing this syntax, but still supporting this check (with an import only
if sys.version_info >= (3,10)
).This means I can support this syntax, but not check for it in a test.
What do you suggest we do?