Implements All Basic Defaults

This commit is contained in:
2025-04-10 00:48:14 -03:00
parent a571e28015
commit 7f0ce337b1
11 changed files with 244 additions and 14 deletions

View File

@@ -1,3 +1,5 @@
import copy
from jambo.parser._type_parser import GenericTypeParser
from typing import TypeVar
@@ -27,6 +29,39 @@ class ArrayTypeParser(GenericTypeParser):
wrapper_type = set if properties.get("uniqueItems", False) else list
return wrapper_type[_item_type], mappings_properties_builder(
properties, _mappings
mapped_properties = mappings_properties_builder(
properties, _mappings, {"description": "description"}
)
if "default" in properties:
default_list = properties["default"]
if not isinstance(default_list, list):
raise ValueError(
f"Default value must be a list, got {type(default_list).__name__}"
)
if len(default_list) > properties.get("maxItems", float("inf")):
raise ValueError(
f"Default list exceeds maxItems limit of {properties.get('maxItems')}"
)
if len(default_list) < properties.get("minItems", 0):
raise ValueError(
f"Default list is below minItems limit of {properties.get('minItems')}"
)
if not all(isinstance(item, _item_type) for item in default_list):
raise ValueError(
f"All items in the default list must be of type {_item_type.__name__}"
)
if wrapper_type is list:
mapped_properties["default_factory"] = lambda: copy.deepcopy(
wrapper_type(default_list)
)
else:
mapped_properties["default_factory"] = lambda: wrapper_type(
default_list
)
return wrapper_type[_item_type], mapped_properties

View File

@@ -1,4 +1,7 @@
from jambo.parser._type_parser import GenericTypeParser
from jambo.utils.properties_builder.mappings_properties_builder import (
mappings_properties_builder,
)
class BooleanTypeParser(GenericTypeParser):
@@ -8,4 +11,7 @@ class BooleanTypeParser(GenericTypeParser):
@staticmethod
def from_properties(name, properties):
return bool, {} # The second argument is not used in this case
_mappings = {
"default": "default",
}
return bool, mappings_properties_builder(properties, _mappings)

View File

@@ -10,6 +10,9 @@ class ObjectTypeParser(GenericTypeParser):
def from_properties(name, properties):
from jambo.schema_converter import SchemaConverter
if "default" in properties:
raise RuntimeError("Default values for objects are not supported.")
return (
SchemaConverter.build_object(name, properties),
{}, # The second argument is not used in this case

View File

@@ -17,4 +17,24 @@ class StringTypeParser(GenericTypeParser):
"pattern": "pattern",
}
return str, mappings_properties_builder(properties, _mappings)
mapped_properties = mappings_properties_builder(properties, _mappings)
if "default" in properties:
default_value = properties["default"]
if not isinstance(default_value, str):
raise ValueError(
f"Default value for {name} must be a string, "
f"but got {type(properties['default'])}."
)
if len(default_value) > properties.get("maxLength", float("inf")):
raise ValueError(
f"Default value for {name} exceeds maxLength limit of {properties.get('maxLength')}"
)
if len(default_value) < properties.get("minLength", 0):
raise ValueError(
f"Default value for {name} is below minLength limit of {properties.get('minLength')}"
)
return str, mapped_properties

View File

@@ -90,5 +90,10 @@ class SchemaConverter:
if description := properties.get("description"):
_field_args["description"] = description
_default_value = ... if name in required_keys else properties.get("default")
return _field_type, Field(_default_value, **_field_args)
if name not in required_keys:
_field_args["default"] = properties.get("default", None)
if "default_factory" in _field_args and "default" in _field_args:
del _field_args["default"]
return _field_type, Field(**_field_args)

0
jambo/types/__init__.py Normal file
View File

View File

@@ -1,4 +1,11 @@
def mappings_properties_builder(properties, mappings):
def mappings_properties_builder(properties, mappings, default_mappings=None):
default_mappings = default_mappings or {
"default": "default",
"description": "description",
}
mappings = default_mappings | mappings
return {
mappings[key]: value for key, value in properties.items() if key in mappings
}

View File

@@ -10,6 +10,42 @@ def numeric_properties_builder(properties):
"maximum": "le",
"exclusiveMaximum": "lt",
"multipleOf": "multiple_of",
"default": "default",
}
return mappings_properties_builder(properties, _mappings)
mapped_properties = mappings_properties_builder(properties, _mappings)
if "default" in properties:
default_value = properties["default"]
if not isinstance(default_value, (int, float)):
raise ValueError(
f"Default value must be a number, got {type(default_value).__name__}"
)
if default_value >= properties.get("maximum", float("inf")):
raise ValueError(
f"Default value exceeds maximum limit of {properties.get('maximum')}"
)
if default_value <= properties.get("minimum", float("-inf")):
raise ValueError(
f"Default value is below minimum limit of {properties.get('minimum')}"
)
if default_value > properties.get("exclusiveMaximum", float("inf")):
raise ValueError(
f"Default value exceeds exclusive maximum limit of {properties.get('exclusiveMaximum')}"
)
if default_value < properties.get("exclusiveMinimum", float("-inf")):
raise ValueError(
f"Default value is below exclusive minimum limit of {properties.get('exclusiveMinimum')}"
)
if "multipleOf" in properties:
if default_value % properties["multipleOf"] != 0:
raise ValueError(
f"Default value {default_value} is not a multiple of {properties['multipleOf']}"
)
return mapped_properties