asq.extension

Adding extension operators.

The extension modules contains tools for registering new extension operators with asq. This is achieved by dynamically adding new methods to Queryable and possibly its subclasses.

add_method Add an existing function to a class as a method.
extend A function decorator for extending an existing class.
asq.extension.add_method(function, klass, name=None)

Add an existing function to a class as a method.

Note

Consider using the extend decorator as a more readable alternative to using this function directly.

Parameters:
  • function – The function to be added to the class klass.
  • klass – The class to which the new method will be added.
  • name – An optional name for the new method. If omitted or None the original name of the function is used.
Returns:

The function argument unmodified.

Raises:
ValueError - If klass already has an attribute with the same name as the

extension method.

Example

Define a function called every_second() which returns every second element from the source and add it to Queryable as a new query operator called alternate():

>>> def every_second(self):
...     def generate():
...         for index, item in enumerate(self):
...             if index % 2 == 0:
...                 yield item
...     return self._create(generate())
...
>>> from asq.extension import add_method
>>> from asq.queryables import Queryable
>>>
>>> add_method(every_second, Queryable, "alternate")
<function every_second at 0x0000000002D2D5C8>
>>> a = [5, 8, 3, 2, 0, 9, 5, 4, 9, 2, 7, 0]
>>> query(a).alternate().to_list()
[5, 3, 0, 5, 9, 7]
asq.extension.extend(klass, name=None)

A function decorator for extending an existing class.

Use as a decorator for functions to add to an existing class.

Parameters:
  • klass – The class to be decorated.
  • name – The name the new method is to be given in the klass class.
Returns:

A decorator function which accepts a single function as its only argument. The decorated function will be added to class klass.

Raises:
ValueError - If klass already has an attribute with the same name as the

extension method.

Example

Define a new query method called pairs() which iterates over successive pairs in the source iterable, add it to the Queryable class and use it to execute a query. Note that extension methods defined in this way will typically need to call internal methods of Queryable, such as the _create() method used here to construct a new Queryable:

>>> from asq.extension import extend
>>> from asq.queryables import Queryable
>>>
>>> @extend(Queryable)
... def pairs(self):
...     def generate_pairs():
...         i = iter(self)
...         sentinel = object()
...         prev = next(i, sentinel)
...         if prev is sentinel:
...             return
...         for item in i:
...             yield prev, item
...             prev = item
...     return self._create(generate_pairs())
...
>>> from asq import query
>>> a = [5, 4, 7, 2, 8, 9, 1, 0, 4]
>>> query(a).pairs().to_list()
[(5, 4), (4, 7), (7, 2), (2, 8), (8, 9), (9, 1), (1, 0), (0, 4)]