Skip to content

Added generic parser - #215

Merged
adanilenka merged 4 commits into
mainfrom
GH-123/generic-parser
Jul 15, 2025
Merged

Added generic parser#215
adanilenka merged 4 commits into
mainfrom
GH-123/generic-parser

Conversation

@adanilenka

Copy link
Copy Markdown
Collaborator

Relates to #213

Changes:

  • (re)introduced GenericStatementSink that just takes statements and can serialize them to N-triples or N-quads
  • added an Adapter that returns s/p/o/g as strings
  • added helper functions with the same logic as in RDFLib integration, but they use GenericStatementSink as a base and return GenericStatemenrSink, Generator[GenericStatementSink], or Generator[Statement | Prefix]
  • introduced generalized RDF conformance tests for parsing (and they pass, apparently)

Comment thread pyjelly/integrations/generic/parse.py Outdated
Comment thread pyjelly/parse/decode.py Outdated
str: decode_bnode,
jelly.RdfLiteral: decode_literal,
jelly.RdfDefaultGraph: decode_default_graph,
jelly.RdfTriple: decode_triple,

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is a preparation for RDF-star

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

by default doesn't seem to work right with RDF-star :(

self._store.append(tuple(statement))

def bind(self, prefix: str, namespace: str) -> None:
self._namespaces.update({prefix: namespace})

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

currently not used anywhere, can potentially remove from here and from adapters, or just raise exception here

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't that needed to pass conformance tests? We will have cases where you need to preserve namespaces.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

current conformance tests rely solely on .nt/.nq format, so no namespaces are there
from the spec, there is only one place that can issue a couple conformance tests:
value (2) – the IRI of the namespace as an RdfIri message. This field is REQUIRED.

self._store.append(tuple(statement))

def bind(self, prefix: str, namespace: str) -> None:
self._namespaces.update({prefix: namespace})

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't that needed to pass conformance tests? We will have cases where you need to preserve namespaces.

Comment thread pyjelly/integrations/generic/parse.py Outdated
Comment thread pyjelly/integrations/generic/parse.py Outdated
@adanilenka
adanilenka marked this pull request as ready for review July 10, 2025 14:31
@adanilenka
adanilenka requested a review from Ja-Gk-00 July 10, 2025 14:31
Comment on lines +57 to +137
class Triple(tuple[Node, Node, Node]):
"""
Class for RDF triples.

Args:
tuple (Node): tuple of three elements (s/p/o),
being of one of the types of Node.

"""

__slots__ = ()

def __new__(cls, s: Node, p: Node, o: Node) -> Self:
return tuple.__new__(cls, (s, p, o))

@property
def s(self) -> Node:
return self[0]

@property
def p(self) -> Node:
return self[1]

@property
def o(self) -> Node:
return self[2]


class Quad(tuple[Node, Node, Node, Node]):
"""
Class for RDF quads.

Args:
tuple (Node): tuple of four elements (s/p/o/g),
being of one of the types of Node.

"""

__slots__ = ()

def __new__(cls, s: Node, p: Node, o: Node, g: Node) -> Self:
return tuple.__new__(cls, (s, p, o, g))

@property
def s(self) -> Node:
return self[0]

@property
def p(self) -> Node:
return self[1]

@property
def o(self) -> Node:
return self[2]

@property
def g(self) -> Node:
return self[3]


class Prefix(tuple[str, IRI]):
"""
Class for generic namespace declaration.

Args:
tuple (str, IRI): namespace prefix and URI.

"""

__slots__ = ()

def __new__(cls, prefix: str, iri: IRI) -> Self:
return tuple.__new__(cls, (prefix, iri))

@property
def prefix(self) -> str:
return self[0]

@property
def iri(self) -> IRI:
return self[1]

@johnslavik johnslavik Jul 13, 2025

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You may want to use typing.NamedTuple here as the base for Triple, Quad and Prefix:

class Triple(NamedTuple):
    """
    Class for RDF triples.
    """

    s: Node
    p: Node
    o: Node


class Quad(NamedTuple):
    """
    Class for RDF quads.
    """
    
    s: Node
    p: Node
    o: Node
    g: Node


class Prefix(NamedTuple):
    """
    Class for generic namespace declaration.
    """

    prefix: str
    iri: IRI

This offers identical benefits (named tuple read-only members, built-in constructor, structural unpacking & fast slot access)

The docstrings were incorrect, as one might have thought a single argument with tuple with values is expected, not multiple positional arguments to fill tuple members.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

great comment, thank you, Bartosz! :)

@Ja-Gk-00 Ja-Gk-00 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's good enough for now, let's merge, then make a quick patch.

@adanilenka
adanilenka force-pushed the GH-123/generic-parser branch from af3b121 to 929379e Compare July 15, 2025 14:52
@adanilenka
adanilenka merged commit 40f213b into main Jul 15, 2025
10 checks passed
@adanilenka
adanilenka deleted the GH-123/generic-parser branch July 15, 2025 14:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants