Skip to content

Commit

Permalink
Merge branch 'master' into 5.0.0-dev
Browse files Browse the repository at this point in the history
* master:
  Revert "Made ClosedNamespace (and _RDFNamespace) inherit from Namespace"
  Revert "re-introduces special handling for DCTERMS.title and test for it"
  Read and discard server response for update queries, otherwise the socket will eventually block
  Remove an unused import
  sparql select nothing doesn't return a row anymore, fixes #554
  test for #554
  minor: isinstance instead of type-equals
  adapted agg_Sample to return None instead of 0 if no binding is found
  SAMPLE may return None if no binding is found
  made test_issue563 py26 compatible
  fixing issue #563
  • Loading branch information
joernhees committed Feb 15, 2016
2 parents 36b0152 + 0d9ede7 commit d7cb263
Show file tree
Hide file tree
Showing 9 changed files with 102 additions and 45 deletions.
37 changes: 16 additions & 21 deletions rdflib/namespace.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,9 @@ def __new__(cls, value):
rt = unicode.__new__(cls, value, 'utf-8')
return rt


@property
def title(self):
# overrides unicode.title to allow DCTERMS.title for example
return URIRef(self + 'title')

def term(self, name):
Expand Down Expand Up @@ -148,34 +148,27 @@ def __repr__(self):



class ClosedNamespace(Namespace):
class ClosedNamespace(object):
"""
A namespace with a closed list of members
Trying to create terms not listen is an error
"""

def __new__(cls, uri, terms):
rt = Namespace.__new__(cls, uri)

rt.__uris = {}
def __init__(self, uri, terms):
self.uri = uri
self.__uris = {}
for t in terms:
rt.__uris[t] = URIRef(rt + t)

return rt
self.__uris[t] = URIRef(self.uri + t)

def term(self, name):
uri = self.__uris.get(name)
if uri is None:
raise Exception(
"term '%s' not in namespace '%s'" % (name, self))
"term '%s' not in namespace '%s'" % (name, self.uri))
else:
return uri

@property
def uri(self): # support legacy code from before ClosedNamespace extended unicode
return self

def __getitem__(self, key, default=None):
return self.term(key)

Expand All @@ -185,18 +178,21 @@ def __getattr__(self, name):
else:
return self.term(name)

def __str__(self):
return str(self.uri)

def __repr__(self):
return """rdf.namespace.ClosedNamespace('%s')""" % self
return """rdf.namespace.ClosedNamespace('%s')""" % str(self.uri)


class _RDFNamespace(ClosedNamespace):
"""
Closed namespace for RDF terms
"""

def __new__(cls):
return ClosedNamespace.__new__(cls, "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
terms=[
def __init__(self):
super(_RDFNamespace, self).__init__(
URIRef("http://www.w3.org/1999/02/22-rdf-syntax-ns#"),
terms=[
# Syntax Names
"RDF", "Description", "ID", "about", "parseType",
"resource", "li", "nodeID", "datatype",
Expand All @@ -217,11 +213,10 @@ def __new__(cls):
"XMLLiteral", "HTML", "langString"]
)


def term(self, name):
try:
i = int(name)
return URIRef("%s_%s" % (self, i))
return URIRef("%s_%s" % (self.uri, i))
except ValueError:
return super(_RDFNamespace, self).term(name)

Expand Down
15 changes: 9 additions & 6 deletions rdflib/plugins/sparql/aggregates.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from rdflib import Literal, XSD

from rdflib.plugins.sparql.evalutils import _eval
from rdflib.plugins.sparql.evalutils import _eval, NotBoundError
from rdflib.plugins.sparql.operators import numeric
from rdflib.plugins.sparql.datatypes import type_promotion

Expand Down Expand Up @@ -88,7 +88,9 @@ def agg_Count(a, group, bindings):
for x in group:
try:
if a.vars != '*':
_eval(a.vars, x)
val = _eval(a.vars, x)
if isinstance(val, NotBoundError):
continue
c += 1
except:
return # error in aggregate => no binding
Expand All @@ -98,10 +100,11 @@ def agg_Count(a, group, bindings):


def agg_Sample(a, group, bindings):
try:
bindings[a.res] = _eval(a.vars, iter(group).next())
except StopIteration:
pass # no res
for ctx in group:
val = _eval(a.vars, ctx)
if not isinstance(val, NotBoundError):
bindings[a.res] = val
break


def agg_GroupConcat(a, group, bindings):
Expand Down
9 changes: 6 additions & 3 deletions rdflib/plugins/stores/sparqlstore.py
Original file line number Diff line number Diff line change
Expand Up @@ -634,9 +634,8 @@ def commit(self):
and reads can degenerate to the original call-per-triple situation that originally existed.
"""
if self._edits and len(self._edits) > 0:
r = self._do_update('\n;\n'.join(self._edits))
self._do_update('\n;\n'.join(self._edits))
self._edits = None
return r

def rollback(self):
self._edits = None
Expand Down Expand Up @@ -712,7 +711,11 @@ def _do_update(self, update):
self.setRequestMethod(URLENCODED if self.postAsEncoded else POSTDIRECTLY)

result = SPARQLWrapper.query(self)
return result

# we must read (and discard) the whole response
# otherwise the network socket buffer will at some point be "full"
# and we will block
result.response.read()

def update(self, query,
initNs={},
Expand Down
8 changes: 5 additions & 3 deletions rdflib/query.py
Original file line number Diff line number Diff line change
Expand Up @@ -256,12 +256,14 @@ def __iter__(self):

if self._genbindings:
for b in self._genbindings:
self._bindings.append(b)
yield ResultRow(b, self.vars)
if b: # don't add a result row in case of empty binding {}
self._bindings.append(b)
yield ResultRow(b, self.vars)
self._genbindings = None
else:
for b in self._bindings:
yield ResultRow(b, self.vars)
if b: # don't add a result row in case of empty binding {}
yield ResultRow(b, self.vars)

def __getattr__(self, name):
if self.type in ("CONSTRUCT", "DESCRIBE") and self.graph is not None:
Expand Down
4 changes: 2 additions & 2 deletions test/test_initbindings.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,15 +101,15 @@ def testDistinctOrderByLimit():
def testPrepare():
q = prepareQuery('SELECT ?target WHERE { }')
r = list(g.query(q))
e = [(None,)] # TODO: https://github.com/RDFLib/rdflib/issues/554
e = []
assert r == e, 'prepare: %r != %r'%(r,e)

r = list(g.query(q, initBindings={'target': Literal('example')}))
e = [(Literal('example'),)]
assert r == e, 'prepare: %r != %r'%(r, e)

r = list(g.query(q))
e = [(None,)] # TODO: https://github.com/RDFLib/rdflib/issues/554
e = []
assert r == e, 'prepare: %r != %r'%(r,e)


Expand Down
1 change: 0 additions & 1 deletion test/test_issue535.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from rdflib import ConjunctiveGraph, URIRef
from rdflib.parser import StringInputSource

def test_nquads_default_graph():
ds = ConjunctiveGraph()
Expand Down
14 changes: 14 additions & 0 deletions test/test_issue554.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# test for https://github.com/RDFLib/rdflib/issues/554

import rdflib

def test_sparql_empty_no_row():
g = rdflib.Graph()
q = 'select ?whatever { }'
r = list(g.query(q))
assert r == [], \
'sparql query %s should return empty list but returns %s' % (q, r)


if __name__ == '__main__':
test_sparql_empty_no_row()
48 changes: 48 additions & 0 deletions test/test_issue563.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
from rdflib import BNode, Literal, Graph, Namespace
from rdflib.compare import isomorphic

EX = Namespace("http://example.org/")
QUERY = """
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
SELECT ?x (%s(?y) as ?ys) (%s(?z) as ?zs) WHERE {
VALUES (?x ?y ?z) {
(2 6 UNDEF)
(2 UNDEF 10)
(3 UNDEF 15)
(3 9 UNDEF)
(5 UNDEF 25)
}
}
GROUP BY ?x
"""

def test_sample():
g = Graph()
results = set(tuple(i) for i in g.query(QUERY % ("SAMPLE", "SAMPLE")))

assert results == set([
(Literal(2), Literal(6), Literal(10)),
(Literal(3), Literal(9), Literal(15)),
(Literal(5), None, Literal(25)),
])

def test_count():
g = Graph()
results = set(tuple(i) for i in g.query(QUERY % ("COUNT", "COUNT")))

assert results == set([
(Literal(2), Literal(1), Literal(1)),
(Literal(3), Literal(1), Literal(1)),
(Literal(5), Literal(0), Literal(1)),
])

if __name__ == "__main__":
test_sample()
test_count()



11 changes: 2 additions & 9 deletions test/test_namespace.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,9 @@
import unittest

from rdflib.namespace import DCTERMS
from rdflib.graph import Graph
from rdflib.term import URIRef
from rdflib.py3compat import b


class NamespaceTest(unittest.TestCase):
def test_dcterms_title(self):
self.assertEqual(DCTERMS.title, URIRef(DCTERMS + 'title'))


class NamespacePrefixTest(unittest.TestCase):

def test_compute_qname(self):
Expand All @@ -21,7 +14,7 @@ def test_compute_qname(self):

self.assertEqual(g.compute_qname(URIRef("http://foo/bar#baz")),
("ns2", URIRef("http://foo/bar#"), "baz"))

# should skip to ns4 when ns3 is already assigned
g.bind("ns3", URIRef("http://example.org/"))
self.assertEqual(g.compute_qname(URIRef("http://blip/blop")),
Expand All @@ -35,7 +28,7 @@ def test_n3(self):
n3 = g.serialize(format="n3")
# Gunnar disagrees that this is right:
# self.assertTrue("<http://example.com/foo> ns1:bar <http://example.com/baz> ." in n3)
# as this is much prettier, and ns1 is already defined:
# as this is much prettier, and ns1 is already defined:
self.assertTrue(b("ns1:foo ns1:bar ns1:baz .") in n3)

def test_n32(self):
Expand Down

0 comments on commit d7cb263

Please sign in to comment.