thorn.utils.functional

Functional-style utilities.

thorn.utils.functional.groupbymax(it, max, key=<built-in function eq>, sentinel=<object object>)[source]

Given an iterator emitting items in sorted order, this will group items together based on the key function, and produces one list for each group.

Parameters:
  • it (Iterable) – Iterator emitting item in order.
  • max (int) – Maximum size of any group (mandatory).
  • key (Callable) – Function used to compare items. Defaults to operator.eq() matching values exactly.

Examples

>>> x = ['A', 'A', 'A', 'B', 'C', 'D', 'D', 'E']
>>> list(groupbymax(x, 3))
[['A', 'A', 'A'], ['A'], ['B'], ['C'], ['D', 'D'], ['E']]
>>> # NOTE: Not technically sorted, but similar items appear in the
>>> # order we're matching for.
>>> x = [('foo:A', 'foo:B', 'bar:C', 'baz:D', 'baz:E', 'baz:F']
>>> list(groupbymax(x, 10,
...     key=lambda a, b: a.split(':')[0] == b.split(':')[0]))
[['foo:A', 'foo:B'], ['bar:C'], ['baz:D', 'baz:E', 'baz:F']]
class thorn.utils.functional.Q(*args, **kwargs)[source]

Object query node.

This class works like django.db.models.Q, but is used for filtering regular Python objects instead of database rows.

Examples

>>> # Match object with `last_name` attribute set to "Costanza":
>>> Q(last_name__eq="Costanza")
>>> # Match object with `author.last_name` attribute set to "Benes":
>>> Q(author__last_name__eq="Benes")
>>> # You are not allowed to specify any key without an operator,
>>> # even when the following would be fine using Django`s Q objects:
>>> Q(author__last_name="Benes")   # <-- ERROR, will raise ValueError
>>> # Attributes can be nested arbitrarily deep:
>>> Q(a__b__c__d__e__f__g__x__gt=3.03)
>>> # The special `*__eq=True` means "match any *true-ish* value":
>>> Q(author__account__is_staff__eq=True)
>>> # Similarly the `*__eq=False` means "match any *false-y*" value":
>>> Q(author__account__is_disabled=False)
Returns:
to match an object with the given predicates,
call the return value with the object to match: Q(x__eq==808)(obj).
Return type:Callable
apply_op(getter, op, rhs, obj, *args)[source]
apply_trans_op(getter, op, rhs, obj)[source]
branches = {False: <built-in function truth>, True: <built-in function not_>}

If the node is negated (~a / a.negate()), branch will be True, and we reverse the query into a not a one.

compile(fields)[source]
compile_node(field)[source]

Compiles node into a cached function that performs the match.

Returns:taking the object to match.
Return type:Callable
compile_op(lhs, rhs, opcode)[source]
gate
gates = {u'AND': <built-in function all>, u'OR': <built-in function any>}

The gate decides the boolean operator of this tree node. A node can either be OR (a | b), or an AND note (a & b). - Default is AND.

operators = {u'gt': <built-in function gt>, u'is': <built-in function is_>, u'now_eq': <function compare>, u'now_endswith': <function compare>, u'endswith': <function endswith>, u'now_gt': <function compare>, u'in': <function reversed>, u'eq': <built-in function eq>, u'now_ne': <function compare>, u'gte': <built-in function ge>, u'contains': <built-in function contains>, u'ne': <built-in function ne>, u'lt': <built-in function lt>, u'now_not_in': <function compare>, u'startswith': <function startswith>, u'now_lt': <function compare>, u'now_lte': <function compare>, u'now_gte': <function compare>, u'not': <function <lambda>>, u'true': <function <lambda>>, u'not_in': <function reversed>, u'is_not': <built-in function is_not>, u'now_in': <function compare>, u'now_is': <function compare>, u'now_is_not': <function compare>, u'lte': <built-in function le>, u'now_contains': <function compare>, u'now_startswith': <function compare>}

Mapping of opcode to binary operator functionf(a, b). Operators may return any true-ish or false-y value.

prepare_opcode(O, rhs)[source]
prepare_statement(lhs, rhs)[source]
stack[source]