This file is indexed.

/usr/lib/python3/dist-packages/chameleon/codegen.py is in python3-chameleon 2.24-1.

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
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
try:
    import ast
except ImportError:
    from chameleon import ast25 as ast

import inspect
import textwrap
import types
import copy

try:
    import __builtin__ as builtins
except ImportError:
    import builtins

reverse_builtin_map = {}
for name, value in builtins.__dict__.items():
    try:
        hash(value)
    except TypeError:
        continue

    reverse_builtin_map[value] = name

try:
    basestring
except NameError:
    basestring = str

from .astutil import ASTCodeGenerator
from .astutil import load
from .astutil import store
from .astutil import parse
from .astutil import Builtin
from .astutil import Symbol
from .astutil import node_annotations

from .exc import CompilationError


try:
    NATIVE_NUMBERS = int, float, long, bool
except NameError:
    NATIVE_NUMBERS = int, float, bool


def template(function, mode='exec', **kw):
    def wrapper(*vargs, **kwargs):
        symbols = dict(zip(args, vargs + defaults))
        symbols.update(kwargs)

        class Visitor(ast.NodeVisitor):
            def visit_FunctionDef(self, node):
                self.generic_visit(node)

                name = symbols.get(node.name, self)
                if name is not self:
                    node_annotations[node] = ast.FunctionDef(
                        name=name,
                        args=node.args,
                        body=node.body,
                        decorator_list=getattr(node, "decorator_list", []),
                        )

            def visit_Name(self, node):
                value = symbols.get(node.id, self)
                if value is not self:
                    if isinstance(value, basestring):
                        value = load(value)
                    if isinstance(value, type) or value in reverse_builtin_map:
                        name = reverse_builtin_map.get(value)
                        if name is not None:
                            value = Builtin(name)
                        else:
                            value = Symbol(value)

                    assert node not in node_annotations
                    assert hasattr(value, '_fields')
                    node_annotations[node] = value

        expr = parse(source, mode=mode)
        if not isinstance(function, basestring):
            expr = expr.body[0]

        Visitor().visit(expr)
        return expr.body

    if isinstance(function, basestring):
        source = function
        defaults = args = ()
        return wrapper(**kw)

    source = textwrap.dedent(inspect.getsource(function))
    argspec = inspect.getargspec(function)
    args = argspec[0]
    defaults = argspec[3] or ()
    return wrapper


class TemplateCodeGenerator(ASTCodeGenerator):
    """Extends the standard Python code generator class with handlers
    for the helper node classes:

    - Symbol (an importable value)
    - Static (value that can be made global)
    - Builtin (from the builtins module)
    - Marker (short-hand for a unique static object)

    """

    names = ()

    def __init__(self, tree):
        self.imports = {}
        self.defines = {}
        self.markers = {}

        # Generate code
        super(TemplateCodeGenerator, self).__init__(tree)

    def visit_Module(self, node):
        super(TemplateCodeGenerator, self).visit_Module(node)

        # Make sure we terminate the line printer
        self.flush()

        # Clear lines array for import visits
        body = self.lines
        self.lines = []

        while self.defines:
            name, node = self.defines.popitem()
            assignment = ast.Assign(targets=[store(name)], value=node)
            self.visit(assignment)

        # Make sure we terminate the line printer
        self.flush()

        # Clear lines array for import visits
        defines = self.lines
        self.lines = []

        while self.imports:
            value, node = self.imports.popitem()

            if isinstance(value, types.ModuleType):
                stmt = ast.Import(
                    names=[ast.alias(name=value.__name__, asname=node.id)])
            elif hasattr(value, '__name__'):
                path = reverse_builtin_map.get(value)
                if path is None:
                    path = value.__module__
                    name = value.__name__
                stmt = ast.ImportFrom(
                    module=path,
                    names=[ast.alias(name=name, asname=node.id)],
                    level=0,
                )
            else:
                raise TypeError(value)

            self.visit(stmt)

        # Clear last import
        self.flush()

        # Stich together lines
        self.lines += defines + body

    def define(self, name, node):
        assert node is not None
        value = self.defines.get(name)

        if value is node:
            pass
        elif value is None:
            self.defines[name] = node
        else:
            raise CompilationError(
                "Duplicate symbol name for define.", name)

        return load(name)

    def require(self, value):
        if value is None:
            return load("None")

        if isinstance(value, NATIVE_NUMBERS):
            return ast.Num(value)

        node = self.imports.get(value)
        if node is None:
            # we come up with a unique symbol based on the class name
            name = "_%s" % getattr(value, '__name__', str(value)).\
                   rsplit('.', 1)[-1]
            node = load(name)
            self.imports[value] = store(node.id)

        return node

    def visit(self, node):
        annotation = node_annotations.get(node)
        if annotation is None:
            super(TemplateCodeGenerator, self).visit(node)
        else:
            self.visit(annotation)

    def visit_Comment(self, node):
        if node.stmt is None:
            self._new_line()
        else:
            self.visit(node.stmt)

        for line in node.text.replace('\r', '\n').split('\n'):
            self._new_line()
            self._write("%s#%s" % (node.space, line))

    def visit_Builtin(self, node):
        name = load(node.id)
        self.visit(name)

    def visit_Symbol(self, node):
        node = self.require(node.value)
        self.visit(node)

    def visit_Static(self, node):
        if node.name is None:
            name = "_static_%s" % str(id(node.value)).replace('-', '_')
        else:
            name = node.name

        node = self.define(name, node.value)
        self.visit(node)