From 66bff0166c99f267c60d0cb92ead48ab7e1c19fc Mon Sep 17 00:00:00 2001 From: Theodore Chang <theodore.chang@physik.hu-berlin.de> Date: Wed, 16 Oct 2024 12:36:48 +0000 Subject: [PATCH] Metainfo add detection of mixed inheritance --- nomad/metainfo/metainfo.py | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/nomad/metainfo/metainfo.py b/nomad/metainfo/metainfo.py index 79717aac9b..a05f08eb9a 100644 --- a/nomad/metainfo/metainfo.py +++ b/nomad/metainfo/metainfo.py @@ -23,6 +23,7 @@ import itertools import json import re import sys +import warnings from collections.abc import Iterable from copy import deepcopy from functools import wraps @@ -1534,6 +1535,14 @@ class MSection(metaclass=MObjectMeta): if sub_section is None: return + if not is_initializing_proto and not isinstance( + sub_section, sub_section_def.sub_section.section_cls + ): + warnings.warn( + f'{sub_section} is not derived from its definition {sub_section_def}.', + category=SyntaxWarning, + ) + sub_section.m_parent = self sub_section.m_parent_sub_section = sub_section_def sub_section.m_parent_index = parent_index @@ -2608,7 +2617,7 @@ class MSection(metaclass=MObjectMeta): if sub_section_def.repeats: copy.__dict__[sub_section_def.name] = sub_sections_copy elif len(sub_sections_copy) == 1: - copy.__dict__[sub_section_def.name] = sub_sections_copy[0] + copy.m_set(sub_section_def, sub_sections_copy[0]) if a_elasticsearch: copy.m_annotations['elasticsearch'] = a_elasticsearch @@ -3799,10 +3808,19 @@ class Section(Definition): for base_section in self.all_base_sections: base_props.update(**base_section.all_properties) + def _common_base(_derived, _base): + _derived_mro = _derived.__class__.mro() + _base_mro = set(_base.__class__.mro()) + return next((_item for _item in _derived_mro if _item in _base_mro), None) + for derived_prop in itertools.chain(self.quantities, self.sub_sections): if (base_prop := base_props.get(derived_prop.name)) is None: continue + # ensure both properties are of the same type + if _common_base(derived_prop, base_prop) in (None, Property): + raise MetainfoError('Cannot inherit from different property types.') + for item in derived_prop.m_def.all_quantities.values(): if not derived_prop.m_is_set(item) and base_prop.m_is_set(item): derived_prop.m_set(item, base_prop.m_get(item)) -- GitLab