This file is indexed.

/usr/lib/python3/dist-packages/sekizai/helpers.py is in python3-django-sekizai 0.9.0-2.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
# -*- coding: utf-8 -*-

from django.conf import settings
from django.template.base import VariableNode, Variable, Context, Template
from django.template.loader import get_template
from django.template.loader_tags import BlockNode, ExtendsNode

try:
    from django.template import engines
except ImportError:
    engines = None


def _get_nodelist(tpl):
    if isinstance(tpl, Template):
        return tpl.nodelist
    else:
        return tpl.template.nodelist


def is_variable_extend_node(node):
    if hasattr(node, 'parent_name_expr') and node.parent_name_expr:
        return True
    if hasattr(node, 'parent_name') and hasattr(node.parent_name, 'filters'):
        if (node.parent_name.filters or
                isinstance(node.parent_name.var, Variable)):
            return True
    return False


def get_context():
    if engines is not None:
        context = Context()
        context.template = Template('')
        return context
    else:
        return Context()


def _extend_blocks(extend_node, blocks):
    """
    Extends the dictionary `blocks` with *new* blocks in the parent node
    (recursive)
    """
    # we don't support variable extensions
    if is_variable_extend_node(extend_node):
        return
    parent = extend_node.get_parent(get_context())
    # Search for new blocks
    for node in _get_nodelist(parent).get_nodes_by_type(BlockNode):
        if node.name not in blocks:
            blocks[node.name] = node
        else:
            # set this node as the super node (for {{ block.super }})
            block = blocks[node.name]
            seen_supers = []
            while (hasattr(block.super, 'nodelist') and
                   block.super not in seen_supers):
                seen_supers.append(block.super)
                block = block.super
            block.super = node
    # search for further ExtendsNodes
    for node in _get_nodelist(parent).get_nodes_by_type(ExtendsNode):
        _extend_blocks(node, blocks)
        break


def _extend_nodelist(extend_node):
    """
    Returns a list of namespaces found in the parent template(s) of this
    ExtendsNode
    """
    # we don't support variable extensions (1.3 way)
    if is_variable_extend_node(extend_node):
        return []
    blocks = extend_node.blocks
    _extend_blocks(extend_node, blocks)
    found = []

    for block in blocks.values():
        found += _scan_namespaces(block.nodelist, block)

    parent_template = extend_node.get_parent(get_context())
    # if this is the topmost template, check for namespaces outside of blocks
    if not _get_nodelist(parent_template).get_nodes_by_type(ExtendsNode):
        found += _scan_namespaces(
            _get_nodelist(parent_template),
            None
        )
    else:
        found += _scan_namespaces(
            _get_nodelist(parent_template),
            extend_node
        )
    return found


def _scan_namespaces(nodelist, current_block=None):
    from sekizai.templatetags.sekizai_tags import RenderBlock
    found = []

    for node in nodelist:
        # check if this is RenderBlock node
        if isinstance(node, RenderBlock):
            # resolve it's name against a dummy context
            found.append(node.kwargs['name'].resolve({}))
            found += _scan_namespaces(node.blocks['nodelist'], node)
        # handle {% extends ... %} tags if check_inheritance is True
        elif isinstance(node, ExtendsNode):
            found += _extend_nodelist(node)
        # in block nodes we have to scan for super blocks
        elif isinstance(node, VariableNode) and current_block:
            if node.filter_expression.token == 'block.super':
                if hasattr(current_block.super, 'nodelist'):
                    found += _scan_namespaces(
                        current_block.super.nodelist,
                        current_block.super
                    )
    return found


def get_namespaces(template):
    compiled_template = get_template(template)
    return _scan_namespaces(_get_nodelist(compiled_template))


def validate_template(template, namespaces):
    """
    Validates that a template (or it's parents if check_inheritance is True)
    contain all given namespaces
    """
    if getattr(settings, 'SEKIZAI_IGNORE_VALIDATION', False):
        return True
    found = get_namespaces(template)
    for namespace in namespaces:
        if namespace not in found:
            return False
    return True


def get_varname():
    return getattr(settings, 'SEKIZAI_VARNAME', 'SEKIZAI_CONTENT_HOLDER')


class Watcher(object):
    """
    Watches a context for changes to the sekizai data, so it can be replayed
    later. This is useful for caching.

    NOTE: This class assumes you ONLY ADD, NEVER REMOVE data from the context!
    """
    def __init__(self, context):
        self.context = context
        self.frozen = dict(
            (key, list(value)) for key, value in self.data.items()
        )

    @property
    def data(self):
        return self.context.get(get_varname(), {})

    def get_changes(self):
        sfrozen = set(self.frozen)
        sdata = set(self.data)
        new_keys = sfrozen ^ sdata
        changes = {}
        for key in new_keys:
            changes[key] = list(self.data[key])
        shared_keys = sfrozen & sdata
        for key in shared_keys:
            old_set = set(self.frozen[key])
            new_values = [
                item for item in self.data[key] if item not in old_set
            ]
            changes[key] = new_values
        return changes