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