def get_action_class_instance(action_cls, config=None, action_service=None):
    """
    Instantiate and return Action class instance.

    :param action_cls: Action class to instantiate.
    :type action_cls: ``class``

    :param config: Config to pass to the action class.
    :type config: ``dict``

    :param action_service: ActionService instance to pass to the class.
    :type action_service: :class:`ActionService`
    """
    kwargs = {}
    kwargs['config'] = config
    kwargs['action_service'] = action_service

    # Note: This is done for backward compatibility reasons. We first try to pass
    # "action_service" argument to the action class constructor, but if that doesn't work (e.g. old
    # action which hasn't been updated yet), we resort to late assignment post class instantiation.
    # TODO: Remove in next major version once all the affected actions have been updated.
    try:
        action_instance = action_cls(**kwargs)
    except __HOLE__ as e:
        if 'unexpected keyword argument \'action_service\'' not in str(e):
            raise e

        LOG.debug('Action class (%s) constructor doesn\'t take "action_service" argument, '
                  'falling back to late assignment...' % (action_cls.__class__.__name__))

        action_service = kwargs.pop('action_service', None)
        action_instance = action_cls(**kwargs)
        action_instance.action_service = action_service

    return action_instance
dataset/ETHPy150Open StackStorm/st2/st2actions/st2actions/runners/utils.py/get_action_class_instance