Skip to content

Commit a79650d

Browse files
committed
Additional fixes
Changed type hints based on more information discovered in mean time.
1 parent 434dc33 commit a79650d

File tree

10 files changed

+97
-50
lines changed

10 files changed

+97
-50
lines changed

rdflib/graph.py

Lines changed: 68 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -37,26 +37,29 @@
3737
from rdflib.resource import Resource
3838
from rdflib.serializer import Serializer
3939
from rdflib.store import Store
40-
from rdflib.term import (
41-
BNode,
42-
Genid,
43-
IdentifiedNode,
44-
Identifier,
45-
Literal,
46-
Node,
47-
RDFLibGenid,
48-
URIRef,
49-
)
40+
from rdflib.term import BNode, Genid, IdentifiedNode, Literal, Node, RDFLibGenid, URIRef
5041

51-
_SubjectType = IdentifiedNode
52-
_PredicateType = IdentifiedNode
53-
_ObjectType = Identifier
42+
_SubjectType = Node
43+
_PredicateType = Node
44+
_ObjectType = Node
5445

5546
_TripleType = Tuple["_SubjectType", "_PredicateType", "_ObjectType"]
5647
_QuadType = Tuple["_SubjectType", "_PredicateType", "_ObjectType", "Graph"]
48+
_OptionalQuadType = Tuple[
49+
"_SubjectType", "_PredicateType", "_ObjectType", Optional["Graph"]
50+
]
51+
_OptionalIdentifiedQuadType = Tuple[
52+
"_SubjectType", "_PredicateType", "_ObjectType", Optional["Node"]
53+
]
5754
_TriplePatternType = Tuple[
5855
Optional["_SubjectType"], Optional["_PredicateType"], Optional["_ObjectType"]
5956
]
57+
_QuadPatternType = Tuple[
58+
Optional["_SubjectType"],
59+
Optional["_PredicateType"],
60+
Optional["_ObjectType"],
61+
Optional["Graph"],
62+
]
6063
_GraphT = TypeVar("_GraphT", bound="Graph")
6164

6265
assert Literal # avoid warning
@@ -522,7 +525,9 @@ def triples(
522525
for _s, _o in p.eval(self, s, o):
523526
yield _s, p, _o
524527
else:
525-
for (_s, _p, _o), cg in self.__store.triples((s, p, o), context=self):
528+
# type error: Argument 1 to "triples" of "Store" has incompatible type "Tuple[Optional[Node], Optional[Node], Optional[Node]]"; expected "Tuple[Optional[IdentifiedNode], Optional[IdentifiedNode], Optional[Node]]"
529+
# NOTE on type error: This is because the store typing is too narrow, willbe fixed in subsequent PR.
530+
for (_s, _p, _o), cg in self.__store.triples((s, p, o), context=self): # type: ignore [arg-type]
526531
yield _s, _p, _o
527532

528533
def __getitem__(self, item):
@@ -1670,11 +1675,21 @@ def __str__(self):
16701675
def _spoc(
16711676
self,
16721677
triple_or_quad: Union[
1673-
Tuple["_SubjectType", "_PredicateType", "_ObjectType", Optional[Any]],
1674-
"_TripleType",
1678+
Tuple[
1679+
Optional["_SubjectType"],
1680+
Optional["_PredicateType"],
1681+
Optional["_ObjectType"],
1682+
Optional[Any],
1683+
],
1684+
"_TriplePatternType",
16751685
],
16761686
default: bool = False,
1677-
) -> Tuple["_SubjectType", "_PredicateType", "_ObjectType", Optional[Graph]]:
1687+
) -> Tuple[
1688+
Optional["_SubjectType"],
1689+
Optional["_PredicateType"],
1690+
Optional["_ObjectType"],
1691+
Optional[Graph],
1692+
]:
16781693
...
16791694

16801695
@overload
@@ -1689,8 +1704,13 @@ def _spoc(
16891704
self,
16901705
triple_or_quad: Optional[
16911706
Union[
1692-
Tuple["_SubjectType", "_PredicateType", "_ObjectType", Optional[Any]],
1693-
"_TripleType",
1707+
Tuple[
1708+
Optional["_SubjectType"],
1709+
Optional["_PredicateType"],
1710+
Optional["_ObjectType"],
1711+
Optional[Any],
1712+
],
1713+
"_TriplePatternType",
16941714
]
16951715
],
16961716
default: bool = False,
@@ -1738,7 +1758,8 @@ def add(
17381758

17391759
_assertnode(s, p, o)
17401760

1741-
self.store.add((s, p, o), context=c, quoted=False)
1761+
# type error: Argument "context" to "add" of "Store" has incompatible type "Optional[Graph]"; expected "Graph"
1762+
self.store.add((s, p, o), context=c, quoted=False) # type: ignore[arg-type]
17421763
return self
17431764

17441765
@overload
@@ -1808,14 +1829,24 @@ def triples(self, triple_or_quad, context=None):
18081829
for (s, p, o), cg in self.store.triples((s, p, o), context=context):
18091830
yield s, p, o
18101831

1811-
def quads(self, triple_or_quad=None):
1832+
def quads(
1833+
self,
1834+
triple_or_quad: Union[
1835+
"_TriplePatternType",
1836+
"_QuadPatternType",
1837+
None,
1838+
] = None,
1839+
) -> Generator[_OptionalQuadType, None, None]:
18121840
"""Iterate over all the quads in the entire conjunctive graph"""
18131841

18141842
s, p, o, c = self._spoc(triple_or_quad)
18151843

1816-
for (s, p, o), cg in self.store.triples((s, p, o), context=c):
1844+
# type error: Argument 1 to "triples" of "Store" has incompatible type "Tuple[Optional[Node], Optional[Node], Optional[Node]]"; expected "Tuple[Optional[IdentifiedNode], Optional[IdentifiedNode], Optional[Node]]"
1845+
# NOTE on type error: This is because the store typing is too narrow, willbe fixed in subsequent PR.
1846+
for (s, p, o), cg in self.store.triples((s, p, o), context=c): # type: ignore[arg-type]
18171847
for ctx in cg:
1818-
yield s, p, o, ctx
1848+
# type error: Incompatible types in "yield" (actual type "Tuple[Optional[Node], Optional[Node], Optional[Node], Any]", expected type "Tuple[Node, Node, Node, Optional[Graph]]")
1849+
yield s, p, o, ctx # type: ignore[misc]
18191850

18201851
def triples_choices(self, triple, context=None):
18211852
"""Iterate over all the triples in the entire conjunctive graph"""
@@ -2145,17 +2176,27 @@ def contexts(self, triple=None):
21452176

21462177
graphs = contexts
21472178

2148-
def quads(self, quad):
2179+
# type error: Return type "Generator[Tuple[Node, Node, Node, Optional[Node]], None, None]" of "quads" incompatible with return type "Generator[Tuple[Node, Node, Node, Optional[Graph]], None, None]" in supertype "ConjunctiveGraph"
2180+
def quads( # type: ignore[override]
2181+
self,
2182+
quad: Union[
2183+
"_TriplePatternType",
2184+
"_QuadPatternType",
2185+
None,
2186+
] = None,
2187+
) -> Generator[_OptionalIdentifiedQuadType, None, None]:
21492188
for s, p, o, c in super(Dataset, self).quads(quad):
2150-
if c.identifier == self.default_context:
2189+
# type error: Item "None" of "Optional[Graph]" has no attribute "identifier"
2190+
if c.identifier == self.default_context: # type: ignore[union-attr]
21512191
yield s, p, o, None
21522192
else:
2153-
yield s, p, o, c.identifier
2193+
# type error: Item "None" of "Optional[Graph]" has no attribute "identifier" [union-attr]
2194+
yield s, p, o, c.identifier # type: ignore[union-attr]
21542195

21552196
# type error: Return type "Generator[Tuple[Node, URIRef, Node, Optional[IdentifiedNode]], None, None]" of "__iter__" incompatible with return type "Generator[Tuple[IdentifiedNode, IdentifiedNode, Union[IdentifiedNode, Literal]], None, None]" in supertype "Graph"
21562197
def __iter__( # type: ignore[override]
21572198
self,
2158-
) -> Generator[Tuple[Node, URIRef, Node, Optional[IdentifiedNode]], None, None]:
2199+
) -> Generator[_OptionalIdentifiedQuadType, None, None]:
21592200
"""Iterates over all quads in the store"""
21602201
return self.quads((None, None, None, None))
21612202

rdflib/plugins/parsers/ntriples.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
from rdflib.exceptions import ParserError as ParseError
1616
from rdflib.parser import InputSource, Parser
1717
from rdflib.term import BNode as bNode
18-
from rdflib.term import Literal, Node
18+
from rdflib.term import Literal
1919
from rdflib.term import URIRef as URI
2020

2121
if TYPE_CHECKING:

rdflib/plugins/serializers/rdfxml.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,8 @@ def serialize(
207207

208208
subject: IdentifiedNode
209209
# Write out subjects that can not be inline
210-
for subject in store.subjects():
210+
# type error: Incompatible types in assignment (expression has type "Node", variable has type "IdentifiedNode")
211+
for subject in store.subjects(): # type: ignore[assignment]
211212
if (None, None, subject) in store:
212213
if (subject, None, subject) in store:
213214
self.subject(subject, 1)
@@ -218,7 +219,8 @@ def serialize(
218219
# write out BNodes last (to ensure they can be inlined where possible)
219220
bnodes = set()
220221

221-
for subject in store.subjects():
222+
# type error: Incompatible types in assignment (expression has type "Node", variable has type "IdentifiedNode")
223+
for subject in store.subjects(): # type: ignore[assignment]
222224
if isinstance(subject, BNode):
223225
bnodes.add(subject)
224226
continue

rdflib/util.py

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
TYPE_CHECKING,
3030
Any,
3131
Callable,
32-
Iterable,
32+
Iterator,
3333
List,
3434
Optional,
3535
Set,
@@ -41,7 +41,7 @@
4141
import rdflib.graph # avoid circular dependency
4242
from rdflib.compat import sign
4343
from rdflib.namespace import XSD, Namespace, NamespaceManager
44-
from rdflib.term import BNode, IdentifiedNode, Literal, Node, URIRef
44+
from rdflib.term import BNode, Literal, Node, URIRef
4545

4646
if TYPE_CHECKING:
4747
from rdflib.graph import Graph
@@ -409,13 +409,13 @@ def find_roots(
409409

410410
def get_tree(
411411
graph: "Graph",
412-
root: "IdentifiedNode",
412+
root: "Node",
413413
prop: "URIRef",
414-
mapper: Callable[["IdentifiedNode"], "IdentifiedNode"] = lambda x: x,
414+
mapper: Callable[["Node"], "Node"] = lambda x: x,
415415
sortkey: Optional[Callable[[Any], Any]] = None,
416-
done: Optional[Set["IdentifiedNode"]] = None,
416+
done: Optional[Set["Node"]] = None,
417417
dir: str = "down",
418-
) -> Optional[Tuple[IdentifiedNode, List[Any]]]:
418+
) -> Optional[Tuple[Node, List[Any]]]:
419419
"""
420420
Return a nested list/tuple structure representing the tree
421421
built by the transitive property given, starting from the root given
@@ -442,12 +442,11 @@ def get_tree(
442442
done.add(root)
443443
tree = []
444444

445-
branches: Iterable[IdentifiedNode]
445+
branches: Iterator[Node]
446446
if dir == "down":
447447
branches = graph.subjects(prop, root)
448448
else:
449-
# type error: Incompatible types in assignment (expression has type "Iterable[Node]", variable has type "Iterable[IdentifiedNode]")
450-
branches = graph.objects(root, prop) # type: ignore[assignment]
449+
branches = graph.objects(root, prop)
451450

452451
for branch in branches:
453452
t = get_tree(graph, branch, prop, mapper, sortkey, done, dir)

test/test_graph/test_canonicalization.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import unittest
22
from collections import Counter
33
from io import StringIO
4-
from test.testutils import GraphHelper
54
from test.utils import GraphHelper
65
from typing import TYPE_CHECKING, Set
76

@@ -12,7 +11,6 @@
1211
from rdflib.compare import to_canonical_graph, to_isomorphic
1312
from rdflib.namespace import FOAF
1413
from rdflib.plugins.stores.memory import Memory
15-
from rdflib.term import Node
1614

1715
if TYPE_CHECKING:
1816
from rdflib.graph import _TripleType

test/test_graph/test_diff.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import unittest
2-
from test.testutils import GraphHelper
32
from test.utils import GraphHelper
43
from typing import TYPE_CHECKING, Set
54
from unittest.case import expectedFailure

test/test_namespace/test_namespace.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,7 @@ def test_expand_curie_exception_messages(self) -> None:
279279
assert str(e.value) == "Argument must be a string, not BNode."
280280

281281
with pytest.raises(TypeError) as e:
282-
assert g.namespace_manager.expand_curie(Graph()) is None
282+
assert g.namespace_manager.expand_curie(Graph()) is None # type: ignore[arg-type]
283283
assert str(e.value) == "Argument must be a string, not Graph."
284284

285285
@pytest.mark.parametrize(

test/test_roundtrip.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -268,10 +268,12 @@ def roundtrip(
268268
#
269269
# So we have to scrub the literals' string datatype declarations...
270270
for c in g2.contexts():
271-
for s, p, o in c.triples((None, None, None)):
271+
# type error: Incompatible types in assignment (expression has type "Node", variable has type "str")
272+
for s, p, o in c.triples((None, None, None)): # type: ignore[assignment]
272273
if type(o) == rdflib.Literal and o.datatype == XSD.string:
273274
c.remove((s, p, o))
274-
c.add((s, p, rdflib.Literal(str(o))))
275+
# type error: Argument 1 to "add" of "Graph" has incompatible type "Tuple[str, Node, Literal]"; expected "Tuple[Node, Node, Node]"
276+
c.add((s, p, rdflib.Literal(str(o)))) # type: ignore[arg-type]
275277

276278
if logger.isEnabledFor(logging.DEBUG):
277279
both, first, second = rdflib.compare.graph_diff(g1, g2)

test/test_typing.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,12 @@
2222

2323
from typing import Set, Tuple
2424

25+
import rdflib
26+
2527
# TODO Bug - rdflib.plugins.sparql.prepareQuery() will run fine if this
2628
# test is run, but mypy can't tell the symbol is exposed.
2729
import rdflib.plugins.sparql.processor
30+
from rdflib.term import Node
2831

2932

3033
def test_rdflib_query_exercise() -> None:
@@ -56,8 +59,8 @@ def test_rdflib_query_exercise() -> None:
5659
graph.add((kb_https_uriref, predicate_q, literal_two))
5760
graph.add((kb_bnode, predicate_p, literal_one))
5861

59-
expected_nodes_using_predicate_q: Set[rdflib.IdentifiedNode] = {kb_https_uriref}
60-
computed_nodes_using_predicate_q: Set[rdflib.IdentifiedNode] = set()
62+
expected_nodes_using_predicate_q: Set[Node] = {kb_https_uriref}
63+
computed_nodes_using_predicate_q: Set[Node] = set()
6164
for triple in graph.triples((None, predicate_q, None)):
6265
computed_nodes_using_predicate_q.add(triple[0])
6366
assert expected_nodes_using_predicate_q == computed_nodes_using_predicate_q

test/utils/__init__.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -169,12 +169,15 @@ def quad_set(
169169
"""
170170
result: GHQuadSet = set()
171171
for sn, pn, on, gn in graph.quads((None, None, None, None)):
172+
gn_id: Identifier
172173
if isinstance(graph, Dataset):
173-
assert isinstance(gn, Identifier)
174-
gn_id = gn
174+
# type error: Subclass of "Graph" and "Identifier" cannot exist: would have incompatible method signatures
175+
assert isinstance(gn, Identifier) # type: ignore[unreachable]
176+
gn_id = gn # type: ignore[unreachable]
175177
elif isinstance(graph, ConjunctiveGraph):
176178
assert isinstance(gn, Graph)
177-
gn_id = gn.identifier
179+
# type error: Incompatible types in assignment (expression has type "Node", variable has type "Identifier")
180+
gn_id = gn.identifier # type: ignore[assignment]
178181
else:
179182
raise ValueError(f"invalid graph type {type(graph)}: {graph!r}")
180183
s, p, o = cls.nodes((sn, pn, on), exclude_blanks)

0 commit comments

Comments
 (0)