def test_base_iterator_List_to_2List(): a = ast.Num(n=10) s = statement_base_iterator(a, List[List[int]], List[List[int]], term_info('a', int), term_info('a+1', int), False) r = s._inner_lambda(term_info('b', int), 'Select') assert r.term == 'b.Select(lambda e0001: e0001.Select(lambda e0002: e0002+1))' assert _is_of_type(r.type, List[List[int]])
def __init__(self, ast_rep: ast.AST, input_sequence_type: Type, result_sequence_type: Type, iterator: term_info, function: Type, pass_through: bool): ''' Arguments: pass_through Input and output types are the same, function result is not checked. ''' statement_base.__init__(self, ast_rep, input_sequence_type, result_sequence_type) _monad_manager.__init__(self) self._iterator = iterator self._func = function for m in function.monad_refs: self.set_monad_ref(m) # Check that the types make sense. The earlier we catch this # the easier it is to debug. final_type = _type_replace(input_sequence_type, iterator.type, function.type) assert final_type is not None, \ f'Internal error - cannot find iterator type {iterator.type} ' \ f'in sequence type {str(input_sequence_type)}' assert pass_through or _is_of_type(final_type, result_sequence_type), \ 'Internal error: types not consistent in iterator statement: ' \ f'input: {input_sequence_type}, result: {result_sequence_type}, ' \ f'iterator: {iterator.type}, function: {function.type}'
def test_base_iterator_obj_to_obj(): a = ast.Num(n=10) s = statement_base_iterator(a, object, object, term_info('a', object), term_info('a', object), False) r = s._inner_lambda(term_info('b', object), 'Select') assert r.term == 'b' assert _is_of_type(r.type, object)
def test_base_iterator_Count_Inner_List(): a = ast.Num(n=10) s = statement_base_iterator(a, List[List[object]], List[int], term_info('a', List[object]), term_info('a.Count()', int), False) r = s._inner_lambda(term_info('b', List[object]), 'Select') assert r.term == 'b.Select(lambda e0001: e0001.Count())' assert _is_of_type(r.type, List[int])
def test_base_iterator_int_to_int(): a = ast.Num(n=10) s = statement_base_iterator(a, int, int, term_info('a', int), term_info('a+1', int), False) r = s._inner_lambda(term_info('b', int), 'Select') assert r.term == 'b+1' assert _is_of_type(r.type, int)
def test_where_apply_func_seq(): a = ast.Num(n=10) rep_type = List[object] eb = term_info('eb', object) w = statement_where(a, rep_type, eb, term_info('eb > 10.0', bool)) trm = w.apply_as_function(term_info('e10', List[object])) assert trm.term == 'e10.Where(lambda e0001: e0001 > 10.0)' assert _is_of_type(trm.type, List[object])
def _render_inner(self, in_type: Type, iter: term_info, op: str) -> term_info: ''' Recursively nest the statement as needed. ''' if _is_of_type(in_type, self._iterator.type): inner_func = self._func.term inner_func = inner_func.replace(self._iterator.term, iter.term) return term_info(inner_func, self._func.type) else: v = new_term(_unwrap_list(in_type)) unwrapped = _unwrap_list(in_type) inner_func = self._render_inner(unwrapped, v, op) use_op = op if _is_of_type(unwrapped, self._iterator.type) else 'Select' inner_type = inner_func.type if use_op == 'Select' else unwrapped return term_info( f'{iter.term}.{use_op}(lambda {v.term}: {inner_func.term})', List[inner_type])
def test_select_obj_apply_func_txt_seq(): a = ast.Num(n=10) rep_type = List[object] eb = term_info('eb', object) w = statement_select(a, rep_type, List[float], eb, term_info('eb.pt()', float)) r = w.apply_as_function(term_info('e5', List[object])) assert r.term == 'e5.Select(lambda e0001: e0001.pt())' assert _is_of_type(r.type, List[float])
def test_select_obj_apply_func_txt_notseq(): a = ast.Num(n=10) rep_type = object eb = term_info('eb', object) w = statement_select(a, rep_type, float, eb, term_info('eb.pt()', float)) r = w.apply_as_function(term_info('e5', object)) assert r.term == 'e5.pt()' assert _is_of_type(r.type, float)
def test_select_obj_apply_func_unwrap(): a = ast.Num(n=10) rep_type = List[object] eb = term_info('eb', object) w_base = statement_select(a, rep_type, List[float], eb, term_info('eb.pt()', float)) w = w_base.unwrap() r = w.apply_as_function(term_info('e5', object)) assert r.term == 'e5.pt()' assert _is_of_type(r.type, float)
def test_where_apply_func_seq_prev_monad(): a = ast.Num(n=10) rep_type = List[float] eb = term_info('eb', float) w = statement_where(a, rep_type, eb, term_info('eb > 10.0', bool)) w.prev_statement_is_monad() trm = w.apply_as_function(term_info('e10', List[float])) assert trm.term == 'e10[0].Where(lambda e0001: e0001 > 10.0)' assert _is_of_type(trm.type, List[float])
def test_where_func_add_monad_seq(): a = ast.Num(n=10) rep_type = List[float] eb = term_info('eb', float) w = statement_where(a, rep_type, eb, term_info('eb > 10.0', bool)) index = w.add_monad('em', 'em.jets()') assert index == 1 trm = w.apply_as_function(term_info('e10', List[float])) assert trm.term == '(e10.Where(lambda e0001: e0001 > 10.0), e10.jets())' assert _is_of_type(trm.type, List[float])
def test_select_apply_pass_monad_ref_through(): a = ast.Num(n=10) rep_type = List[object] eb = term_info('eb', object) w = statement_select(a, rep_type, List[float], eb, term_info('eb.pt()', float)) r = w.apply_as_function(term_info('e5', List[object], ['<monad-ref>'])) assert r.term == 'e5.Select(lambda e0001: e0001.pt())' assert _is_of_type(r.type, List[float]) assert len(r.monad_refs) == 1 assert r.monad_refs[0] == '<monad-ref>'
def test_select_apply_func_monad_passed(): a = ast.Num(n=10) rep_type = List[object] eb = term_info('eb', object) w = statement_select(a, rep_type, List[object], eb, term_info('<monad-ref>[1].pt(eb.index)', object)) w.prev_statement_is_monad() w.set_monad_ref('<monad-ref>') r = w.apply_as_function(term_info('e5', List[object])) assert r.term == 'e5[0].Select(lambda e0001: <monad-ref>[1].pt(e0001.index))' assert _is_of_type(r.type, List[object]) assert len(r.monad_refs) == 1 assert r.monad_refs[0] == '<monad-ref>'
def test_select_apply_func_monad_new_sequence(): a = ast.Num(n=10) rep_type = object eb = term_info('eb', object) w = statement_select(a, rep_type, List[object], eb, term_info('<monad-ref>[1].jets()', List[object])) w.prev_statement_is_monad() w.set_monad_ref('<monad-ref>') r = w.apply_as_function(term_info('e5', object)) assert r.term == '<monad-ref>[1].jets()' assert _is_of_type(r.type, List[object]) assert len(r.monad_refs) == 1 assert r.monad_refs[0] == '<monad-ref>'
def test_select_apply_gain_monad_ref_through(): a = ast.Num(n=10) rep_type = List[object] eb = term_info('eb', object) w = statement_select(a, rep_type, List[float], eb, term_info('eb.pt()', float)) w.prev_statement_is_monad() w.set_monad_ref('<monad-ref-1>') r = w.apply_as_function(term_info('e5', List[object], ['<monad-ref-2>'])) assert r.term == 'e5[0].Select(lambda e0001: e0001.pt())' assert _is_of_type(r.type, List[float]) assert '<monad-ref-1>' in r.monad_refs assert '<monad-ref-2>' in r.monad_refs assert len(r.monad_refs) == 2
def _render_as_function(self, sequence: term_info, op: str, render_monads: bool = False) -> term_info: ''' Helper function to render as a inline function ready to use in code. ''' assert _is_of_type(self._input_sequence_type, sequence.type), \ f'Internal Error: sequence type {self._input_sequence_type} not compatible ' \ f'with iterator sequence type {sequence.type}.' # Pass all monad references forward, we do not resolve them. monad_refs = self._monad_ref if not render_monads: self._monad_ref = [] # Next, we have to code up the outter statement inner_expr = self._inner_lambda(sequence, op) inner_expr_txt = self.render(sequence.term, inner_expr.term) self._monad_ref = monad_refs return term_info(inner_expr_txt, inner_expr.type, monad_refs + sequence.monad_refs)
def test_is_type_list_not_object_inverse(): assert not _is_of_type(object, List[int])
def test_is_type_list_not_object(): assert not _is_of_type(List[int], object)
def test_is_type_list_diff(): assert not _is_of_type(List[int], List[float])
def test_is_type_list_dict_obj(): assert not _is_of_type(Dict[int, str], List[object])
def test_is_type_list_obj(): assert _is_of_type(List[int], List[object])
def test_is_type_list(): assert _is_of_type(List[int], List[int])
def test_is_type_object(): assert _is_of_type(int, object)
def test_is_type_not(): assert not _is_of_type(int, List[int])