예제 #1
0
    def visit_let_node(self, node: LetNode):
        for kv_node in node.assignments_node.kv_nodes:
            lhs_chain = []
            with self.consumer(lambda v: lhs_chain.append(v)):
                self._unwind_lhs(kv_node.key_node)

            rhs = Ref()
            with self.consumer(lambda v: rhs.set(v)):
                kv_node.value_node.accept(self)

            if len(lhs_chain) == 1:
                self.context[lhs_chain[0]] = rhs.get()
            else:
                if not lhs_chain[0] in self.context:
                    raise PeekError(f'Unknown name: {lhs_chain[0]!r}')
                lhs = self.context[lhs_chain[0]]
                for x in lhs_chain[1:-1]:
                    if isinstance(lhs, dict) or (isinstance(lhs, list)
                                                 and isinstance(x, int)):
                        lhs = lhs[x]
                    else:
                        raise PeekError(
                            f'Invalid lhs for assignment: {lhs_chain}')

                x = lhs_chain[-1]
                if isinstance(lhs, dict) or (isinstance(lhs, list)
                                             and isinstance(x, int)):
                    lhs[x] = rhs.get()
                else:
                    raise PeekError(f'Invalid lhs for assignment: {lhs_chain}')
예제 #2
0
    def visit_unary_op_node(self, node: UnaryOpNode):
        operand = Ref()
        with self.consumer(lambda v: operand.set(v)):
            node.operand_node.accept(self)

        op_func = self._unary_op_funcs.get(node.op_token.value, None)
        if op_func is None:
            raise PeekError(f'Unknown unary operator: {node.op_token.value!r}')
        self.consume(op_func(operand.get()))
예제 #3
0
def _map(app, values, ret):
    ret_nodes = app.parser.parse('return ' + ret['return'], log_level='WARNING')
    results = []
    for value in values:
        app.vm.context['s'] = value
        v_ref = Ref()
        with app.vm.consumer(lambda v: v_ref.set(v)):
            ret_nodes[0].args_node.value_nodes[0].accept(app.vm)
        results.append(v_ref.get())
    return results
예제 #4
0
 def visit_dict_node(self, node: DictNode):
     d_ref = Ref()
     with self.consumer(lambda v: d_ref.set(v)):
         self._do_visit_dict_node(node, resolve_key_name=False)
     d = d_ref.get()
     if d.get('...', None) is not None:
         splat = d.pop('...')
         assert isinstance(splat, dict), f'Cannot splat type other than dict, got: {splat!r}'
         d.update(splat)
     self.consume(d)
예제 #5
0
    def visit_for_in_node(self, node: ForInNode):
        var_name = node.item.token.value
        items_ref = Ref()
        with self.consumer(lambda v: items_ref.set(v)):
            node.items.accept(self)
        items = items_ref.get()
        if not isinstance(items, list):
            raise PeekError(
                f'For in loop must operator over a list, got {items!r}')

        for i in items:
            self.context[var_name] = i
            for n in node.suite:
                n.accept(self)
예제 #6
0
    def visit_bin_op_node(self, node: BinOpNode):
        left_operand = Ref()
        with self.consumer(lambda v: left_operand.set(v)):
            node.left_node.accept(self)

        right_operand = Ref()
        with self.consumer(lambda v: right_operand.set(v)):
            node.right_node.accept(self)

        op_func = self._bin_op_funcs.get(node.op_token.value, None)
        if op_func is None:
            raise PeekError(
                f'Unknown binary operator: {node.op_token.value!r}')
        self.consume(op_func(left_operand.get(), right_operand.get()))
예제 #7
0
    def visit_es_api_call_node(self, node: EsApiCallNode):
        if isinstance(node.path_node, TextNode):
            path = node.path
        else:
            path_ref = Ref()
            with self.consumer(lambda v: path_ref.set(v)):
                node.path_node.accept(self)
            path = path_ref.get()
            path = path if path.startswith('/') else ('/' + path)

        options = Ref()
        with self.consumer(lambda v: options.set(v)):
            self._do_visit_dict_node(node.options_node)
        options = options.get()

        if isinstance(node, EsApiCallInlinePayloadNode):
            dicts = []
            with self.consumer(lambda v: dicts.append(v)):
                for dict_node in node.dict_nodes:
                    dict_node.accept(self)
            lines = [json.dumps(d) for d in dicts]
            payload = ('\n'.join(lines) + '\n') if lines else None
        elif isinstance(node, EsApiCallFilePayloadNode):
            f_ref = Ref()
            with self.consumer(lambda v: f_ref.set(v)):
                node.file_node.accept(self)
            with open(os.path.expanduser(f_ref.get().strip())) as ins:
                payload = ins.read()
                if self.app.config.as_bool('parse_payload_file'):
                    dicts = []
                    with self.consumer(lambda v: dicts.append(v)):
                        # NOTE this reuses the parser from the main app. It is not a problem
                        # because parser always finishes its job before returning. So in a
                        # single thread execution model, we won't corrupt the internals.
                        for pnode in self.app.parser.parse(payload,
                                                           payload_only=True):
                            self.execute_node(pnode)
                    lines = [json.dumps(d) for d in dicts]
                    payload = ('\n'.join(lines) + '\n') if lines else None
                elif not payload.endswith('\n'):
                    payload += '\n'
        else:
            raise ValueError(f'Unknown node: {node!r}')

        conn = options.pop('conn') if 'conn' in options else None
        headers = options.pop('headers') if 'headers' in options else {}
        xoid = options.pop('xoid') if 'xoid' in options else None
        if xoid:
            headers['x-opaque-id'] = str(xoid)
        runas = options.pop('runas') if 'runas' in options else None
        if runas is not None:
            headers['es-security-runas-user'] = runas
        if conn is not None:
            es_client = self.app.es_client_manager.get_client(conn)
        else:
            es_client = self.app.es_client_manager.current
        quiet = options.pop('quiet', False)
        if options:
            self.app.display.error(f'Unknown options: {options}')
            return

        try:
            with warnings.catch_warnings(record=True) as ws:
                response = es_client.perform_request(
                    node.method,
                    _maybe_encode_date_math(path),
                    payload,
                    headers=headers if headers else None)
            for w in ws:
                if not quiet and self._should_show_warnings(w):
                    self.app.display.warn(str(w.message))
            self.context['_'] = _maybe_decode_json(response)
            if not quiet:
                self.app.display.info(response,
                                      header_text=self._get_header_text(
                                          conn, runas))
        except Exception as e:
            if getattr(e, 'info', None) is not None and isinstance(
                    getattr(e, 'status_code', None), int):
                self.context['_'] = _maybe_decode_json(e.info) if isinstance(
                    e.info, str) else e.info
                self.app.display.info(e.info,
                                      header_text=self._get_header_text(
                                          conn, runas))
            else:
                self.app.display.error(e,
                                       header_text=self._get_header_text(
                                           conn, runas))
                _logger.exception(f'Error on ES API call: {node!r}')
예제 #8
0
    def visit_func_call_node(self, node: FuncCallNode):
        if isinstance(node.name_node, NameNode):
            func = self.get_value(node.name_node.token.value)
        else:
            func_ref = Ref()
            with self.consumer(lambda v: func_ref.set(v)):
                node.name_node.accept(self)
            func = func_ref.get()
        if not callable(func):
            raise PeekError(
                f'{node.name_node!r} is not a callable, but {func!r}')

        func_symbols = Ref()
        with self.consumer(lambda v: func_symbols.set(v)):
            node.symbols_node.accept(self)

        func_args = Ref()
        with self.consumer(lambda v: func_args.set(v)):
            node.args_node.accept(self)

        for kv_node in node.kwargs_node.kv_nodes:
            assert isinstance(kv_node.key_node,
                              NameNode), f'{kv_node.key_node!r}'
        func_kwargs = Ref()
        with self.consumer(lambda v: func_kwargs.set(v)):
            self._do_visit_dict_node(node.kwargs_node, resolve_key_name=False)
        kwargs = func_kwargs.get()
        if func_symbols.get():
            kwargs['@'] = func_symbols.get()
        try:
            result = func(self.app, *func_args.get(), **kwargs)
            if node.is_stmt:
                self.app.display.info(result)
            else:
                self.consume(result)
        except Exception as e:
            _logger.exception(
                f'Error on invoking function: {node.name_node!r}')
            self.app.display.error(e)