Пример #1
0
    def add_ref(
        self,
        fromtype: RefType,
        fromname: ElementName,
        totype: RefType,
        toname: ElementName,
    ) -> None:
        """ Add an inverse reference, indicating that to type/name is referenced by from type/name

        :param fromtype: Referencer type
        :param fromname: Referencer name
        :param totype: Referencee type
        :param toname: Referencee name
        :return:
        """
        if totype is ClassType:
            self.classrefs.setdefault(cast(ClassDefinitionName, toname),
                                      References()).addref(fromtype, fromname)
        elif totype is SlotType:
            self.slotrefs.setdefault(cast(SlotDefinitionName, toname),
                                     References()).addref(fromtype, fromname)
        elif totype is TypeType:
            self.typerefs.setdefault(cast(TypeDefinitionName, toname),
                                     References()).addref(fromtype, fromname)
        elif totype is SubsetType:
            self.subsetrefs.setdefault(cast(SubsetDefinitionName, toname),
                                       References()).addref(
                                           fromtype, fromname)
        else:
            raise TypeError("Unknown typ: {typ}")
Пример #2
0
    def summarize_definition(self, typ: RefType, k: DefinitionName, v: Definition) -> None:
        """
        Summarize slot and class definitions

        :param typ: type (slot or class)
        :param k: name
        :param v: definition
        :return:
        """
        self.summarize_element(typ, k, v)
        if v.is_a:
            self.isarefs.setdefault(v.is_a, References()).addref(typ, k)
            self.add_ref(typ, k, typ, v.is_a)
        else:
            self.roots.addref(typ, k)
        if v.abstract:
            self.abstracts.addref(typ, k)
        if v.mixin:
            self.mixins.addref(typ, k)
        for mixin in v.mixins:
            self.mixinrefs.setdefault(mixin, References()).addref(typ, k)
            self.add_ref(typ, k, typ, mixin)
        if v.apply_to:
            self.applytos.addref(typ, k)
        for applyto in v.apply_to:
            self.applytorefs.setdefault(applyto, References()).addref(typ, k)
            self.add_ref(typ, k, typ, applyto)
Пример #3
0
    def children(self, name: str) -> List[str]:
        """
        Gets a list of names of children.

        Parameters
        ----------
        name: str
            The name of an element in the Biolink Model.

        Returns
        -------
        List[str]
            The names of the given elements children.

        """
        return self._union_of(self.synopsis.isarefs.get(name, References()))
Пример #4
0
 def test_meta_neighborhood(self):
     """ Test the neighborhood function in the metamodel """
     gen = GeneratorTest(LOCAL_YAML_PATH)
     errfile = StringIO()
     with redirect_stderr(errfile):
         gen.neighborhood(['Definition'])
     self.assertEqual(
         "Warning: neighborhood(Definition) - Definition is undefined",
         errfile.getvalue().strip())
     self.assertEqual(
         References(
             classrefs={
                 'class_definition', 'local_name', 'schema_definition',
                 'subset_definition', 'alt_description', 'definition',
                 'example', 'slot_definition', 'element'
             },
             slotrefs={'is_a', 'apply_to', 'mixins', 'default_range'},
             typerefs={'uriorcurie', 'boolean', 'uri', 'ncname', 'string'},
             subsetrefs=set()), gen.neighborhood('definition'))
Пример #5
0
    def test_meta_neighborhood(self):
        """ Test the neighborhood function in the metamodel """
        gen = GeneratorTest(LOCAL_METAMODEL_YAML_FILE)
        gen.neighborhood([cast(ElementName, 'Definition')])
        self.assertEqual("neighborhood(Definition) - Definition is undefined",
                         gen.logstream.getvalue().strip())
        gen.logstream.truncate(0)
        gen.logstream.seek(0)

        self.assertEqual(
            References(classrefs={
                'element', 'subset_definition', 'slot_definition',
                'local_name', 'extension', 'example', 'class_definition',
                'definition', 'alt_description', 'annotation'
            },
                       slotrefs={'is_a', 'apply_to', 'mixins', 'owner'},
                       typerefs={
                           'boolean', 'datetime', 'uri', 'string',
                           'uriorcurie', 'ncname'
                       },
                       subsetrefs=set()), gen.neighborhood('definition'))
Пример #6
0
 def test_meta_neighborhood(self):
     """ Test the neighborhood function in the metamodel """
     gen = GeneratorTest(LOCAL_METAMODEL_YAML_FILE)
     errfile = StringIO()
     with redirect_stderr(errfile):
         gen.neighborhood([cast(ElementName, 'Definition')])
         # Note: There is something about the PyCharm / UnitTest package that, if you are running a lot of tests, the
         # output ends up getting redirected to the test runner rather than stderr.  If there is nothing at all, we
         # will assume that this is the case.
         if errfile.getvalue().strip():
             self.assertEqual(
                 "Warning: neighborhood(Definition) - Definition is undefined",
                 errfile.getvalue().strip())
         else:
             print(
                 "*** Warning not tested -- stderr redirect isn't working")
     self.assertEqual(
         References(
             classrefs={
                 cast(ClassDefinitionName, e)
                 for e in [
                     'class_definition', 'local_name', 'subset_definition',
                     'alt_description', 'definition', 'example',
                     'slot_definition', 'element'
                 ]
             },
             slotrefs={
                 cast(SlotDefinitionName, e)
                 for e in ['is_a', 'apply_to', 'mixins', 'owner']
             },
             typerefs={
                 cast(TypeDefinitionName, e)
                 for e in
                 ['uriorcurie', 'boolean', 'uri', 'ncname', 'string']
             },
             subsetrefs=set()), gen.neighborhood('definition'))
Пример #7
0
    def neighborhood(self, elements: Union[str, ElementName, List[ElementName]]) \
            -> References:
        """ Return a list of all slots, classes and types that touch any element in elements, including the element
        itself

        @param elements: Element names to do proximity with
        @return: All slots and classes that touch element
        """
        if isinstance(elements, (str, ElementName)):
            elements = [elements]
        touches = References()
        for element in elements:
            if element in self.schema.classes:
                touches.classrefs.add(cast(ClassDefinitionName, element))
                cls = self.schema.classes[cast(ClassDefinitionName, element)]
                if cls.is_a:
                    touches.classrefs.add(cls.is_a)
                # Mixins include apply_to's
                touches.classrefs.update(set(cls.mixins))
                for slotname in cls.slots:
                    slot = self.schema.slots[slotname]
                    if slot.range in self.schema.classes:
                        touches.classrefs.add(
                            cast(ClassDefinitionName, slot.range))
                    elif slot.range in self.schema.types:
                        touches.typerefs.add(
                            cast(TypeDefinitionName, slot.range))
                for cv in self.schema.classes.values():
                    if cv.is_a == element:
                        touches.classrefs.add(cv.name)
                if element in self.synopsis.rangerefs:
                    for slotname in self.synopsis.rangerefs[element]:
                        touches.slotrefs.add(slotname)
                        if self.schema.slots[slotname].domain:
                            touches.classrefs.add(
                                self.schema.slots[slotname].domain)
                if cls.in_subset:
                    touches.subsetrefs.update(cls.in_subset)
            if element in self.schema.slots:
                touches.slotrefs.add(cast(SlotDefinitionName, element))
                slot = self.schema.slots[cast(SlotDefinitionName, element)]
                touches.slotrefs.update(set(slot.mixins))
                if slot.is_a:
                    touches.slotrefs.add(slot.is_a)
                if element in self.synopsis.inverses:
                    touches.slotrefs.update(self.synopsis.inverses[cast(
                        SlotDefinitionName, element)])
                if slot.domain:
                    touches.classrefs.add(slot.domain)
                if slot.range in self.schema.classes:
                    touches.classrefs.add(cast(ClassDefinitionName,
                                               slot.range))
                elif slot.range in self.schema.types:
                    touches.typerefs.add(cast(TypeDefinitionName, slot.range))
                if slot.in_subset:
                    touches.subsetrefs.update(slot.in_subset)
                for sv in self.schema.slots.values():
                    if sv.is_a == element:
                        touches.slotrefs.add(sv.name)
            if element in self.schema.types:
                touches.typerefs.add(cast(TypeDefinitionName, element))
                typ = self.schema.types[cast(TypeDefinitionName, element)]
                if element in self.synopsis.rangerefs:
                    touches.slotrefs.update(self.synopsis.rangerefs[element])
                if typ.typeof:
                    touches.typerefs.add(cast(TypeDefinitionName, typ.typeof))
                if typ.in_subset:
                    touches.subsetrefs.update(typ.in_subset)
                for tv in self.schema.types.values():
                    if tv.typeof == element:
                        touches.slotrefs.add(tv.name)
            if element in self.schema.subsets:
                touches.subsetrefs.add(cast(SubsetDefinitionName, element))
                if element in self.synopsis.subsetrefs:
                    touches.update(self.synopsis.subsetrefs[cast(
                        SubsetDefinitionName, element)])
            if not bool(touches):
                self.logger.warning(
                    f"neighborhood({element}) - {element} is undefined")

        return touches