Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,5 @@ __pycache__
build
src/rune.runtime.egg-info
rune.runtime-*.whl
src/rune/runtime/version.py
src/rune/runtime/version.py
/.coverage
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ dependencies = [
]
optional-dependencies.dev = [
"pytest",
"pytest-cov",
"pytest-mock"
]
description = "rune-runtime: the Rune DSL runtime for Python"
Expand Down
12 changes: 9 additions & 3 deletions src/rune/runtime/metadata.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
'''Classes representing annotated basic Rune types'''
from enum import Enum
import uuid
import datetime
import importlib
from enum import Enum
from functools import partial, lru_cache
import uuid
from decimal import Decimal
from typing import Any, Never, get_args
import datetime
from typing_extensions import Self, Tuple
from pydantic import (PlainSerializer, PlainValidator, WrapValidator,
WrapSerializer)
from pydantic_core import PydanticCustomError
# from rune.runtime.object_registry import get_object

META_CONTAINER = '__rune_metadata'
Expand Down Expand Up @@ -365,6 +366,11 @@ def deserialize(cls, obj, allowed_meta: set[str]):
if isinstance(obj, Reference):
return obj

if not isinstance(obj, dict):
raise PydanticCustomError('Input Validation Error',
'Expected either {my_type} or dict but '
'got {type}.',
{'type': type(obj), 'my_type': cls})
metadata = {k: obj[k] for k in obj.keys() if k.startswith('@')}

# References deserialization treatment
Expand Down
23 changes: 23 additions & 0 deletions test/cdm/test_validation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
'''Full attribute validation - pydantic and constraints'''
import pytest
from pydantic import ValidationError
try:
# pylint: disable=unused-import
# type: ignore
from cdm.base.math.NonNegativeQuantity import NonNegativeQuantity
from cdm.base.math.UnitType import UnitType
NO_SER_TEST_MOD = False
except ImportError:
NO_SER_TEST_MOD = True


@pytest.mark.skipif(NO_SER_TEST_MOD, reason='CDM package not found')
def test_bad_attrib_validation():
'''Invalid attribute assigned'''
unit = UnitType(currency='EUR')
mq = NonNegativeQuantity(value=10, unit=unit)
mq.frequency = 'Blah'
with pytest.raises(ValidationError):
mq.validate_model()

# EOF
13 changes: 11 additions & 2 deletions test/serializer-round-trip/test_enumtype.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,19 @@
@pytest.mark.skipif(NO_SER_TEST_MOD, reason='Generated test package not found')
def test_enum_types_single():
'''no doc'''
# import serialization.test.passing.enumtypes.Root
# import serialization.test.passing.enumtypes.EnumSingle
# import serialization.test.passing.enumtypes.EnumType

# root = serialization.test.passing.enumtypes.Root.Root(
# enumSingle=serialization.test.passing.enumtypes.EnumSingle.EnumSingle(
# enumType=serialization.test.passing.enumtypes.EnumType.EnumType.A
# ))
# resp_json = root.rune_serialize()
json_str = '''
{
"@model": "serialization",
"@type": "serialization.test.enumtypes.Root",
"@type": "serialization.test.passing.enumtypes.Root",
"@version": "0.0.0",
"enumSingle": {
"enumType": "A"
Expand All @@ -36,7 +45,7 @@ def test_enum_types_list():
json_str = '''
{
"@model": "serialization",
"@type": "serialization.test.enumtypes.Root",
"@type": "serialization.test.passing.enumtypes.Root",
"@version": "0.0.0",
"enumList": {
"enumType": ["A", "B", "C", "B"]
Expand Down
22 changes: 11 additions & 11 deletions test/serializer-round-trip/test_extension.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def test_base_type():
'''no doc'''
json_str = '''{
"@model": "serialization",
"@type": "serialization.test.extension.Root",
"@type": "serialization.test.passing.extension.Root",
"@version": "0.0.0",
"typeA": {
"fieldA": "foo"
Expand All @@ -34,12 +34,12 @@ def test_extended_type_concrete():
'''no doc'''
json_str = '''{
"@model": "serialization",
"@type": "serialization.test.extension.Root",
"@type": "serialization.test.passing.extension.Root",
"@version": "0.0.0",
"typeB": {
"fieldA": "foo",
"fieldB": "foo",
"@type": "serialization.test.extension.B"
"@type": "serialization.test.passing.extension.B"
}
}'''
model = BaseDataClass.rune_deserialize(json_str)
Expand All @@ -55,15 +55,15 @@ def test_extended_type_polymorphic():
'''no doc'''
json_str = '''{
"@model": "serialization",
"@type": "serialization.test.extension.Root",
"@type": "serialization.test.passing.extension.Root",
"@version": "0.0.0",
"typeA": {
"fieldA": "bar",
"fieldB": "foo",
"@type": "serialization.test.extension.B"
"@type": "serialization.test.passing.extension.B"
}
}'''
# import serialization.test.extension.Root
# import serialization.test.passing.extension.Root
model = BaseDataClass.rune_deserialize(json_str)
resp_json = model.rune_serialize()
assert json.loads(resp_json) == json.loads(json_str)
Expand All @@ -72,14 +72,14 @@ def test_extended_type_polymorphic():
@pytest.mark.skipif(NO_SER_TEST_MOD, reason='Generated test package not found')
def test_at_type():
'''no doc'''
from serialization.test.extension.B import B
from serialization.test.passing.extension.B import B
json_str = '''
{
"@type": "serialization.test.extension.Root",
"@type": "serialization.test.passing.extension.Root",
"typeA" : {
"fieldA" : "bar",
"fieldB" : "foo",
"@type" : "serialization.test.extension.B"
"@type" : "serialization.test.passing.extension.B"
}
}
'''
Expand All @@ -90,7 +90,7 @@ def test_at_type():
@pytest.mark.skipif(NO_SER_TEST_MOD, reason='Generated test package not found')
def test_temp():
'''no doc'''
from serialization.test.metakey.Root import Root
from serialization.test.passing.metakey.Root import Root
json_str = '''
{
"nodeRef" : {
Expand All @@ -112,7 +112,7 @@ def test_temp():
@pytest.mark.skipif(NO_SER_TEST_MOD, reason='Generated test package not found')
def test_enums():
'''no doc'''
from serialization.test.enumtypes.Root import Root
from serialization.test.passing.enumtypes.Root import Root
json_str = '{"enumSingle":{"enumType":"A"}}'
json_dict = json.loads(json_str)
model1 = Root.model_validate(json_dict)
Expand Down
8 changes: 4 additions & 4 deletions test/serializer-round-trip/test_metakey.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ def test_generated_attribute_ref():
'''attribute-ref.json'''
json_str = '''{
"@model": "serialization",
"@type": "serialization.test.metakey.Root",
"@type": "serialization.test.passing.metakey.Root",
"@version": "0.0.0",
"attributeRef": {
"dateField": {
Expand All @@ -198,7 +198,7 @@ def test_generated_node_ref():
'''attribute-ref.json'''
json_str = '''{
"@model": "serialization",
"@type": "serialization.test.metakey.Root",
"@type": "serialization.test.passing.metakey.Root",
"@version": "0.0.0",
"nodeRef": {
"typeA": {
Expand All @@ -224,7 +224,7 @@ def test_generated_dangling_node_ref():
'''attribute-ref.json'''
json_str = '''{
"@model": "serialization",
"@type": "serialization.test.metakey.Root",
"@type": "serialization.test.passing.metakey.Root",
"@version": "0.0.0",
"nodeRef": {
"aReference": {
Expand All @@ -243,7 +243,7 @@ def test_generated_dangling_attribute_ref():
'''attribute-ref.json'''
json_str = '''{
"@model": "serialization",
"@type": "serialization.test.metakey.Root",
"@type": "serialization.test.passing.metakey.Root",
"@version": "0.0.0",
"attributeRef": {
"dateReference": {
Expand Down
2 changes: 1 addition & 1 deletion test/serializer-round-trip/test_metalocation.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def test_address():
'''no doc'''
json_str = ''' {
"@model": "serialization",
"@type": "serialization.test.metalocation.Root",
"@type": "serialization.test.passing.metalocation.Root",
"@version": "0.0.0",
"typeA": {
"b": {
Expand Down
4 changes: 2 additions & 2 deletions test/serializer-round-trip/test_metascheme.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def test_enum_single():
json_str = '''
{
"@model": "serialization",
"@type": "serialization.test.metascheme.Root",
"@type": "serialization.test.passing.metascheme.Root",
"@version": "0.0.0",
"enumType": {
"@data": "A",
Expand All @@ -37,7 +37,7 @@ def test_enum_list():
json_str = '''
{
"@model": "serialization",
"@type": "serialization.test.metascheme.Root",
"@type": "serialization.test.passing.metascheme.Root",
"@version": "0.0.0",
"enumTypeList": [{
"@data": "A",
Expand Down