Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is this python expression parameter is not expanded at call time?

In google appengine NDB there are queries like this:

query = Account.query(Account.userid >= 40)

How come the Account.userid >= 40 expression is not expanded at call time to true or false before passed as an argument? How is the filter expression passed to the query? Is it done with operator overloading?

like image 204
Tom Avatar asked Nov 09 '17 14:11

Tom


1 Answers

Ignacio is correct, the NDB code is defining custom magic methods on its Property class for comparison checking. These functions (__eq__, __ne__, __lt__, etc.) are all calling this custom _comparison function under the hood.

def _comparison(self, op, value):
    """Internal helper for comparison operators.
    Args:
      op: The operator ('=', '<' etc.).
    Returns:
      A FilterNode instance representing the requested comparison.
    """
    # NOTE: This is also used by query.gql().
    if not self._indexed:
      raise datastore_errors.BadFilterError(
          'Cannot query for unindexed property %s' % self._name)
    from .query import FilterNode  # Import late to avoid circular imports.
    if value is not None:
      value = self._do_validate(value)
      value = self._call_to_base_type(value)
      value = self._datastore_type(value)
    return FilterNode(self._name, op, value)

As you can see, the code doesn't return a boolean result, it returns an instance of FilterNode which itself evaluates to a truthy/falsey value appropriately for the comparison.

How come the Account.userid >= 40 expression is not expanded at call time to true or false before passed as an argument?

It technically is getting expanded/evaluated before the query() function is called, it just isn't evaluating to a boolean value.

like image 192
Jesse Webb Avatar answered Oct 13 '22 07:10

Jesse Webb