<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def call(cmd, stdout=PIPE, stderr=PIPE, on_error='raise', **kwargs):
 """Call out to the shell using `subprocess.Popen` Parameters stdout : `file-like`, optional stream for stdout stderr : `file-like`, optional stderr for stderr on_error : `str`, optional what to do when the command fails, one of - 'ignore' - do nothing - 'warn' - print a warning - 'raise' - raise an exception **kwargs other keyword arguments to pass to `subprocess.Popen` Returns ------- out : `str` the output stream of the command err : `str` the error stream from the command Raises ------ OSError if `cmd` is a `str` (or `shell=True` is passed) and the executable is not found subprocess.CalledProcessError if the command fails otherwise """

    if isinstance(cmd, (list, tuple)):
        cmdstr = ' '.join(cmd)
        kwargs.setdefault('shell', False)
    else:
        cmdstr = str(cmd)
        kwargs.setdefault('shell', True)
    proc = Popen(cmd, stdout=stdout, stderr=stderr, **kwargs)
    out, err = proc.communicate()
    if proc.returncode:
        if on_error == 'ignore':
            pass
        elif on_error == 'warn':
            e = CalledProcessError(proc.returncode, cmdstr)
            warnings.warn(str(e))
        else:
            raise CalledProcessError(proc.returncode, cmdstr)
    return out.decode('utf-8'), err.decode('utf-8')