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 554 forks source link

Maximum recursion depth exceeded when parsing a nested SERVICE query #2136

Open GreenfishK opened 1 year ago

GreenfishK commented 1 year ago

Consider following query straight from wikidata (Cats, with pictures). To execute this query and get results using my local GraphDB instance, I need to wrap the body with SERVICE pointing ot the wikidata SPARQL endpoint. So the query is valid and returns a non-empty result set.

query = """
PREFIX wikibase: <http://wikiba.se/ontology#>
PREFIX wdt: <http://www.wikidata.org/prop/direct/>
PREFIX bd: <http://www.bigdata.com/rdf#>
PREFIX wd: <http://www.wikidata.org/entity/>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
SELECT ?item ?pic 
WHERE 
{
    SERVICE <https://query.wikidata.org/sparql> {
        ?item wdt:P31 wd:Q146 .
        ?item wdt:P18 ?pic
        SERVICE wikibase:label {
            bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en".
        } # Helps get the label in your language, if not, then en language
    }
}

"""

However, when I parse it using rdflib's parseQuery I get the error message "RecursionError: maximum recursion depth exceeded in comparison".

Full stack trace

    query_tree = parser.parseQuery(query)
../../anaconda3/envs/baseDSEnv/lib/python3.8/site-packages/rdflib/plugins/sparql/parser.py:1544: in parseQuery
    return Query.parseString(q, parseAll=True)
../../anaconda3/envs/baseDSEnv/lib/python3.8/site-packages/pyparsing/core.py:1131: in parse_string
    loc, tokens = self._parse(instring, 0)
../../anaconda3/envs/baseDSEnv/lib/python3.8/site-packages/pyparsing/core.py:817: in _parseNoCache
    loc, tokens = self.parseImpl(instring, pre_loc, doActions)
../../anaconda3/envs/baseDSEnv/lib/python3.8/site-packages/pyparsing/core.py:3886: in parseImpl
    loc, exprtokens = e._parse(instring, loc, doActions)
../../anaconda3/envs/baseDSEnv/lib/python3.8/site-packages/pyparsing/core.py:817: in _parseNoCache
    loc, tokens = self.parseImpl(instring, pre_loc, doActions)
../../anaconda3/envs/baseDSEnv/lib/python3.8/site-packages/pyparsing/core.py:4114: in parseImpl
    return e._parse(
../../anaconda3/envs/baseDSEnv/lib/python3.8/site-packages/pyparsing/core.py:817: in _parseNoCache
    loc, tokens = self.parseImpl(instring, pre_loc, doActions)
../../anaconda3/envs/baseDSEnv/lib/python3.8/site-packages/pyparsing/core.py:4375: in parseImpl
    return self.expr._parse(instring, loc, doActions, callPreParse=False)
../../anaconda3/envs/baseDSEnv/lib/python3.8/site-packages/pyparsing/core.py:817: in _parseNoCache
    loc, tokens = self.parseImpl(instring, pre_loc, doActions)
../../anaconda3/envs/baseDSEnv/lib/python3.8/site-packages/pyparsing/core.py:3886: in parseImpl
    loc, exprtokens = e._parse(instring, loc, doActions)
../../anaconda3/envs/baseDSEnv/lib/python3.8/site-packages/pyparsing/core.py:817: in _parseNoCache
    loc, tokens = self.parseImpl(instring, pre_loc, doActions)
../../anaconda3/envs/baseDSEnv/lib/python3.8/site-packages/pyparsing/core.py:4375: in parseImpl
    return self.expr._parse(instring, loc, doActions, callPreParse=False)
../../anaconda3/envs/baseDSEnv/lib/python3.8/site-packages/pyparsing/core.py:817: in _parseNoCache
    loc, tokens = self.parseImpl(instring, pre_loc, doActions)
../../anaconda3/envs/baseDSEnv/lib/python3.8/site-packages/pyparsing/core.py:5226: in parseImpl
    return super().parseImpl(instring, loc, doActions)
../../anaconda3/envs/baseDSEnv/lib/python3.8/site-packages/pyparsing/core.py:4375: in parseImpl
    return self.expr._parse(instring, loc, doActions, callPreParse=False)
../../anaconda3/envs/baseDSEnv/lib/python3.8/site-packages/pyparsing/core.py:817: in _parseNoCache
    loc, tokens = self.parseImpl(instring, pre_loc, doActions)
../../anaconda3/envs/baseDSEnv/lib/python3.8/site-packages/pyparsing/core.py:3886: in parseImpl
    loc, exprtokens = e._parse(instring, loc, doActions)
../../anaconda3/envs/baseDSEnv/lib/python3.8/site-packages/pyparsing/core.py:817: in _parseNoCache
    loc, tokens = self.parseImpl(instring, pre_loc, doActions)
../../anaconda3/envs/baseDSEnv/lib/python3.8/site-packages/pyparsing/core.py:4114: in parseImpl
    return e._parse(
../../anaconda3/envs/baseDSEnv/lib/python3.8/site-packages/pyparsing/core.py:817: in _parseNoCache
    loc, tokens = self.parseImpl(instring, pre_loc, doActions)
../../anaconda3/envs/baseDSEnv/lib/python3.8/site-packages/pyparsing/core.py:4375: in parseImpl
    return self.expr._parse(instring, loc, doActions, callPreParse=False)
../../anaconda3/envs/baseDSEnv/lib/python3.8/site-packages/pyparsing/core.py:817: in _parseNoCache
    loc, tokens = self.parseImpl(instring, pre_loc, doActions)
../../anaconda3/envs/baseDSEnv/lib/python3.8/site-packages/pyparsing/core.py:3886: in parseImpl
    loc, exprtokens = e._parse(instring, loc, doActions)
../../anaconda3/envs/baseDSEnv/lib/python3.8/site-packages/pyparsing/core.py:817: in _parseNoCache
    loc, tokens = self.parseImpl(instring, pre_loc, doActions)
../../anaconda3/envs/baseDSEnv/lib/python3.8/site-packages/pyparsing/core.py:4891: in parseImpl
    return super().parseImpl(instring, loc, doActions)
../../anaconda3/envs/baseDSEnv/lib/python3.8/site-packages/pyparsing/core.py:4790: in parseImpl
    loc, tokens = self_expr_parse(instring, loc, doActions)
../../anaconda3/envs/baseDSEnv/lib/python3.8/site-packages/pyparsing/core.py:817: in _parseNoCache
    loc, tokens = self.parseImpl(instring, pre_loc, doActions)
../../anaconda3/envs/baseDSEnv/lib/python3.8/site-packages/pyparsing/core.py:3864: in parseImpl
    loc, resultlist = self.exprs[0]._parse(
../../anaconda3/envs/baseDSEnv/lib/python3.8/site-packages/pyparsing/core.py:817: in _parseNoCache
    loc, tokens = self.parseImpl(instring, pre_loc, doActions)
../../anaconda3/envs/baseDSEnv/lib/python3.8/site-packages/pyparsing/core.py:4375: in parseImpl
    return self.expr._parse(instring, loc, doActions, callPreParse=False)
../../anaconda3/envs/baseDSEnv/lib/python3.8/site-packages/pyparsing/core.py:817: in _parseNoCache
    loc, tokens = self.parseImpl(instring, pre_loc, doActions)
../../anaconda3/envs/baseDSEnv/lib/python3.8/site-packages/pyparsing/core.py:4114: in parseImpl
    return e._parse(
../../anaconda3/envs/baseDSEnv/lib/python3.8/site-packages/pyparsing/core.py:817: in _parseNoCache
    loc, tokens = self.parseImpl(instring, pre_loc, doActions)
../../anaconda3/envs/baseDSEnv/lib/python3.8/site-packages/pyparsing/core.py:4375: in parseImpl
    return self.expr._parse(instring, loc, doActions, callPreParse=False)
../../anaconda3/envs/baseDSEnv/lib/python3.8/site-packages/pyparsing/core.py:817: in _parseNoCache
    loc, tokens = self.parseImpl(instring, pre_loc, doActions)
../../anaconda3/envs/baseDSEnv/lib/python3.8/site-packages/pyparsing/core.py:3886: in parseImpl
    loc, exprtokens = e._parse(instring, loc, doActions)
../../anaconda3/envs/baseDSEnv/lib/python3.8/site-packages/pyparsing/core.py:817: in _parseNoCache
    loc, tokens = self.parseImpl(instring, pre_loc, doActions)
../../anaconda3/envs/baseDSEnv/lib/python3.8/site-packages/pyparsing/core.py:4375: in parseImpl
    return self.expr._parse(instring, loc, doActions, callPreParse=False)
../../anaconda3/envs/baseDSEnv/lib/python3.8/site-packages/pyparsing/core.py:817: in _parseNoCache
    loc, tokens = self.parseImpl(instring, pre_loc, doActions)
../../anaconda3/envs/baseDSEnv/lib/python3.8/site-packages/pyparsing/core.py:5226: in parseImpl
    return super().parseImpl(instring, loc, doActions)
../../anaconda3/envs/baseDSEnv/lib/python3.8/site-packages/pyparsing/core.py:4375: in parseImpl
    return self.expr._parse(instring, loc, doActions, callPreParse=False)
../../anaconda3/envs/baseDSEnv/lib/python3.8/site-packages/pyparsing/core.py:817: in _parseNoCache
    loc, tokens = self.parseImpl(instring, pre_loc, doActions)
../../anaconda3/envs/baseDSEnv/lib/python3.8/site-packages/pyparsing/core.py:3886: in parseImpl
    loc, exprtokens = e._parse(instring, loc, doActions)
../../anaconda3/envs/baseDSEnv/lib/python3.8/site-packages/pyparsing/core.py:817: in _parseNoCache
    loc, tokens = self.parseImpl(instring, pre_loc, doActions)
../../anaconda3/envs/baseDSEnv/lib/python3.8/site-packages/pyparsing/core.py:4114: in parseImpl
    return e._parse(
../../anaconda3/envs/baseDSEnv/lib/python3.8/site-packages/pyparsing/core.py:817: in _parseNoCache
    loc, tokens = self.parseImpl(instring, pre_loc, doActions)
../../anaconda3/envs/baseDSEnv/lib/python3.8/site-packages/pyparsing/core.py:4375: in parseImpl
    return self.expr._parse(instring, loc, doActions, callPreParse=False)
../../anaconda3/envs/baseDSEnv/lib/python3.8/site-packages/pyparsing/core.py:817: in _parseNoCache
    loc, tokens = self.parseImpl(instring, pre_loc, doActions)
../../anaconda3/envs/baseDSEnv/lib/python3.8/site-packages/pyparsing/core.py:3886: in parseImpl
    loc, exprtokens = e._parse(instring, loc, doActions)
../../anaconda3/envs/baseDSEnv/lib/python3.8/site-packages/pyparsing/core.py:817: in _parseNoCache
    loc, tokens = self.parseImpl(instring, pre_loc, doActions)
../../anaconda3/envs/baseDSEnv/lib/python3.8/site-packages/pyparsing/core.py:4891: in parseImpl
    return super().parseImpl(instring, loc, doActions)
../../anaconda3/envs/baseDSEnv/lib/python3.8/site-packages/pyparsing/core.py:4790: in parseImpl
    loc, tokens = self_expr_parse(instring, loc, doActions)
../../anaconda3/envs/baseDSEnv/lib/python3.8/site-packages/pyparsing/core.py:817: in _parseNoCache
    loc, tokens = self.parseImpl(instring, pre_loc, doActions)
../../anaconda3/envs/baseDSEnv/lib/python3.8/site-packages/pyparsing/core.py:3864: in parseImpl
    loc, resultlist = self.exprs[0]._parse(
../../anaconda3/envs/baseDSEnv/lib/python3.8/site-packages/pyparsing/core.py:817: in _parseNoCache
    loc, tokens = self.parseImpl(instring, pre_loc, doActions)
../../anaconda3/envs/baseDSEnv/lib/python3.8/site-packages/pyparsing/core.py:4375: in parseImpl
    return self.expr._parse(instring, loc, doActions, callPreParse=False)
../../anaconda3/envs/baseDSEnv/lib/python3.8/site-packages/pyparsing/core.py:817: in _parseNoCache
    loc, tokens = self.parseImpl(instring, pre_loc, doActions)
../../anaconda3/envs/baseDSEnv/lib/python3.8/site-packages/pyparsing/core.py:4114: in parseImpl
    return e._parse(
../../anaconda3/envs/baseDSEnv/lib/python3.8/site-packages/pyparsing/core.py:823: in _parseNoCache
    tokens = self.postParse(instring, loc, tokens)
../../anaconda3/envs/baseDSEnv/lib/python3.8/site-packages/rdflib/plugins/sparql/parserutils.py:227: in postParse
    service_string = sgp.searchString(instring)[0][0]
../../anaconda3/envs/baseDSEnv/lib/python3.8/site-packages/pyparsing/core.py:1311: in search_string
    [t for t, s, e in self.scan_string(instring, maxMatches, debug=debug)]
../../anaconda3/envs/baseDSEnv/lib/python3.8/site-packages/pyparsing/core.py:1311: in <listcomp>
    [t for t, s, e in self.scan_string(instring, maxMatches, debug=debug)]
../../anaconda3/envs/baseDSEnv/lib/python3.8/site-packages/pyparsing/core.py:1202: in scan_string
    nextLoc, tokens = parseFn(instring, preloc, callPreParse=False)
../../anaconda3/envs/baseDSEnv/lib/python3.8/site-packages/pyparsing/core.py:817: in _parseNoCache
    loc, tokens = self.parseImpl(instring, pre_loc, doActions)
../../anaconda3/envs/baseDSEnv/lib/python3.8/site-packages/pyparsing/core.py:3886: in parseImpl
    loc, exprtokens = e._parse(instring, loc, doActions)
../../anaconda3/envs/baseDSEnv/lib/python3.8/site-packages/pyparsing/core.py:817: in _parseNoCache
    loc, tokens = self.parseImpl(instring, pre_loc, doActions)
E   RecursionError: maximum recursion depth exceeded
!!! Recursion detected (same locals & position)
----------------------------- Captured stderr call -----------------------------
Traceback (most recent call last):
  File "/home/fkovacev/.vscode/extensions/ms-python.python-2022.16.0/pythonFiles/lib/python/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_trace_dispatch_regular.py", line 359, in __call__
    is_stepping = pydev_step_cmd != -1
RecursionError: maximum recursion depth exceeded in comparison
ghost commented 1 year ago

Ew, so this results in RecursionError:

    g = Graph()
    g.query(query)

I'll hazard a guess that the issue lies somewhere in the RDFLib expression of the SPARQL grammar - based on the fact that jeroenbruijning's SPARQL parser implementation (which also uses pyparsing) successfully parses the query (results included below for info) which suggests it's not a pyparsing issue:

[QueryUnit] /PREFIX wikibase: <http://wikiba.se/ontology#> PREFIX wdt: <http://www.wikidata.org/prop/direct/> PREFIX bd: <http://www.bigdata.com/rdf#> PREFIX wd: <http://www.wikidata.org/entity/> PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> SELECT ?item ?pic WHERE { SERVICE <https://query.wikidata.org/sparql> { ?item wdt:P31 wd:Q146 . ?item wdt:P18 ?pic SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en" . } } }/
|  [Query] /PREFIX wikibase: <http://wikiba.se/ontology#> PREFIX wdt: <http://www.wikidata.org/prop/direct/> PREFIX bd: <http://www.bigdata.com/rdf#> PREFIX wd: <http://www.wikidata.org/entity/> PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> SELECT ?item ?pic WHERE { SERVICE <https://query.wikidata.org/sparql> { ?item wdt:P31 wd:Q146 . ?item wdt:P18 ?pic SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en" . } } }/
|  |  > prologue:
|  |  [Prologue] /PREFIX wikibase: <http://wikiba.se/ontology#> PREFIX wdt: <http://www.wikidata.org/prop/direct/> PREFIX bd: <http://www.bigdata.com/rdf#> PREFIX wd: <http://www.wikidata.org/entity/> PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>/
|  |  |  [PrefixDecl] /PREFIX wikibase: <http://wikiba.se/ontology#>/
|  |  |  |  [PREFIX] /PREFIX/
|  |  |  |  |  PREFIX
|  |  |  |  > prefix:
|  |  |  |  [PNAME_NS] /wikibase:/
|  |  |  |  |  wikibase:
|  |  |  |  > namespace:
|  |  |  |  [IRIREF] /<http://wikiba.se/ontology#>/
|  |  |  |  |  <http://wikiba.se/ontology#>
|  |  |  [PrefixDecl] /PREFIX wdt: <http://www.wikidata.org/prop/direct/>/
|  |  |  |  [PREFIX] /PREFIX/
|  |  |  |  |  PREFIX
|  |  |  |  > prefix:
|  |  |  |  [PNAME_NS] /wdt:/
|  |  |  |  |  wdt:
|  |  |  |  > namespace:
|  |  |  |  [IRIREF] /<http://www.wikidata.org/prop/direct/>/
|  |  |  |  |  <http://www.wikidata.org/prop/direct/>
|  |  |  [PrefixDecl] /PREFIX bd: <http://www.bigdata.com/rdf#>/
|  |  |  |  [PREFIX] /PREFIX/
|  |  |  |  |  PREFIX
|  |  |  |  > prefix:
|  |  |  |  [PNAME_NS] /bd:/
|  |  |  |  |  bd:
|  |  |  |  > namespace:
|  |  |  |  [IRIREF] /<http://www.bigdata.com/rdf#>/
|  |  |  |  |  <http://www.bigdata.com/rdf#>
|  |  |  [PrefixDecl] /PREFIX wd: <http://www.wikidata.org/entity/>/
|  |  |  |  [PREFIX] /PREFIX/
|  |  |  |  |  PREFIX
|  |  |  |  > prefix:
|  |  |  |  [PNAME_NS] /wd:/
|  |  |  |  |  wd:
|  |  |  |  > namespace:
|  |  |  |  [IRIREF] /<http://www.wikidata.org/entity/>/
|  |  |  |  |  <http://www.wikidata.org/entity/>
|  |  |  [PrefixDecl] /PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>/
|  |  |  |  [PREFIX] /PREFIX/
|  |  |  |  |  PREFIX
|  |  |  |  > prefix:
|  |  |  |  [PNAME_NS] /xsd:/
|  |  |  |  |  xsd:
|  |  |  |  > namespace:
|  |  |  |  [IRIREF] /<http://www.w3.org/2001/XMLSchema#>/
|  |  |  |  |  <http://www.w3.org/2001/XMLSchema#>
|  |  [SelectQuery] /SELECT ?item ?pic WHERE { SERVICE <https://query.wikidata.org/sparql> { ?item wdt:P31 wd:Q146 . ?item wdt:P18 ?pic SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en" . } } }/
|  |  |  [SelectClause] /SELECT ?item ?pic/
|  |  |  |  [SELECT] /SELECT/
|  |  |  |  |  SELECT
|  |  |  |  [Var] /?item/
|  |  |  |  |  [VAR1] /?item/
|  |  |  |  |  |  ?item
|  |  |  |  [Var] /?pic/
|  |  |  |  |  [VAR1] /?pic/
|  |  |  |  |  |  ?pic
|  |  |  > where:
|  |  |  [WhereClause] /WHERE { SERVICE <https://query.wikidata.org/sparql> { ?item wdt:P31 wd:Q146 . ?item wdt:P18 ?pic SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en" . } } }/
|  |  |  |  [WHERE] /WHERE/
|  |  |  |  |  WHERE
|  |  |  |  [GroupGraphPattern] /{ SERVICE <https://query.wikidata.org/sparql> { ?item wdt:P31 wd:Q146 . ?item wdt:P18 ?pic SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en" . } } }/
|  |  |  |  |  [LCURL] /{/
|  |  |  |  |  |  {
|  |  |  |  |  [GroupGraphPatternSub] /SERVICE <https://query.wikidata.org/sparql> { ?item wdt:P31 wd:Q146 . ?item wdt:P18 ?pic SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en" . } }/
|  |  |  |  |  |  [GraphPatternNotTriples] /SERVICE <https://query.wikidata.org/sparql> { ?item wdt:P31 wd:Q146 . ?item wdt:P18 ?pic SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en" . } }/
|  |  |  |  |  |  |  [ServiceGraphPattern] /SERVICE <https://query.wikidata.org/sparql> { ?item wdt:P31 wd:Q146 . ?item wdt:P18 ?pic SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en" . } }/
|  |  |  |  |  |  |  |  [SERVICE] /SERVICE/
|  |  |  |  |  |  |  |  |  SERVICE
|  |  |  |  |  |  |  |  [VarOrIri] /<https://query.wikidata.org/sparql>/
|  |  |  |  |  |  |  |  |  [iri] /<https://query.wikidata.org/sparql>/
|  |  |  |  |  |  |  |  |  |  [IRIREF] /<https://query.wikidata.org/sparql>/
|  |  |  |  |  |  |  |  |  |  |  <https://query.wikidata.org/sparql>
|  |  |  |  |  |  |  |  [GroupGraphPattern] /{ ?item wdt:P31 wd:Q146 . ?item wdt:P18 ?pic SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en" . } }/
|  |  |  |  |  |  |  |  |  [LCURL] /{/
|  |  |  |  |  |  |  |  |  |  {
|  |  |  |  |  |  |  |  |  [GroupGraphPatternSub] /?item wdt:P31 wd:Q146 . ?item wdt:P18 ?pic SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en" . }/
|  |  |  |  |  |  |  |  |  |  [TriplesBlock] /?item wdt:P31 wd:Q146 . ?item wdt:P18 ?pic/
|  |  |  |  |  |  |  |  |  |  |  > subjpath:
|  |  |  |  |  |  |  |  |  |  |  [TriplesSameSubjectPath] /?item wdt:P31 wd:Q146/
|  |  |  |  |  |  |  |  |  |  |  |  [VarOrTerm] /?item/
|  |  |  |  |  |  |  |  |  |  |  |  |  [Var] /?item/
|  |  |  |  |  |  |  |  |  |  |  |  |  |  [VAR1] /?item/
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ?item
|  |  |  |  |  |  |  |  |  |  |  |  [PropertyListPathNotEmpty] /wdt:P31 wd:Q146/
|  |  |  |  |  |  |  |  |  |  |  |  |  [VerbPath] /wdt:P31/
|  |  |  |  |  |  |  |  |  |  |  |  |  |  [Path] /wdt:P31/
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  [PathAlternative] /wdt:P31/
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  [PathSequence] /wdt:P31/
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  [PathEltOrInverse] /wdt:P31/
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  [PathElt] /wdt:P31/
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  [PathPrimary] /wdt:P31/
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  [iri] /wdt:P31/
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  [PrefixedName] /wdt:P31/
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  [PNAME_LN] /wdt:P31/
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  wdt:P31
|  |  |  |  |  |  |  |  |  |  |  |  |  [ObjectListPath] /wd:Q146/
|  |  |  |  |  |  |  |  |  |  |  |  |  |  [ObjectPath] /wd:Q146/
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  [GraphNodePath] /wd:Q146/
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  [VarOrTerm] /wd:Q146/
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  [GraphTerm] /wd:Q146/
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  [iri] /wd:Q146/
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  [PrefixedName] /wd:Q146/
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  [PNAME_LN] /wd:Q146/
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  wd:Q146
|  |  |  |  |  |  |  |  |  |  |  .
|  |  |  |  |  |  |  |  |  |  |  > subjpath:
|  |  |  |  |  |  |  |  |  |  |  [TriplesSameSubjectPath] /?item wdt:P18 ?pic/
|  |  |  |  |  |  |  |  |  |  |  |  [VarOrTerm] /?item/
|  |  |  |  |  |  |  |  |  |  |  |  |  [Var] /?item/
|  |  |  |  |  |  |  |  |  |  |  |  |  |  [VAR1] /?item/
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ?item
|  |  |  |  |  |  |  |  |  |  |  |  [PropertyListPathNotEmpty] /wdt:P18 ?pic/
|  |  |  |  |  |  |  |  |  |  |  |  |  [VerbPath] /wdt:P18/
|  |  |  |  |  |  |  |  |  |  |  |  |  |  [Path] /wdt:P18/
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  [PathAlternative] /wdt:P18/
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  [PathSequence] /wdt:P18/
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  [PathEltOrInverse] /wdt:P18/
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  [PathElt] /wdt:P18/
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  [PathPrimary] /wdt:P18/
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  [iri] /wdt:P18/
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  [PrefixedName] /wdt:P18/
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  [PNAME_LN] /wdt:P18/
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  wdt:P18
|  |  |  |  |  |  |  |  |  |  |  |  |  [ObjectListPath] /?pic/
|  |  |  |  |  |  |  |  |  |  |  |  |  |  [ObjectPath] /?pic/
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  [GraphNodePath] /?pic/
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  [VarOrTerm] /?pic/
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  [Var] /?pic/
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  [VAR1] /?pic/
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ?pic
|  |  |  |  |  |  |  |  |  |  [GraphPatternNotTriples] /SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en" . }/
|  |  |  |  |  |  |  |  |  |  |  [ServiceGraphPattern] /SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en" . }/
|  |  |  |  |  |  |  |  |  |  |  |  [SERVICE] /SERVICE/
|  |  |  |  |  |  |  |  |  |  |  |  |  SERVICE
|  |  |  |  |  |  |  |  |  |  |  |  [VarOrIri] /wikibase:label/
|  |  |  |  |  |  |  |  |  |  |  |  |  [iri] /wikibase:label/
|  |  |  |  |  |  |  |  |  |  |  |  |  |  [PrefixedName] /wikibase:label/
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  [PNAME_LN] /wikibase:label/
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  wikibase:label
|  |  |  |  |  |  |  |  |  |  |  |  [GroupGraphPattern] /{ bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en" . }/
|  |  |  |  |  |  |  |  |  |  |  |  |  [LCURL] /{/
|  |  |  |  |  |  |  |  |  |  |  |  |  |  {
|  |  |  |  |  |  |  |  |  |  |  |  |  [GroupGraphPatternSub] /bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en" ./
|  |  |  |  |  |  |  |  |  |  |  |  |  |  [TriplesBlock] /bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en" ./
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  > subjpath:
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  [TriplesSameSubjectPath] /bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en"/
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  [VarOrTerm] /bd:serviceParam/
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  [GraphTerm] /bd:serviceParam/
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  [iri] /bd:serviceParam/
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  [PrefixedName] /bd:serviceParam/
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  [PNAME_LN] /bd:serviceParam/
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  bd:serviceParam
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  [PropertyListPathNotEmpty] /wikibase:language "[AUTO_LANGUAGE],en"/
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  [VerbPath] /wikibase:language/
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  [Path] /wikibase:language/
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  [PathAlternative] /wikibase:language/
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  [PathSequence] /wikibase:language/
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  [PathEltOrInverse] /wikibase:language/
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  [PathElt] /wikibase:language/
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  [PathPrimary] /wikibase:language/
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  [iri] /wikibase:language/
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  [PrefixedName] /wikibase:language/
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  [PNAME_LN] /wikibase:language/
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  wikibase:language
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  [ObjectListPath] /"[AUTO_LANGUAGE],en"/
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  [ObjectPath] /"[AUTO_LANGUAGE],en"/
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  [GraphNodePath] /"[AUTO_LANGUAGE],en"/
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  [VarOrTerm] /"[AUTO_LANGUAGE],en"/
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  [GraphTerm] /"[AUTO_LANGUAGE],en"/
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  [RDFLiteral] /"[AUTO_LANGUAGE],en"/
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  > lexical_form:
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  [String] /"[AUTO_LANGUAGE],en"/
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  [STRING_LITERAL2] /"[AUTO_LANGUAGE],en"/
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  "[AUTO_LANGUAGE],en"
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  [PERIOD] /./
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  .
|  |  |  |  |  |  |  |  |  |  |  |  |  [RCURL] /}/
|  |  |  |  |  |  |  |  |  |  |  |  |  |  }
|  |  |  |  |  |  |  |  |  [RCURL] /}/
|  |  |  |  |  |  |  |  |  |  }
|  |  |  |  |  [RCURL] /}/
|  |  |  |  |  |  }
|  |  |  [SolutionModifier] //
|  |  [ValuesClause] //
vemonet commented 2 weeks ago

Here is a minimal code for reproduction, you don't even need to go as far as calling graph.query() to get the error, just trying to parseQuery() without running translateQuery() triggers the error:

from rdflib.plugins.sparql.parser import parseQuery

query = """
PREFIX wikibase: <http://wikiba.se/ontology#>
PREFIX wdt: <http://www.wikidata.org/prop/direct/>
PREFIX bd: <http://www.bigdata.com/rdf#>
PREFIX wd: <http://www.wikidata.org/entity/>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
SELECT ?item ?pic
WHERE
{
    SERVICE <https://query.wikidata.org/sparql> {
        ?item wdt:P31 wd:Q146 .
        ?item wdt:P18 ?pic
        SERVICE wikibase:label {
            bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en".
        }
    }
}"""
parsed_query = parseQuery(query)

Simplified stack trace:

Traceback (most recent call last):
  File "notebooks/error.py", line 24, in <module>
    parsed_query = parseQuery(query)
  File ".venv/lib/python3.10/site-packages/rdflib/plugins/sparql/parser.py", line 1542, in parseQuery
    return Query.parseString(q, parseAll=True)
  File ".venv/lib/python3.10/site-packages/pyparsing/util.py", line 256, in _inner
    return fn(self, *args, **kwargs)
  File ".venv/lib/python3.10/site-packages/pyparsing/core.py", line 1189, in parse_string
    loc, tokens = self._parse(instring, 0)
  File ".venv/lib/python3.10/site-packages/pyparsing/core.py", line 851, in _parseNoCache
    loc, tokens = self.parseImpl(instring, pre_loc, do_actions)
  File ".venv/lib/python3.10/site-packages/pyparsing/core.py", line 4080, in parseImpl
    loc, exprtokens = e._parse(instring, loc, do_actions)
  File ".venv/lib/python3.10/site-packages/pyparsing/core.py", line 851, in _parseNoCache
    loc, tokens = self.parseImpl(instring, pre_loc, do_actions)

... pyparsing seems to be stuck on iterating over parseImpl for thousands of iterations

line 851, in _parseNoCache
    loc, tokens = self.parseImpl(instring, pre_loc, do_actions)
  File ".venv/lib/python3.10/site-packages/pyparsing/core.py", line 4058, in parseImpl
    loc, resultlist = self.exprs[0]._parse(
  File ".venv/lib/python3.10/site-packages/pyparsing/core.py", line 855, in _parseNoCache
    loc, tokens = self.parseImpl(instring, pre_loc, do_actions)
  File ".venv/lib/python3.10/site-packages/pyparsing/core.py", line 2455, in parseImpl
    if instring[loc] == self.firstMatchChar:
RecursionError: maximum recursion depth exceeded in comparison

It seems to be triggered by Query.parseString(q, parseAll=True)

Which is defined around here: https://github.com/RDFLib/rdflib/blob/main/rdflib/plugins/sparql/parser.py#L1504

Since this error seems to be triggered only by SERVICE inside SERVICE the problem must be coming somewhere from these syntax definition:

ServiceGraphPattern = Comp(
    "ServiceGraphPattern",
    Keyword("SERVICE")
    + _Silent
    + Param("term", VarOrIri)
    + Param("graph", GroupGraphPattern),
)

GroupGraphPattern = Forward()

# [53] GroupGraphPattern ::= '{' ( SubSelect | GroupGraphPatternSub ) '}'
GroupGraphPattern <<= Suppress("{") + (SubSelect | GroupGraphPatternSub) + Suppress("}")

Seems like Forward comes from pyparsing itself: from pyparsing import Forward

https://pythonhosted.org/pyparsing/pyparsing.Forward-class.html

Forward declaration of an expression to be defined later - used for recursive grammars, such as algebraic infix notation. When the expression is known, it is assigned to the Forward variable using the '<<' operator.

Not sure why it triggers this recursion error as soon as we put a SERVICE clause inside a SERVICE though