code: def request(self, name, *args, **kwargs):
          r
          if (self._session._loop_thread is not None
                  and threading.current_thread() != self._session._loop_thread):
  
              msg = ("Request from non-main thread.\n"
                     "Requests from different threads should be wrapped "
                     "with nvim.async_call(cb, ...) \n{}\n"
                     .format('\n'.join(format_stack(None, 5)[:-1])))
  
              self.async_call(self._err_cb, msg)
              raise NvimError("request from non-main thread")
  
          decode = kwargs.pop('decode', self._decode)
          args = walk(self._to_nvim, args)
          res = self._session.request(name, *args, **kwargs)
          return walk(self._from_nvim, res, decode=decode)
docs: r"""Send an API request or notification to nvim.
  
          It is rarely needed to call this function directly, as most API
          functions have python wrapper functions. The `api` object can
          be also be used to call API functions as methods:
  
              vim.api.err_write('ERROR\n', async_=True)
              vim.current.buffer.api.get_mark('.')
  
          is equivalent to
  
              vim.request('nvim_err_write', 'ERROR\n', async_=True)
              vim.request('nvim_buf_get_mark', vim.current.buffer, '.')
  
  
          Normally a blocking request will be sent.  If the `async_` flag is
          present and True, a asynchronous notification is sent instead. This
          will never block, and the return value or error is ignored.