Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lodkit/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
)
from lodkit.rdf_importer import RDFImporter
from lodkit.testing_tools.strategies import TripleStrategies, tst, tst_xml
from lodkit.triple_tools.ttl_constructor import ttl
from lodkit.triple_tools.ttl_constructor import TripleChain, ttl
from lodkit.uri_tools.uribase import uribase
from lodkit.uri_tools.uriclass import make_uriclass, uriclass
from lodkit.uri_tools.utils import (
Expand Down
53 changes: 22 additions & 31 deletions lodkit/triple_tools/ttl_constructor.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
"""LODKit Triple utilities."""

from collections.abc import Iterable, Iterator
import functools
from itertools import repeat
import itertools
from typing import Self

from lodkit.lod_types import _Triple, _TripleObject, _TripleSubject
from rdflib import BNode, Graph, Literal, URIRef
Expand All @@ -19,38 +22,31 @@
type _TPredicateObjectPair = tuple[URIRef, _TPredicateObjectPairObject]


class ttl(Iterable[_Triple]):
"""Triple generation facility that implements a Turtle-like interface.
class _ToGraphMixin:
def to_graph(self: Iterable[_Triple], graph: Graph | None = None) -> Graph:
"""Generate a graph instance from a ttl Iterator."""
_graph = Graph() if graph is None else graph

The generator takes a triple subject and an aribitrary number of predicate/object pairs
and produces an Iterator of RDFLib object 3-tuples.
for triple in self:
_graph.add(triple)
return _graph

Triple objects passed to the constructor can be
- URIRefs, BNodes, Literals
- Python lists of predicate/object tuples (resolved as blank nodes),
- tuples (resolved as Turtle object lists)
- ttl constructors (resolved recursively)

Args:
uri (_TripleSubject): The subject of a triple
*predicate_object_pairs (tuple[ URIRef, _TripleObject | list | Iterator | Self | str | tuple[_TripleObject, ...]]): Predicate-object pairs
class TripleChain(Iterator[_Triple], _ToGraphMixin):
def __init__(self, *triples: Iterable[_Triple]) -> None:
self._triples = itertools.chain.from_iterable(triples)

Returns:
None
def __iter__(self) -> Self:
return self

Examples:
def __next__(self) -> _Triple:
return next(self._triples)

triples: Iterator[lodkit._Triple] = ttl(
URIRef('https://subject'),
(RDF.type, URIRef('https://some_type')),
(RDFS.label, Literal('label 1'), 'label 2'),
(RDFS.seeAlso, [(RDFS.label, 'label 3')]),
(RDFS.isDefinedBy, ttl(URIRef('https://subject_2'), (RDF.type, URI('https://another_type'))))
)
def __or__(self, other: Iterable[_Triple]) -> Self:
return self.__class__(self, other)

graph: Graph = triples.to_graph()
"""

class ttl(Iterable[_Triple], _ToGraphMixin):
def __init__(
self,
uri: _TripleSubject,
Expand Down Expand Up @@ -84,10 +80,5 @@ def __iter__(self) -> Iterator[_Triple]:
"See the ttl docs and type annotation for applicable object types."
)

def to_graph(self, graph: Graph | None = None) -> Graph:
"""Generate a graph instance from a ttl Iterator."""
_graph = Graph() if graph is None else graph

for triple in self:
_graph.add(triple)
return _graph
def __or__(self, other: Iterable[_Triple]) -> TripleChain:
return TripleChain(self, other)