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 Aug 23, 2022
1 parent c487be6 commit bb3775f
Show file tree
Hide file tree
Showing 78 changed files with 1,831 additions and 804 deletions.
3 changes: 3 additions & 0 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,9 @@ def find_version(filename):
("py:class", "_TripleType"),
("py:class", "_TripleOrTriplePathType"),
("py:class", "TextIO"),
("py:class", "HTTPResponse"),
("py:class", "HTTPMessage"),
("py:class", "EntryPoint"),
]
)

Expand Down
1 change: 1 addition & 0 deletions rdflib/_type_checking.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,4 @@
from typing_extensions import Literal as PyLiteral

_NamespaceSetString = PyLiteral["core", "rdflib", "none"]
_MulPathMod = PyLiteral["*", "+", "?"] # noqa: F722
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")
48 changes: 30 additions & 18 deletions rdflib/collection.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
from __future__ import annotations

from typing import TYPE_CHECKING, Iterable, Iterator, List, Optional

from rdflib.namespace import RDF
from rdflib.term import BNode, Literal
from rdflib.term import BNode, Node

if TYPE_CHECKING:
from rdflib import Graph

__all__ = ["Collection"]

Expand All @@ -9,6 +16,7 @@ class Collection(object):
See "Emulating container types":
https://docs.python.org/reference/datamodel.html#emulating-container-types
>>> from rdflib.term import Literal
>>> from rdflib.graph import Graph
>>> from pprint import pprint
>>> listname = BNode()
Expand Down Expand Up @@ -43,13 +51,14 @@ class Collection(object):
True
"""

def __init__(self, graph, uri, seq=[]):
def __init__(self, graph: Graph, uri: Node, seq: List[Node] = []):
self.graph = graph
self.uri = uri or BNode()
self += seq

def n3(self):
def n3(self) -> str:
"""
>>> from rdflib.term import Literal
>>> from rdflib.graph import Graph
>>> listname = BNode()
>>> g = Graph('Memory')
Expand All @@ -73,13 +82,14 @@ def n3(self):
"2"^^<http://www.w3.org/2001/XMLSchema#integer>
"3"^^<http://www.w3.org/2001/XMLSchema#integer> )
"""
return "( %s )" % (" ".join([i.n3() for i in self]))
# type error: "Node" has no attribute "n3"
return "( %s )" % (" ".join([i.n3() for i in self])) # type: ignore[attr-defined]

def _get_container(self, index):
def _get_container(self, index: int) -> Optional[Node]:
"""Gets the first, rest holding node at index."""
assert isinstance(index, int)
graph = self.graph
container = self.uri
container: Optional[Node] = self.uri
i = 0
while i < index:
i += 1
Expand All @@ -88,11 +98,11 @@ def _get_container(self, index):
break
return container

def __len__(self):
def __len__(self) -> int:
"""length of items in collection."""
return len(list(self.graph.items(self.uri)))

def index(self, item):
def index(self, item: Node) -> int:
"""
Returns the 0-based numerical index of the item in the list
"""
Expand All @@ -112,7 +122,7 @@ def index(self, item):
assert len(newlink) == 1, "Malformed RDF Collection: %s" % self.uri
listname = newlink[0]

def __getitem__(self, key):
def __getitem__(self, key: int) -> Node:
"""TODO"""
c = self._get_container(key)
if c:
Expand All @@ -124,15 +134,15 @@ def __getitem__(self, key):
else:
raise IndexError(key)

def __setitem__(self, key, value):
def __setitem__(self, key: int, value: Node) -> None:
"""TODO"""
c = self._get_container(key)
if c:
self.graph.set((c, RDF.first, value))
else:
raise IndexError(key)

def __delitem__(self, key):
def __delitem__(self, key: int) -> None:
"""
>>> from rdflib.namespace import RDF, RDFS
>>> from rdflib import Graph
Expand Down Expand Up @@ -184,7 +194,8 @@ def __delitem__(self, key):
elif key == len(self) - 1:
# the tail
priorlink = self._get_container(key - 1)
self.graph.set((priorlink, RDF.rest, RDF.nil))
# type error: Argument 1 to "set" of "Graph" has incompatible type "Tuple[Optional[Node], URIRef, URIRef]"; expected "Tuple[Node, Node, Any]"
self.graph.set((priorlink, RDF.rest, RDF.nil)) # type: ignore[arg-type]
graph.remove((current, None, None))
else:
next = self._get_container(key + 1)
Expand All @@ -193,11 +204,11 @@ def __delitem__(self, key):
graph.remove((current, None, None))
graph.set((prior, RDF.rest, next))

def __iter__(self):
def __iter__(self) -> Iterator[Node]:
"""Iterator over items in Collections"""
return self.graph.items(self.uri)

def _end(self):
def _end(self) -> Node:
# find end of list
container = self.uri
while True:
Expand All @@ -207,8 +218,9 @@ def _end(self):
else:
container = rest

def append(self, item):
def append(self, item: Node) -> Collection:
"""
>>> from rdflib.term import Literal
>>> from rdflib.graph import Graph
>>> listname = BNode()
>>> g = Graph()
Expand All @@ -231,7 +243,7 @@ def append(self, item):
self.graph.add((end, RDF.rest, RDF.nil))
return self

def __iadd__(self, other):
def __iadd__(self, other: Iterable[Node]) -> Collection:

end = self._end()
self.graph.remove((end, RDF.rest, None))
Expand All @@ -247,8 +259,8 @@ def __iadd__(self, other):
self.graph.add((end, RDF.rest, RDF.nil))
return self

def clear(self):
container = self.uri
def clear(self) -> Collection:
container: Optional[Node] = self.uri
graph = self.graph
while container:
rest = graph.value(container, RDF.rest)
Expand Down
6 changes: 4 additions & 2 deletions rdflib/compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
and different versions of support libraries.
"""

from __future__ import annotations

import codecs
import re
import warnings
Expand Down Expand Up @@ -101,6 +103,6 @@ def decodeUnicodeEscape(escaped: str) -> str:

# Migration to abc in Python 3.8
try:
from collections.abc import Mapping, MutableMapping
from collections.abc import Mapping, MutableMapping # noqa: F401
except:
from collections import Mapping, MutableMapping
pass
14 changes: 9 additions & 5 deletions rdflib/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,32 +5,36 @@
__all__ = [
"Error",
"ParserError",
"UniquenessError",
]


from typing import Any, Optional


class Error(Exception):
"""Base class for rdflib exceptions."""

def __init__(self, msg=None):
def __init__(self, msg: Optional[str] = None):
Exception.__init__(self, msg)
self.msg = msg


class ParserError(Error):
"""RDF Parser error."""

def __init__(self, msg):
def __init__(self, msg: str):
Error.__init__(self, msg)
self.msg = msg
self.msg: str = msg

def __str__(self):
def __str__(self) -> str:
return self.msg


class UniquenessError(Error):
"""A uniqueness assumption was made in the context, and that is not true"""

def __init__(self, values):
def __init__(self, values: Any):
Error.__init__(
self,
"\
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 @@ -110,11 +110,10 @@
import itertools
import logging

from rdflib import OWL, RDF, RDFS, XSD, BNode, Literal, Namespace, URIRef, Variable
from rdflib.collection import Collection
from rdflib.graph import Graph
from rdflib.namespace import 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
6 changes: 4 additions & 2 deletions rdflib/graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -1534,12 +1534,14 @@ def query(
except NotImplementedError:
pass # store has no own implementation

if not isinstance(result, query.Result):
# type error: Subclass of "str" and "Result" cannot exist: would have incompatible method signatures
if not isinstance(result, query.Result): # type: ignore[unreachable]
result = plugin.get(cast(str, result), query.Result)
if not isinstance(processor, query.Processor):
processor = plugin.get(processor, query.Processor)(self)

return result(processor.query(query_object, initBindings, initNs, **kwargs))
# type error: Argument 1 to "Result" has incompatible type "Mapping[str, Any]"; expected "str"
return result(processor.query(query_object, initBindings, initNs, **kwargs)) # type: ignore[arg-type]

def update(
self,
Expand Down
2 changes: 0 additions & 2 deletions rdflib/namespace/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import json
import logging
import sys
import warnings
from functools import lru_cache
from pathlib import Path
Expand Down
Loading

0 comments on commit bb3775f

Please sign in to comment.