Commit 34843512 authored by Markus Scheidgen's avatar Markus Scheidgen
Browse files

Added package with actual sub sections.

parent f3cac900
......@@ -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. """
......
......@@ -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. """
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment