Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

build(deps-dev): bump mypy from 1.13.0 to 1.14.1 #3023

Merged
merged 11 commits into from
Jan 10, 2025
76 changes: 41 additions & 35 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

44 changes: 26 additions & 18 deletions rdflib/graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -661,10 +661,11 @@ def triples(

def __getitem__(self, item):
"""
A graph can be "sliced" as a shortcut for the triples method
The python slice syntax is (ab)used for specifying triples.
A generator over matches is returned,
the returned tuples include only the parts not given
A graph can be "sliced" as a shortcut for the triples method.
The Python slice syntax is (ab)used for specifying triples.

A generator over matches is returned, the returned tuples include only the
parts not given.

>>> import rdflib
>>> g = rdflib.Graph()
Expand Down Expand Up @@ -701,30 +702,37 @@ def __getitem__(self, item):

"""

if isinstance(item, slice):
if isinstance(item, IdentifiedNode):
yield from self.predicate_objects(item)
elif isinstance(item, slice):
s, p, o = item.start, item.stop, item.step
# type narrowing since we cannot use typing within a slice()
assert isinstance(s, IdentifiedNode) or isinstance(s, Variable) or s is None
assert (
isinstance(p, IdentifiedNode)
or isinstance(p, Path)
or isinstance(p, Variable)
or p is None
)
assert isinstance(o, Node) or isinstance(o, Variable) or o is None

if s is None and p is None and o is None:
return self.triples((s, p, o))
yield from self.triples((s, p, o))
elif s is None and p is None:
return self.subject_predicates(o)
yield from self.subject_predicates(o) # type: ignore[arg-type]
elif s is None and o is None:
return self.subject_objects(p)
yield from self.subject_objects(p)
elif p is None and o is None:
return self.predicate_objects(s)
yield from self.predicate_objects(s)
elif s is None:
return self.subjects(p, o)
yield from self.subjects(p, o) # type: ignore[arg-type]
elif p is None:
return self.predicates(s, o)
yield from self.predicates(s, o) # type: ignore[arg-type]
elif o is None:
return self.objects(s, p)
yield from self.objects(s, p)
else:
# all given
return (s, p, o) in self

elif isinstance(item, (Path, Node)):
# type error: Argument 1 to "predicate_objects" of "Graph" has incompatible type "Union[Path, Node]"; expected "Optional[Node]"
return self.predicate_objects(item) # type: ignore[arg-type]

yield s, p, o
else:
raise TypeError(
"You can only index a graph by a single rdflib term or path, or a slice of rdflib terms."
Expand Down
3 changes: 2 additions & 1 deletion test/test_graph/test_graph_items.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from rdflib import RDF, Graph, Namespace
from rdflib import Graph, Namespace
from rdflib.namespace import RDF

EX = Namespace("http://example.org/")

Expand Down
77 changes: 64 additions & 13 deletions test/test_graph/test_slice.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
from rdflib import Graph
from rdflib import Graph, Literal, Namespace, URIRef
from rdflib.namespace import RDFS
from test.data import BOB, CHEESE, HATES, LIKES, MICHEL, PIZZA, TAREK

EX = Namespace("http://example.org/")


class TestGraphSlice:
def test_slice(self):
"""
We pervert the slice object,
and use start, stop, step as subject, predicate, object
We pervert the slice object, and use start, stop, step as subject, predicate,
object

all operations return generators over full triples
All operations return generators over full triples
"""

def sl(x, y):
return len(list(x)) == y
def sl(x):
return len(list(x))

def soe(x, y):
return set([a[2] for a in x]) == set(y) # equals objects
Expand All @@ -30,25 +33,73 @@ def soe(x, y):

# single index slices by subject, i.e. return triples((x,None,None))
# tell me everything about "TAREK"
sl(g[TAREK], 2)
assert sl(g[TAREK]) == 2

# single slice slices by s,p,o, with : used to split
# tell me everything about "TAREK" (same as above)
sl(g[TAREK::], 2)
assert sl(g[TAREK::]) == 2

# give me every "LIKES" relationship
sl(g[:LIKES:], 5)
assert sl(g[:LIKES:]) == 5

# give me every relationship to PIZZA
sl(g[::PIZZA], 3)
assert sl(g[::PIZZA]) == 3

# give me everyone who LIKES PIZZA
sl(g[:LIKES:PIZZA], 2)
assert sl(g[:LIKES:PIZZA]) == 2

# does TAREK like PIZZA?
assert g[TAREK:LIKES:PIZZA] is True
assert sorted(next(g[TAREK:LIKES:PIZZA])) == sorted(
(
URIRef("urn:example:tarek"),
URIRef("urn:example:likes"),
URIRef("urn:example:pizza"),
)
)

# More intesting is using paths

# everything hated or liked
sl(g[: HATES | LIKES], 7)
assert sl(g[: HATES | LIKES]) == 7


def test_graph_slice_eg():
g = Graph()
g.add((URIRef("urn:bob"), RDFS.label, Literal("Bob")))
assert sorted(list(g[URIRef("urn:bob")])) == sorted(
[(URIRef("http://www.w3.org/2000/01/rdf-schema#label"), Literal("Bob"))]
)

assert sorted(list(g[: RDFS.label])) == sorted(
[(URIRef("urn:bob"), Literal("Bob"))]
)

assert sorted(list(g[:: Literal("Bob")])) == sorted(
[(URIRef("urn:bob"), URIRef("http://www.w3.org/2000/01/rdf-schema#label"))]
)


def test_graph_slice_all():
g = Graph()
g.parse(
data="""
PREFIX ex: <http://example.org/>

ex:a ex:b ex:c .
ex:a ex:d ex:e .
ex:f ex:b ex:c .
ex:g ex:b ex:h .
"""
)

assert len(list(g[EX.a])) == 2

assert len(list(g[EX.f])) == 1

assert len(list(g[: EX.b])) == 3

assert len(list(g[:: EX.c])) == 2

assert len(list(g[EX.a : EX.b : EX.c])) == 1

assert sorted(list(g[EX.a])) == sorted(list(g.predicate_objects(EX.a)))
Loading