Mercurial > repos > shellac > sam_consensus_v3
comparison env/lib/python3.9/site-packages/rdflib/query.py @ 0:4f3585e2f14b draft default tip
"planemo upload commit 60cee0fc7c0cda8592644e1aad72851dec82c959"
| author | shellac |
|---|---|
| date | Mon, 22 Mar 2021 18:12:50 +0000 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:4f3585e2f14b |
|---|---|
| 1 from __future__ import absolute_import | |
| 2 from __future__ import division | |
| 3 from __future__ import print_function | |
| 4 | |
| 5 import os | |
| 6 import itertools | |
| 7 import shutil | |
| 8 import tempfile | |
| 9 import warnings | |
| 10 import types | |
| 11 | |
| 12 from six import BytesIO | |
| 13 from six import PY2 | |
| 14 from six import text_type | |
| 15 from six.moves.urllib.parse import urlparse | |
| 16 | |
| 17 __all__ = ['Processor', 'Result', 'ResultParser', 'ResultSerializer', | |
| 18 'ResultException'] | |
| 19 | |
| 20 | |
| 21 class Processor(object): | |
| 22 """ | |
| 23 Query plugin interface. | |
| 24 | |
| 25 This module is useful for those wanting to write a query processor | |
| 26 that can plugin to rdf. If you are wanting to execute a query you | |
| 27 likely want to do so through the Graph class query method. | |
| 28 | |
| 29 """ | |
| 30 | |
| 31 def __init__(self, graph): | |
| 32 pass | |
| 33 | |
| 34 def query(self, strOrQuery, initBindings={}, initNs={}, DEBUG=False): | |
| 35 pass | |
| 36 | |
| 37 | |
| 38 class UpdateProcessor(object): | |
| 39 """ | |
| 40 Update plugin interface. | |
| 41 | |
| 42 This module is useful for those wanting to write an update | |
| 43 processor that can plugin to rdflib. If you are wanting to execute | |
| 44 an update statement you likely want to do so through the Graph | |
| 45 class update method. | |
| 46 | |
| 47 .. versionadded:: 4.0 | |
| 48 | |
| 49 """ | |
| 50 | |
| 51 def __init__(self, graph): | |
| 52 pass | |
| 53 | |
| 54 def update(self, strOrQuery, initBindings={}, initNs={}): | |
| 55 pass | |
| 56 | |
| 57 | |
| 58 class ResultException(Exception): | |
| 59 pass | |
| 60 | |
| 61 | |
| 62 class EncodeOnlyUnicode(object): | |
| 63 """ | |
| 64 This is a crappy work-around for | |
| 65 http://bugs.python.org/issue11649 | |
| 66 | |
| 67 | |
| 68 """ | |
| 69 | |
| 70 def __init__(self, stream): | |
| 71 self.__stream = stream | |
| 72 | |
| 73 def write(self, arg): | |
| 74 if isinstance(arg, text_type): | |
| 75 self.__stream.write(arg.encode("utf-8")) | |
| 76 else: | |
| 77 self.__stream.write(arg) | |
| 78 | |
| 79 def __getattr__(self, name): | |
| 80 return getattr(self.__stream, name) | |
| 81 | |
| 82 | |
| 83 class ResultRow(tuple): | |
| 84 """ | |
| 85 a single result row | |
| 86 allows accessing bindings as attributes or with [] | |
| 87 | |
| 88 >>> from rdflib import URIRef, Variable | |
| 89 >>> rr=ResultRow({ Variable('a'): URIRef('urn:cake') }, [Variable('a')]) | |
| 90 | |
| 91 >>> rr[0] | |
| 92 rdflib.term.URIRef(u'urn:cake') | |
| 93 >>> rr[1] | |
| 94 Traceback (most recent call last): | |
| 95 ... | |
| 96 IndexError: tuple index out of range | |
| 97 | |
| 98 >>> rr.a | |
| 99 rdflib.term.URIRef(u'urn:cake') | |
| 100 >>> rr.b | |
| 101 Traceback (most recent call last): | |
| 102 ... | |
| 103 AttributeError: b | |
| 104 | |
| 105 >>> rr['a'] | |
| 106 rdflib.term.URIRef(u'urn:cake') | |
| 107 >>> rr['b'] | |
| 108 Traceback (most recent call last): | |
| 109 ... | |
| 110 KeyError: 'b' | |
| 111 | |
| 112 >>> rr[Variable('a')] | |
| 113 rdflib.term.URIRef(u'urn:cake') | |
| 114 | |
| 115 .. versionadded:: 4.0 | |
| 116 | |
| 117 """ | |
| 118 | |
| 119 def __new__(cls, values, labels): | |
| 120 | |
| 121 instance = super(ResultRow, cls).__new__( | |
| 122 cls, (values.get(v) for v in labels)) | |
| 123 instance.labels = dict((text_type(x[1]), x[0]) | |
| 124 for x in enumerate(labels)) | |
| 125 return instance | |
| 126 | |
| 127 def __getattr__(self, name): | |
| 128 if name not in self.labels: | |
| 129 raise AttributeError(name) | |
| 130 return tuple.__getitem__(self, self.labels[name]) | |
| 131 | |
| 132 def __getitem__(self, name): | |
| 133 try: | |
| 134 return tuple.__getitem__(self, name) | |
| 135 except TypeError: | |
| 136 if name in self.labels: | |
| 137 return tuple.__getitem__(self, self.labels[name]) | |
| 138 if text_type(name) in self.labels: # passing in variable object | |
| 139 return tuple.__getitem__(self, self.labels[text_type(name)]) | |
| 140 raise KeyError(name) | |
| 141 | |
| 142 def get(self, name, default=None): | |
| 143 try: | |
| 144 return self[name] | |
| 145 except KeyError: | |
| 146 return default | |
| 147 | |
| 148 def asdict(self): | |
| 149 return dict((v, self[v]) for v in self.labels if self[v] is not None) | |
| 150 | |
| 151 | |
| 152 class Result(object): | |
| 153 """ | |
| 154 A common class for representing query result. | |
| 155 | |
| 156 There is a bit of magic here that makes this appear like different | |
| 157 Python objects, depending on the type of result. | |
| 158 | |
| 159 If the type is "SELECT", iterating will yield lists of ResultRow objects | |
| 160 | |
| 161 If the type is "ASK", iterating will yield a single bool (or | |
| 162 bool(result) will return the same bool) | |
| 163 | |
| 164 If the type is "CONSTRUCT" or "DESCRIBE" iterating will yield the | |
| 165 triples. | |
| 166 | |
| 167 len(result) also works. | |
| 168 | |
| 169 """ | |
| 170 | |
| 171 def __init__(self, type_): | |
| 172 | |
| 173 if type_ not in ('CONSTRUCT', 'DESCRIBE', 'SELECT', 'ASK'): | |
| 174 raise ResultException('Unknown Result type: %s' % type_) | |
| 175 | |
| 176 self.type = type_ | |
| 177 self.vars = None | |
| 178 self._bindings = None | |
| 179 self._genbindings = None | |
| 180 self.askAnswer = None | |
| 181 self.graph = None | |
| 182 | |
| 183 def _get_bindings(self): | |
| 184 if self._genbindings: | |
| 185 self._bindings += list(self._genbindings) | |
| 186 self._genbindings = None | |
| 187 | |
| 188 return self._bindings | |
| 189 | |
| 190 def _set_bindings(self, b): | |
| 191 if isinstance(b, (types.GeneratorType, itertools.islice)): | |
| 192 self._genbindings = b | |
| 193 self._bindings = [] | |
| 194 else: | |
| 195 self._bindings = b | |
| 196 | |
| 197 bindings = property( | |
| 198 _get_bindings, _set_bindings, doc="a list of variable bindings as dicts") | |
| 199 | |
| 200 @staticmethod | |
| 201 def parse(source=None, format=None, content_type=None, **kwargs): | |
| 202 from rdflib import plugin | |
| 203 | |
| 204 if format: | |
| 205 plugin_key = format | |
| 206 elif content_type: | |
| 207 plugin_key = content_type.split(";", 1)[0] | |
| 208 else: | |
| 209 plugin_key = 'xml' | |
| 210 | |
| 211 parser = plugin.get(plugin_key, ResultParser)() | |
| 212 | |
| 213 return parser.parse(source, content_type=content_type, **kwargs) | |
| 214 | |
| 215 def serialize( | |
| 216 self, destination=None, encoding="utf-8", format='xml', **args): | |
| 217 | |
| 218 if self.type in ('CONSTRUCT', 'DESCRIBE'): | |
| 219 return self.graph.serialize( | |
| 220 destination, encoding=encoding, format=format, **args) | |
| 221 | |
| 222 """stolen wholesale from graph.serialize""" | |
| 223 from rdflib import plugin | |
| 224 serializer = plugin.get(format, ResultSerializer)(self) | |
| 225 if destination is None: | |
| 226 stream = BytesIO() | |
| 227 stream2 = EncodeOnlyUnicode(stream) | |
| 228 serializer.serialize(stream2, encoding=encoding, **args) | |
| 229 return stream.getvalue() | |
| 230 if hasattr(destination, "write"): | |
| 231 stream = destination | |
| 232 serializer.serialize(stream, encoding=encoding, **args) | |
| 233 else: | |
| 234 location = destination | |
| 235 scheme, netloc, path, params, query, fragment = urlparse(location) | |
| 236 if netloc != "": | |
| 237 print("WARNING: not saving as location" + | |
| 238 "is not a local file reference") | |
| 239 return | |
| 240 fd, name = tempfile.mkstemp() | |
| 241 stream = os.fdopen(fd, 'wb') | |
| 242 serializer.serialize(stream, encoding=encoding, **args) | |
| 243 stream.close() | |
| 244 if hasattr(shutil, "move"): | |
| 245 shutil.move(name, path) | |
| 246 else: | |
| 247 shutil.copy(name, path) | |
| 248 os.remove(name) | |
| 249 | |
| 250 def __len__(self): | |
| 251 if self.type == 'ASK': | |
| 252 return 1 | |
| 253 elif self.type == 'SELECT': | |
| 254 return len(self.bindings) | |
| 255 else: | |
| 256 return len(self.graph) | |
| 257 | |
| 258 def __bool__(self): | |
| 259 if self.type == 'ASK': | |
| 260 return self.askAnswer | |
| 261 else: | |
| 262 return len(self) > 0 | |
| 263 | |
| 264 if PY2: | |
| 265 __nonzero__ = __bool__ | |
| 266 | |
| 267 def __iter__(self): | |
| 268 if self.type in ("CONSTRUCT", "DESCRIBE"): | |
| 269 for t in self.graph: | |
| 270 yield t | |
| 271 elif self.type == 'ASK': | |
| 272 yield self.askAnswer | |
| 273 elif self.type == 'SELECT': | |
| 274 # this iterates over ResultRows of variable bindings | |
| 275 | |
| 276 if self._genbindings: | |
| 277 for b in self._genbindings: | |
| 278 if b: # don't add a result row in case of empty binding {} | |
| 279 self._bindings.append(b) | |
| 280 yield ResultRow(b, self.vars) | |
| 281 self._genbindings = None | |
| 282 else: | |
| 283 for b in self._bindings: | |
| 284 if b: # don't add a result row in case of empty binding {} | |
| 285 yield ResultRow(b, self.vars) | |
| 286 | |
| 287 def __getattr__(self, name): | |
| 288 if self.type in ("CONSTRUCT", "DESCRIBE") and self.graph is not None: | |
| 289 return self.graph.__getattr__(self, name) | |
| 290 elif self.type == 'SELECT' and name == 'result': | |
| 291 warnings.warn( | |
| 292 "accessing the 'result' attribute is deprecated." | |
| 293 " Iterate over the object instead.", | |
| 294 DeprecationWarning, stacklevel=2) | |
| 295 # copied from __iter__, above | |
| 296 return [(tuple(b[v] for v in self.vars)) for b in self.bindings] | |
| 297 else: | |
| 298 raise AttributeError( | |
| 299 "'%s' object has no attribute '%s'" % (self, name)) | |
| 300 | |
| 301 def __eq__(self, other): | |
| 302 try: | |
| 303 if self.type != other.type: | |
| 304 return False | |
| 305 if self.type == 'ASK': | |
| 306 return self.askAnswer == other.askAnswer | |
| 307 elif self.type == 'SELECT': | |
| 308 return self.vars == other.vars \ | |
| 309 and self.bindings == other.bindings | |
| 310 else: | |
| 311 return self.graph == other.graph | |
| 312 | |
| 313 except: | |
| 314 return False | |
| 315 | |
| 316 | |
| 317 class ResultParser(object): | |
| 318 | |
| 319 def __init__(self): | |
| 320 pass | |
| 321 | |
| 322 def parse(self, source, **kwargs): | |
| 323 """return a Result object""" | |
| 324 pass # abstract | |
| 325 | |
| 326 | |
| 327 class ResultSerializer(object): | |
| 328 | |
| 329 def __init__(self, result): | |
| 330 self.result = result | |
| 331 | |
| 332 def serialize(self, stream, encoding="utf-8", **kwargs): | |
| 333 """return a string properly serialized""" | |
| 334 pass # abstract |
