Better Object Internal Structure and Type Selection #16
@@ -1,8 +1,9 @@
|
|||||||
|
from jambo.types.type_parser_options import TypeParserOptions
|
||||||
|
|
||||||
from pydantic import Field, TypeAdapter
|
from pydantic import Field, TypeAdapter
|
||||||
from typing_extensions import Annotated, Self
|
from typing_extensions import Annotated, Any, Generic, Self, TypeVar, Unpack
|
||||||
|
|
||||||
from abc import ABC, abstractmethod
|
from abc import ABC, abstractmethod
|
||||||
from typing import Any, Generic, TypeVar
|
|
||||||
|
|
||||||
|
|
||||||
T = TypeVar("T")
|
T = TypeVar("T")
|
||||||
@@ -18,9 +19,14 @@ class GenericTypeParser(ABC, Generic[T]):
|
|||||||
"description": "description",
|
"description": "description",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def from_properties(
|
||||||
|
self, name: str, properties: dict[str, Any], **kwargs: Unpack[TypeParserOptions]
|
||||||
|
) -> tuple[T, dict]: ...
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def type_from_properties(
|
def type_from_properties(
|
||||||
cls, name: str, properties: dict[str, Any], **kwargs
|
cls, name: str, properties: dict[str, Any], **kwargs: Unpack[TypeParserOptions]
|
||||||
) -> tuple[type, dict]:
|
) -> tuple[type, dict]:
|
||||||
parser = cls._get_impl(properties)
|
parser = cls._get_impl(properties)
|
||||||
|
|
||||||
@@ -51,12 +57,9 @@ class GenericTypeParser(ABC, Generic[T]):
|
|||||||
|
|
||||||
return schema_definition[0], schema_definition[1]
|
return schema_definition[0], schema_definition[1]
|
||||||
|
|
||||||
@abstractmethod
|
def mappings_properties_builder(
|
||||||
def from_properties(
|
self, properties, required=False, **kwargs: Unpack[TypeParserOptions]
|
||||||
self, name: str, properties: dict[str, Any], required: bool = False
|
) -> dict[str, Any]:
|
||||||
) -> tuple[T, dict]: ...
|
|
||||||
|
|
||||||
def mappings_properties_builder(self, properties, required=False) -> dict[str, Any]:
|
|
||||||
if self.type_mappings is None:
|
if self.type_mappings is None:
|
||||||
raise NotImplementedError("Type mappings not defined")
|
raise NotImplementedError("Type mappings not defined")
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
from jambo.parser._type_parser import GenericTypeParser
|
from jambo.parser._type_parser import GenericTypeParser
|
||||||
|
from jambo.types.type_parser_options import TypeParserOptions
|
||||||
|
|
||||||
from typing import Any
|
from typing_extensions import Any, Unpack
|
||||||
|
|
||||||
|
|
||||||
class AllOfTypeParser(GenericTypeParser):
|
class AllOfTypeParser(GenericTypeParser):
|
||||||
@@ -8,7 +9,7 @@ class AllOfTypeParser(GenericTypeParser):
|
|||||||
|
|
||||||
json_schema_type = "allOf"
|
json_schema_type = "allOf"
|
||||||
|
|
||||||
def from_properties(self, name, properties, required=False):
|
def from_properties(self, name, properties, **kwargs: Unpack[TypeParserOptions]):
|
||||||
sub_properties = properties.get("allOf", [])
|
sub_properties = properties.get("allOf", [])
|
||||||
|
|
||||||
root_type = properties.get("type")
|
root_type = properties.get("type")
|
||||||
@@ -22,7 +23,7 @@ class AllOfTypeParser(GenericTypeParser):
|
|||||||
sub_properties
|
sub_properties
|
||||||
)
|
)
|
||||||
|
|
||||||
return parser().from_properties(name, combined_properties)
|
return parser().from_properties(name, combined_properties, **kwargs)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _get_type_parser(
|
def _get_type_parser(
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
from jambo.parser._type_parser import GenericTypeParser
|
from jambo.parser._type_parser import GenericTypeParser
|
||||||
|
from jambo.types.type_parser_options import TypeParserOptions
|
||||||
|
|
||||||
from pydantic import Field
|
from pydantic import Field
|
||||||
from typing_extensions import Annotated
|
from typing_extensions import Annotated, Union, Unpack
|
||||||
|
|
||||||
from typing import Union
|
|
||||||
|
|
||||||
|
|
||||||
class AnyOfTypeParser(GenericTypeParser):
|
class AnyOfTypeParser(GenericTypeParser):
|
||||||
@@ -11,7 +10,7 @@ class AnyOfTypeParser(GenericTypeParser):
|
|||||||
|
|
||||||
json_schema_type = "anyOf"
|
json_schema_type = "anyOf"
|
||||||
|
|
||||||
def from_properties(self, name, properties, required=False):
|
def from_properties(self, name, properties, **kwargs: Unpack[TypeParserOptions]):
|
||||||
if "anyOf" not in properties:
|
if "anyOf" not in properties:
|
||||||
raise ValueError(f"Invalid JSON Schema: {properties}")
|
raise ValueError(f"Invalid JSON Schema: {properties}")
|
||||||
|
|
||||||
@@ -20,11 +19,11 @@ class AnyOfTypeParser(GenericTypeParser):
|
|||||||
|
|
||||||
mapped_properties = dict()
|
mapped_properties = dict()
|
||||||
|
|
||||||
subProperties = properties["anyOf"]
|
sub_properties = properties["anyOf"]
|
||||||
|
|
||||||
sub_types = [
|
sub_types = [
|
||||||
GenericTypeParser.type_from_properties(name, subProperty)
|
GenericTypeParser.type_from_properties(name, subProperty, **kwargs)
|
||||||
for subProperty in subProperties
|
for subProperty in sub_properties
|
||||||
]
|
]
|
||||||
|
|
||||||
default_value = properties.get("default")
|
default_value = properties.get("default")
|
||||||
@@ -42,12 +41,14 @@ class AnyOfTypeParser(GenericTypeParser):
|
|||||||
|
|
||||||
mapped_properties["default"] = default_value
|
mapped_properties["default"] = default_value
|
||||||
|
|
||||||
if not required:
|
if not kwargs.get("required", False):
|
||||||
mapped_properties["default"] = mapped_properties.get("default")
|
mapped_properties["default"] = mapped_properties.get("default")
|
||||||
|
|
||||||
# By defining the type as Union of Annotated type we can use the Field validator
|
# By defining the type as Union of Annotated type we can use the Field validator
|
||||||
# to enforce the constraints of each union type when needed.
|
# to enforce the constraints of each union type when needed.
|
||||||
# We use Annotated to attach the Field validators to the type.
|
# We use Annotated to attach the Field validators to the type.
|
||||||
field_types = [Annotated[t, Field(**v)] if v else t for t, v in sub_types]
|
field_types = [
|
||||||
|
Annotated[t, Field(**v)] if v is not None else t for t, v in sub_types
|
||||||
|
]
|
||||||
|
|
||||||
return Union[(*field_types,)], mapped_properties
|
return Union[(*field_types,)], mapped_properties
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
from jambo.parser._type_parser import GenericTypeParser
|
from jambo.parser._type_parser import GenericTypeParser
|
||||||
|
|
||||||
|
from typing_extensions import TypeVar
|
||||||
|
|
||||||
import copy
|
import copy
|
||||||
from typing import TypeVar
|
|
||||||
|
|
||||||
|
|
||||||
V = TypeVar("V")
|
V = TypeVar("V")
|
||||||
|
|||||||
@@ -2,8 +2,7 @@ from jambo.parser._type_parser import GenericTypeParser
|
|||||||
|
|
||||||
from pydantic import Field, create_model
|
from pydantic import Field, create_model
|
||||||
from pydantic.main import ModelT
|
from pydantic.main import ModelT
|
||||||
|
from typing_extensions import Any
|
||||||
from typing import Any
|
|
||||||
|
|
||||||
|
|
||||||
class ObjectTypeParser(GenericTypeParser):
|
class ObjectTypeParser(GenericTypeParser):
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
from typing import Dict, List, Literal, TypedDict, Union
|
from typing_extensions import Dict, List, Literal, TypedDict, Union
|
||||||
|
|
||||||
|
|
||||||
JSONSchemaType = Literal[
|
JSONSchemaType = Literal[
|
||||||
|
|||||||
5
jambo/types/type_parser_options.py
Normal file
5
jambo/types/type_parser_options.py
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
from typing_extensions import TypedDict
|
||||||
|
|
||||||
|
|
||||||
|
class TypeParserOptions(TypedDict):
|
||||||
|
required: bool
|
||||||
@@ -1,8 +1,7 @@
|
|||||||
from jambo.parser.anyof_type_parser import AnyOfTypeParser
|
from jambo.parser.anyof_type_parser import AnyOfTypeParser
|
||||||
|
|
||||||
from typing_extensions import Annotated
|
from typing_extensions import Annotated, Union, get_args, get_origin
|
||||||
|
|
||||||
from typing import Union, get_args, get_origin
|
|
||||||
from unittest import TestCase
|
from unittest import TestCase
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
from jambo.parser import ArrayTypeParser
|
from jambo.parser import ArrayTypeParser
|
||||||
|
|
||||||
from typing import get_args
|
from typing_extensions import get_args
|
||||||
|
|
||||||
from unittest import TestCase
|
from unittest import TestCase
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user