From 9db3c5654926c84655b88c911f22ec660a2209f0 Mon Sep 17 00:00:00 2001 From: Graham Higgins Date: Wed, 22 Mar 2023 13:50:16 +0000 Subject: [PATCH 01/17] docstring updates tidy `# docstring` syntax and replace antiquated namespace_manager bindings with moderm graph ns bindings. --- rdflib/extras/infixowl.py | 66 ++++++++++++--------------------------- 1 file changed, 20 insertions(+), 46 deletions(-) diff --git a/rdflib/extras/infixowl.py b/rdflib/extras/infixowl.py index f4daab776..27722e9b9 100644 --- a/rdflib/extras/infixowl.py +++ b/rdflib/extras/infixowl.py @@ -12,12 +12,9 @@ Uses Manchester Syntax for __repr__ ->>> exNs = Namespace('http://example.com/') ->>> namespace_manager = NamespaceManager(Graph()) ->>> namespace_manager.bind('ex', exNs, override=False) ->>> namespace_manager.bind('owl', OWL, override=False) +>>> exNs = Namespace("http://example.com/") >>> g = Graph() ->>> g.namespace_manager = namespace_manager +>>> g.bind("ex", exNs, override=False) Now we have an empty graph, we can construct OWL classes in it using the Python classes defined in this module @@ -39,8 +36,6 @@ This can also be used against already populated graphs: >>> owlGraph = Graph().parse(str(OWL)) ->>> namespace_manager.bind('owl', OWL, override=False) ->>> owlGraph.namespace_manager = namespace_manager >>> list(Class(OWL.Class, graph=owlGraph).subClassOf) [Class: rdfs:Class ] @@ -830,12 +825,9 @@ def DeepClassClear(class_to_prune): # noqa: N802 Recursively clear the given class, continuing where any related class is an anonymous class - >>> EX = Namespace('http://example.com/') - >>> namespace_manager = NamespaceManager(Graph()) - >>> namespace_manager.bind('ex', EX, override=False) - >>> namespace_manager.bind('owl', OWL, override=False) + >>> EX = Namespace("http://example.com/") >>> g = Graph() - >>> g.namespace_manager = namespace_manager + >>> g.bind("ex", EX, override=False) >>> Individual.factoryGraph = g >>> classB = Class(EX.B) >>> classC = Class(EX.C) @@ -1114,20 +1106,16 @@ def __and__(self, other): Construct an anonymous class description consisting of the intersection of this class and 'other' and return it - >>> exNs = Namespace('http://example.com/') - >>> namespace_manager = NamespaceManager(Graph()) - >>> namespace_manager.bind('ex', exNs, override=False) - >>> namespace_manager.bind('owl', OWL, override=False) - >>> g = Graph() - >>> g.namespace_manager = namespace_manager - Chaining 3 intersections + >>> exNs = Namespace("http://example.com/") + >>> g = Graph() + >>> g.bind("ex", exNs, override=False) >>> female = Class(exNs.Female, graph=g) >>> human = Class(exNs.Human, graph=g) >>> youngPerson = Class(exNs.YoungPerson, graph=g) >>> youngWoman = female & human & youngPerson - >>> youngWoman #doctest: +SKIP + >>> youngWoman #doctest: +SKIP ex:YoungPerson THAT ( ex:Female AND ex:Human ) >>> isinstance(youngWoman, BooleanClass) True @@ -1231,11 +1219,8 @@ def _get_parents(self): >>> from rdflib.util import first >>> exNs = Namespace('http://example.com/') - >>> namespace_manager = NamespaceManager(Graph()) - >>> namespace_manager.bind('ex', exNs, override=False) - >>> namespace_manager.bind('owl', OWL, override=False) >>> g = Graph() - >>> g.namespace_manager = namespace_manager + >>> g.bind("ex", exNs, override=False) >>> Individual.factoryGraph = g >>> brother = Class(exNs.Brother) >>> sister = Class(exNs.Sister) @@ -1463,25 +1448,21 @@ class EnumeratedClass(OWLRDFListProxy, Class): axiom ::= 'EnumeratedClass(' classID ['Deprecated'] { annotation } { individualID } ')' - - >>> exNs = Namespace('http://example.com/') - >>> namespace_manager = NamespaceManager(Graph()) - >>> namespace_manager.bind('ex', exNs, override=False) - >>> namespace_manager.bind('owl', OWL, override=False) + >>> exNs = Namespace("http://example.com/") >>> g = Graph() - >>> g.namespace_manager = namespace_manager + >>> g.bind("ex", exNs, override=False) >>> Individual.factoryGraph = g >>> ogbujiBros = EnumeratedClass(exNs.ogbujicBros, ... members=[exNs.chime, ... exNs.uche, ... exNs.ejike]) - >>> ogbujiBros #doctest: +SKIP + >>> ogbujiBros # doctest: +SKIP { ex:chime ex:uche ex:ejike } >>> col = Collection(g, first( ... g.objects(predicate=OWL.oneOf, subject=ogbujiBros.identifier))) >>> sorted([g.qname(item) for item in col]) ['ex:chime', 'ex:ejike', 'ex:uche'] - >>> print(g.serialize(format='n3')) #doctest: +SKIP + >>> print(g.serialize(format='n3')) # doctest: +SKIP @prefix ex: . @prefix owl: . @prefix rdf: . @@ -1532,16 +1513,14 @@ class BooleanClassExtentHelper: >>> testGraph = Graph() >>> Individual.factoryGraph = testGraph >>> EX = Namespace("http://example.com/") - >>> namespace_manager = NamespaceManager(Graph()) - >>> namespace_manager.bind('ex', EX, override=False) - >>> testGraph.namespace_manager = namespace_manager + >>> testGraph.bind("ex", EX, override=False) >>> fire = Class(EX.Fire) >>> water = Class(EX.Water) >>> testClass = BooleanClass(members=[fire, water]) >>> testClass2 = BooleanClass( ... operator=OWL.unionOf, members=[fire, water]) >>> for c in BooleanClass.getIntersections(): - ... print(c) #doctest: +SKIP + ... print(c) # doctest: +SKIP ( ex:Fire AND ex:Water ) >>> for c in BooleanClass.getUnions(): ... print(c) #doctest: +SKIP @@ -1638,13 +1617,10 @@ def changeOperator(self, newOperator): # noqa: N802, N803 Converts a unionOf / intersectionOf class expression into one that instead uses the given operator - >>> testGraph = Graph() >>> Individual.factoryGraph = testGraph >>> EX = Namespace("http://example.com/") - >>> namespace_manager = NamespaceManager(Graph()) - >>> namespace_manager.bind('ex', EX, override=False) - >>> testGraph.namespace_manager = namespace_manager + >>> testGraph.bind("ex", EX, override=False) >>> fire = Class(EX.Fire) >>> water = Class(EX.Water) >>> testClass = BooleanClass(members=[fire,water]) @@ -1656,7 +1632,7 @@ def changeOperator(self, newOperator): # noqa: N802, N803 >>> try: ... testClass.changeOperator(OWL.unionOf) ... except Exception as e: - ... print(e) #doctest: +SKIP + ... print(e) # doctest: +SKIP The new operator is already being used! """ @@ -1775,16 +1751,14 @@ def serialize(self, graph): >>> g1 = Graph() >>> g2 = Graph() >>> EX = Namespace("http://example.com/") - >>> namespace_manager = NamespaceManager(g1) - >>> namespace_manager.bind('ex', EX, override=False) - >>> namespace_manager = NamespaceManager(g2) - >>> namespace_manager.bind('ex', EX, override=False) + >>> g1.bind("ex", EX, override=False) + >>> g2.bind("ex", EX, override=False) >>> Individual.factoryGraph = g1 >>> prop = Property(EX.someProp, baseType=OWL.DatatypeProperty) >>> restr1 = (Property( ... EX.someProp, ... baseType=OWL.DatatypeProperty)) << some >> (Class(EX.Foo)) - >>> restr1 #doctest: +SKIP + >>> restr1 # doctest: +SKIP ( ex:someProp SOME ex:Foo ) >>> restr1.serialize(g2) >>> Individual.factoryGraph = g2 From 359d69f851d52eaf9d48ddf054fafb9aea04cf6c Mon Sep 17 00:00:00 2001 From: Graham Higgins Date: Wed, 22 Mar 2023 13:52:58 +0000 Subject: [PATCH 02/17] change to use `@` as infix operator --- rdflib/extras/infixowl.py | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/rdflib/extras/infixowl.py b/rdflib/extras/infixowl.py index 27722e9b9..0dfa2ead1 100644 --- a/rdflib/extras/infixowl.py +++ b/rdflib/extras/infixowl.py @@ -92,13 +92,13 @@ Restrictions can also be created using Manchester OWL syntax in 'colloquial' Python ->>> exNs.hasParent << some >> Class(exNs.Physician, graph=g) +>>> exNs.hasParent @ some @ Class(exNs.Physician, graph=g) ( ex:hasParent SOME ex:Physician ) ->>> Property(exNs.hasParent, graph=g) << max >> Literal(1) +>>> Property(exNs.hasParent, graph=g) @ max @ Literal(1) ( ex:hasParent MAX 1 ) ->>> print(g.serialize(format='pretty-xml')) #doctest: +SKIP +>>> print(g.serialize(format='pretty-xml')) # doctest: +SKIP """ @@ -166,9 +166,7 @@ # definition of an Infix operator class # this recipe also works in jython -# calling sequence for the infix is either: -# x << op >> y -# or: +# calling sequence for the infix is: # x @ op @ y @@ -834,14 +832,14 @@ def DeepClassClear(class_to_prune): # noqa: N802 >>> classD = Class(EX.D) >>> classE = Class(EX.E) >>> classF = Class(EX.F) - >>> anonClass = EX.someProp << some >> classD + >>> anonClass = EX.someProp @ some @ classD >>> classF += anonClass >>> list(anonClass.subClassOf) [Class: ex:F ] >>> classA = classE | classF | anonClass >>> classB += classA >>> classA.equivalentClass = [Class()] - >>> classB.subClassOf = [EX.someProp << some >> classC] + >>> classB.subClassOf = [EX.someProp @ some @ classC] >>> classA ( ex:E OR ex:F OR ( ex:someProp SOME ex:D ) ) >>> DeepClassClear(classA) @@ -1757,7 +1755,7 @@ def serialize(self, graph): >>> prop = Property(EX.someProp, baseType=OWL.DatatypeProperty) >>> restr1 = (Property( ... EX.someProp, - ... baseType=OWL.DatatypeProperty)) << some >> (Class(EX.Foo)) + ... baseType=OWL.DatatypeProperty)) @ some @ (Class(EX.Foo)) >>> restr1 # doctest: +SKIP ( ex:someProp SOME ex:Foo ) >>> restr1.serialize(g2) From 4e8301e0a0a9bf3d19bb5ab23859df200ff407d9 Mon Sep 17 00:00:00 2001 From: Graham Higgins Date: Wed, 22 Mar 2023 19:35:52 +0000 Subject: [PATCH 03/17] Add documentation to Individual, rename serialize. --- rdflib/extras/infixowl.py | 63 +++++++++++++++++++++++++++++++++++---- 1 file changed, 57 insertions(+), 6 deletions(-) diff --git a/rdflib/extras/infixowl.py b/rdflib/extras/infixowl.py index 0dfa2ead1..9488f9031 100644 --- a/rdflib/extras/infixowl.py +++ b/rdflib/extras/infixowl.py @@ -351,17 +351,14 @@ def _remover(inst): return _remover -class Individual(object): +class Individual: """ - A typed individual + A typed individual, the base class of the InfixOWL classes. + """ factoryGraph = Graph() # noqa: N815 - def serialize(self, graph): - for fact in self.factoryGraph.triples((self.identifier, None, None)): - graph.add(fact) - def __init__(self, identifier=None, graph=None): self.__identifier = identifier is not None and identifier or BNode() if graph is None: @@ -376,17 +373,71 @@ def __init__(self, identifier=None, graph=None): except Exception: # pragma: no cover pass # pragma: no cover + def snc(self, graph, bnc=False): + """ + Take terms referencing this individual as a subject and + add them to the provided graph. + """ + for fact in self.factoryGraph.triples((self.identifier, None, None)): + graph.add(fact) + + return graph + + def bnc(self, graph, bnc=False): + """ + Take terms related to this individual using a blank node + closure and add them to the provided graph. + """ + for fact in self.factoryGraph.triples((self.identifier, None, None)): + graph.add(fact) + if ( + isinstance(fact[2], BNode) + and (fact[2], None, None) not in self.factoryGraph + ): + graph += self.factoryGraph.triples((fact[2], None, None)) + + return graph + def clearInDegree(self): # noqa: N802 + """ + Remove references to this individual as an object in the + backing store. + """ self.graph.remove((None, None, self.identifier)) def clearOutDegree(self): # noqa: N802 + """ + Remove all statements to this individual as a subject in the + backing store. Note that this only removes the statements + themselves, not the blank node closure so there is a chance + that this will cause orphaned blank nodes to remain in the + graph. + """ self.graph.remove((self.identifier, None, None)) def delete(self): + """ + Delete the individual from the graph, clearing the in and + out degrees. + """ self.clearInDegree() self.clearOutDegree() def replace(self, other): + """ + Replace the individual in the graph with the given other, + causing all triples that refer to it to be changed and then + delete the individual. + + >>> g = Graph() + >>> b = Individual(OWL.Restriction, g) + >>> b.type = RDFS.Resource + >>> len(list(b.type)) + 1 + >>> del b.type + >>> len(list(b.type)) + 0 + """ for s, p, _o in self.graph.triples((None, None, self.identifier)): self.graph.add((s, p, classOrIdentifier(other))) self.delete() From 4069831d31fc7ba023b58ec55536636222bf5cce Mon Sep 17 00:00:00 2001 From: Graham Higgins Date: Wed, 22 Mar 2023 19:37:34 +0000 Subject: [PATCH 04/17] modernize OWLRDFListProxy class def, add _rdfList field. --- rdflib/extras/infixowl.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/rdflib/extras/infixowl.py b/rdflib/extras/infixowl.py index 9488f9031..370dea695 100644 --- a/rdflib/extras/infixowl.py +++ b/rdflib/extras/infixowl.py @@ -1417,7 +1417,9 @@ def __repr__(self, full=False, normalization=True): ) + klassdescr -class OWLRDFListProxy(object): +class OWLRDFListProxy: + _rdfList: list = [] # noqa: N815 + def __init__(self, rdf_list, members=None, graph=None): if graph: self.graph = graph From 0bb25a3cefb8797437b4111c7fa7a56f0882d903 Mon Sep 17 00:00:00 2001 From: Graham Higgins Date: Wed, 22 Mar 2023 19:39:03 +0000 Subject: [PATCH 05/17] Robustify return of string --- rdflib/extras/infixowl.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rdflib/extras/infixowl.py b/rdflib/extras/infixowl.py index 370dea695..fd2e7ee0c 100644 --- a/rdflib/extras/infixowl.py +++ b/rdflib/extras/infixowl.py @@ -326,7 +326,8 @@ def castToQName(x): # noqa: N802 except Exception: if isinstance(thing, BNode): return thing.n3() - return "<" + thing + ">" + # Expect the unexpected + return thing.identifier if not isinstance(thing, str) else thing label = first(Class(thing, graph=store).label) if label: return label From 0aac6a6ba63cc5946282d8bac31adbc0d66f1ddd Mon Sep 17 00:00:00 2001 From: Graham Higgins Date: Wed, 22 Mar 2023 19:40:23 +0000 Subject: [PATCH 06/17] Add documentation of operator mapping --- rdflib/extras/infixowl.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/rdflib/extras/infixowl.py b/rdflib/extras/infixowl.py index fd2e7ee0c..7b35a6f36 100644 --- a/rdflib/extras/infixowl.py +++ b/rdflib/extras/infixowl.py @@ -2,6 +2,19 @@ __doc__ = """RDFLib Python binding for OWL Abstract Syntax +OWL Constructor DL Syntax Manchester OWL Syntax Example +==================================================================================== +intersectionOf C ∩ D C AND D Human AND Male +unionOf C ∪ D C OR D Man OR Woman +complementOf ¬ C NOT C NOT Male +oneOf {a} ∪ {b}... {a b ...} {England Italy Spain} +someValuesFrom ∃ R C R SOME C hasColleague SOME Professor +allValuesFrom ∀ R C R ONLY C hasColleague ONLY Professor +minCardinality ≥ N R R MIN 3 hasColleague MIN 3 +maxCardinality ≤ N R R MAX 3 hasColleague MAX 3 +cardinality = N R R EXACTLY 3 hasColleague EXACTLY 3 +hasValue ∃ R {a} R VALUE a hasColleague VALUE Matthew + see: http://www.w3.org/TR/owl-semantics/syntax.html http://owl-workshop.man.ac.uk/acceptedLong/submission_9.pdf From 45fc1eb7fca92a5a7cc245d6dbd50c8310600e68 Mon Sep 17 00:00:00 2001 From: Graham Higgins Date: Wed, 22 Mar 2023 19:41:41 +0000 Subject: [PATCH 07/17] Fix Callable issue --- rdflib/extras/infixowl.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/rdflib/extras/infixowl.py b/rdflib/extras/infixowl.py index 7b35a6f36..2266c26b3 100644 --- a/rdflib/extras/infixowl.py +++ b/rdflib/extras/infixowl.py @@ -1605,7 +1605,10 @@ def _getExtent(): # noqa: N802 class Callable: def __init__(self, anycallable): - self.__call__ = anycallable + self.__callfn__ = anycallable + + def __call__(self, *args, **kwargs): + return self.__callfn__(*args, **kwargs) class BooleanClass(OWLRDFListProxy, Class): From da93538e8c92a5a7799819c9a23a4c58e6c0eee3 Mon Sep 17 00:00:00 2001 From: Graham Higgins Date: Wed, 22 Mar 2023 19:44:08 +0000 Subject: [PATCH 08/17] Fix cardinality issue --- rdflib/extras/infixowl.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/rdflib/extras/infixowl.py b/rdflib/extras/infixowl.py index 2266c26b3..5e37617bf 100644 --- a/rdflib/extras/infixowl.py +++ b/rdflib/extras/infixowl.py @@ -1749,6 +1749,7 @@ class Restriction(Class): OWL.allValuesFrom, OWL.someValuesFrom, OWL.hasValue, + OWL.cardinality, OWL.maxCardinality, OWL.minCardinality, ] @@ -1960,7 +1961,7 @@ def _get_cardinality(self): def _set_cardinality(self, other): if not other: return - triple = (self.identifier, OWL.cardinality, classOrIdentifier(other)) + triple = (self.identifier, OWL.cardinality, classOrTerm(other)) if triple in self.graph: return else: @@ -1982,7 +1983,7 @@ def _get_maxcardinality(self): def _set_maxcardinality(self, other): if not other: return - triple = (self.identifier, OWL.maxCardinality, classOrIdentifier(other)) + triple = (self.identifier, OWL.maxCardinality, classOrTerm(other)) if triple in self.graph: return else: From c6fb13fbe1386cf6d9161e38aa76cd1b4a750c12 Mon Sep 17 00:00:00 2001 From: Graham Higgins Date: Wed, 22 Mar 2023 19:45:23 +0000 Subject: [PATCH 09/17] Change assertions to exceptions --- rdflib/extras/infixowl.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/rdflib/extras/infixowl.py b/rdflib/extras/infixowl.py index 5e37617bf..90aa30193 100644 --- a/rdflib/extras/infixowl.py +++ b/rdflib/extras/infixowl.py @@ -1643,16 +1643,17 @@ def __init__( ): props.append(p) operator = p - assert len(props) == 1, repr(props) + if len(props) != 1: + raise Exception( + f"Cannot create a BooleanClass for {identifier} with the given graph." + ) Class.__init__(self, identifier, graph=graph) assert operator in [OWL.intersectionOf, OWL.unionOf], str(operator) self._operator = operator rdf_list = list(self.graph.objects(predicate=operator, subject=self.identifier)) - assert ( - not members or not rdf_list - ), "This is a previous boolean class description!" + repr( - Collection(self.graph, rdf_list[0]).n3() - ) + if members != [] and rdf_list != []: + c = Collection(self.graph, rdf_list[0]) + raise Exception(f"This is a previous boolean class description {c.n3()}.") OWLRDFListProxy.__init__(self, rdf_list, members) def copy(self): From 80b1c7d0d1e6e730dee661694aaeeff8226c3835 Mon Sep 17 00:00:00 2001 From: Graham Higgins Date: Thu, 23 Mar 2023 17:40:24 +0000 Subject: [PATCH 10/17] Add _rdfList class variable, revert Exceptions back to AssertionErrors. --- rdflib/extras/infixowl.py | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/rdflib/extras/infixowl.py b/rdflib/extras/infixowl.py index 90aa30193..66c91ca54 100644 --- a/rdflib/extras/infixowl.py +++ b/rdflib/extras/infixowl.py @@ -1432,7 +1432,7 @@ def __repr__(self, full=False, normalization=True): class OWLRDFListProxy: - _rdfList: list = [] # noqa: N815 + _rdfList: "Collection" = None # noqa: N815 def __init__(self, rdf_list, members=None, graph=None): if graph: @@ -1643,17 +1643,14 @@ def __init__( ): props.append(p) operator = p - if len(props) != 1: - raise Exception( - f"Cannot create a BooleanClass for {identifier} with the given graph." - ) + assert len(props) == 1, repr(props) Class.__init__(self, identifier, graph=graph) assert operator in [OWL.intersectionOf, OWL.unionOf], str(operator) self._operator = operator rdf_list = list(self.graph.objects(predicate=operator, subject=self.identifier)) - if members != [] and rdf_list != []: - c = Collection(self.graph, rdf_list[0]) - raise Exception(f"This is a previous boolean class description {c.n3()}.") + assert ( + not members or not rdf_list + ), "This is a previous boolean class description." OWLRDFListProxy.__init__(self, rdf_list, members) def copy(self): @@ -1714,7 +1711,11 @@ def __repr__(self): """ Returns the Manchester Syntax equivalent for this class """ - return manchesterSyntax(self._rdfList.uri, self.graph, boolean=self._operator) + return manchesterSyntax( + self._rdfList.uri if isinstance(self._rdfList, Collection) else BNode(), + self.graph, + boolean=self._operator, + ) def __or__(self, other): """ From c89bc792f2727e8b5b42e802fd4849863fe221bb Mon Sep 17 00:00:00 2001 From: Graham Higgins Date: Thu, 23 Mar 2023 17:40:53 +0000 Subject: [PATCH 11/17] update infixowl tests --- .../test_infixowl/test_booleanclass.py | 8 +- .../test_infixowl/test_logic_structuring.py | 1 + .../test_infixowl/test_manchester_syntax.py | 1 + .../test_infixowl/test_restriction.py | 144 +++++++++++++++--- 4 files changed, 125 insertions(+), 29 deletions(-) diff --git a/test/test_extras/test_infixowl/test_booleanclass.py b/test/test_extras/test_infixowl/test_booleanclass.py index 86f7a223e..893e58226 100644 --- a/test/test_extras/test_infixowl/test_booleanclass.py +++ b/test/test_extras/test_infixowl/test_booleanclass.py @@ -17,7 +17,7 @@ def graph(): del g -@pytest.mark.xfail(reason="assert len(props) == 1, repr(props), so AssertionError: []") +@pytest.mark.xfail(reason="AssertionError, len(props) != 1") def test_booleanclass_operator_as_none(graph): fire = Class(EXNS.Fire) water = Class(EXNS.Water) @@ -63,16 +63,10 @@ def test_booleanclass_with_or_operator(graph): assert str(c) == "( ex:Fire OR ex:Water )" -@pytest.mark.xfail( - reason="BooleanClass.getIntersections() - TypeError: 'Callable' object is not callable" -) def test_getintersections(graph): _ = BooleanClass.getIntersections() -@pytest.mark.xfail( - reason="BooleanClass.getUnions() - TypeError: 'Callable' object is not callable" -) def test_getunions(graph): _ = BooleanClass.getUnions() diff --git a/test/test_extras/test_infixowl/test_logic_structuring.py b/test/test_extras/test_infixowl/test_logic_structuring.py index de3134f39..8e831f7c1 100644 --- a/test/test_extras/test_infixowl/test_logic_structuring.py +++ b/test/test_extras/test_infixowl/test_logic_structuring.py @@ -19,6 +19,7 @@ def graph(): del g +@pytest.mark.xfail(reason="Harness oddity, passes if run individually") def test_logic_structuring(graph): isPartOf = Property(EXNS.isPartOf) # noqa: N806 graph.add((isPartOf.identifier, RDF.type, OWL.TransitiveProperty)) diff --git a/test/test_extras/test_infixowl/test_manchester_syntax.py b/test/test_extras/test_infixowl/test_manchester_syntax.py index 52669af6e..68c76d11b 100644 --- a/test/test_extras/test_infixowl/test_manchester_syntax.py +++ b/test/test_extras/test_infixowl/test_manchester_syntax.py @@ -43,6 +43,7 @@ def test_manchester_syntax(graph): assert res == Literal("Caprina", lang="pt") +@pytest.mark.xfail(reason="Harness oddity, passes if run individually") def test_manchester_syntax_parse_with_transientlist(graph): graph.parse(TEST_DATA_DIR / "owl" / "pizza.owl", format="xml") diff --git a/test/test_extras/test_infixowl/test_restriction.py b/test/test_extras/test_infixowl/test_restriction.py index c57cacb2c..7f8a4fc3a 100644 --- a/test/test_extras/test_infixowl/test_restriction.py +++ b/test/test_extras/test_infixowl/test_restriction.py @@ -1,6 +1,6 @@ import pytest -from rdflib import OWL, XSD, BNode, Graph, Literal, Namespace, URIRef +from rdflib import OWL, XSD, BNode, Graph, Literal, Namespace, RDF, URIRef from rdflib.extras.infixowl import Class, Individual, Property, Restriction, some EXNS = Namespace("http://example.org/vocab/") @@ -20,12 +20,9 @@ def graph(): del g +@pytest.mark.xfail(reason="Harness oddity, passes if run individually") def test_restriction_str_and_hash(graph): - r1 = ( - (Property(EXNS.someProp, baseType=OWL.DatatypeProperty)) - @ some - @ (Class(EXNS.Foo)) - ) + r1 = Property(EXNS.someProp, baseType=OWL.DatatypeProperty) @ some @ Class(EXNS.Foo) assert str(r1) == "( ex:someProp SOME ex:Foo )" @@ -236,34 +233,40 @@ def test_restriction_cardinality_value(graph): assert str(r.cardinality) == "Some Class " -@pytest.mark.xfail(reason="_set_cardinality fails to handle Literal") def test_restriction_cardinality_set_value(graph): r = Restriction( onProperty=EXNS.hasChild, graph=graph, - cardinality=OWL.cardinality, + cardinality=Literal("0", datatype=XSD.nonNegativeInteger), + identifier=URIRef(EXNS.r1), ) + assert str(r) == "( ex:hasChild EQUALS 0 )" + assert graph.serialize(format="ttl") == ( "@prefix ex: .\n" "@prefix owl: .\n" + "@prefix xsd: .\n" "\n" - "[] a owl:Restriction ;\n" - " owl:cardinality owl:cardinality ;\n" + "ex:r1 a owl:Restriction ;\n" + ' owl:cardinality "0"^^xsd:nonNegativeInteger ;\n' " owl:onProperty ex:hasChild .\n" "\n" ) - assert r.cardinality is not None - - assert str(r) == "( ex:hasChild EQUALS http://www.w3.org/2002/07/owl#cardinality )" - - assert str(r.cardinality) == "Class: owl:cardinality " + r.cardinality = Literal("1", datatype=XSD.nonNegativeInteger) - r.cardinality = Literal("0", datatype=XSD.nonNegativeInteger) + assert str(r) == "( ex:hasChild EQUALS 1 )" - assert ( - str(r) == '( ex:hasChild EQUALS owl:cardinality "0"^^xsd:nonNegativeInteger )' + assert graph.serialize(format="ttl") == ( + "@prefix ex: .\n" + "@prefix owl: .\n" + "@prefix xsd: .\n" + "\n" + "ex:r1 a owl:Restriction ;\n" + ' owl:cardinality "1"^^xsd:nonNegativeInteger ;\n' + " owl:onProperty ex:hasChild .\n" + "\n" ) @@ -271,21 +274,114 @@ def test_restriction_maxcardinality(graph): r = Restriction( onProperty=EXNS.hasChild, graph=graph, - maxCardinality=OWL.maxCardinality, + maxCardinality=Literal("0", datatype=XSD.nonNegativeInteger), + identifier=URIRef(EXNS.r1), ) - assert str(r.maxCardinality) == "Class: owl:maxCardinality " + assert graph.serialize(format="ttl") == ( + "@prefix ex: .\n" + "@prefix owl: .\n" + "@prefix xsd: .\n" + "\n" + "ex:r1 a owl:Restriction ;\n" + ' owl:maxCardinality "0"^^xsd:nonNegativeInteger ;\n' + " owl:onProperty ex:hasChild .\n" + "\n" + ) + + # FIXME: Don't do this, it changes the value!! + assert str(r.maxCardinality) == "Some Class " + + assert graph.serialize(format="ttl") == ( + "@prefix ex: .\n" + "@prefix owl: .\n" + "@prefix xsd: .\n" + "\n" + "ex:r1 a owl:Restriction ;\n" + ' owl:maxCardinality "0"^^xsd:nonNegativeInteger ;\n' + " owl:onProperty ex:hasChild .\n" + "\n" + "[] a owl:Class .\n" + "\n" + ) r.maxCardinality = OWL.maxCardinality + assert graph.serialize(format="ttl") == ( + "@prefix ex: .\n" + "@prefix owl: .\n" + "\n" + "ex:r1 a owl:Restriction ;\n" + " owl:maxCardinality owl:maxCardinality ;\n" + " owl:onProperty ex:hasChild .\n" + "\n" + "[] a owl:Class .\n" + "\n" + ) + + # Ignored r.maxCardinality = None - r.maxCardinality = EXNS.foo + assert graph.serialize(format="ttl") != "" + + superfluous_assertion_subject = list(graph.subjects(RDF.type, OWL.Class))[0] + + assert isinstance(superfluous_assertion_subject, BNode) + + graph.remove((superfluous_assertion_subject, RDF.type, OWL.Class)) + + assert graph.serialize(format="ttl") == ( + "@prefix ex: .\n" + "@prefix owl: .\n" + "\n" + "ex:r1 a owl:Restriction ;\n" + " owl:maxCardinality owl:maxCardinality ;\n" + " owl:onProperty ex:hasChild .\n" + "\n" + ) + + r.maxCardinality = EXNS.maxkids + + assert str(r) == "( ex:hasChild MAX http://example.org/vocab/maxkids )" + + assert graph.serialize(format="ttl") == ( + "@prefix ex: .\n" + "@prefix owl: .\n" + "\n" + "ex:r1 a owl:Restriction ;\n" + " owl:maxCardinality ex:maxkids ;\n" + " owl:onProperty ex:hasChild .\n" + "\n" + ) del r.maxCardinality + assert graph.serialize(format="ttl") == ( + "@prefix ex: .\n" + "@prefix owl: .\n" + "\n" + "ex:r1 a owl:Restriction ;\n" + " owl:onProperty ex:hasChild .\n" + "\n" + ) + assert r.maxCardinality is None + r.maxCardinality = Literal("2", datatype=XSD.nonNegativeInteger) + + assert str(r) == "( ex:hasChild MAX 2 )" + + assert graph.serialize(format="ttl") == ( + "@prefix ex: .\n" + "@prefix owl: .\n" + "@prefix xsd: .\n" + "\n" + "ex:r1 a owl:Restriction ;\n" + ' owl:maxCardinality "2"^^xsd:nonNegativeInteger ;\n' + " owl:onProperty ex:hasChild .\n" + "\n" + ) + def test_restriction_mincardinality(graph): r = Restriction( @@ -300,12 +396,16 @@ def test_restriction_mincardinality(graph): r.minCardinality = None - r.minCardinality = EXNS.foo + r.minCardinality = EXNS.minkids + + assert str(r) == "( ex:hasChild MIN http://example.org/vocab/minkids )" del r.minCardinality assert r.minCardinality is None + r.minCardinality = Literal("0", datatype=XSD.nonNegativeInteger) + def test_restriction_kind(graph): r = Restriction( From 7861598f606d543f7833fe3d6aa737763c4575fa Mon Sep 17 00:00:00 2001 From: Graham Higgins Date: Thu, 23 Mar 2023 17:52:10 +0000 Subject: [PATCH 12/17] Add example of ontology creation using infixowl syntax --- examples/infixowl_ontology_creation.py | 281 +++++++++++++++++++++++++ 1 file changed, 281 insertions(+) create mode 100644 examples/infixowl_ontology_creation.py diff --git a/examples/infixowl_ontology_creation.py b/examples/infixowl_ontology_creation.py new file mode 100644 index 000000000..580f38c5f --- /dev/null +++ b/examples/infixowl_ontology_creation.py @@ -0,0 +1,281 @@ +from rdflib import Graph, Namespace, Literal, URIRef +from rdflib.extras.infixowl import ( + Class, + Property, + Ontology, + some, + only, + min, +) + +CPR = Namespace("http://purl.org/cpr/0.75#") +INF = Namespace("http://www.loa-cnr.it/ontologies/InformationObjects.owl#") +EDNS = Namespace("http://www.loa-cnr.it/ontologies/ExtendedDnS.owl#") +DOLCE = Namespace("http://www.loa-cnr.it/ontologies/DOLCE-Lite.owl#") +REL = Namespace("http://www.geneontology.org/owl#") +GALEN = Namespace("http://www.co-ode.org/ontologies/galen#") +TIME = Namespace("http://www.w3.org/2006/time#") +CYC = Namespace("http://sw.cyc.com/2006/07/27/cyc/") + + +def infixowl_example(): + g = Graph() + g.bind("cpr", CPR, override=False) + g.bind("ro", REL, override=False) + g.bind("inf", INF, override=False) + g.bind("edns", EDNS, override=False) + g.bind("dol", DOLCE, override=False) + g.bind("time", TIME, override=False) + g.bind("galen", GALEN, override=False) + + Class.factoryGraph = g + Property.factoryGraph = g + Ontology.factoryGraph = g + + cprOntology = Ontology(URIRef("http://purl.org/cpr/owl")) + cprOntology.imports = [ + URIRef("http://obo.sourceforge.net/relationship/relationship.owl"), + URIRef(DOLCE), + URIRef(EDNS), + URIRef("http://www.w3.org/2006/time#"), + ] + cprOntology.comment = [ + Literal( + """This OWL ontology was generated by Fuxi 0.85b.dev-r107 + (with newly added Infix OWL syntax library). It imports the + OBO relationship ontology, DOLCE, and OWL time. It formally + defines a focused, core set of archetypes [Jung, C.] + replicated in various patient record terminology. This core is + defined in RDF and follows the normalization principles + of "rigorous formal ontologies" [Rector, A.].""" + ) + ] + cprOntology.setVersion(Literal("0.75")) + + # Relations + # represented-by + representationOf = Property( + CPR["representation-of"], + inverseOf=Property(CPR["represented-by"]), + comment=[ + Literal( + """Patient records stand in the cpr:representation-of relation + with patients""" + ) + ], + ) + representedBy = Property(CPR["represented-by"], inverseOf=representationOf) + # description-of + descrOf = Property( + CPR["description-of"], + comment=[ + Literal( + """Clinical descriptions stand in the cpr:description-of + relation with various clinical phenomenon""" + ) + ], + domain=[Class(CPR["clinical-description"])], + ) + # cpr:interpreted-by + interpretedBy = Property( + CPR["interpreted-by"], + comment=[ + Literal( + """Signs and symptoms are interpreted by rational physical + objects (people)""" + ) + ], + domain=[Class(CPR["medical-sign"]) | Class(CPR["symptom"])], + range=[Class(CPR.person)], + ) + ##cpr:realized-by + realizedBy = Property( + CPR["realized-by"], + comment=[ + Literal( + """The epistemological relation in which screening acts and + the problems they realize stand to each other""" + ) + ], + inverseOf=Property(CPR["realizes"]), + domain=[Class(CPR["medical-problem"])], + range=[Class(CPR["screening-act"])], + ) + ##cpr:realizes + realizes = Property(CPR["realizes"], inverseOf=realizedBy) + + ##Classes + # cpr:person + person = Class(CPR.person) + person.comment = [ + Literal( + """A class which directly corresponds with the “Person” class in + both GALEN and Cyc""" + ) + ] + person.subClassOf = [Class(EDNS["rational-physical-object"])] + person.equivalentClass = [Class(GALEN.Person), Class(CYC.Person)] + + # cpr:patient + patient = Class(CPR.patient) + patient.comment = [ + Literal( + """A class which directly corresponds with the “Patient” + and “MedicalPatient” classes in GALEN / Cyc""" + ) + ] + # patient.equivalentClass = [Class(GALEN.Patient),Class(CYC.MedicalPatient)] + patient.subClassOf = [CPR["represented-by"] @ some @ Class(CPR["patient-record"])] + person += patient + + # cpr:clinician + clinician = Class(CPR.person) + clinician.comment = [ + Literal( + """A person who plays the clinician role (typically Nurse, + Physician / Doctor, etc.)""" + ) + ] + person += clinician + + # bytes + bytes = Class(CPR.bytes) + bytes.comment = [ + Literal( + """The collection of physical objects which constitute a stream of + bytes in memory, disk, etc.""" + ) + ] + bytes.subClassOf = [DOLCE["non-agentive-physical-object"]] + + # cpr:patient-record + patientRecord = Class(CPR["patient-record"]) + patientRecord.comment = [ + Literal( + """a class (a representational artifact [REFTERM]) depicting + relevant clinical information about a specific patient and is + primarily comprised of one or more + cpr:clinical-descriptions.""" + ) + ] + patientRecord.seeAlso = [URIRef("")] + patientRecord.subClassOf = [ + bytes, + # Class(CYC.InformationBearingThing), + CPR["representation-of"] @ only @ patient, + REL.OBO_REL_has_proper_part @ some @ Class(CPR["clinical-description"]), + ] + + ##cpr:medical-problem + problem = Class( + CPR["medical-problem"], + subClassOf=[ + Class(DOLCE.quality), + realizedBy @ only @ Class(CPR["screening-act"]), + ], + ) + problem.comment = [ + Literal( + """.. problems that clearly require the intervention of a health + care professional. These include acute problems requiring + hospitalization and chronic problems requiring long-term + management.""" + ) + ] + + # cpr:clinical-description + clinDescr = Class(CPR["clinical-description"]) + clinDescr.disjointWith = [CPR["patient-record"]] + clinDescr.comment = [ + Literal( + """A class which corresponds (at least syntactically) with the HL7 + RIM Act Class, insofar as its members consist of clinical + recordings (representational artifacts) of natural phenomena + of clinical significance""" + ) + ] + clinDescr.subClassOf = [ + bytes, + # Class(CYC.InformationBearingThing), + DOLCE["has-quality"] @ some @ Class(TIME.TemporalEntity), + descrOf @ min @ Literal(1), + ] + + # cpr:medical-sign + sign = Class( + CPR["medical-sign"], + subClassOf=[ + problem, + Property(CPR["interpreted-by"]) @ only @ clinician, + Property(CPR["interpreted-by"]) @ some @ clinician, + ], + disjointWith=[CPR.symptom], + ) + sign.comment = [ + Literal( + """A cpr:medical-problem which are specifically interpreted by a + clinician. As such, this class is informally defined as an + objective indication of a quality typically detected by a + physician during a physical examination of a patient.""" + ) + ] + + symptom = Class( + CPR["symptom"], + subClassOf=[ + problem, + Property(CPR["interpreted-by"]) @ only @ patient, + Property(CPR["interpreted-by"]) @ some @ patient, + ], + disjointWith=[sign], + ) + symptom.comment = [ + Literal( + """(Medicine) any sensation or change in bodily function that is + experienced by a patient and is associated with a particular + disease.""" + ) + ] + + # clinical-act heriarchy + clinicalAct = Class(CPR["clinical-act"], subClassOf=[Class(EDNS.activity)]) + + therapy = Class(CPR["therapeutic-act"], subClassOf=[clinicalAct]) + therapy += Class(CPR["physical-therapy"], disjointWith=[CPR["medical-therapy"]]) + therapy += Class( + CPR["psychological-therapy"], + disjointWith=[CPR["medical-therapy"], CPR["physical-therapy"]], + ) + + medicalTherapy = Class( + CPR["medical-therapy"], + disjointWith=[CPR["physical-therapy"], CPR["psychological-therapy"]], + ) + therapy += medicalTherapy + medicalTherapy += Class(CPR["substance-administration"]) + + diagnosticAct = Class(CPR["diagnostic-act"], subClassOf=[clinicalAct]) + diagnosticAct.disjointWith = [CPR["therapeutic-act"]] + + screeningAct = Class(CPR["screening-act"]) + screeningAct += Class(CPR["laboratory-test"]) + + diagnosticAct += screeningAct + + screeningAct += Class( + CPR["medical-history-screening-act"], + disjointWith=[CPR["clinical-examination"], CPR["laboratory-test"]], + ) + + screeningAct += Class( + CPR["clinical-examination"], + disjointWith=[CPR["laboratory-test"], CPR["medical-history-screening-act"]], + ) + + device = Class(CPR["medical-device"], subClassOf=[Class(GALEN.Device)]) + + print(g.serialize(format="turtle")) + + +if __name__ == "__main__": + infixowl_example() From 2ea0763d1e68d23852c835dcf3b2344458a74822 Mon Sep 17 00:00:00 2001 From: Graham Higgins Date: Thu, 23 Mar 2023 18:52:04 +0000 Subject: [PATCH 13/17] fix isort issues --- examples/infixowl_ontology_creation.py | 11 ++--------- test/test_extras/test_infixowl/test_restriction.py | 2 +- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/examples/infixowl_ontology_creation.py b/examples/infixowl_ontology_creation.py index 580f38c5f..0e4c6d63b 100644 --- a/examples/infixowl_ontology_creation.py +++ b/examples/infixowl_ontology_creation.py @@ -1,12 +1,5 @@ -from rdflib import Graph, Namespace, Literal, URIRef -from rdflib.extras.infixowl import ( - Class, - Property, - Ontology, - some, - only, - min, -) +from rdflib import Graph, Literal, Namespace, URIRef +from rdflib.extras.infixowl import Class, Ontology, Property, min, only, some CPR = Namespace("http://purl.org/cpr/0.75#") INF = Namespace("http://www.loa-cnr.it/ontologies/InformationObjects.owl#") diff --git a/test/test_extras/test_infixowl/test_restriction.py b/test/test_extras/test_infixowl/test_restriction.py index 7f8a4fc3a..4854683ca 100644 --- a/test/test_extras/test_infixowl/test_restriction.py +++ b/test/test_extras/test_infixowl/test_restriction.py @@ -1,6 +1,6 @@ import pytest -from rdflib import OWL, XSD, BNode, Graph, Literal, Namespace, RDF, URIRef +from rdflib import OWL, RDF, XSD, BNode, Graph, Literal, Namespace, URIRef from rdflib.extras.infixowl import Class, Individual, Property, Restriction, some EXNS = Namespace("http://example.org/vocab/") From 2da73e93de2cb479d8286b4f3388a4c6fdedc9c6 Mon Sep 17 00:00:00 2001 From: Graham Higgins Date: Thu, 23 Mar 2023 19:19:41 +0000 Subject: [PATCH 14/17] busywork --- examples/infixowl_ontology_creation.py | 42 +++++++++++++++----------- 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/examples/infixowl_ontology_creation.py b/examples/infixowl_ontology_creation.py index 0e4c6d63b..8efeb69ca 100644 --- a/examples/infixowl_ontology_creation.py +++ b/examples/infixowl_ontology_creation.py @@ -25,7 +25,7 @@ def infixowl_example(): Property.factoryGraph = g Ontology.factoryGraph = g - cprOntology = Ontology(URIRef("http://purl.org/cpr/owl")) + cprOntology = Ontology(URIRef("http://purl.org/cpr/owl")) # noqa: N806 cprOntology.imports = [ URIRef("http://obo.sourceforge.net/relationship/relationship.owl"), URIRef(DOLCE), @@ -47,7 +47,7 @@ def infixowl_example(): # Relations # represented-by - representationOf = Property( + representationOf = Property( # noqa: N806 CPR["representation-of"], inverseOf=Property(CPR["represented-by"]), comment=[ @@ -57,9 +57,11 @@ def infixowl_example(): ) ], ) - representedBy = Property(CPR["represented-by"], inverseOf=representationOf) + representedBy = Property( # noqa: F841, N806 + CPR["represented-by"], inverseOf=representationOf + ) # description-of - descrOf = Property( + descrOf = Property( # noqa: N806 CPR["description-of"], comment=[ Literal( @@ -70,7 +72,7 @@ def infixowl_example(): domain=[Class(CPR["clinical-description"])], ) # cpr:interpreted-by - interpretedBy = Property( + interpretedBy = Property( # noqa: F841, N806 CPR["interpreted-by"], comment=[ Literal( @@ -81,8 +83,8 @@ def infixowl_example(): domain=[Class(CPR["medical-sign"]) | Class(CPR["symptom"])], range=[Class(CPR.person)], ) - ##cpr:realized-by - realizedBy = Property( + # cpr:realized-by + realizedBy = Property( # noqa: N806 CPR["realized-by"], comment=[ Literal( @@ -94,10 +96,10 @@ def infixowl_example(): domain=[Class(CPR["medical-problem"])], range=[Class(CPR["screening-act"])], ) - ##cpr:realizes - realizes = Property(CPR["realizes"], inverseOf=realizedBy) + # cpr:realizes + realizes = Property(CPR["realizes"], inverseOf=realizedBy) # noqa: F841 - ##Classes + # Classes # cpr:person person = Class(CPR.person) person.comment = [ @@ -142,7 +144,7 @@ def infixowl_example(): bytes.subClassOf = [DOLCE["non-agentive-physical-object"]] # cpr:patient-record - patientRecord = Class(CPR["patient-record"]) + patientRecord = Class(CPR["patient-record"]) # noqa: N806 patientRecord.comment = [ Literal( """a class (a representational artifact [REFTERM]) depicting @@ -159,7 +161,7 @@ def infixowl_example(): REL.OBO_REL_has_proper_part @ some @ Class(CPR["clinical-description"]), ] - ##cpr:medical-problem + # cpr:medical-problem problem = Class( CPR["medical-problem"], subClassOf=[ @@ -177,7 +179,7 @@ def infixowl_example(): ] # cpr:clinical-description - clinDescr = Class(CPR["clinical-description"]) + clinDescr = Class(CPR["clinical-description"]) # noqa: N806 clinDescr.disjointWith = [CPR["patient-record"]] clinDescr.comment = [ Literal( @@ -231,7 +233,9 @@ def infixowl_example(): ] # clinical-act heriarchy - clinicalAct = Class(CPR["clinical-act"], subClassOf=[Class(EDNS.activity)]) + clinicalAct = Class( # noqa: N806 + CPR["clinical-act"], subClassOf=[Class(EDNS.activity)] + ) therapy = Class(CPR["therapeutic-act"], subClassOf=[clinicalAct]) therapy += Class(CPR["physical-therapy"], disjointWith=[CPR["medical-therapy"]]) @@ -240,17 +244,17 @@ def infixowl_example(): disjointWith=[CPR["medical-therapy"], CPR["physical-therapy"]], ) - medicalTherapy = Class( + medicalTherapy = Class( # noqa: N806 CPR["medical-therapy"], disjointWith=[CPR["physical-therapy"], CPR["psychological-therapy"]], ) therapy += medicalTherapy medicalTherapy += Class(CPR["substance-administration"]) - diagnosticAct = Class(CPR["diagnostic-act"], subClassOf=[clinicalAct]) + diagnosticAct = Class(CPR["diagnostic-act"], subClassOf=[clinicalAct]) # noqa: N806 diagnosticAct.disjointWith = [CPR["therapeutic-act"]] - screeningAct = Class(CPR["screening-act"]) + screeningAct = Class(CPR["screening-act"]) # noqa: N806 screeningAct += Class(CPR["laboratory-test"]) diagnosticAct += screeningAct @@ -265,7 +269,9 @@ def infixowl_example(): disjointWith=[CPR["laboratory-test"], CPR["medical-history-screening-act"]], ) - device = Class(CPR["medical-device"], subClassOf=[Class(GALEN.Device)]) + device = Class( # noqa: F841 + CPR["medical-device"], subClassOf=[Class(GALEN.Device)] + ) print(g.serialize(format="turtle")) From 1e61070f191d1eb8b9aff78ff5e945bf17cb9285 Mon Sep 17 00:00:00 2001 From: Graham Higgins Date: Thu, 23 Mar 2023 19:22:06 +0000 Subject: [PATCH 15/17] revert ill-conceived field addition --- rdflib/extras/infixowl.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/rdflib/extras/infixowl.py b/rdflib/extras/infixowl.py index 66c91ca54..8e4b2b8d1 100644 --- a/rdflib/extras/infixowl.py +++ b/rdflib/extras/infixowl.py @@ -1432,8 +1432,6 @@ def __repr__(self, full=False, normalization=True): class OWLRDFListProxy: - _rdfList: "Collection" = None # noqa: N815 - def __init__(self, rdf_list, members=None, graph=None): if graph: self.graph = graph From 39e33d85ad4b8b9b07832d18d62197d5a4efeed9 Mon Sep 17 00:00:00 2001 From: Iwan Aucamp Date: Fri, 7 Apr 2023 18:54:40 +0000 Subject: [PATCH 16/17] remove xfails that are not needed --- test/test_extras/test_infixowl/test_logic_structuring.py | 1 - test/test_extras/test_infixowl/test_manchester_syntax.py | 1 - test/test_extras/test_infixowl/test_restriction.py | 1 - 3 files changed, 3 deletions(-) diff --git a/test/test_extras/test_infixowl/test_logic_structuring.py b/test/test_extras/test_infixowl/test_logic_structuring.py index 8e831f7c1..de3134f39 100644 --- a/test/test_extras/test_infixowl/test_logic_structuring.py +++ b/test/test_extras/test_infixowl/test_logic_structuring.py @@ -19,7 +19,6 @@ def graph(): del g -@pytest.mark.xfail(reason="Harness oddity, passes if run individually") def test_logic_structuring(graph): isPartOf = Property(EXNS.isPartOf) # noqa: N806 graph.add((isPartOf.identifier, RDF.type, OWL.TransitiveProperty)) diff --git a/test/test_extras/test_infixowl/test_manchester_syntax.py b/test/test_extras/test_infixowl/test_manchester_syntax.py index 68c76d11b..52669af6e 100644 --- a/test/test_extras/test_infixowl/test_manchester_syntax.py +++ b/test/test_extras/test_infixowl/test_manchester_syntax.py @@ -43,7 +43,6 @@ def test_manchester_syntax(graph): assert res == Literal("Caprina", lang="pt") -@pytest.mark.xfail(reason="Harness oddity, passes if run individually") def test_manchester_syntax_parse_with_transientlist(graph): graph.parse(TEST_DATA_DIR / "owl" / "pizza.owl", format="xml") diff --git a/test/test_extras/test_infixowl/test_restriction.py b/test/test_extras/test_infixowl/test_restriction.py index 4854683ca..94ffc36f5 100644 --- a/test/test_extras/test_infixowl/test_restriction.py +++ b/test/test_extras/test_infixowl/test_restriction.py @@ -20,7 +20,6 @@ def graph(): del g -@pytest.mark.xfail(reason="Harness oddity, passes if run individually") def test_restriction_str_and_hash(graph): r1 = Property(EXNS.someProp, baseType=OWL.DatatypeProperty) @ some @ Class(EXNS.Foo) From febf6bd6e65a2626d579cdc645d576362045ad1b Mon Sep 17 00:00:00 2001 From: Graham Higgins Date: Tue, 9 May 2023 02:03:12 +0100 Subject: [PATCH 17/17] Minor changes as per https://github.com/RDFLib/rdflib/pull/2307#pullrequestreview-1376146695 --- rdflib/extras/infixowl.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rdflib/extras/infixowl.py b/rdflib/extras/infixowl.py index 357504099..35701a328 100644 --- a/rdflib/extras/infixowl.py +++ b/rdflib/extras/infixowl.py @@ -386,7 +386,7 @@ def __init__(self, identifier=None, graph=None): except Exception: # pragma: no cover pass # pragma: no cover - def snc(self, graph, bnc=False): + def subject_node_closure(self, graph): """ Take terms referencing this individual as a subject and add them to the provided graph. @@ -396,7 +396,7 @@ def snc(self, graph, bnc=False): return graph - def bnc(self, graph, bnc=False): + def blank_node_closure(self, graph): """ Take terms related to this individual using a blank node closure and add them to the provided graph. @@ -1177,7 +1177,7 @@ def __and__(self, other): >>> human = Class(exNs.Human, graph=g) >>> youngPerson = Class(exNs.YoungPerson, graph=g) >>> youngWoman = female & human & youngPerson - >>> youngWoman #doctest: +SKIP + >>> youngWoman # doctest: +SKIP ex:YoungPerson THAT ( ex:Female AND ex:Human ) >>> isinstance(youngWoman, BooleanClass) True