From 3484351250e2bd43bac7f90bd05f803396a30670 Mon Sep 17 00:00:00 2001 From: Markus Scheidgen <markus.scheidgen@gmail.com> Date: Sat, 28 Sep 2019 12:28:09 +0200 Subject: [PATCH] Added package with actual sub sections. --- nomad/metainfo/metainfo.py | 49 ++++++++++++++++++++++++++++++++++++-- tests/test_metainfo.py | 12 ++++++++-- 2 files changed, 57 insertions(+), 4 deletions(-) diff --git a/nomad/metainfo/metainfo.py b/nomad/metainfo/metainfo.py index 79a15ce85d..58a8918c91 100644 --- a/nomad/metainfo/metainfo.py +++ b/nomad/metainfo/metainfo.py @@ -293,7 +293,7 @@ class MObject(metaclass=MObjectMeta): @classmethod def __init_section_cls__(cls): # only works after bootstrapping, since functionality is still missing - if not all([hasattr(__module__, cls) for cls in ['Quantity', 'Section', 'sub_section']]): + if not all([hasattr(__module__, cls) for cls in ['Quantity', 'Section', 'Package', 'Category', 'sub_section']]): return # ensure that the m_section is defined @@ -329,6 +329,11 @@ class MObject(metaclass=MObjectMeta): if attr.section_def.name is None: attr.section_def.name = inflection.camelize(name) + # add section cls' section to the module's package + module_name = cls.__module__ + pkg = Package.from_module(module_name) + pkg.m_add_sub_section(cls.m_section) + @staticmethod def m_type_check(definition: 'Quantity', value: Any, check_item: bool = False): """Checks if the value fits the given quantity in type and shape; raises @@ -399,6 +404,27 @@ class MObject(metaclass=MObjectMeta): return section + def m_sub_sections(self, definition: SectionDef) -> List[MObjectBound]: + """Returns all sub sections for the given section definition + + Args: + definition: The definition of the section. + + Raises: + KeyError: If the definition is not for a sub section + """ + section_def = self._resolve_section(definition) + + m_data_value = self.m_data.get(section_def.name, None) + + if m_data_value is None: + return [] + + if section_def.repeats: + return m_data_value + else: + return [m_data_value] + def m_sub_section(self, definition: SectionDef, parent_index: int = -1) -> MObjectBound: """Returns the sub section for the given section definition and possible parent_index (for repeatable sections). @@ -837,7 +863,21 @@ class Section(Definition): class Package(Definition): - pass + + @staticmethod + def from_module(module_name: str): + module = sys.modules[module_name] + + pkg: 'Package' = getattr(module, 'm_package', None) + if pkg is None: + pkg = Package() + setattr(module, 'm_package', pkg) + + pkg.name = module_name + if pkg.description is None and module.__doc__ is not None: + pkg.description = inspect.cleandoc(module.__doc__) + + return pkg class sub_section: @@ -880,6 +920,11 @@ class Category(Definition): In the old meta-info this was known as `abstract types`. """ + def __init__(self, module_name, *args, **kwargs): + super().__init__(*args, **kwargs) + + Package.from_module(module_name).m_add_sub_section(self) + @cached_property def definitions(self) -> Iterable[Definition]: """ All definitions that are directly or indirectly in this category. """ diff --git a/tests/test_metainfo.py b/tests/test_metainfo.py index c4d94116dd..be47636923 100644 --- a/tests/test_metainfo.py +++ b/tests/test_metainfo.py @@ -15,7 +15,7 @@ import pytest import numpy as np -from nomad.metainfo.metainfo import MObject, Section, Quantity, Definition, Category, sub_section +from nomad.metainfo.metainfo import MObject, Section, Quantity, Definition, Category, Package, sub_section def assert_section_def(section_def: Section): @@ -79,8 +79,10 @@ class TestPureReflection: assert getattr(obj, 'test_quantity') == 'test_value' +m_package = Package(description='package doc') + material_defining = Category( - name='material_defining', + __name__, name='material_defining', description='Quantities that add to what constitutes a different material.') @@ -167,6 +169,12 @@ class TestM2: assert material_defining in System.atom_label.categories assert System.atom_label in material_defining.definitions + def test_package(self): + assert m_package.name == __name__ + assert m_package.description is not None + assert len(m_package.m_sub_sections(Section)) == 3 + assert len(m_package.m_sub_sections(Category)) == 1 + class TestM1: """ Test for meta-info instances. """ -- GitLab