Skip to content

Commit

Permalink
Check explicitly for modelType in Python (#509)
Browse files Browse the repository at this point in the history
We add an explicit check for missing ``modelType`` in generated Python
code to account for the case where a concrete class without descendants
needs a model type for backwards compatibility even though the model
type property is redundant.
  • Loading branch information
mristin authored Jul 7, 2024
1 parent bcab1a9 commit 84ccbb6
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 1 deletion.
22 changes: 21 additions & 1 deletion aas_core_codegen/python/jsonization/_generate.py
Original file line number Diff line number Diff line change
Expand Up @@ -706,6 +706,26 @@ def _generate_concrete_class_from_jsonable(
Stripped(f"setter = {setter_cls_name}()"),
] # type: List[Stripped]

# NOTE (mristin):
# If the class has no concrete descendants, this function will be the sole entry
# point for the de-serialization. In that case, we have to explicitly check if
# the ``modelType`` is present — for cases where the serialization rules impose
# a model type for backwards compatibility even though it is redundant.
#
# If the class has concrete descendants, we can only publicly de-serialize it
# through a dispatching function, which will innately check for model type, so we
# do not have to repeat the check here.
if len(cls.concrete_descendants) == 0 and cls.serialization.with_model_type:
blocks.append(
Stripped(
f"""\
if 'modelType' not in jsonable:
{I}raise DeserializationException(
{II}"Expected the property modelType, but found none"
{I})"""
)
)

# region Switch on property name

map_name = python_naming.private_constant_name(
Expand Down Expand Up @@ -793,7 +813,7 @@ def _generate_concrete_class_from_jsonable(

writer = io.StringIO()

if len(cls._concrete_descendants) == 0:
if len(cls.concrete_descendants) == 0:
function_name = python_naming.function_name(
Identifier(f"{cls.name}_from_jsonable")
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1443,6 +1443,11 @@ def asset_administration_shell_from_jsonable(

setter = _SetterForAssetAdministrationShell()

if 'modelType' not in jsonable:
raise DeserializationException(
"Expected the property modelType, but found none"
)

for key, jsonable_value in jsonable.items():
setter_method = (
_SETTER_MAP_FOR_ASSET_ADMINISTRATION_SHELL.get(key)
Expand Down Expand Up @@ -2291,6 +2296,11 @@ def submodel_from_jsonable(

setter = _SetterForSubmodel()

if 'modelType' not in jsonable:
raise DeserializationException(
"Expected the property modelType, but found none"
)

for key, jsonable_value in jsonable.items():
setter_method = (
_SETTER_MAP_FOR_SUBMODEL.get(key)
Expand Down Expand Up @@ -3190,6 +3200,11 @@ def submodel_element_list_from_jsonable(

setter = _SetterForSubmodelElementList()

if 'modelType' not in jsonable:
raise DeserializationException(
"Expected the property modelType, but found none"
)

for key, jsonable_value in jsonable.items():
setter_method = (
_SETTER_MAP_FOR_SUBMODEL_ELEMENT_LIST.get(key)
Expand Down Expand Up @@ -3563,6 +3578,11 @@ def submodel_element_collection_from_jsonable(

setter = _SetterForSubmodelElementCollection()

if 'modelType' not in jsonable:
raise DeserializationException(
"Expected the property modelType, but found none"
)

for key, jsonable_value in jsonable.items():
setter_method = (
_SETTER_MAP_FOR_SUBMODEL_ELEMENT_COLLECTION.get(key)
Expand Down Expand Up @@ -3968,6 +3988,11 @@ def property_from_jsonable(

setter = _SetterForProperty()

if 'modelType' not in jsonable:
raise DeserializationException(
"Expected the property modelType, but found none"
)

for key, jsonable_value in jsonable.items():
setter_method = (
_SETTER_MAP_FOR_PROPERTY.get(key)
Expand Down Expand Up @@ -4353,6 +4378,11 @@ def multi_language_property_from_jsonable(

setter = _SetterForMultiLanguageProperty()

if 'modelType' not in jsonable:
raise DeserializationException(
"Expected the property modelType, but found none"
)

for key, jsonable_value in jsonable.items():
setter_method = (
_SETTER_MAP_FOR_MULTI_LANGUAGE_PROPERTY.get(key)
Expand Down Expand Up @@ -4723,6 +4753,11 @@ def range_from_jsonable(

setter = _SetterForRange()

if 'modelType' not in jsonable:
raise DeserializationException(
"Expected the property modelType, but found none"
)

for key, jsonable_value in jsonable.items():
setter_method = (
_SETTER_MAP_FOR_RANGE.get(key)
Expand Down Expand Up @@ -5071,6 +5106,11 @@ def reference_element_from_jsonable(

setter = _SetterForReferenceElement()

if 'modelType' not in jsonable:
raise DeserializationException(
"Expected the property modelType, but found none"
)

for key, jsonable_value in jsonable.items():
setter_method = (
_SETTER_MAP_FOR_REFERENCE_ELEMENT.get(key)
Expand Down Expand Up @@ -5426,6 +5466,11 @@ def blob_from_jsonable(

setter = _SetterForBlob()

if 'modelType' not in jsonable:
raise DeserializationException(
"Expected the property modelType, but found none"
)

for key, jsonable_value in jsonable.items():
setter_method = (
_SETTER_MAP_FOR_BLOB.get(key)
Expand Down Expand Up @@ -5787,6 +5832,11 @@ def file_from_jsonable(

setter = _SetterForFile()

if 'modelType' not in jsonable:
raise DeserializationException(
"Expected the property modelType, but found none"
)

for key, jsonable_value in jsonable.items():
setter_method = (
_SETTER_MAP_FOR_FILE.get(key)
Expand Down Expand Up @@ -6185,6 +6235,11 @@ def annotated_relationship_element_from_jsonable(

setter = _SetterForAnnotatedRelationshipElement()

if 'modelType' not in jsonable:
raise DeserializationException(
"Expected the property modelType, but found none"
)

for key, jsonable_value in jsonable.items():
setter_method = (
_SETTER_MAP_FOR_ANNOTATED_RELATIONSHIP_ELEMENT.get(key)
Expand Down Expand Up @@ -6626,6 +6681,11 @@ def entity_from_jsonable(

setter = _SetterForEntity()

if 'modelType' not in jsonable:
raise DeserializationException(
"Expected the property modelType, but found none"
)

for key, jsonable_value in jsonable.items():
setter_method = (
_SETTER_MAP_FOR_ENTITY.get(key)
Expand Down Expand Up @@ -7375,6 +7435,11 @@ def basic_event_element_from_jsonable(

setter = _SetterForBasicEventElement()

if 'modelType' not in jsonable:
raise DeserializationException(
"Expected the property modelType, but found none"
)

for key, jsonable_value in jsonable.items():
setter_method = (
_SETTER_MAP_FOR_BASIC_EVENT_ELEMENT.get(key)
Expand Down Expand Up @@ -7835,6 +7900,11 @@ def operation_from_jsonable(

setter = _SetterForOperation()

if 'modelType' not in jsonable:
raise DeserializationException(
"Expected the property modelType, but found none"
)

for key, jsonable_value in jsonable.items():
setter_method = (
_SETTER_MAP_FOR_OPERATION.get(key)
Expand Down Expand Up @@ -8237,6 +8307,11 @@ def capability_from_jsonable(

setter = _SetterForCapability()

if 'modelType' not in jsonable:
raise DeserializationException(
"Expected the property modelType, but found none"
)

for key, jsonable_value in jsonable.items():
setter_method = (
_SETTER_MAP_FOR_CAPABILITY.get(key)
Expand Down Expand Up @@ -8540,6 +8615,11 @@ def concept_description_from_jsonable(

setter = _SetterForConceptDescription()

if 'modelType' not in jsonable:
raise DeserializationException(
"Expected the property modelType, but found none"
)

for key, jsonable_value in jsonable.items():
setter_method = (
_SETTER_MAP_FOR_CONCEPT_DESCRIPTION.get(key)
Expand Down Expand Up @@ -10286,6 +10366,11 @@ def data_specification_iec_61360_from_jsonable(

setter = _SetterForDataSpecificationIEC61360()

if 'modelType' not in jsonable:
raise DeserializationException(
"Expected the property modelType, but found none"
)

for key, jsonable_value in jsonable.items():
setter_method = (
_SETTER_MAP_FOR_DATA_SPECIFICATION_IEC_61360.get(key)
Expand Down

0 comments on commit 84ccbb6

Please sign in to comment.