This file is indexed.

/usr/lib/python3/dist-packages/pygal/graph/base.py is in python3-pygal 2.4.0-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
234
# -*- coding: utf-8 -*-
# This file is part of pygal
#
# A python svg graph plotting library
# Copyright © 2012-2016 Kozea
#
# This library is free software: you can redistribute it and/or modify it under
# the terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# This library is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
# details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with pygal. If not, see <http://www.gnu.org/licenses/>.

"""Base for pygal charts"""

from __future__ import division

import os
from functools import reduce
from uuid import uuid4

from pygal._compat import is_list_like
from pygal.adapters import decimal_to_float, not_zero, positive
from pygal.config import Config, SerieConfig
from pygal.serie import Serie
from pygal.state import State
from pygal.svg import Svg
from pygal.util import compose, ident
from pygal.view import Box, Margin


class BaseGraph(object):

    """Chart internal behaviour related functions"""

    _adapters = []

    def __init__(self, config=None, **kwargs):
        """Config preparation and various initialization"""
        if config:
            if isinstance(config, type):
                config = config()
            else:
                config = config.copy()
        else:
            config = Config()

        config(**kwargs)
        self.config = config
        self.state = None
        self.uuid = str(uuid4())
        self.raw_series = []
        self.xml_filters = []

    def __setattr__(self, name, value):
        """Set an attribute on the class or in the state if there is one"""
        if name.startswith('__') or getattr(self, 'state', None) is None:
            super(BaseGraph, self).__setattr__(name, value)
        else:
            setattr(self.state, name, value)

    def __getattribute__(self, name):
        """Get an attribute from the class or from the state if there is one"""
        if name.startswith('__') or name == 'state' or getattr(
                self, 'state', None
        ) is None or name not in self.state.__dict__:
            return super(BaseGraph, self).__getattribute__(name)
        return getattr(self.state, name)

    def prepare_values(self, raw, offset=0):
        """Prepare the values to start with sane values"""
        from pygal.graph.map import BaseMap
        from pygal import Histogram

        if self.zero == 0 and isinstance(self, BaseMap):
            self.zero = 1

        if self.x_label_rotation:
            self.x_label_rotation %= 360

        if self.y_label_rotation:
            self.y_label_rotation %= 360

        for key in ('x_labels', 'y_labels'):
            if getattr(self, key):
                setattr(self, key, list(getattr(self, key)))
        if not raw:
            return

        adapters = list(self._adapters) or [lambda x:x]
        if self.logarithmic:
            for fun in not_zero, positive:
                if fun in adapters:
                    adapters.remove(fun)
            adapters = adapters + [positive, not_zero]
        adapters = adapters + [decimal_to_float]

        self._adapt = reduce(compose, adapters) if not self.strict else ident
        self._x_adapt = reduce(
            compose, self._x_adapters) if not self.strict and getattr(
                self, '_x_adapters', None) else ident

        series = []

        raw = [(
            list(raw_values) if not isinstance(
                raw_values, dict) else raw_values,
            serie_config_kwargs
        ) for raw_values, serie_config_kwargs in raw]

        width = max([len(values) for values, _ in raw] +
                    [len(self.x_labels or [])])

        for raw_values, serie_config_kwargs in raw:
            metadata = {}
            values = []
            if isinstance(raw_values, dict):
                if isinstance(self, BaseMap):
                    raw_values = list(raw_values.items())
                else:
                    value_list = [None] * width
                    for k, v in raw_values.items():
                        if k in (self.x_labels or []):
                            value_list[self.x_labels.index(k)] = v
                    raw_values = value_list

            for index, raw_value in enumerate(
                    raw_values + (
                        (width - len(raw_values)) * [None]  # aligning values
                        if len(raw_values) < width else [])):
                if isinstance(raw_value, dict):
                    raw_value = dict(raw_value)
                    value = raw_value.pop('value', None)
                    metadata[index] = raw_value
                else:
                    value = raw_value

                # Fix this by doing this in charts class methods
                if isinstance(self, Histogram):
                    if value is None:
                        value = (None, None, None)
                    elif not is_list_like(value):
                        value = (value, self.zero, self.zero)
                    elif len(value) == 2:
                        value = (1, value[0], value[1])
                    value = list(map(self._adapt, value))
                elif self._dual:
                    if value is None:
                        value = (None, None)
                    elif not is_list_like(value):
                        value = (value, self.zero)
                    if self._x_adapt:
                        value = (
                            self._x_adapt(value[0]),
                            self._adapt(value[1]))
                    if isinstance(self, BaseMap):
                        value = (self._adapt(value[0]), value[1])
                    else:
                        value = list(map(self._adapt, value))
                else:
                    value = self._adapt(value)

                values.append(value)
            serie_config = SerieConfig()
            serie_config(**dict((k, v) for k, v in self.state.__dict__.items()
                                if k in dir(serie_config)))
            serie_config(**serie_config_kwargs)
            series.append(
                Serie(offset + len(series), values, serie_config, metadata))
        return series

    def setup(self, **kwargs):
        """Set up the transient state prior rendering"""
        # Keep labels in case of map
        if getattr(self, 'x_labels', None) is not None:
            self.x_labels = list(self.x_labels)
        if getattr(self, 'y_labels', None) is not None:
            self.y_labels = list(self.y_labels)
        self.state = State(self, **kwargs)
        if isinstance(self.style, type):
            self.style = self.style()
        self.series = self.prepare_values(
            [rs for rs in self.raw_series if not rs[1].get('secondary')]) or []
        self.secondary_series = self.prepare_values(
            [rs for rs in self.raw_series if rs[1].get('secondary')],
            len(self.series)) or []
        self.horizontal = getattr(self, 'horizontal', False)
        self.svg = Svg(self)
        self._x_labels = None
        self._y_labels = None
        self._x_2nd_labels = None
        self._y_2nd_labels = None
        self.nodes = {}
        self.margin_box = Margin(
            self.margin_top or self.margin,
            self.margin_right or self.margin,
            self.margin_bottom or self.margin,
            self.margin_left or self.margin)
        self._box = Box()
        self.view = None
        if self.logarithmic and self.zero == 0:
            # Explicit min to avoid interpolation dependency
            positive_values = list(filter(
                lambda x: x > 0,
                [val[1] or 1 if self._dual else val
                 for serie in self.series for val in serie.safe_values]))

            self.zero = min(positive_values or (1,)) or 1
        if self._len < 3:
            self.interpolate = None
        self._draw()
        self.svg.pre_render()

    def teardown(self):
        """Remove the transient state after rendering"""
        if os.getenv('PYGAL_KEEP_STATE'):
            return

        del self.state
        self.state = None

    def _repr_svg_(self):
        """Display svg in IPython notebook"""
        return self.render(disable_xml_declaration=True)

    def _repr_png_(self):
        """Display png in IPython notebook"""
        return self.render_to_png()