class_docstr: Container for a running subprocess. Supports communication with the
  subprocess via stdin and stdout.
class_docstr_tok: ["Container","for","a","running","subprocess",".","Supports","communication","with","the","subprocess","via","stdin","and","stdout","."]
docstr: Send requests to the subprocess and return the responses. We expect one
  response per request. How the response is structured is determined by
  output_proc. If output_proc returns not-None, the responses is
  considered to be a response.
  
  If output_proc is not provided, we assume that a single response is
  a single line.
  
  If the subprocess does not exist yet it is started before the first
  command is sent.
  
  Parameters
  ----------
  cmds : str or tuple or list of (str or tuple)
      request for the subprocess
  
  Returns
  -------
  (return_type[self.output_proc] | str)
  | list[(return_type[self.output_proc] | str)]
  
      Responses received from process. Either a single element, or a list
      of elements, if `cmds` was a list.
      The type of the elements is `str`, if `self.output_proc` is `None`.
      If `self.output_proc` is not `None`, the result type of
      `self.output_proc` determines the type of the elements.
code: def __call__(self, cmds: Union[str, Tuple, List]):
      """
      Send requests to the subprocess and return the responses. We expect one
      response per request. How the response is structured is determined by
      output_proc. If output_proc returns not-None, the responses is
      considered to be a response.
  
      If output_proc is not provided, we assume that a single response is
      a single line.
  
      If the subprocess does not exist yet it is started before the first
      command is sent.
  
      Parameters
      ----------
      cmds : str or tuple or list of (str or tuple)
          request for the subprocess
  
      Returns
      -------
      (return_type[self.output_proc] | str)
      | list[(return_type[self.output_proc] | str)]
  
          Responses received from process. Either a single element, or a list
          of elements, if `cmds` was a list.
          The type of the elements is `str`, if `self.output_proc` is `None`.
          If `self.output_proc` is not `None`, the result type of
          `self.output_proc` determines the type of the elements.
      """
      self._active += 1
      requests = cmds
  
      input_multiple = isinstance(requests, list)
      if not input_multiple:
          requests = [requests]
  
      responses = []
      try:
          # This code assumes that each processing request is
          # a single line and leads to a response that triggers a
          # `send_result` in the protocol.
          for request in requests:
              while True:
                  try:
                      responses.append(self.process_request(request))
                      self.last_request = request
                      break
                  except StopIteration:
                      # The process finished executing, store the last return
                      # code and restart the process.
                      lgr.debug("%s: command exited", self)
                      self.return_code = self.generator.return_code
                      self.runner = None
  
      except CommandError as command_error:
          # Convert CommandError into BatchedCommandError
          self.runner = None
          self.return_code = command_error.code
          raise BatchedCommandError(
              cmd=command_error.cmd,
              last_processed_request=self.last_request,
              msg=command_error.msg,
              code=command_error.code,
              stdout=command_error.stdout,
              stderr=command_error.stderr,
              cwd=command_error.cwd,
              **command_error.kwargs,
          ) from command_error
  
      finally:
          self._active -= 1
      return (
          responses
          if input_multiple
          else responses[0]
          if responses
          else None
      )
  
imports: from __future__ import annotations
  import logging
  import os
  import queue
  import sys
  import warnings
  from datetime import datetime
  from operator import attrgetter
  from queue import Queue
  from subprocess import TimeoutExpired
  from typing import Any, Callable, List, Optional, Tuple, Union
  from weakref import ReferenceType, WeakValueDictionary, ref
  from datalad import cfg
  from datalad.runner.coreprotocols import KillOutput, NoCapture, StdErrCapture, StdOutCapture, StdOutErrCapture
  from datalad.runner.gitrunner import GIT_SSH_COMMAND, GitRunnerBase, GitWitlessRunner
  from datalad.runner.nonasyncrunner import STDERR_FILENO, STDOUT_FILENO, _ResultGenerator, run_command
  from datalad.runner.protocol import GeneratorMixIn, WitlessProtocol
  from datalad.runner.runner import WitlessRunner
  from datalad.runner.utils import LineSplitter
  from datalad.support.exceptions import CommandError
  from datalad.utils import auto_repr, ensure_unicode
label_desc: Use image node_id 5 for calling the BatchedCommand obj's underlying member method code with example usage: obj.__call__(cmds) and returns: unknown