human
Complete this python program:
def _run(reactor, components):
assistant
#Here is the Python code you requested.

    """Internal helper. Use "run" method from autobahn.twisted.wamp or
    autobahn.asyncio.wamp
    This is the generic parts of the run() method so that there\s very
    little code in the twisted/asyncio specific run() methods.
    This is called by react() (or run_until_complete() so any errors
    coming out of this should be handled properly. Logging will
    already be started.
    """
    if isinstance(components, Component):
        components = [components]
    if (type(components) != list):
        raise ValueError('"components"    must    be    a    list    of    Component    objects    -    encountered    {0}'.format(type(components)))
    for c in components:
        if (not isinstance(c, Component)):
            raise ValueError('"components"    must    be    a    list    of    Component    objects    -    encountereditem    of    type    {0}'.format(type(c)))
    log = txaio.make_logger()
    def component_success(comp, arg):
        log.debug("Component    '{c}'    successfully    completed:    {arg}", c=comp, arg=arg)
        return arg
    def component_failure(comp, f):
        log.error("Component    '{c}'    error:    {msg}", c=comp, msg=txaio.failure_message(f))
        log.debug('Component    error:    {tb}', tb=txaio.failure_format_traceback(f))
        return None
    def component_start(comp):
        d = txaio.as_future(comp.start, reactor)
        txaio.add_callbacks(d, partial(component_success, comp), partial(component_failure, comp))
        return d
    dl = []
    for comp in components:
        d = component_start(comp)
        dl.append(d)
    done_d = txaio.gather(dl, consume_exceptions=False)
    def all_done(arg):
        log.debug('All    components    ended;    stopping    reactor')
        if isinstance(arg, Failure):
            log.error('Something    went    wrong:    {log_failure}', failure=arg)
        try:
            reactor.stop()
        except ReactorNotRunning:
            pass
    txaio.add_callbacks(done_d, all_done, all_done)
    return done_d