RDFLib / rdflib

RDFLib is a Python library for working with RDF, a simple yet powerful language for representing information.
https://rdflib.readthedocs.org
BSD 3-Clause "New" or "Revised" License
2.15k stars 555 forks source link

Default bound namespaces not used when parsing data with `Graph.parse()` #2427

Closed noahgorstein closed 1 year ago

noahgorstein commented 1 year ago

Hey đź‘‹ ! I'm new to rdflib and think I may have hit a bug. Any help is much appreciated. Apologies in advance if I'm missing something very obvious here.

I am just trying to parse some Turtle without including the namespaces that should be included from the Graph's NamespaceManager. From reading the docs, I thought this was supported but maybe I'm misunderstanding:

Each RDFLib graph has a namespace_manager that keeps a list of namespace to prefix mappings. The namespace manager is populated when reading in RDF, and these prefixes are used when serialising RDF, or when parsing SPARQL queries.

Using Python 3.10 with rdflib 6.3.2

Code to reproduce

from rdflib import Graph

# should use the `rdflib` strategy which includes `skos` and `owl` prefix in the Turtle
g = Graph()

# confirm namespaces 
namespaces = []
for prefix, _ in g.namespaces():
    namespaces.append(prefix)

data = """
skos:Concept a owl:Class .
"""

print(namespaces)
print()
g.parse(data=data)

Output including full traceback:

['brick', 'csvw', 'dc', 'dcat', 'dcmitype', 'dcterms', 'dcam', 'doap', 'foaf', 'geo', 'odrl', 'org', 'prof', 'prov', 'qb', 'schema', 'sh', 'skos', 'sosa', 'ssn', 'time', 'vann', 'void', 'wgs', 'owl', 'rdf', 'rdfs', 'xsd', 'xml']

Traceback (most recent call last):
  File "/Users/noahgorstein/projects/stardog-tutorials/music/venv/lib/python3.10/site-packages/rdflib/plugins/parsers/notation3.py", line 1232, in uri_ref2
    ns = self._bindings[pfx]
KeyError: 'skos'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/noahgorstein/projects/stardog-tutorials/music/venv/lib/python3.10/site-packages/rdflib/graph.py", line 1494, in parse
    parser.parse(source, self, **args)
  File "/Users/noahgorstein/projects/stardog-tutorials/music/venv/lib/python3.10/site-packages/rdflib/plugins/parsers/notation3.py", line 2021, in parse
    p.loadStream(stream)
  File "/Users/noahgorstein/projects/stardog-tutorials/music/venv/lib/python3.10/site-packages/rdflib/plugins/parsers/notation3.py", line 479, in loadStream
    return self.loadBuf(stream.read())  # Not ideal
  File "/Users/noahgorstein/projects/stardog-tutorials/music/venv/lib/python3.10/site-packages/rdflib/plugins/parsers/notation3.py", line 485, in loadBuf
    self.feed(buf)
  File "/Users/noahgorstein/projects/stardog-tutorials/music/venv/lib/python3.10/site-packages/rdflib/plugins/parsers/notation3.py", line 511, in feed
    i = self.directiveOrStatement(s, j)
  File "/Users/noahgorstein/projects/stardog-tutorials/music/venv/lib/python3.10/site-packages/rdflib/plugins/parsers/notation3.py", line 530, in directiveOrStatement
    j = self.statement(argstr, i)
  File "/Users/noahgorstein/projects/stardog-tutorials/music/venv/lib/python3.10/site-packages/rdflib/plugins/parsers/notation3.py", line 774, in statement
    i = self.object(argstr, i, r)  # Allow literal for subject - extends RDF
  File "/Users/noahgorstein/projects/stardog-tutorials/music/venv/lib/python3.10/site-packages/rdflib/plugins/parsers/notation3.py", line 1487, in object
    j = self.subject(argstr, i, res)
  File "/Users/noahgorstein/projects/stardog-tutorials/music/venv/lib/python3.10/site-packages/rdflib/plugins/parsers/notation3.py", line 785, in subject
    return self.item(argstr, i, res)
  File "/Users/noahgorstein/projects/stardog-tutorials/music/venv/lib/python3.10/site-packages/rdflib/plugins/parsers/notation3.py", line 877, in item
    return self.path(argstr, i, res)
  File "/Users/noahgorstein/projects/stardog-tutorials/music/venv/lib/python3.10/site-packages/rdflib/plugins/parsers/notation3.py", line 884, in path
    j = self.nodeOrLiteral(argstr, i, res)
  File "/Users/noahgorstein/projects/stardog-tutorials/music/venv/lib/python3.10/site-packages/rdflib/plugins/parsers/notation3.py", line 1515, in nodeOrLiteral
    j = self.node(argstr, i, res)
  File "/Users/noahgorstein/projects/stardog-tutorials/music/venv/lib/python3.10/site-packages/rdflib/plugins/parsers/notation3.py", line 1102, in node
    j = self.uri_ref2(argstr, i, res)
  File "/Users/noahgorstein/projects/stardog-tutorials/music/venv/lib/python3.10/site-packages/rdflib/plugins/parsers/notation3.py", line 1240, in uri_ref2
    self.BadSyntax(argstr, i, 'Prefix "%s:" not bound' % (pfx))
  File "/Users/noahgorstein/projects/stardog-tutorials/music/venv/lib/python3.10/site-packages/rdflib/plugins/parsers/notation3.py", line 1730, in BadSyntax
    raise BadSyntax(self._thisDoc, self.lines, argstr, i, msg)
rdflib.plugins.parsers.notation3.BadSyntax: at line 2 of <>:
Bad syntax (Prefix "skos:" not bound) at ^ in:
"b'\n'^b'skos:Concept a owl:Class .\n'"

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/noahgorstein/projects/stardog-tutorials/music/venv/lib/python3.10/site-packages/rdflib/graph.py", line 1497, in parse
    raise ParserError(
rdflib.exceptions.ParserError: Could not guess RDF format for <rdflib.parser.StringInputSource object at 0x1050e5ff0> from file extension so tried Turtle but failed.You can explicitly specify format using the format argument.
ghost commented 1 year ago

When it says “these prefixes are used when serialising RDF, or when parsing SPARQL queries”, it means that prefixes are only used when serializing RDF, or when parsing SPARQL queries.

The predefined prefixes cannot be used when parsing arbitrary RDF-as-turtle because namespace prefixes are a convention and so any prefixes need to be explicitly declared as directives in the source document:

data = """@prefix skos: <http://www.w3.org/2004/02/skos/core#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
skos:Concept a owl:Class .
"""
noahgorstein commented 1 year ago

ah okay - thanks @gjhiggins !