fix(jambo): Fix allOf, anyOf, null and array type parsing #33
@@ -1,7 +1,7 @@
|
||||
from jambo.types.type_parser_options import TypeParserOptions
|
||||
|
||||
from pydantic import Field, TypeAdapter
|
||||
from typing_extensions import Annotated, Any, Generic, Self, TypeVar, Unpack
|
||||
from typing import Annotated, Any, Generic, Self, TypeVar, Unpack
|
||||
|
|
||||
|
||||
from abc import ABC, abstractmethod
|
||||
|
||||
@@ -47,7 +47,7 @@ class GenericTypeParser(ABC, Generic[T]):
|
||||
|
||||
if not self._validate_default(parsed_type, parsed_properties):
|
||||
raise ValueError(
|
||||
f"Default value {properties.get('default')} is not valid for type {parsed_type.__name__}"
|
||||
f"Default value {properties.get('default')} is not valid for type {parsed_type}"
|
||||
)
|
||||
|
||||
return parsed_type, parsed_properties
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from jambo.parser._type_parser import GenericTypeParser
|
||||
from jambo.types.type_parser_options import TypeParserOptions
|
||||
|
||||
from typing_extensions import Any, Unpack
|
||||
from typing import Any, Unpack
|
||||
|
||||
|
`typing_extensions` is prefered for Python3.10 compatibility
|
||||
|
||||
class AllOfTypeParser(GenericTypeParser):
|
||||
|
||||
@@ -2,11 +2,14 @@ from jambo.parser._type_parser import GenericTypeParser
|
||||
from jambo.types.type_parser_options import TypeParserOptions
|
||||
|
||||
from pydantic import Field
|
||||
from typing_extensions import Annotated, Union, Unpack
|
||||
from typing import Annotated, Unpack
|
||||
from types import UnionType
|
||||
|
`typing_extensions` is prefered for Python3.10 compatibility
|
||||
from functools import reduce
|
||||
from operator import or_
|
||||
|
||||
|
||||
class AnyOfTypeParser(GenericTypeParser):
|
||||
mapped_type = Union
|
||||
mapped_type = UnionType
|
||||
|
||||
json_schema_type = "anyOf"
|
||||
|
||||
@@ -41,4 +44,6 @@ class AnyOfTypeParser(GenericTypeParser):
|
||||
for t, v in sub_types
|
||||
]
|
||||
|
||||
return Union[(*field_types,)], mapped_properties
|
||||
union_type = reduce(or_, field_types)
|
||||
|
||||
return union_type, mapped_properties
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from jambo.parser._type_parser import GenericTypeParser
|
||||
from jambo.types.type_parser_options import TypeParserOptions
|
||||
|
||||
from typing_extensions import Iterable, TypeVar, Unpack
|
||||
from typing import Iterable, TypeVar, Unpack
|
||||
|
||||
import copy
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from jambo.parser._type_parser import GenericTypeParser
|
||||
from jambo.types.type_parser_options import TypeParserOptions
|
||||
|
||||
from typing_extensions import Unpack
|
||||
from typing import Unpack
|
||||
|
`typing_extensions` is prefered for Python3.10 compatibility
|
||||
|
||||
|
||||
class BooleanTypeParser(GenericTypeParser):
|
||||
|
||||
@@ -3,7 +3,7 @@ from jambo.types.json_schema_type import JSONSchemaNativeTypes
|
||||
from jambo.types.type_parser_options import TypeParserOptions
|
||||
|
||||
from pydantic import AfterValidator
|
||||
from typing_extensions import Annotated, Any, Literal, Unpack
|
||||
from typing import Annotated, Any, Literal, Unpack
|
||||
|
`typing_extensions` is prefered for Python3.10 compatibility
|
||||
|
||||
|
||||
class ConstTypeParser(GenericTypeParser):
|
||||
|
||||
@@ -2,7 +2,7 @@ from jambo.parser._type_parser import GenericTypeParser
|
||||
from jambo.types.json_schema_type import JSONSchemaNativeTypes
|
||||
from jambo.types.type_parser_options import TypeParserOptions
|
||||
|
||||
from typing_extensions import Unpack
|
||||
from typing import Unpack
|
||||
|
`typing_extensions` is prefered for Python3.10 compatibility
|
||||
|
||||
from enum import Enum
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from jambo.parser._type_parser import GenericTypeParser
|
||||
from jambo.types.type_parser_options import TypeParserOptions
|
||||
|
||||
from typing_extensions import Unpack
|
||||
from typing import Unpack
|
||||
|
`typing_extensions` is prefered for Python3.10 compatibility
|
||||
|
||||
|
||||
class FloatTypeParser(GenericTypeParser):
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from jambo.parser._type_parser import GenericTypeParser
|
||||
from jambo.types.type_parser_options import TypeParserOptions
|
||||
|
||||
from typing_extensions import Unpack
|
||||
from typing import Unpack
|
||||
|
`typing_extensions` is prefered for Python3.10 compatibility
|
||||
|
||||
|
||||
class IntTypeParser(GenericTypeParser):
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
|
Already implemented in a previous PR that was merged, sorry Already implemented in a previous PR that was merged, sorry
Already implemented in a previous PR that was merged, sorry Already implemented in a previous PR that was merged, sorry
|
||||
from jambo.parser._type_parser import GenericTypeParser
|
||||
from jambo.types.type_parser_options import TypeParserOptions
|
||||
|
||||
from typing_extensions import Unpack
|
||||
|
Already implemented in a previous PR that was merged, sorry Already implemented in a previous PR that was merged, sorry
|
||||
from typing import Unpack
|
||||
|
Already implemented in a previous PR that was merged, sorry Already implemented in a previous PR that was merged, sorry
|
||||
|
||||
|
||||
class NullTypeParser(GenericTypeParser):
|
||||
|
||||
|
Already implemented in a previous PR that was merged, sorry Already implemented in a previous PR that was merged, sorry
Already implemented in a previous PR that was merged, sorry Already implemented in a previous PR that was merged, sorry
|
||||
@@ -2,7 +2,7 @@ from jambo.parser._type_parser import GenericTypeParser
|
||||
from jambo.types.type_parser_options import TypeParserOptions
|
||||
|
||||
from pydantic import BaseModel, ConfigDict, Field, create_model
|
||||
from typing_extensions import Any, Unpack
|
||||
from typing import Any, Unpack
|
||||
|
`typing_extensions` is prefered for Python3.10 compatibility
|
||||
|
||||
|
||||
class ObjectTypeParser(GenericTypeParser):
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
|
This entire feature should be in a separate PR This entire feature should be in a separate PR
This entire feature should be in a separate PR This entire feature should be in a separate PR
|
||||
from types import UnionType
|
||||
|
This entire feature should be in a separate PR This entire feature should be in a separate PR
|
||||
|
||||
|
This entire feature should be in a separate PR This entire feature should be in a separate PR
|
||||
from jambo.parser._type_parser import GenericTypeParser
|
||||
from jambo.types.type_parser_options import TypeParserOptions
|
||||
|
||||
from pydantic import Field, BeforeValidator, TypeAdapter, ValidationError
|
||||
from typing_extensions import Annotated, Union, Unpack, Any
|
||||
|
This entire feature should be in a separate PR This entire feature should be in a separate PR
|
||||
|
||||
|
This entire feature should be in a separate PR This entire feature should be in a separate PR
|
||||
from typing import Annotated, Unpack, Any
|
||||
|
`typing_extensions` is prefered for Python3.10 compatibility
This entire feature should be in a separate PR This entire feature should be in a separate PR
|
||||
from functools import reduce
|
||||
|
This entire feature should be in a separate PR This entire feature should be in a separate PR
|
||||
from operator import or_
|
||||
|
This entire feature should be in a separate PR This entire feature should be in a separate PR
|
||||
|
||||
class OneOfTypeParser(GenericTypeParser):
|
||||
mapped_type = Union
|
||||
|
This entire feature should be in a separate PR This entire feature should be in a separate PR
|
||||
mapped_type = UnionType
|
||||
|
This entire feature should be in a separate PR This entire feature should be in a separate PR
|
||||
|
||||
json_schema_type = "oneOf"
|
||||
|
||||
@@ -36,7 +39,7 @@ class OneOfTypeParser(GenericTypeParser):
|
||||
|
This entire feature should be in a separate PR This entire feature should be in a separate PR
This entire feature should be in a separate PR This entire feature should be in a separate PR
|
||||
for t, v in sub_types
|
||||
]
|
||||
|
||||
union_type = Union[(*field_types,)]
|
||||
|
This entire feature should be in a separate PR This entire feature should be in a separate PR
|
||||
union_type = reduce(or_, field_types)
|
||||
|
This entire feature should be in a separate PR This entire feature should be in a separate PR
|
||||
|
||||
discriminator = properties.get("discriminator")
|
||||
if discriminator and isinstance(discriminator, dict):
|
||||
|
||||
|
This entire feature should be in a separate PR This entire feature should be in a separate PR
This entire feature should be in a separate PR This entire feature should be in a separate PR
|
||||
@@ -1,10 +1,12 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from jambo.parser import GenericTypeParser
|
||||
from jambo.types.type_parser_options import TypeParserOptions
|
||||
|
`typing_extensions` is prefered for Python3.10 compatibility
|
||||
|
||||
from typing_extensions import Any, ForwardRef, Literal, TypeVar, Union, Unpack
|
||||
from typing import Any, ForwardRef, Literal, TypeVar, Unpack
|
||||
|
||||
|
||||
RefType = TypeVar("RefType", bound=Union[type, ForwardRef])
|
||||
RefType = TypeVar("RefType", bound=type | ForwardRef)
|
||||
|
||||
RefStrategy = Literal["forward_ref", "def_ref"]
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ from jambo.parser._type_parser import GenericTypeParser
|
||||
from jambo.types.type_parser_options import TypeParserOptions
|
||||
|
||||
from pydantic import EmailStr, HttpUrl, IPvAnyAddress, FilePath
|
||||
from typing_extensions import Unpack
|
||||
from typing import Unpack
|
||||
|
`typing_extensions` is prefered for Python3.10 compatibility
|
||||
|
||||
from datetime import date, datetime, time
|
||||
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
|
A large change with little impact, is there a necessity for this change? A large change with little impact, is there a necessity for this change?
A large change with little impact, is there a necessity for this change? A large change with little impact, is there a necessity for this change?
|
||||
from typing_extensions import Dict, List, Literal, TypedDict, Union
|
||||
|
A large change with little impact, is there a necessity for this change? A large change with little impact, is there a necessity for this change?
|
||||
from __future__ import annotations
|
||||
|
A large change with little impact, is there a necessity for this change? A large change with little impact, is there a necessity for this change?
|
||||
|
||||
|
A large change with little impact, is there a necessity for this change? A large change with little impact, is there a necessity for this change?
|
||||
from typing import Literal, TypedDict
|
||||
|
A large change with little impact, is there a necessity for this change? A large change with little impact, is there a necessity for this change?
|
||||
|
||||
from types import NoneType
|
||||
|
||||
@@ -19,7 +21,7 @@ JSONSchemaNativeTypes: tuple[type, ...] = (
|
||||
|
A large change with little impact, is there a necessity for this change? A large change with little impact, is there a necessity for this change?
A large change with little impact, is there a necessity for this change? A large change with little impact, is there a necessity for this change?
|
||||
)
|
||||
|
||||
|
||||
JSONType = Union[str, int, float, bool, None, Dict[str, "JSONType"], List["JSONType"]]
|
||||
|
A large change with little impact, is there a necessity for this change? A large change with little impact, is there a necessity for this change?
|
||||
JSONType = str | int | float | bool | None | dict[str, "JSONType"] | list["JSONType"]
|
||||
|
A large change with little impact, is there a necessity for this change? A large change with little impact, is there a necessity for this change?
|
||||
|
||||
|
||||
class JSONSchema(TypedDict, total=False):
|
||||
@@ -27,23 +29,23 @@ class JSONSchema(TypedDict, total=False):
|
||||
|
A large change with little impact, is there a necessity for this change? A large change with little impact, is there a necessity for this change?
A large change with little impact, is there a necessity for this change? A large change with little impact, is there a necessity for this change?
|
||||
title: str
|
||||
description: str
|
||||
default: JSONType
|
||||
examples: List[JSONType]
|
||||
|
A large change with little impact, is there a necessity for this change? A large change with little impact, is there a necessity for this change?
|
||||
examples: list[JSONType]
|
||||
|
A large change with little impact, is there a necessity for this change? A large change with little impact, is there a necessity for this change?
|
||||
|
||||
# Type definitions
|
||||
type: Union[JSONSchemaType, List[JSONSchemaType]]
|
||||
|
A large change with little impact, is there a necessity for this change? A large change with little impact, is there a necessity for this change?
|
||||
type: JSONSchemaType | list[JSONSchemaType]
|
||||
|
A large change with little impact, is there a necessity for this change? A large change with little impact, is there a necessity for this change?
|
||||
|
||||
# Object-specific keywords
|
||||
properties: Dict[str, "JSONSchema"]
|
||||
|
A large change with little impact, is there a necessity for this change? A large change with little impact, is there a necessity for this change?
|
||||
required: List[str]
|
||||
|
A large change with little impact, is there a necessity for this change? A large change with little impact, is there a necessity for this change?
|
||||
additionalProperties: Union[bool, "JSONSchema"]
|
||||
|
A large change with little impact, is there a necessity for this change? A large change with little impact, is there a necessity for this change?
|
||||
properties: dict[str, "JSONSchema"]
|
||||
|
A large change with little impact, is there a necessity for this change? A large change with little impact, is there a necessity for this change?
|
||||
required: list[str]
|
||||
|
A large change with little impact, is there a necessity for this change? A large change with little impact, is there a necessity for this change?
|
||||
additionalProperties: bool | "JSONSchema"
|
||||
|
A large change with little impact, is there a necessity for this change? A large change with little impact, is there a necessity for this change?
|
||||
minProperties: int
|
||||
maxProperties: int
|
||||
patternProperties: Dict[str, "JSONSchema"]
|
||||
|
A large change with little impact, is there a necessity for this change? A large change with little impact, is there a necessity for this change?
|
||||
dependencies: Dict[str, Union[List[str], "JSONSchema"]]
|
||||
|
A large change with little impact, is there a necessity for this change? A large change with little impact, is there a necessity for this change?
|
||||
patternProperties: dict[str, "JSONSchema"]
|
||||
|
A large change with little impact, is there a necessity for this change? A large change with little impact, is there a necessity for this change?
|
||||
dependencies: dict[str, list[str] | "JSONSchema"]
|
||||
|
A large change with little impact, is there a necessity for this change? A large change with little impact, is there a necessity for this change?
|
||||
|
||||
# Array-specific keywords
|
||||
items: Union["JSONSchema", List["JSONSchema"]]
|
||||
|
A large change with little impact, is there a necessity for this change? A large change with little impact, is there a necessity for this change?
|
||||
additionalItems: Union[bool, "JSONSchema"]
|
||||
|
A large change with little impact, is there a necessity for this change? A large change with little impact, is there a necessity for this change?
|
||||
items: "JSONSchema" | list["JSONSchema"]
|
||||
|
A large change with little impact, is there a necessity for this change? A large change with little impact, is there a necessity for this change?
|
||||
additionalItems: bool | "JSONSchema"
|
||||
|
A large change with little impact, is there a necessity for this change? A large change with little impact, is there a necessity for this change?
|
||||
minItems: int
|
||||
maxItems: int
|
||||
uniqueItems: bool
|
||||
@@ -62,7 +64,7 @@ class JSONSchema(TypedDict, total=False):
|
||||
|
A large change with little impact, is there a necessity for this change? A large change with little impact, is there a necessity for this change?
A large change with little impact, is there a necessity for this change? A large change with little impact, is there a necessity for this change?
|
||||
multipleOf: float
|
||||
|
||||
# Enum and const
|
||||
enum: List[JSONType]
|
||||
|
A large change with little impact, is there a necessity for this change? A large change with little impact, is there a necessity for this change?
|
||||
enum: list[JSONType]
|
||||
|
A large change with little impact, is there a necessity for this change? A large change with little impact, is there a necessity for this change?
|
||||
const: JSONType
|
||||
|
||||
# Conditionals
|
||||
@@ -71,23 +73,23 @@ class JSONSchema(TypedDict, total=False):
|
||||
|
A large change with little impact, is there a necessity for this change? A large change with little impact, is there a necessity for this change?
A large change with little impact, is there a necessity for this change? A large change with little impact, is there a necessity for this change?
|
||||
else_: "JSONSchema" # 'else' is also a reserved word
|
||||
|
||||
# Combination keywords
|
||||
allOf: List["JSONSchema"]
|
||||
|
A large change with little impact, is there a necessity for this change? A large change with little impact, is there a necessity for this change?
|
||||
anyOf: List["JSONSchema"]
|
||||
|
A large change with little impact, is there a necessity for this change? A large change with little impact, is there a necessity for this change?
|
||||
oneOf: List["JSONSchema"]
|
||||
|
A large change with little impact, is there a necessity for this change? A large change with little impact, is there a necessity for this change?
|
||||
allOf: list["JSONSchema"]
|
||||
|
A large change with little impact, is there a necessity for this change? A large change with little impact, is there a necessity for this change?
|
||||
anyOf: list["JSONSchema"]
|
||||
|
A large change with little impact, is there a necessity for this change? A large change with little impact, is there a necessity for this change?
|
||||
oneOf: list["JSONSchema"]
|
||||
|
A large change with little impact, is there a necessity for this change? A large change with little impact, is there a necessity for this change?
|
||||
not_: "JSONSchema" # 'not' is a reserved word
|
||||
|
||||
|
||||
# Fix forward references
|
||||
JSONSchema.__annotations__["properties"] = Dict[str, JSONSchema]
|
||||
|
A large change with little impact, is there a necessity for this change? A large change with little impact, is there a necessity for this change?
|
||||
JSONSchema.__annotations__["items"] = Union[JSONSchema, List[JSONSchema]]
|
||||
|
A large change with little impact, is there a necessity for this change? A large change with little impact, is there a necessity for this change?
|
||||
JSONSchema.__annotations__["additionalItems"] = Union[bool, JSONSchema]
|
||||
|
A large change with little impact, is there a necessity for this change? A large change with little impact, is there a necessity for this change?
|
||||
JSONSchema.__annotations__["additionalProperties"] = Union[bool, JSONSchema]
|
||||
|
A large change with little impact, is there a necessity for this change? A large change with little impact, is there a necessity for this change?
|
||||
JSONSchema.__annotations__["patternProperties"] = Dict[str, JSONSchema]
|
||||
|
A large change with little impact, is there a necessity for this change? A large change with little impact, is there a necessity for this change?
|
||||
JSONSchema.__annotations__["dependencies"] = Dict[str, Union[List[str], JSONSchema]]
|
||||
|
A large change with little impact, is there a necessity for this change? A large change with little impact, is there a necessity for this change?
|
||||
JSONSchema.__annotations__["properties"] = dict[str, JSONSchema]
|
||||
|
A large change with little impact, is there a necessity for this change? A large change with little impact, is there a necessity for this change?
|
||||
JSONSchema.__annotations__["items"] = JSONSchema | list[JSONSchema]
|
||||
|
A large change with little impact, is there a necessity for this change? A large change with little impact, is there a necessity for this change?
|
||||
JSONSchema.__annotations__["additionalItems"] = bool | JSONSchema
|
||||
|
A large change with little impact, is there a necessity for this change? A large change with little impact, is there a necessity for this change?
|
||||
JSONSchema.__annotations__["additionalProperties"] = bool | JSONSchema
|
||||
|
A large change with little impact, is there a necessity for this change? A large change with little impact, is there a necessity for this change?
|
||||
JSONSchema.__annotations__["patternProperties"] = dict[str, JSONSchema]
|
||||
|
A large change with little impact, is there a necessity for this change? A large change with little impact, is there a necessity for this change?
|
||||
JSONSchema.__annotations__["dependencies"] = dict[str, list[str] | JSONSchema]
|
||||
|
A large change with little impact, is there a necessity for this change? A large change with little impact, is there a necessity for this change?
|
||||
JSONSchema.__annotations__["if_"] = JSONSchema
|
||||
JSONSchema.__annotations__["then"] = JSONSchema
|
||||
JSONSchema.__annotations__["else_"] = JSONSchema
|
||||
JSONSchema.__annotations__["allOf"] = List[JSONSchema]
|
||||
|
A large change with little impact, is there a necessity for this change? A large change with little impact, is there a necessity for this change?
|
||||
JSONSchema.__annotations__["anyOf"] = List[JSONSchema]
|
||||
|
A large change with little impact, is there a necessity for this change? A large change with little impact, is there a necessity for this change?
|
||||
JSONSchema.__annotations__["oneOf"] = List[JSONSchema]
|
||||
|
A large change with little impact, is there a necessity for this change? A large change with little impact, is there a necessity for this change?
|
||||
JSONSchema.__annotations__["allOf"] = list[JSONSchema]
|
||||
|
A large change with little impact, is there a necessity for this change? A large change with little impact, is there a necessity for this change?
|
||||
JSONSchema.__annotations__["anyOf"] = list[JSONSchema]
|
||||
|
A large change with little impact, is there a necessity for this change? A large change with little impact, is there a necessity for this change?
|
||||
JSONSchema.__annotations__["oneOf"] = list[JSONSchema]
|
||||
|
A large change with little impact, is there a necessity for this change? A large change with little impact, is there a necessity for this change?
|
||||
JSONSchema.__annotations__["not_"] = JSONSchema
|
||||
|
||||
|
A large change with little impact, is there a necessity for this change? A large change with little impact, is there a necessity for this change?
A large change with little impact, is there a necessity for this change? A large change with little impact, is there a necessity for this change?
|
||||
@@ -1,6 +1,6 @@
|
||||
from jambo.types.json_schema_type import JSONSchema
|
||||
|
||||
from typing_extensions import TypedDict
|
||||
from typing import TypedDict
|
||||
|
`typing_extensions` is prefered for Python3.10 compatibility
|
||||
|
||||
|
||||
class TypeParserOptions(TypedDict):
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from jambo.parser.anyof_type_parser import AnyOfTypeParser
|
||||
|
||||
from typing_extensions import Annotated, Union, get_args, get_origin
|
||||
from typing import Annotated, get_args, get_origin
|
||||
|
||||
from unittest import TestCase
|
||||
|
||||
@@ -42,7 +42,7 @@ class TestAnyOfTypeParser(TestCase):
|
||||
)
|
||||
|
||||
# check union type has string and int
|
||||
self.assertEqual(get_origin(type_parsing), Union)
|
||||
self.assertEqual(get_origin(type_parsing), type(str | int))
|
||||
|
||||
type_1, type_2 = get_args(type_parsing)
|
||||
|
||||
@@ -67,7 +67,7 @@ class TestAnyOfTypeParser(TestCase):
|
||||
)
|
||||
|
||||
# check union type has string and int
|
||||
self.assertEqual(get_origin(type_parsing), Union)
|
||||
self.assertEqual(get_origin(type_parsing), type(str | int))
|
||||
|
||||
type_1, type_2 = get_args(type_parsing)
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from jambo.parser import ArrayTypeParser
|
||||
|
||||
from typing_extensions import get_args
|
||||
from typing import get_args
|
||||
|
||||
from unittest import TestCase
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from jambo.parser import ConstTypeParser
|
||||
|
||||
from typing_extensions import Annotated, Literal, get_args, get_origin
|
||||
from typing import Annotated, Literal, get_args, get_origin
|
||||
|
||||
from unittest import TestCase
|
||||
|
||||
|
||||
typing_extensionsis prefered for Python3.10 compatibility