diff --git a/nomad/app/optimade/filterparser.py b/nomad/app/optimade/filterparser.py index 40e0e477b2c8b47b56b7f7ccdfd2efe8ac647524..61ebc153a8cb9cac48de979a5f365e337452987f 100644 --- a/nomad/app/optimade/filterparser.py +++ b/nomad/app/optimade/filterparser.py @@ -29,7 +29,7 @@ quantities: Dict[str, Quantity] = { q.name, es_field='optimade.%s' % q.name, elastic_mapping_type=q.m_annotations['elastic']['type']) - for q in OptimadeStructureEntry.m_section.quantities.values() + for q in OptimadeStructureEntry.m_def.quantities.values() if 'elastic' in q.m_annotations} quantities['elements'].length_quantity = quantities['nelements'] diff --git a/nomad/datamodel/dft.py b/nomad/datamodel/dft.py index b19a8329c050f46f859b21f057f7d0cad4e613c7..e2d3a6e983cf8ddb8effa6e7ad92813a59ff708b 100644 --- a/nomad/datamodel/dft.py +++ b/nomad/datamodel/dft.py @@ -182,7 +182,7 @@ class DFTCalcWithMetadata(CalcWithMetadata): self.n_total_energies = n_total_energies self.n_geometries = n_geometries - self.optimade = backend.get_mi2_section(optimade.OptimadeStructureEntry.m_section) + self.optimade = backend.get_mi2_section(optimade.OptimadeStructureEntry.m_def) def only_atoms(atoms): diff --git a/nomad/metainfo/API_CONCEPT.md b/nomad/metainfo/API_CONCEPT.md index 8e58b5812d4e50f0f6da470980ff380b90c2c743..9729d05618e055ad7d0d2feb38d491aebbce0fc2 100644 --- a/nomad/metainfo/API_CONCEPT.md +++ b/nomad/metainfo/API_CONCEPT.md @@ -188,7 +188,7 @@ Section object need to support: - access to subsection via subsection name - access of properties via property name - array access for repeatable sections -- navigation to its containing section: `.m_section` +- navigation to its containing section: `.m_def` - allow to create/(re-)open subsections via calling the subsection name as a method: `.system()` - close a section so that the underlying resource implementation can potentially remove the section from memory and write it to a database/.hdf5 file - the *GraphQL* like access methods with dictionary to specify multiple sub-sections diff --git a/nomad/metainfo/api_tryout.py b/nomad/metainfo/api_tryout.py index 0283e72a6e813a6d829f1d08f086a48018cbe62f..de5ad7a1544a7dc24b6ee659338f10a0db79560a 100644 --- a/nomad/metainfo/api_tryout.py +++ b/nomad/metainfo/api_tryout.py @@ -4,24 +4,24 @@ Some playground to try the API_CONCEPT.md ideas. class MObject: - def __init__(self, m_definition: 'MElementDef', m_section: 'MSection' = None): + def __init__(self, m_definition: 'MElementDef', m_def: 'MSection' = None): self.m_definition = m_definition - self.m_section = m_section + self.m_def = m_def @property - def m_section(self): + def m_def(self): return self._section - @m_section.setter - def m_section(self, m_section: 'MSection'): - self._section = m_section + @m_def.setter + def m_def(self, m_def: 'MSection'): + self._section = m_def # add yourself to the parent section - if m_section is not None: - subsection = m_section.subsections.get(self.m_definition.name) + if m_def is not None: + subsection = m_def.subsections.get(self.m_definition.name) if subsection is None: subsection = [] - m_section.subsections[self.m_definition.name] = subsection + m_def.subsections[self.m_definition.name] = subsection subsection.append(self) @@ -42,7 +42,7 @@ class MSection(MObject): raise KeyError('Section "%s" does not have subsection "%s", available subsections are %s' % (self.m_definition.name, name, '?')) def constructor(**kwargs): - new_section = subsection.impl(m_definition=subsection, m_section=self) + new_section = subsection.impl(m_definition=subsection, m_def=self) for key, value in kwargs.items(): setattr(new_section, key, value) @@ -84,13 +84,13 @@ class MSectionDef(MElementDef): self.impl = impl def get_subsection(self, name: str): - return self.m_section.get_section(name) + return self.m_def.get_section(name) -m_section = MSectionDef(m_definition=None, name='section', repeats=True, impl=MSectionDef) -m_section.m_definition = m_section -m_element = MSectionDef(m_definition=m_section, name='element', abstract=True, impl=None) -m_package = MSectionDef(m_definition=m_section, name='package') +m_def = MSectionDef(m_definition=None, name='section', repeats=True, impl=MSectionDef) +m_def.m_definition = m_def +m_element = MSectionDef(m_definition=m_def, name='element', abstract=True, impl=None) +m_package = MSectionDef(m_definition=m_def, name='package') class MPackageDef(MElementDef): @@ -107,9 +107,9 @@ class MPackageDef(MElementDef): metainfo = MPackageDef(name='metainfo') -m_element.m_section = metainfo -m_section.m_section = metainfo -m_package.m_section = metainfo +m_element.m_def = metainfo +m_def.m_def = metainfo +m_package.m_def = metainfo m_property = metainfo.new_section(name='property', repeats=True, extends=m_element, section=m_package) print(metainfo.subsections['section']) diff --git a/nomad/metainfo/metainfo.py b/nomad/metainfo/metainfo.py index 58a8918c91a07e8388a5eec578bb9dd50af61779..7fcc281e201a1fff3d78c39bfeeffa3ad78bbe54 100644 --- a/nomad/metainfo/metainfo.py +++ b/nomad/metainfo/metainfo.py @@ -36,7 +36,7 @@ Here is a simple example that demonstrates the definition of System related quan system (a.k.a. geometry). \"\"\" - m_section = Section(repeats=True, parent=Run) + m_def = Section(repeats=True, parent=Run) n_atoms = Quantity( type=int, description=''' @@ -74,10 +74,10 @@ This last statement, will produce the following JSON: .. code-block:: JSON { - "m_section" = "Run", + "m_def" = "Run", "System": [ { - "m_section" = "System", + "m_def" = "System", "m_parent_index" = 0, "n_atoms" = 3, "atom_labels" = [ @@ -121,7 +121,7 @@ definitions. The following classes can be used to define and structure meta-info data: - sections are defined by sub-classes :class:`MObject` and using :class:`Section` to - populate the classattribute `m_section` + populate the classattribute `m_def` - quantities are defined by assigning classattributes of a section with :class:`Quantity` instances - references (from one section to another) can be defined with quantities that use @@ -196,7 +196,7 @@ class Dimension(DataType): if isinstance(value, Section): return - if isinstance(value, type) and hasattr(value, 'm_section'): + if isinstance(value, type) and hasattr(value, 'm_def'): return raise TypeError('%s is not a valid dimension' % str(value)) @@ -248,7 +248,7 @@ class MObject(metaclass=MObjectMeta): assert run.m_sub_section(System, system.m_parent_index) == system Attributes: - m_section: The section definition that defines this sections, its possible + m_def: The section definition that defines this sections, its possible sub-sections and quantities. m_parent: The parent section instance that this section is a sub-section of. m_parent_index: For repeatable sections, parent keep a list of sub-sections for @@ -260,19 +260,19 @@ class MObject(metaclass=MObjectMeta): if possible. """ - m_section: 'Section' = None + m_def: 'Section' = None - def __init__(self, m_section: 'Section' = None, m_parent: 'MObject' = None, _bs: bool = False, **kwargs): - self.m_section: 'Section' = m_section + def __init__(self, m_def: 'Section' = None, m_parent: 'MObject' = None, _bs: bool = False, **kwargs): + self.m_def: 'Section' = m_def self.m_parent: 'MObject' = m_parent self.m_parent_index = -1 cls = self.__class__ - if self.m_section is None: - self.m_section = cls.m_section + if self.m_def is None: + self.m_def = cls.m_def - if cls.m_section is not None: - assert self.m_section == cls.m_section, \ + if cls.m_def is not None: + assert self.m_def == cls.m_def, \ 'Section class and section definition must match' self.m_annotations: Dict[str, Any] = {} @@ -296,22 +296,22 @@ class MObject(metaclass=MObjectMeta): if not all([hasattr(__module__, cls) for cls in ['Quantity', 'Section', 'Package', 'Category', 'sub_section']]): return - # ensure that the m_section is defined - m_section = cls.m_section - if m_section is None and cls != MObject: - m_section = Section() - setattr(cls, 'm_section', m_section) + # ensure that the m_def is defined + m_def = cls.m_def + if m_def is None and cls != MObject: + m_def = Section() + setattr(cls, 'm_def', m_def) - # transfer name and description to m_section - m_section.name = cls.__name__ + # transfer name and description to m_def + m_def.name = cls.__name__ if cls.__doc__ is not None: - m_section.description = inspect.cleandoc(cls.__doc__) - m_section.section_cls = cls + m_def.description = inspect.cleandoc(cls.__doc__) + m_def.section_cls = cls # add sub_section to parent section - if m_section.parent is not None: - sub_section_name = inflection.underscore(m_section.name) - setattr(m_section.parent.section_cls, sub_section_name, sub_section(m_section)) + if m_def.parent is not None: + sub_section_name = inflection.underscore(m_def.name) + setattr(m_def.parent.section_cls, sub_section_name, sub_section(m_def)) for name, attr in cls.__dict__.items(): # transfer names and descriptions for quantities @@ -321,18 +321,18 @@ class MObject(metaclass=MObjectMeta): attr.description = inspect.cleandoc(attr.description) attr.__doc__ = attr.description # manual manipulation of m_data due to bootstrapping - m_section.m_data.setdefault('Quantity', []).append(attr) + m_def.m_data.setdefault('Quantity', []).append(attr) # set names and parent on sub-sections elif isinstance(attr, sub_section): - attr.section_def.parent = m_section + attr.section_def.parent = m_def 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) + pkg.m_add_sub_section(cls.m_def) @staticmethod def m_type_check(definition: 'Quantity', value: Any, check_item: bool = False): @@ -353,7 +353,7 @@ class MObject(metaclass=MObjectMeta): raise TypeError('Value has wrong type.') elif isinstance(definition.type, Section): - if not isinstance(value, MObject) or value.m_section != definition.type: + if not isinstance(value, MObject) or value.m_def != definition.type: raise TypeError('The value is not a section of wrong section definition') else: @@ -392,14 +392,14 @@ class MObject(metaclass=MObjectMeta): def _resolve_section(self, definition: SectionDef) -> 'Section': """Resolves and checks the given section definition. """ if isinstance(definition, str): - section = self.m_section.sub_sections[definition] + section = self.m_def.sub_sections[definition] else: if isinstance(definition, type): - section = getattr(definition, 'm_section') + section = getattr(definition, 'm_def') else: section = definition - if section.name not in self.m_section.sub_sections: + if section.name not in self.m_def.sub_sections: raise KeyError('Not a sub section.') return section @@ -468,7 +468,7 @@ class MObject(metaclass=MObjectMeta): def m_add_sub_section(self, sub_section: MObjectBound) -> MObjectBound: """Adds the given section instance as a sub section to this section.""" - section_def = sub_section.m_section + section_def = sub_section.m_def if section_def.repeats: m_data_sections = self.m_data.setdefault(section_def.name, []) @@ -497,17 +497,17 @@ class MObject(metaclass=MObjectMeta): section_def: 'Section' = self._resolve_section(definition) section_cls = section_def.section_cls - section_instance = section_cls(m_section=section_def, m_parent=self, **kwargs) + section_instance = section_cls(m_def=section_def, m_parent=self, **kwargs) return self.m_add_sub_section(section_instance) def __resolve_quantity(self, definition: Union[str, 'Quantity']) -> 'Quantity': """Resolves and checks the given quantity definition. """ if isinstance(definition, str): - quantity = self.m_section.quantities[definition] + quantity = self.m_def.quantities[definition] else: - if definition.m_parent != self.m_section: + if definition.m_parent != self.m_def: raise KeyError('Quantity is not a quantity of this section.') quantity = definition @@ -538,7 +538,7 @@ class MObject(metaclass=MObjectMeta): def m_update(self, **kwargs): """ Updates all quantities and sub-sections with the given arguments. """ for name, value in kwargs.items(): - attribute = self.m_section.attributes.get(name, None) + attribute = self.m_def.attributes.get(name, None) if attribute is None: raise KeyError('%s is not an attribute of this section' % name) @@ -559,11 +559,11 @@ class MObject(metaclass=MObjectMeta): """Returns the data of this section as a json serializeable dictionary. """ def items() -> Iterable[Tuple[str, Any]]: - yield 'm_section', self.m_section.name + yield 'm_def', self.m_def.name if self.m_parent_index != -1: yield 'm_parent_index', self.m_parent_index - for name, sub_section in self.m_section.sub_sections.items(): + for name, sub_section in self.m_def.sub_sections.items(): if name not in self.m_data: continue @@ -572,7 +572,7 @@ class MObject(metaclass=MObjectMeta): else: yield name, self.m_data[name].m_to_dict() - for name in self.m_section.quantities: + for name in self.m_def.quantities: if name in self.m_data: value = getattr(self, name) if hasattr(value, 'tolist'): @@ -583,10 +583,10 @@ class MObject(metaclass=MObjectMeta): @classmethod def m_from_dict(cls: Type[MObjectBound], dct: Dict[str, Any]) -> MObjectBound: - section_def = cls.m_section + section_def = cls.m_def - # remove m_section and m_parent_index, they set themselves automatically - assert section_def.name == dct.pop('m_section', None) + # remove m_def and m_parent_index, they set themselves automatically + assert section_def.name == dct.pop('m_def', None) dct.pop('m_parent_index', -1) def items(): @@ -632,7 +632,7 @@ class MObject(metaclass=MObjectMeta): yield value, value, name, self def __repr__(self): - m_section_name = self.m_section.name + m_section_name = self.m_def.name name = '' if 'name' in self.m_data: name = self.m_data['name'] @@ -851,7 +851,7 @@ class Section(Definition): class System(MObject): pass - System.m_section.add_quantity(Quantity(name='n_atoms', type=int)) + System.m_def.add_quantity(Quantity(name='n_atoms', type=int)) This will add the quantity definition to this section definition, and add the respective Python descriptor as an attribute to this class. @@ -885,7 +885,7 @@ class sub_section: def __init__(self, section: SectionDef, **kwargs): if isinstance(section, type): - self.section_def = cast(MObject, section).m_section + self.section_def = cast(MObject, section).m_def else: self.section_def = cast(Section, section) @@ -933,11 +933,11 @@ class Category(Definition): if self in definition.all_categories]) -Section.m_section = Section(repeats=True, name='Section', _bs=True) -Section.m_section.m_section = Section.m_section -Section.m_section.section_cls = Section +Section.m_def = Section(repeats=True, name='Section', _bs=True) +Section.m_def.m_def = Section.m_def +Section.m_def.section_cls = Section -Quantity.m_section = Section(repeats=True, parent=Section.m_section, name='Quantity', _bs=True) +Quantity.m_def = Section(repeats=True, parent=Section.m_def, name='Quantity', _bs=True) Definition.name = Quantity( type=str, name='name', _bs=True, description=''' @@ -952,7 +952,7 @@ Definition.links = Quantity( A list of URLs to external resource that describe this definition. ''') Definition.categories = Quantity( - type=Category.m_section, shape=['0..*'], default=[], name='categories', _bs=True, + type=Category.m_def, shape=['0..*'], default=[], name='categories', _bs=True, description=''' The categories that this definition belongs to. See :class:`Category`. ''') @@ -963,12 +963,12 @@ Section.repeats = Quantity( Wether instances of this section can occur repeatedly in the parent section. ''') Section.parent = Quantity( - type=Section.m_section, name='parent', _bs=True, description=''' + type=Section.m_def, name='parent', _bs=True, description=''' The section definition of parent sections. Only section instances of this definition can contain section instances of this definition. ''') -Quantity.m_section.section_cls = Quantity +Quantity.m_def.section_cls = Quantity Quantity.type = Quantity( type=Union[type, Enum, Section, np.dtype], name='type', _bs=True, description=''' The type of the quantity. @@ -1014,18 +1014,17 @@ Quantity.default = Quantity( The default value for this quantity. ''') -Package.m_section = Section(repeats=True, name='Package', _bs=True) -Package.m_section.parent = Package.m_section +Package.m_def = Section(repeats=True, name='Package', _bs=True) +Package.m_def.parent = Package.m_def -Section.m_section.parent = Package.m_section +Section.m_def.parent = Package.m_def -Category.m_section = Section(repeats=True, parent=Package.m_section) +Category.m_def = Section(repeats=True, parent=Package.m_def) Package.__init_section_cls__() Category.__init_section_cls__() Section.__init_section_cls__() Quantity.__init_section_cls__() - units = UnitRegistry() """ The default pint unit registry that should be used to give units to quantity definitions. """ diff --git a/nomad/metainfo/optimade.py b/nomad/metainfo/optimade.py index 3d849f60c35d4a40accab361092037720c2807cd..2f287f5c3fe3099bce9bbfbf84d8268d2c6678ea 100644 --- a/nomad/metainfo/optimade.py +++ b/nomad/metainfo/optimade.py @@ -28,7 +28,7 @@ class Optimade(): class OptimadeStructureEntry(MObject): - m_section = Section( + m_def = Section( links=optimade_links('h.6.2'), a_flask=dict(skip_none=True), a_elastic=dict(type=InnerDoc)) @@ -173,8 +173,8 @@ class Species(MObject): given site by multiple chemical elements. """ - m_section = Section( - repeats=True, parent=OptimadeStructureEntry.m_section, + m_def = Section( + repeats=True, parent=OptimadeStructureEntry.m_def, links=optimade_links('h.6.2.13')) name = Quantity( @@ -252,7 +252,7 @@ def elastic_obj(source: MObject, target_cls: type): target = target_cls() - for name, quantity in source.m_section.quantities.items(): + for name, quantity in source.m_def.quantities.items(): elastic_annotation = quantity.m_annotations.get('elastic') if elastic_annotation is None: continue @@ -267,4 +267,4 @@ def elastic_obj(source: MObject, target_cls: type): return target -ESOptimadeEntry = elastic_mapping(OptimadeStructureEntry.m_section, InnerDoc) +ESOptimadeEntry = elastic_mapping(OptimadeStructureEntry.m_def, InnerDoc) diff --git a/nomad/parsing/backend.py b/nomad/parsing/backend.py index 8b11ac6a0558e46e9c0758ddd8419ac5772e5479..395fabeaa6c8db690c182e2a8284f9758851f72b 100644 --- a/nomad/parsing/backend.py +++ b/nomad/parsing/backend.py @@ -351,7 +351,7 @@ class LocalBackend(LegacyParserBackend): def add_mi2_section(self, section: MObject): """ Allows to mix a metainfo2 style section into backend. """ - self.mi2_data[section.m_section.name] = section + self.mi2_data[section.m_def.name] = section def get_mi2_section(self, section_def: MI2Section): """ Allows to mix a metainfo2 style section into backend. """ diff --git a/tests/test_metainfo.py b/tests/test_metainfo.py index be47636923da1feaf7bb924bc413da623e4f7acb..800562bc2ca7eaacf09a57a9b4caefdc4ec9ce53 100644 --- a/tests/test_metainfo.py +++ b/tests/test_metainfo.py @@ -20,10 +20,10 @@ from nomad.metainfo.metainfo import MObject, Section, Quantity, Definition, Cate def assert_section_def(section_def: Section): assert isinstance(section_def, Section) - assert section_def.m_section is not None - assert isinstance(section_def.m_section, Section) - assert section_def.m_section.name is not None - assert section_def.m_section.m_section == Section.m_section + assert section_def.m_def is not None + assert isinstance(section_def.m_def, Section) + assert section_def.m_def.name is not None + assert section_def.m_def.m_def == Section.m_def assert section_def.name is not None @@ -36,33 +36,33 @@ def assert_section_def(section_def: Section): def assert_section_instance(section: MObject): - assert_section_def(section.m_section) + assert_section_def(section.m_def) if section.m_parent is not None: - assert section.m_parent.m_sub_section(section.m_section, section.m_parent_index) == section + assert section.m_parent.m_sub_section(section.m_def, section.m_parent_index) == section class TestM3: """ Test for meta-info definition that are used to define other definitions. """ def test_section(self): - assert Section.m_section == Section.m_section.m_section - assert Section.m_section.name == 'Section' + assert Section.m_def == Section.m_def.m_def + assert Section.m_def.name == 'Section' assert Section.name is not None assert Section.name == Definition.name - assert Section.name.m_section == Quantity.m_section + assert Section.name.m_def == Quantity.m_def assert Section.description.description is not None - assert Section.m_section.m_sub_section(Quantity, 0).name in Section.m_section.attributes + assert Section.m_def.m_sub_section(Quantity, 0).name in Section.m_def.attributes - assert_section_instance(Section.m_section) + assert_section_instance(Section.m_def) def test_quantity(self): - assert Quantity.m_section.m_section == Section.m_section - assert Quantity.m_section.name == 'Quantity' - assert Quantity.m_section.parent == Section.m_section + assert Quantity.m_def.m_def == Section.m_def + assert Quantity.m_def.name == 'Quantity' + assert Quantity.m_def.parent == Section.m_def - assert_section_instance(Quantity.m_section) + assert_section_instance(Quantity.m_def) class TestPureReflection: @@ -72,8 +72,8 @@ class TestPureReflection: test_section_def = Section(name='TestSection') test_section_def.m_create(Quantity, name='test_quantity') - obj = MObject(m_section=test_section_def) - assert obj.m_section.name == 'TestSection' + obj = MObject(m_def=test_section_def) + assert obj.m_def.name == 'TestSection' # FIXME assert obj.m_get('test_quantity') is None setattr(obj, 'test_quantity', 'test_value') assert getattr(obj, 'test_quantity') == 'test_value' @@ -99,65 +99,65 @@ class Run(MObject): class System(MObject): - m_section = Section(repeats=True, parent=Run.m_section) + m_def = Section(repeats=True, parent=Run.m_def) n_atoms = Quantity(type=int, default=0, categories=[material_defining]) atom_label = Quantity(type=str, shape=['n_atoms'], categories=[material_defining]) atom_positions = Quantity(type=np.dtype('f8'), shape=['n_atoms', 3]) class Parsing(MObject): - m_section = Section(parent=Run.m_section) + m_def = Section(parent=Run.m_def) class TestM2: """ Test for meta-info definitions. """ def test_basics(self): - assert_section_def(Run.m_section) - assert_section_def(System.m_section) + assert_section_def(Run.m_def) + assert_section_def(System.m_def) def test_default_section_def(self): """ A section class without an explicit section def must set a default section def. """ - assert Run.m_section is not None - assert Run.m_section.name == 'Run' - assert not Run.m_section.repeats - assert Run.m_section.parent is None + assert Run.m_def is not None + assert Run.m_def.name == 'Run' + assert not Run.m_def.repeats + assert Run.m_def.parent is None def test_quantities(self): - assert len(Run.m_section.quantities) == 1 - assert Run.m_section.quantities['code_name'] == Run.__dict__['code_name'] + assert len(Run.m_def.quantities) == 1 + assert Run.m_def.quantities['code_name'] == Run.__dict__['code_name'] def test_sub_sections(self): - assert len(Run.m_section.sub_sections) == 2 - assert Run.m_section.sub_sections['System'] == System.m_section + assert len(Run.m_def.sub_sections) == 2 + assert Run.m_def.sub_sections['System'] == System.m_def def test_attributes(self): - assert len(Run.m_section.attributes) == 3 - assert Run.m_section.attributes['System'] == System.m_section - assert Run.m_section.attributes['code_name'] == Run.__dict__['code_name'] + assert len(Run.m_def.attributes) == 3 + assert Run.m_def.attributes['System'] == System.m_def + assert Run.m_def.attributes['code_name'] == Run.__dict__['code_name'] def test_get_quantity_def(self): - assert System.n_atoms == System.m_section.attributes['n_atoms'] + assert System.n_atoms == System.m_def.attributes['n_atoms'] def test_add_quantity(self): - System.m_section.add_quantity(Quantity(name='test', type=str)) + System.m_def.add_quantity(Quantity(name='test', type=str)) system = System() system.test = 'test_value' assert 'test' in system.m_data assert system.test == 'test_value' - assert getattr(System, 'test') == System.m_section.quantities['test'] + assert getattr(System, 'test') == System.m_def.quantities['test'] def test_section_name(self): - assert Run.m_section.name == 'Run' + assert Run.m_def.name == 'Run' def test_quantity_name(self): assert Run.code_name.name == 'code_name' def test_section_description(self): - assert Run.m_section.description is not None - assert Run.m_section.description.strip() == Run.m_section.description.strip() + assert Run.m_def.description is not None + assert Run.m_def.description.strip() == Run.m_def.description.strip() def test_quantity_description(self): assert Run.code_name.description is not None @@ -185,15 +185,15 @@ class TestM1: run = Run() - assert run.m_section == Run.m_section - assert run.m_section.name == 'Run' + assert run.m_def == Run.m_def + assert run.m_def.name == 'Run' assert len(run.m_data) == 0 assert_section_instance(run) def test_system(self): class System(MObject): - m_section = Section() + m_def = Section() atom_labels = Quantity(type=str, shape=['1..*']) system = System() @@ -215,7 +215,7 @@ class TestM1: assert False, 'Expected AttributeError' def test_m_section(self): - assert Run().m_section == Run.m_section + assert Run().m_def == Run.m_def def test_children_parent(self): run = Run() @@ -292,11 +292,11 @@ class TestM1: def assert_example_data(self, data: Run): assert_section_instance(data) - assert data.m_section == Run.m_section + assert data.m_def == Run.m_def assert data.code_name == 'test code name' system: System = data.m_sub_section(System, 0) assert_section_instance(system) - assert system.m_section == System.m_section + assert system.m_def == System.m_def assert system.n_atoms == 3 assert system.atom_label == ['H', 'H', 'O'] assert type(system.atom_positions) == np.ndarray