'cmd is an array, where each element is encoded as bytes (PY3) or str
(PY2)'

def __init__(self, cmd, call_args, stdin, stdout, stderr):

    enc = call_args['encoding']
    self.ran = '    '.join([arg.decode(enc, 'ignore') for arg in cmd])
    self.call_args = call_args
    self.cmd = cmd
    self.process = None
    self._process_completed = False
    should_wait = True
    spawn_process = True
    self._stopped_iteration = False
    if call_args['with']:
        spawn_process = False
        get_prepend_stack().append(self)
    if (call_args['piped'] or call_args['iter'] or call_args['iter_noblock']):
        should_wait = False
    if call_args['bg']:
        should_wait = False
    if call_args['err_to_out']:
        stderr = OProc.STDOUT
    done_callback = call_args['done']
    if done_callback:
        call_args['done'] = partial(done_callback, self)
    pipe = OProc.STDOUT
    if ((call_args['iter'] == 'out') or (call_args['iter'] is True)):
        pipe = OProc.STDOUT
    elif (call_args['iter'] == 'err'):
        pipe = OProc.STDERR
    if ((call_args['iter_noblock'] == 'out') or (call_args['iter_noblock'] is True)):
        pipe = OProc.STDOUT
    elif (call_args['iter_noblock'] == 'err'):
        pipe = OProc.STDERR
    self._spawned_and_waited = False
    if spawn_process:
        log_str_factory = (call_args['log_msg'] or default_logger_str)
        logger_str = log_str_factory(self.ran, call_args)
        self.log = Logger('command', logger_str)
        self.log.info('starting    process')
        if should_wait:
            self._spawned_and_waited = True
        process_assign_lock = threading.Lock()
        with process_assign_lock:
            self.process = OProc(self, self.log, cmd, stdin, stdout, stderr, self.call_args, pipe, process_assign_lock)
        logger_str = log_str_factory(self.ran, call_args, self.process.pid)
        self.log.set_context(logger_str)
        self.log.info('process    started')
        if should_wait:
            self.wait()
