def testNulls(self): r = None # Should be zero elements but not raise. self.assertEqual(repeated.getvalues(r), ()) r = repeated.meld(None, None) # None should get skipped. self.assertEqual(repeated.getvalues(r), ())
def testNulls(self): r = None for _ in repeated.getvalues(r): # Should be zero elements but not raise. self.assertFail() r = repeated.meld(None, None) # None should get skipped. for _ in repeated.getvalues(r): self.assertFail()
def testNulls(self): r = None for _ in repeated.getvalues(r): # Should be zero elements but not raise. self.assertFail() r = repeated.meld(None, None) # None should get skipped. for _ in repeated.getvalues(r): self.assertFail()
def testProtocol(self): def _generator(): yield "a" single = lazy_repetition.LazyRepetition(_generator) self.assertEqual(list(repeated.getvalues(single)), ["a"]) self.assertEqual(repeated.getvalue(single), "a") def _generator(): yield "a" yield "b" double = lazy_repetition.LazyRepetition(_generator) self.assertEqual(list(repeated.getvalues(double)), ["a", "b"]) self.assertEqual(repeated.getvalue(double), "a")
def solve_resolve(expr, vars): """Use IStructured.resolve to get member (rhs) from the object (lhs).""" objs = __within_lhs_as_repeated(expr.lhs, vars) member = solve(expr.rhs, vars).value try: results = [structured.resolve(o, member) for o in repeated.getvalues(objs)] except (KeyError, AttributeError): # Raise a better exception for the non-existent member. raise errors.EfilterKeyError(root=expr.rhs, key=member, query=expr.source) except (TypeError, ValueError): # Is this a null object error? if vars is None: raise errors.EfilterNoneError( root=expr, query=expr.source, message="Cannot resolve member %r from a null." % member) else: raise except NotImplementedError: raise errors.EfilterError( root=expr, query=expr.source, message="Cannot resolve members from a non-structured value.") return Result(repeated.meld(*results), ())
def solve_select(expr, vars): """Use IAssociative.select to get key (rhs) from the data (lhs). This operation supports both scalars and repeated values on the LHS - selecting from a repeated value implies a map-like operation and returns a new repeated value. """ data = solve(expr.lhs, vars).value key = solve(expr.rhs, vars).value try: results = [associative.select(d, key) for d in repeated.getvalues(data)] except (KeyError, AttributeError): # Raise a better exception for accessing a non-existent key. raise errors.EfilterKeyError(root=expr, key=key, query=expr.source) except (TypeError, ValueError): # Raise a better exception for what is probably a null pointer error. if vars.locals is None: raise errors.EfilterNoneError( root=expr, query=expr.source, message="Cannot select key %r from a null." % key) else: raise except NotImplementedError: raise errors.EfilterError( root=expr, query=expr.source, message="Cannot select keys from a non-associative value.") return Result(repeated.meld(*results), ())
def solve_select(expr, vars): """Use IAssociative.select to get key (rhs) from the data (lhs). This operation supports both scalars and repeated values on the LHS - selecting from a repeated value implies a map-like operation and returns a new repeated value. """ data = __solve_for_repeated(expr.lhs, vars) key = solve(expr.rhs, vars).value try: results = [associative.select(d, key) for d in repeated.getvalues(data)] except (KeyError, AttributeError): # Raise a better exception for accessing a non-existent key. raise errors.EfilterKeyError(root=expr, key=key, query=expr.source) except (TypeError, ValueError): # Raise a better exception for what is probably a null pointer error. if vars.locals is None: raise errors.EfilterNoneError( root=expr, query=expr.source, message="Cannot select key %r from a null." % key) else: raise except NotImplementedError: raise errors.EfilterError( root=expr, query=expr.source, message="Cannot select keys from a non-associative value.") return Result(repeated.meld(*results), ())
def solve_resolve(expr, vars): """Use IStructured.resolve to get member (rhs) from the object (lhs). This operation supports both scalars and repeated values on the LHS - resolving from a repeated value implies a map-like operation and returns a new repeated values. """ objs, _ = __solve_for_repeated(expr.lhs, vars) member = solve(expr.rhs, vars).value try: results = [ structured.resolve(o, member) for o in repeated.getvalues(objs) ] except (KeyError, AttributeError): # Raise a better exception for the non-existent member. raise errors.EfilterKeyError(root=expr.rhs, key=member, query=expr.source) except (TypeError, ValueError): # Is this a null object error? if vars.locals is None: raise errors.EfilterNoneError( root=expr, query=expr.source, message="Cannot resolve member %r from a null." % member) else: raise except NotImplementedError: raise errors.EfilterError( root=expr, query=expr.source, message="Cannot resolve members from a non-structured value.") return Result(repeated.meld(*results), ())
def solve_resolve(expr, vars): """Use IStructured.resolve to get member (rhs) from the object (lhs). This operation supports both scalars and repeated values on the LHS - resolving from a repeated value implies a map-like operation and returns a new repeated values. """ objs = __solve_for_repeated(expr.lhs, vars) member = solve(expr.rhs, vars).value try: results = [structured.resolve(o, member) for o in repeated.getvalues(objs)] except (KeyError, AttributeError): # Raise a better exception for the non-existent member. raise errors.EfilterKeyError(root=expr.rhs, key=member, query=expr.source) except (TypeError, ValueError): # Is this a null object error? if vars.locals is None: raise errors.EfilterNoneError( root=expr, query=expr.source, message="Cannot resolve member %r from a null." % member) else: raise except NotImplementedError: raise errors.EfilterError( root=expr, query=expr.source, message="Cannot resolve members from a non-structured value.") return Result(repeated.meld(*results), ())
def testProtocol(self): def _generator(): yield "a" single = lazy_repetition.LazyRepetition(_generator) self.assertEqual(list(repeated.getvalues(single)), ["a"]) self.assertEqual(repeated.getvalue(single), "a") def _generator(): yield "a" yield "b" double = lazy_repetition.LazyRepetition(_generator) self.assertEqual(list(repeated.getvalues(double)), ["a", "b"]) with self.assertRaises(TypeError): repeated.getvalue(double)
def add_value(self, value): """Add a value to this repeated var. WARNING: this mutates the object (it's NOT copy on write). Unless you're absolutely certain of what you're doing, you most likely want to call repeated.meld(x, y) instead. """ self._delegate.extend(repeated.getvalues(value))
def lazy_map(): try: for lhs_value in repeated.getvalues(lhs_values): nested_scope = scope.ScopeStack(vars, lhs_value) yield solve(expr.rhs, nested_scope).value except errors.EfilterNoneError as error: error.root = expr raise
def lazy_map(): try: for lhs_value in repeated.getvalues(lhs_values): yield solve(expr.rhs, __nest_scope(expr.lhs, vars, lhs_value)).value except errors.EfilterNoneError as error: error.root = expr raise
def lazy_map(): try: for lhs_value in repeated.getvalues(lhs_values): yield solve(expr.rhs, __nest_scope(expr.lhs, vars, lhs_value)).value except errors.EfilterNoneError as error: error.root = expr raise
def solve_membership(expr, vars): element = solve(expr.element, vars).value values = solve(expr.set, vars).value if isinstance(values, repeated.IRepeated): return Result(element in repeated.getvalues(values), ()) return Result(element in values, ())
def collect(self): try: result = solve.solve(self.query, self) return repeated.getvalues(result.value) except errors.EfilterError: if self.silent: return None raise
def collect(self): try: result = solve.solve(self.query, self) return repeated.getvalues(result.value) except errors.EfilterError: if self.silent: return None raise
def solve_any(expr, vars): """Same as Each, except returning True on first true result at LHS.""" lhs_values = solve(expr.lhs, vars).value try: rhs = expr.rhs except IndexError: # Child 1 is out of range. There is no condition on the RHS. # Just see if we have anything on the LHS. return Result(len(repeated.getvalues(lhs_values)) > 0, ()) result = Result(False, ()) for lhs_value in repeated.getvalues(lhs_values): result = solve(rhs, __nest_scope(expr.lhs, vars, lhs_value)) if result.value: # Any is required to return an actual boolean. return result._replace(value=True) return result
def solve_any(expr, vars): """Same as Each, except returning True on first true result at LHS.""" lhs_values = __solve_for_repeated(expr.lhs, vars) try: rhs = expr.rhs except IndexError: # Child 1 is out of range. There is no condition on the RHS. # Just see if we have anything on the LHS. return Result(len(repeated.getvalues(lhs_values)) > 0, ()) result = Result(False, ()) for lhs_value in repeated.getvalues(lhs_values): result = solve(rhs, __nest_scope(expr.lhs, vars, lhs_value)) if result.value: # Any is required to return an actual boolean. return result._replace(value=True) return result
def collect(self): """Return the search results without displaying them.""" try: result = solve.solve(self.query, self) return repeated.getvalues(result.value) except errors.EfilterError: if self.silent: return None raise
def run(self): replacements = [] if self.fixture_name is not None: replacements.append(testlib.get_fixture_path(self.fixture_name)) result = api.apply(self.query, replacements=replacements, allow_io=True) # Force lazy results to be realized, but don't do anything with them. for _ in repeated.getvalues(result): pass
def generate_chunks(data, chunk_size=DEFAULT_CHUNK_SIZE): """Yield 'chunk_size' items from 'data' at a time.""" iterator = iter(repeated.getvalues(data)) while True: chunk = list(itertools.islice(iterator, chunk_size)) if not chunk: return yield chunk
def collect(self): """Return the search results without displaying them.""" try: result = solve.solve(self.query, self) return repeated.getvalues(result.value) except errors.EfilterError: if self.silent: return None raise
def _generator(): if isinstance(x, tuple): values = x else: values = repeated.getvalues(x) for idx, value in enumerate(values): if idx < count: continue yield value
def _generator(): if isinstance(x, tuple): values = x else: values = repeated.getvalues(x) for idx, value in enumerate(values): if idx < count: continue yield value
def solve_sort(expr, vars): """Sort values on the LHS by the value they yield when passed to RHS.""" lhs_values = repeated.getvalues(__solve_for_repeated(expr.lhs, vars)) sort_expression = expr.rhs def _key_func(x): return solve(sort_expression, __nest_scope(expr.lhs, vars, x)).value results = ordered.ordered(lhs_values, key_func=_key_func) return Result(repeated.meld(*results), ())
def solve_sort(expr, vars): """Sort values on the LHS by the value they yield when passed to RHS.""" lhs_values = repeated.getvalues(__solve_for_repeated(expr.lhs, vars)[0]) sort_expression = expr.rhs def _key_func(x): return solve(sort_expression, __nest_scope(expr.lhs, vars, x)).value results = ordered.ordered(lhs_values, key_func=_key_func) return Result(repeated.meld(*results), ())
def lazy_filter(): for lhs_value in repeated.getvalues(lhs_values): filter_result = solve(expr.rhs, __nest_scope( expr.lhs, vars, lhs_value)).value # Repeating values are chosen if any of the values returns # true. if repeated.isrepeating(filter_result): if any(filter_result): yield lhs_value else: # Todo: Implement a bool protocol - for now we use the # python bool. Scalar values must evaluate to true. if bool(filter_result): yield lhs_value
def solve_sort(expr, vars): """Sort values on the LHS by the value they yield when passed to RHS.""" lhs_values = repeated.getvalues(solve(expr.lhs, vars)[0]) sort_expression = expr.rhs def _key_func(x): return solve(sort_expression, __nest_scope(expr.lhs, vars, x)).value # In order to sort we must expand the list into memory and apply # the sort expression to each element. We then use the ordered and # eq protocols to compare any two items until the list is sorted. sorted_list = [(x, _key_func(x)) for x in lhs_values] key_func = functools.cmp_to_key(_cmp) sorted_list.sort(key=lambda x: key_func(x[1])) return Result([x[0] for x in sorted_list], ())
def testNesting(self): """Test that repeated vars remain flat.""" r = repeated.repeated("foo", "bar") r = repeated.repeated(r, "baz") self.assertValueEq(repeated.repeated("foo", "bar", "baz"), r) r = repeated.repeated("zoo", r) self.assertValueEq(repeated.repeated("zoo", "foo", "bar", "baz"), r) # value_eq should ignore order. self.assertValueEq(repeated.repeated("bar", "foo", "baz", "zoo"), r) # Order should be preserved for getvalues, though. self.assertEqual(repeated.getvalues(r), ["zoo", "foo", "bar", "baz"]) self.assertEqual(repeated.value_type(r), type("foo"))
def testNesting(self): """Test that repeated vars remain flat.""" r = repeated.repeated("foo", "bar") r = repeated.repeated(r, "baz") self.assertValueEq(repeated.repeated("foo", "bar", "baz"), r) r = repeated.repeated("zoo", r) self.assertValueEq(repeated.repeated("zoo", "foo", "bar", "baz"), r) # value_eq should ignore order. self.assertValueEq(repeated.repeated("bar", "foo", "baz", "zoo"), r) # Order should be preserved for getvalues, though. self.assertEqual(repeated.getvalues(r), ["zoo", "foo", "bar", "baz"]) self.assertEqual(repeated.value_type(r), type("foo"))
def getvalues(result): """Return an iterator of results of 'apply'. The 'apply' function can return one or more values, depending on the query. If you are unsure whether your query evaluates to a scalar or a collection of scalars, 'getvalues' will always return an iterator with one or more elements. Arguments: result: Anything. If it's an instance of IRepeated, all values will be returned. Returns: An iterator of at least one element. """ return repeated.getvalues(result)
def getvalues(result): """Return an iterator of results of 'apply'. The 'apply' function can return one or more values, depending on the query. If you are unsure whether your query evaluates to a scalar or a collection of scalars, 'getvalues' will always return an iterator with one or more elements. Arguments: result: Anything. If it's an instance of IRepeated, all values will be returned. Returns: An iterator of at least one element. """ return repeated.getvalues(result)
def collect(self): """Return the search results without displaying them. Returns: A list of results from the query solver. Raises: EfilterError unless 'silent' flag was set. """ try: result = self.solve() return repeated.getvalues(result) except errors.EfilterError: if self.silent: return None raise
def collect(self): """Return the search results without displaying them. Returns: A list of results from the query solver. Raises: EfilterError unless 'silent' flag was set. """ try: result = self.solve() return repeated.getvalues(result) except errors.EfilterError: if self.plugin_args.silent: return None raise
def solve_each(expr, vars): """Return True if RHS evaluates to a true value with each state of LHS. If LHS evaluates to a normal IAssociative object then this is the same as a regular let-form, except the return value is always a boolean. If LHS evaluates to a repeared var (see efilter.protocols.repeated) of IAssociative objects then RHS will be evaluated with each state and True will be returned only if each result is true. """ lhs_values = solve(expr.lhs, vars).value for lhs_value in repeated.getvalues(lhs_values): result = solve(expr.rhs, __nest_scope(expr.lhs, vars, lhs_value)) if not result.value: # Each is required to return an actual boolean. return result._replace(value=False) return Result(True, ())
def solve_each(expr, vars): """Return True if RHS evaluates to a true value with each state of LHS. If LHS evaluates to a normal IAssociative object then this is the same as a regular let-form, except the return value is always a boolean. If LHS evaluates to a repeared var (see efilter.protocols.repeated) of IAssociative objects then RHS will be evaluated with each state and True will be returned only if each result is true. """ lhs_values = __solve_for_repeated(expr.lhs, vars) for lhs_value in repeated.getvalues(lhs_values): result = solve(expr.rhs, __nest_scope(expr.lhs, vars, lhs_value)) if not result.value: # Each is required to return an actual boolean. return result._replace(value=False) return Result(True, ())
def solve_resolve(expr, vars): """Use IStructured.resolve to get member (rhs) from the object (lhs). This operation supports both scalars and repeated values on the LHS - resolving from a repeated value implies a map-like operation and returns a new repeated values. """ objs = solve(expr.lhs, vars).value member = solve(expr.rhs, vars).value results = [] if repeated.isrepeating(objs): for o in repeated.getvalues(objs): results.append(structured.resolve(o, member)) return Result(results, ()) return Result(structured.resolve(objs, member), ())
def solve_select(expr, vars): """Use IAssociative.select to get key (rhs) from the data (lhs).""" data = __within_lhs_as_repeated(expr.lhs, vars) key = solve(expr.rhs, vars).value try: results = [associative.select(d, key) for d in repeated.getvalues(data)] except (KeyError, AttributeError): # Raise a better exception for accessing a non-existent key. raise errors.EfilterKeyError(root=expr, key=key, query=expr.source) except (TypeError, ValueError): # Raise a better exception for what is probably a null pointer error. if vars is None: raise errors.EfilterNoneError( root=expr, query=expr.source, message="Cannot select key %r from a null." % key) else: raise except NotImplementedError: raise errors.EfilterError( root=expr, query=expr.source, message="Cannot select keys from a non-associative value.") return Result(repeated.meld(*results), ())
def lazy_filter(): for lhs_value in repeated.getvalues(lhs_values): if solve(expr.rhs, __nest_scope(expr.lhs, vars, lhs_value)).value: yield lhs_value
def __call__(self, x): if isinstance(x, tuple): return tuple(reversed(x)) return repeated.meld(*reversed(repeated.getvalues(x)))
def value_eq(self, other): """This is required by the IRepeated protocol, but not actually used.""" return self.getvalues() == repeated.getvalues(other)
def assertValuesEqual(self, x, y): self.assertItemsEqual(repeated.getvalues(x), repeated.getvalues(y))
def value_eq(self, other): """Sorted comparison of values.""" self_sorted = ordered.ordered(self.getvalues()) other_sorted = ordered.ordered(repeated.getvalues(other)) return self_sorted == other_sorted
def value_eq(self, other): """This is required by the IRepeated protocol, but not actually used.""" return self.getvalues() == repeated.getvalues(other)
def __call__(self, x): if isinstance(x, tuple): return tuple(reversed(x)) return repeated.meld(*reversed(repeated.getvalues(x)))
def __call__(self, x): for value in repeated.getvalues(x): return value
def __call__(self, x): for value in repeated.getvalues(x): return value
def lazy_filter(): for lhs_value in repeated.getvalues(lhs_values): if solve(expr.rhs, __nest_scope(expr.lhs, vars, lhs_value)).value: yield lhs_value
def state_eq(self, other): if isinstance(other, type(self)): return self._delegate == other._delegate return sorted(self._delegate) == sorted(repeated.getvalues(other))
def value_eq(self, other): """Sorted comparison of values.""" self_sorted = ordered.ordered(self.getvalues()) other_sorted = ordered.ordered(repeated.getvalues(other)) return self_sorted == other_sorted
def assertValuesEqual(self, x, y): self.assertItemsEqual(repeated.getvalues(x), repeated.getvalues(y))
def filter(self, query, **query_args): query = q.Query(query, params=query_args) return repeated.getvalues(solve.solve(query, self).value)
def filter(self, query, **query_args): query = q.Query(query, params=query_args) return repeated.getvalues(solve.solve(query, self).value)
def lazy_filter(): for lhs_value in repeated.getvalues(lhs_values): nested_scope = scope.ScopeStack(vars, lhs_value) if solve(expr.rhs, nested_scope).value: yield lhs_value