'Initialise the Stack.
Initialise from a context, name, Template object and (optionally)
Environment object. The database ID may also be initialised, if the
stack is already in the database.
Creating a stack with cache_data creates a lightweight stack which
will not load any resources from the database and resolve the
functions from the cache_data specified.'

def __init__(self, context, stack_name, tmpl, stack_id=None, action=None, status=None, status_reason='', timeout_mins=None, disable_rollback=True, parent_resource=None, owner_id=None, adopt_stack_data=None, stack_user_project_id=None, created_time=None, updated_time=None, user_creds_id=None, tenant_id=None, use_stored_context=False, username=None, nested_depth=0, strict_validate=True, convergence=False, current_traversal=None, tags=None, prev_raw_template_id=None, current_deps=None, cache_data=None, deleted_time=None):

    def _validate_stack_name(name):
        try:
            if (not re.match('[a-zA-Z][a-zA-Z0-9_.-]{0,254}$', name)):
                message = (_('Invalid    stack    name    %s    must    contain    only    alphanumeric    or    "_-."    characters,    must    start    with    alpha    and    must    be    255    characters    or    less.') % name)
                raise exception.StackValidationFailed(message=message)
        except TypeError:
            message = (_('Invalid    stack    name    %s,    must    be    a    string') % name)
            raise exception.StackValidationFailed(message=message)
    if (owner_id is None):
        _validate_stack_name(stack_name)
    self.id = stack_id
    self.owner_id = owner_id
    self.context = context
    self.name = stack_name
    self.action = (self.ADOPT if adopt_stack_data else (self.CREATE if (action is None) else action))
    self.status = (self.IN_PROGRESS if (status is None) else status)
    self.status_reason = status_reason
    self.timeout_mins = timeout_mins
    self.disable_rollback = disable_rollback
    self._outputs = None
    self._resources = None
    self._dependencies = None
    self._implicit_deps_loaded = False
    self._access_allowed_handlers = {}
    self._db_resources = None
    self._tags = tags
    self.adopt_stack_data = adopt_stack_data
    self.stack_user_project_id = stack_user_project_id
    self.created_time = created_time
    self.updated_time = updated_time
    self.deleted_time = deleted_time
    self.user_creds_id = user_creds_id
    self.nested_depth = nested_depth
    self.convergence = convergence
    self.current_traversal = current_traversal
    self.tags = tags
    self.prev_raw_template_id = prev_raw_template_id
    self.current_deps = current_deps
    self._worker_client = None
    self._convg_deps = None
    self.thread_group_mgr = None
    self.strict_validate = strict_validate
    self.in_convergence_check = (cache_data is not None)
    if use_stored_context:
        self.context = self.stored_context()
    self.clients = self.context.clients
    self.tenant_id = (tenant_id or self.context.tenant_id)
    self.username = (username or self.context.username)
    resources.initialise()
    parent_info = parent_rsrc.ParentResourceProxy(context, parent_resource, owner_id)
    if (tmpl is not None):
        self.defn = stk_defn.StackDefinition(context, tmpl, self.identifier(), (cache_data or {}), parent_info)
    else:
        self.defn = None
