Skip to content

Commit

Permalink
[DO NOT REVIEW] Add a bunch of typing
Browse files Browse the repository at this point in the history
This is a branch I'm maintaing with a bunch of typing, I'm planning to
integrate it with master in parts, anyone is welcome to have a look but
most of what is happening here is subject to change.
  • Loading branch information
aucampia committed May 7, 2022
1 parent eba1373 commit c3e431c
Show file tree
Hide file tree
Showing 60 changed files with 1,656 additions and 743 deletions.
8 changes: 7 additions & 1 deletion Taskfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -108,11 +108,17 @@ tasks:
- "{{._PYTHON}} -m isort --check --diff ."
- "{{._PYTHON}} -m black --check --diff ."

typecheck:
desc: Check type hints
cmds:
- "{{._PYTHON}} -m mypy --show-error-context --show-error-codes"


validate:static:
desc: Perform static validation
cmds:
- task: lint
- "{{._PYTHON}} -m mypy --show-error-context --show-error-codes"
- task: typecheck

validate:fix:
desc: Fix auto-fixable validation errors.
Expand Down
3 changes: 2 additions & 1 deletion rdflib/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@
"VOID",
"XSD",
"util",
"_typing",
]

import logging
Expand Down Expand Up @@ -194,5 +195,5 @@
assert plugin
assert query

from rdflib import util
from rdflib import _typing, util
from rdflib.container import *
23 changes: 23 additions & 0 deletions rdflib/_typing.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# import sys
# from typing import TYPE_CHECKING, Optional, Tuple, TypeVar

# if sys.version_info >= (3, 10):
# from typing import TypeAlias
# else:
# from typing_extensions import TypeAlias

# if TYPE_CHECKING:
# from rdflib.graph import Graph
# from rdflib.term import IdentifiedNode, Identifier

# _SubjectType: TypeAlias = "IdentifiedNode"
# _PredicateType: TypeAlias = "IdentifiedNode"
# _ObjectType: TypeAlias = "Identifier"

# _TripleType = Tuple["_SubjectType", "_PredicateType", "_ObjectType"]
# _QuadType = Tuple["_SubjectType", "_PredicateType", "_ObjectType", "Graph"]
# _TriplePatternType = Tuple[
# Optional["_SubjectType"], Optional["_PredicateType"], Optional["_ObjectType"]
# ]

# _GraphT = TypeVar("_GraphT", bound="Graph")
25 changes: 14 additions & 11 deletions rdflib/compare.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@
Union,
)

from rdflib.graph import ConjunctiveGraph, Graph, ReadOnlyGraphAggregate
from rdflib.graph import ConjunctiveGraph, Graph, ReadOnlyGraphAggregate, _TripleType
from rdflib.term import BNode, IdentifiedNode, Node, URIRef

if TYPE_CHECKING:
Expand Down Expand Up @@ -281,7 +281,6 @@ def copy(self):
)


_TripleT = List[Node]
_HashT = Callable[[], "HASH"]


Expand Down Expand Up @@ -326,7 +325,9 @@ def _initial_color(self) -> List[Color]:
self._neighbors[p].add(p)
if len(bnodes) > 0:
return [Color(list(bnodes), self.hashfunc, hash_cache=self._hash_cache)] + [
Color([x], self.hashfunc, x, hash_cache=self._hash_cache)
# type error: List item 0 has incompatible type "Union[IdentifiedNode, Literal]"; expected "IdentifiedNode"
# type error: Argument 3 to "Color" has incompatible type "Union[IdentifiedNode, Literal]"; expected "Tuple[Tuple[Union[int, str], URIRef, Union[int, str]], ...]"
Color([x], self.hashfunc, x, hash_cache=self._hash_cache) # type: ignore[list-item, arg-type]
for x in others
]
else:
Expand Down Expand Up @@ -521,7 +522,7 @@ def canonical_triples(self, stats: Optional[Stats] = None):

def _canonicalize_bnodes(
self,
triple: Tuple[IdentifiedNode, IdentifiedNode, Node],
triple: "_TripleType",
labels: Dict[Node, str],
):
for term in triple:
Expand All @@ -531,7 +532,7 @@ def _canonicalize_bnodes(
yield term


def to_isomorphic(graph):
def to_isomorphic(graph: Graph) -> IsomorphicGraph:
if isinstance(graph, IsomorphicGraph):
return graph
result = IsomorphicGraph()
Expand All @@ -541,7 +542,7 @@ def to_isomorphic(graph):
return result


def isomorphic(graph1, graph2):
def isomorphic(graph1: Graph, graph2: Graph) -> bool:
"""Compare graph for equality.
Uses an algorithm to compute unique hashes which takes bnodes into account.
Expand Down Expand Up @@ -577,7 +578,9 @@ def isomorphic(graph1, graph2):
return gd1 == gd2


def to_canonical_graph(g1, stats=None):
def to_canonical_graph(
g1: Graph, stats: Optional[Stats] = None
) -> ReadOnlyGraphAggregate:
"""Creates a canonical, read-only graph.
Creates a canonical, read-only graph where all bnode id:s are based on
Expand All @@ -588,7 +591,7 @@ def to_canonical_graph(g1, stats=None):
return ReadOnlyGraphAggregate([graph])


def graph_diff(g1, g2):
def graph_diff(g1: Graph, g2: Graph) -> Tuple[Graph, Graph, Graph]:
"""Returns three sets of triples: "in both", "in first" and "in second"."""
# bnodes have deterministic values in canonical graphs:
cg1 = to_canonical_graph(g1)
Expand All @@ -602,7 +605,7 @@ def graph_diff(g1, g2):
_MOCK_BNODE = BNode()


def similar(g1, g2):
def similar(g1: Graph, g2: Graph):
"""Checks if the two graphs are "similar".
Checks if the two graphs are "similar", by comparing sorted triples where
Expand All @@ -615,12 +618,12 @@ def similar(g1, g2):
return all(t1 == t2 for (t1, t2) in _squashed_graphs_triples(g1, g2))


def _squashed_graphs_triples(g1, g2):
def _squashed_graphs_triples(g1: Graph, g2: Graph):
for (t1, t2) in zip(sorted(_squash_graph(g1)), sorted(_squash_graph(g2))):
yield t1, t2


def _squash_graph(graph):
def _squash_graph(graph: Graph):
return (_squash_bnodes(triple) for triple in graph)


Expand Down
28 changes: 16 additions & 12 deletions rdflib/extras/external_graph_libs.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
"""

import logging
from typing import Any, Dict, List

from rdflib.graph import Graph

logger = logging.getLogger(__name__)

Expand All @@ -22,9 +25,9 @@ def _identity(x):


def _rdflib_to_networkx_graph(
graph,
graph: Graph,
nxgraph,
calc_weights,
calc_weights: bool,
edge_attrs,
transform_s=_identity,
transform_o=_identity,
Expand Down Expand Up @@ -70,7 +73,7 @@ def _rdflib_to_networkx_graph(


def rdflib_to_networkx_multidigraph(
graph, edge_attrs=lambda s, p, o: {"key": p}, **kwds
graph: Graph, edge_attrs=lambda s, p, o: {"key": p}, **kwds
):
"""Converts the given graph into a networkx.MultiDiGraph.
Expand Down Expand Up @@ -124,8 +127,8 @@ def rdflib_to_networkx_multidigraph(


def rdflib_to_networkx_digraph(
graph,
calc_weights=True,
graph: Graph,
calc_weights: bool = True,
edge_attrs=lambda s, p, o: {"triples": [(s, p, o)]},
**kwds,
):
Expand Down Expand Up @@ -187,8 +190,8 @@ def rdflib_to_networkx_digraph(


def rdflib_to_networkx_graph(
graph,
calc_weights=True,
graph: Graph,
calc_weights: bool = True,
edge_attrs=lambda s, p, o: {"triples": [(s, p, o)]},
**kwds,
):
Expand Down Expand Up @@ -250,9 +253,9 @@ def rdflib_to_networkx_graph(


def rdflib_to_graphtool(
graph,
v_prop_names=[str("term")],
e_prop_names=[str("term")],
graph: Graph,
v_prop_names: List[str] = [str("term")],
e_prop_names: List[str] = [str("term")],
transform_s=lambda s, p, o: {str("term"): s},
transform_p=lambda s, p, o: {str("term"): p},
transform_o=lambda s, p, o: {str("term"): o},
Expand Down Expand Up @@ -313,7 +316,8 @@ def rdflib_to_graphtool(
True
"""
import graph_tool as gt
# pytype error: Can't find module 'graph_tool'.
import graph_tool as gt # pytype: disable=import-error

g = gt.Graph()

Expand All @@ -323,7 +327,7 @@ def rdflib_to_graphtool(
eprops = [(epn, g.new_edge_property("object")) for epn in e_prop_names]
for epn, eprop in eprops:
g.edge_properties[epn] = eprop
node_to_vertex = {}
node_to_vertex: Dict[Any, Any] = {}
for s, p, o in graph:
sv = node_to_vertex.get(s)
if sv is None:
Expand Down
5 changes: 2 additions & 3 deletions rdflib/extras/infixowl.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,11 +111,10 @@
import itertools
import logging

from rdflib import RDF, RDFS, BNode, Literal, Namespace, URIRef, Variable
from rdflib.collection import Collection
from rdflib.graph import Graph
from rdflib.namespace import OWL, XSD, NamespaceManager
from rdflib.term import Identifier
from rdflib.namespace import OWL, RDF, RDFS, XSD, Namespace, NamespaceManager
from rdflib.term import BNode, Identifier, Literal, URIRef, Variable
from rdflib.util import first

logger = logging.getLogger(__name__)
Expand Down
Loading

0 comments on commit c3e431c

Please sign in to comment.