Implements Object Defaults
This commit is contained in:
@@ -1,5 +1,7 @@
|
|||||||
from jambo.parser._type_parser import GenericTypeParser
|
from jambo.parser._type_parser import GenericTypeParser
|
||||||
from jambo.utils.properties_builder.numeric_properties_builder import numeric_properties_builder
|
from jambo.utils.properties_builder.numeric_properties_builder import (
|
||||||
|
numeric_properties_builder,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class FloatTypeParser(GenericTypeParser):
|
class FloatTypeParser(GenericTypeParser):
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
from jambo.parser._type_parser import GenericTypeParser
|
from jambo.parser._type_parser import GenericTypeParser
|
||||||
from jambo.utils.properties_builder.numeric_properties_builder import numeric_properties_builder
|
from jambo.utils.properties_builder.numeric_properties_builder import (
|
||||||
|
numeric_properties_builder,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class IntTypeParser(GenericTypeParser):
|
class IntTypeParser(GenericTypeParser):
|
||||||
|
|||||||
@@ -10,10 +10,12 @@ class ObjectTypeParser(GenericTypeParser):
|
|||||||
def from_properties(name, properties):
|
def from_properties(name, properties):
|
||||||
from jambo.schema_converter import SchemaConverter
|
from jambo.schema_converter import SchemaConverter
|
||||||
|
|
||||||
if "default" in properties:
|
type_parsing = SchemaConverter.build_object(name, properties)
|
||||||
raise RuntimeError("Default values for objects are not supported.")
|
type_properties = {}
|
||||||
|
|
||||||
return (
|
if "default" in properties:
|
||||||
SchemaConverter.build_object(name, properties),
|
type_properties["default_factory"] = lambda: type_parsing.model_validate(
|
||||||
{}, # The second argument is not used in this case
|
properties["default"]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
return type_parsing, type_properties
|
||||||
|
|||||||
@@ -1,13 +1,11 @@
|
|||||||
from jambo.parser import GenericTypeParser
|
from jambo.parser import GenericTypeParser
|
||||||
|
from jambo.types.json_schema_type import JSONSchema
|
||||||
|
|
||||||
from jsonschema.exceptions import SchemaError
|
from jsonschema.exceptions import SchemaError
|
||||||
from jsonschema.protocols import Validator
|
from jsonschema.protocols import Validator
|
||||||
from pydantic import create_model
|
from pydantic import create_model
|
||||||
from pydantic.fields import Field
|
from pydantic.fields import Field
|
||||||
|
from pydantic.main import ModelT
|
||||||
from typing import Type
|
|
||||||
|
|
||||||
from jambo.types.json_schema_type import JSONSchema
|
|
||||||
|
|
||||||
|
|
||||||
class SchemaConverter:
|
class SchemaConverter:
|
||||||
@@ -20,7 +18,7 @@ class SchemaConverter:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def build(schema: JSONSchema) -> Type:
|
def build(schema: JSONSchema) -> ModelT:
|
||||||
"""
|
"""
|
||||||
Converts a JSON Schema to a Pydantic model.
|
Converts a JSON Schema to a Pydantic model.
|
||||||
:param schema: The JSON Schema to convert.
|
:param schema: The JSON Schema to convert.
|
||||||
@@ -35,7 +33,7 @@ class SchemaConverter:
|
|||||||
def build_object(
|
def build_object(
|
||||||
name: str,
|
name: str,
|
||||||
schema: JSONSchema,
|
schema: JSONSchema,
|
||||||
) -> Type:
|
) -> ModelT:
|
||||||
"""
|
"""
|
||||||
Converts a JSON Schema object to a Pydantic model given a name.
|
Converts a JSON Schema object to a Pydantic model given a name.
|
||||||
:param name:
|
:param name:
|
||||||
@@ -60,7 +58,7 @@ class SchemaConverter:
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def _build_model_from_properties(
|
def _build_model_from_properties(
|
||||||
model_name: str, model_properties: dict, required_keys: list[str]
|
model_name: str, model_properties: dict, required_keys: list[str]
|
||||||
) -> Type:
|
) -> ModelT:
|
||||||
properties = SchemaConverter._parse_properties(model_properties, required_keys)
|
properties = SchemaConverter._parse_properties(model_properties, required_keys)
|
||||||
|
|
||||||
return create_model(model_name, **properties)
|
return create_model(model_name, **properties)
|
||||||
|
|||||||
@@ -66,3 +66,4 @@ section-order=[
|
|||||||
"third-party",
|
"third-party",
|
||||||
"standard-library",
|
"standard-library",
|
||||||
]
|
]
|
||||||
|
lines-after-imports = 2
|
||||||
|
|||||||
@@ -21,3 +21,29 @@ class TestObjectTypeParser(TestCase):
|
|||||||
|
|
||||||
self.assertEqual(obj.name, "name")
|
self.assertEqual(obj.name, "name")
|
||||||
self.assertEqual(obj.age, 10)
|
self.assertEqual(obj.age, 10)
|
||||||
|
|
||||||
|
def test_object_type_parser_with_default(self):
|
||||||
|
parser = ObjectTypeParser()
|
||||||
|
|
||||||
|
properties = {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"name": {"type": "string"},
|
||||||
|
"age": {"type": "integer"},
|
||||||
|
},
|
||||||
|
"default": {
|
||||||
|
"name": "default_name",
|
||||||
|
"age": 20,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
_, type_validator = parser.from_properties("placeholder", properties)
|
||||||
|
|
||||||
|
# Check default value
|
||||||
|
default_obj = type_validator["default_factory"]()
|
||||||
|
self.assertEqual(default_obj.name, "default_name")
|
||||||
|
self.assertEqual(default_obj.age, 20)
|
||||||
|
|
||||||
|
# Chekc default factory new object id
|
||||||
|
new_obj = type_validator["default_factory"]()
|
||||||
|
self.assertNotEqual(id(default_obj), id(new_obj))
|
||||||
|
|||||||
@@ -256,3 +256,28 @@ class TestSchemaConverter(TestCase):
|
|||||||
model_set = SchemaConverter.build(schema_set)
|
model_set = SchemaConverter.build(schema_set)
|
||||||
|
|
||||||
self.assertEqual(model_set().friends, {"John", "Jane"})
|
self.assertEqual(model_set().friends, {"John", "Jane"})
|
||||||
|
|
||||||
|
def test_default_for_object(self):
|
||||||
|
schema = {
|
||||||
|
"title": "Person",
|
||||||
|
"description": "A person",
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"address": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"street": {"type": "string"},
|
||||||
|
"city": {"type": "string"},
|
||||||
|
},
|
||||||
|
"default": {"street": "123 Main St", "city": "Springfield"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"required": ["address"],
|
||||||
|
}
|
||||||
|
|
||||||
|
model = SchemaConverter.build(schema)
|
||||||
|
|
||||||
|
obj = model(address={"street": "123 Main St", "city": "Springfield"})
|
||||||
|
|
||||||
|
self.assertEqual(obj.address.street, "123 Main St")
|
||||||
|
self.assertEqual(obj.address.city, "Springfield")
|
||||||
|
|||||||
Reference in New Issue
Block a user