'Return the set of all attributes referenced in the template.
This enables the resource to calculate which of its attributes will
be used. By default, attributes referenced in either other resources
or outputs will be included. Either can be excluded by setting the
`in_resources` or `in_outputs` parameters to False. To limit to a
subset of outputs, pass an iterable of the output names to examine
for the `in_outputs` parameter.
The set of referenced attributes is calculated from the
StackDefinition object provided, or from the stack\'s current
definition if none is passed.'

def referenced_attrs(self, stk_defn=None, in_resources=True, in_outputs=True, load_all=False):

    if (stk_defn is None):
        stk_defn = self.stack.defn
    def get_dep_attrs(source):
        return set(itertools.chain.from_iterable((s.dep_attrs(self.name, load_all) for s in source)))
    refd_attrs = set()
    if in_resources:
        enabled_resources = stk_defn.enabled_rsrc_names()
        refd_attrs |= get_dep_attrs((stk_defn.resource_definition(r_name) for r_name in enabled_resources))
    subset_outputs = isinstance(in_outputs, collections.Iterable)
    if (subset_outputs or in_outputs):
        if (not subset_outputs):
            in_outputs = stk_defn.enabled_output_names()
        refd_attrs |= get_dep_attrs((stk_defn.output_definition(op_name) for op_name in in_outputs))
    if (attributes.ALL_ATTRIBUTES in refd_attrs):
        refd_attrs.remove(attributes.ALL_ATTRIBUTES)
        refd_attrs |= (set(self.attributes) - {self.SHOW})
    return refd_attrs
