xotl.ql.core
– The core API¶
The module xotl.ql.core
provide the high level API for obtaining a
query object from a query expression.
-
xotl.ql.core.
this
¶ This is an object whose meaning is the entire universe of objects when used as a generator inside a query expression. Its precise semantics varies with the object model. The documentation of query translators must give the precise meaning of this object.
-
xotl.ql.core.
get_query_object
(generator, query_type='xotl.ql.core.QueryObject', frame_type=None, **kwargs)¶ Get the query object from a query expression.
This function expects a query expression in the form of a generator object and returns an object that complies with the interface
xotl.ql.interfaces.QueryObject
.Parameters: - query – The query expression.
- query_type – An object which complies with the interface
xotl.ql.interfaces.QueryObjectType
or the fully qualified name of such an object. - frame_type – An object with complies with the interface
xotl.ql.interfaces.FrameType
or the fully qualified name of such an object.
This function works by inspecting the byte-code of the generator object to obtain the Query Syntax Tree. This function uses the attribute gi_frame of the generator to build the frame object needed by query objects.
Nested sub-queries are not expanded automatically:
>>> from xotl.ql.core import this, get_query_object >>> query = get_query_object(y for y in (x for x in this)) >>> print(query.qst) <ast: Expression> body: <ast: GeneratorExp> elt: <ast: Name> id: 'y' ctx: <ast: Load> generators[0]: <ast: comprehension> target: <ast: Name> id: 'y' ctx: <ast: Store> iter: <ast: Name> id: '.0' ctx: <ast: Load>
The sub-query
(x for x in this)
is simply encoded as a variable ‘.0’.If no frame_type is provided, use the attribute
frame_type
of the query object type.Additional keyword arguments are passed unchanged when instantiating the query object.
-
xotl.ql.core.
normalize_query
(which, **kwargs)¶ Ensure a query object.
If which is a query expression (more precisely a generator object) it is passed to
get_query_object()
along with all keyword arguments.If which is not a query expression it must be a query object, other types are a TypeError.
-
class
xotl.ql.core.
QueryObject
(qst, frame, **kwargs)¶ A query object implementation.
Instances of this class implement the interface
xotl.ql.interfaces.QueryObject
and this class itself complies withxotl.ql.interfaces.QueryObjectType
.
-
class
xotl.ql.core.
Frame
(locals, globals)¶ Instances of this class implement the interface
xotl.ql.interfaces.Frame
and the class itself complies withxotl.ql.interface.FrameType
.The f_locals and f_globals are immutable mapping views that support all the collections.Mapping interface.
In order to support for the view concept to work we keep a references to the original locals and globals.
Additional attributes and methods:
-
auto_expand_subqueries
¶ When trying to get the name ‘.0’ from either view, if the current value is a generator object obtained via a generator expression, we actually return the result of calling
get_query_object()
on the current value.You may suppress this behavior by setting this attribute to False. The default is True.
Warning
Notice this will use the default query object type and frame type.
Example:
>>> from xotl.ql.core import this, get_query_object >>> query = get_query_object(y for y in (x for x in this)) >>> query.locals['.0'] <xotl.ql.core.QueryObject...>
-
-
xotl.ql.core.
thesefy
(target, make_subquery=True)¶ Allow an object to participate in queries.
Example as a wrapper:
class People(object): # ... pass query = (who for who in thesefy(People))
Example as a decorator:
@thesefy class People(object): pass query = (who for who in People)
If target already support the iterable protocol (i.e implement
__iter__
), return it unchanged.If make_subquery is True, then the query shown above will be equivalent to:
query = (who for who in (x for x in this if isinstance(x, People)))
If make_subquery is False, thesefy injects an
__iter__()
that simply returns the same object and anext()
method that immediately stops the iteration.Notice that in order to use make_subquery you call
thesefy()
as a decorator-returning function:class Person(object): pass query = (x for x in thesefy(make_subquery=False)(Person)) # or simply as a decorator @thesefy(make_subquery=False) class Person(object): pass