Skip to content

Dataset.quads() does not restrict results to specified graph #3314

@edmondchuc

Description

@edmondchuc

I'm not sure if the following behaviour is expected or a bug in either Dataset/ConjunctiveGraph or the MemoryStore.

The test below shows that when iterating over quads from a specific graph, statements from other graphs leak into the result, except when using DATASET_DEFAULT_GRAPH_ID.

Only the third parameterized test (with DATASET_DEFAULT_GRAPH_ID) passes as expected. The first two tests (for named graphs urn:graph:a and urn:graph:b) incorrectly include statements from other graphs.

import pytest

from rdflib import RDF, SKOS, Dataset, Graph, Literal, URIRef
from rdflib.graph import DATASET_DEFAULT_GRAPH_ID


@pytest.mark.parametrize(
    "graph_name, expected_quads",
    [
        [
            URIRef("urn:graph:a"),
            {
                (
                    URIRef("http://example.com/s"),
                    RDF.type,
                    SKOS.Concept,
                    URIRef("urn:graph:a"),
                ),
                (
                    URIRef("http://example.com/s"),
                    SKOS.prefLabel,
                    Literal("Label"),
                    URIRef("urn:graph:a"),
                ),
            },
        ],
        [
            URIRef("urn:graph:b"),
            {
                (
                    URIRef("http://example.com/s"),
                    SKOS.prefLabel,
                    Literal("Label"),
                    URIRef("urn:graph:b"),
                ),
            },
        ],
        [
            DATASET_DEFAULT_GRAPH_ID,
            {
                (
                    URIRef("http://example.com/s"),
                    SKOS.definition,
                    Literal("Definition"),
                    DATASET_DEFAULT_GRAPH_ID,
                ),
            },
        ],
    ],
)
def test_mem_quads(
    graph_name: URIRef, expected_quads: set[tuple[URIRef, URIRef, Literal, URIRef]]
):
    data = f"""
        <http://example.com/s> <{RDF.type}> <{SKOS.Concept}> <urn:graph:a> .
        <http://example.com/s> <{SKOS.prefLabel}> "Label" <urn:graph:a> .
        <http://example.com/s> <{SKOS.prefLabel}> "Label" <urn:graph:b> .
        <http://example.com/s> <{SKOS.definition}> "Definition" .
    """
    ds = Dataset()
    ds..parse(data=data, format="nquads")
    quads = set(ds.quads((None, None, None, Graph(identifier=graph_name))))
    assert quads == expected_quads

Actual result when graph name is urn:graph:a:

Extra items in the left set:
  (rdflib.term.URIRef('http://example.com/s'), rdflib.term.URIRef('http://www.w3.org/2004/02/skos/core#prefLabel'), rdflib.term.Literal('Label'), rdflib.term.URIRef('urn:graph:b'))
  
  Full diff:
    {
        (
            rdflib.term.URIRef('http://example.com/s'),
            rdflib.term.URIRef('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'),
            rdflib.term.URIRef('http://www.w3.org/2004/02/skos/core#Concept'),
            rdflib.term.URIRef('urn:graph:a'),
        ),
        (
            rdflib.term.URIRef('http://example.com/s'),
            rdflib.term.URIRef('http://www.w3.org/2004/02/skos/core#prefLabel'),
            rdflib.term.Literal('Label'),
            rdflib.term.URIRef('urn:graph:a'),
        ),
  +     (
  +         rdflib.term.URIRef('http://example.com/s'),
  +         rdflib.term.URIRef('http://www.w3.org/2004/02/skos/core#prefLabel'),
  +         rdflib.term.Literal('Label'),
  +         rdflib.term.URIRef('urn:graph:b'),
  +     ),
    }

Actual result when graph name is urn:graph:b:

Extra items in the left set:
  (rdflib.term.URIRef('http://example.com/s'), rdflib.term.URIRef('http://www.w3.org/2004/02/skos/core#prefLabel'), rdflib.term.Literal('Label'), rdflib.term.URIRef('urn:graph:a'))
  
  Full diff:
    {
  +     (
  +         rdflib.term.URIRef('http://example.com/s'),
  +         rdflib.term.URIRef('http://www.w3.org/2004/02/skos/core#prefLabel'),
  +         rdflib.term.Literal('Label'),
  +         rdflib.term.URIRef('urn:graph:a'),
  +     ),
        (
            rdflib.term.URIRef('http://example.com/s'),
            rdflib.term.URIRef('http://www.w3.org/2004/02/skos/core#prefLabel'),
            rdflib.term.Literal('Label'),
            rdflib.term.URIRef('urn:graph:b'),
        ),
    }

I tested this with RDFLib 7.4.0 as well as an older 7.0.0 and both had the same results.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions