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 |