| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586 |
- from __future__ import annotations
- from io import StringIO
- from typing import IO, List, Optional, Union
- from rdflib.namespace import NamespaceManager
- from rdflib.query import ResultSerializer
- from rdflib.term import BNode, Literal, URIRef, Variable
- def _termString(
- t: Optional[Union[URIRef, Literal, BNode]],
- namespace_manager: Optional[NamespaceManager],
- ) -> str:
- if t is None:
- return "-"
- if namespace_manager:
- if isinstance(t, URIRef):
- return namespace_manager.normalizeUri(t)
- elif isinstance(t, BNode):
- return t.n3()
- elif isinstance(t, Literal):
- return t._literal_n3(qname_callback=namespace_manager.normalizeUri)
- else:
- return t.n3()
- class TXTResultSerializer(ResultSerializer):
- """
- A write-only QueryResult serializer for text/ascii tables
- """
- def serialize(
- self,
- stream: IO,
- encoding: str = "utf-8",
- *,
- namespace_manager: Optional[NamespaceManager] = None,
- **kwargs,
- ) -> None:
- """
- return a text table of query results
- """
- def c(s, w):
- """
- center the string s in w wide string
- """
- w -= len(s)
- h1 = h2 = w // 2
- if w % 2:
- h2 += 1
- return " " * h1 + s + " " * h2
- if self.result.type != "SELECT":
- raise Exception("Can only pretty print SELECT results!")
- string_stream = StringIO()
- if not self.result:
- string_stream.write("(no results)\n")
- else:
- keys: List[Variable] = self.result.vars # type: ignore[assignment]
- maxlen = [0] * len(keys)
- b = [
- # type error: Value of type "Union[Tuple[Node, Node, Node], bool, ResultRow]" is not indexable
- # type error: Argument 1 to "_termString" has incompatible type "Union[Node, Any]"; expected "Union[URIRef, Literal, BNode, None]" [arg-type]
- # type error: No overload variant of "__getitem__" of "tuple" matches argument type "Variable"
- # NOTE on type error: The problem here is that r can be more types than _termString expects because result can be a result of multiple types.
- [_termString(r[k], namespace_manager) for k in keys] # type: ignore[index, arg-type, call-overload]
- for r in self.result
- ]
- for r in b:
- for i in range(len(keys)):
- maxlen[i] = max(maxlen[i], len(r[i]))
- string_stream.write(
- "|".join([c(k, maxlen[i]) for i, k in enumerate(keys)]) + "\n"
- )
- string_stream.write("-" * (len(maxlen) + sum(maxlen)) + "\n")
- for r in sorted(b):
- string_stream.write(
- "|".join([t + " " * (i - len(t)) for i, t in zip(maxlen, r)]) + "\n"
- )
- text_val = string_stream.getvalue()
- try:
- stream.write(text_val.encode(encoding))
- except (TypeError, ValueError):
- stream.write(text_val)
|