Browse Source

More pylint

pull/8/head
Florian Mounier 13 years ago
parent
commit
e61551e4f4
  1. 6
      .pylintrc
  2. 12
      pygal/graph/base.py
  3. 28
      pygal/svg.py
  4. 35
      pygal/util.py
  5. 1
      pygal/view.py

6
.pylintrc

@ -33,7 +33,7 @@ load-plugins=
# can either give multiple identifier separated by comma (,) or put this option # can either give multiple identifier separated by comma (,) or put this option
# multiple time (only on the command line, not in the configuration file where # multiple time (only on the command line, not in the configuration file where
# it should appear only once). # it should appear only once).
disable=W0142 disable=I0011,W0142,C0102
[REPORTS] [REPORTS]
@ -133,7 +133,7 @@ module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$
const-rgx=(([A-Za-z_][A-Za-z0-9_]*)|(__.*__))$ const-rgx=(([A-Za-z_][A-Za-z0-9_]*)|(__.*__))$
# Regular expression which should only match correct class names # Regular expression which should only match correct class names
class-rgx=[A-Z_][a-zA-Z0-9]+$ class-rgx=[a-zA-Z_][a-zA-Z0-9]+$
# Regular expression which should only match correct function names # Regular expression which should only match correct function names
function-rgx=[a-z_][a-z0-9_]{2,30}$ function-rgx=[a-z_][a-z0-9_]{2,30}$
@ -148,7 +148,7 @@ attr-rgx=[a-z_][a-z0-9_]{0,30}$
argument-rgx=[a-z_][a-z0-9_]{0,30}$ argument-rgx=[a-z_][a-z0-9_]{0,30}$
# Regular expression which should only match correct variable names # Regular expression which should only match correct variable names
variable-rgx=[a-z_][a-z0-9_]{0,30}$ variable-rgx=[A-Za-z_][a-z0-9_]{0,30}$
# Regular expression which should only match correct list comprehension / # Regular expression which should only match correct list comprehension /
# generator expression variable names # generator expression variable names

12
pygal/graph/base.py

@ -42,8 +42,8 @@ class BaseGraph(object):
"""Add a serie to this graph""" """Add a serie to this graph"""
self.series.append(Serie(title, values, len(self.series))) self.series.append(Serie(title, values, len(self.series)))
def _init(self): def reinit(self):
"""Init the graph""" """(Re-)Init the graph"""
self.margin = Margin(*([20] * 4)) self.margin = Margin(*([20] * 4))
self._box = Box() self._box = Box()
@ -191,13 +191,13 @@ class BaseGraph(object):
def _render(self): def _render(self):
"""Make the graph internally""" """Make the graph internally"""
self._init() self.reinit()
self.svg._init() self.svg.reinit()
if self._has_data(): if self._has_data():
self._draw() self._draw()
self.svg._pre_render(False) self.svg.pre_render(False)
else: else:
self.svg._pre_render(True) self.svg.pre_render(True)
def render(self, is_unicode=False): def render(self, is_unicode=False):
"""Render the graph, and return the svg string""" """Render the graph, and return the svg string"""

28
pygal/svg.py

@ -16,11 +16,16 @@
# #
# You should have received a copy of the GNU Lesser General Public License # You should have received a copy of the GNU Lesser General Public License
# along with pygal. If not, see <http://www.gnu.org/licenses/>. # along with pygal. If not, see <http://www.gnu.org/licenses/>.
"""
Svg helper
"""
from __future__ import division from __future__ import division
import io import io
import os import os
from lxml import etree from lxml import etree
from pygal.util import template from pygal.util import template, coord_format
from pygal import __version__ from pygal import __version__
@ -30,8 +35,11 @@ class Svg(object):
def __init__(self, graph): def __init__(self, graph):
self.graph = graph self.graph = graph
self.root = None
self.defs = None
def _init(self): def reinit(self):
"""(Re-)initialization"""
self.root = etree.Element( self.root = etree.Element(
"{%s}svg" % self.ns, "{%s}svg" % self.ns,
nsmap={ nsmap={
@ -45,6 +53,7 @@ class Svg(object):
self.defs = self.node(tag='defs') self.defs = self.node(tag='defs')
def add_style(self, css): def add_style(self, css):
"""Add the css to the svg"""
style = self.node(self.defs, 'style', type='text/css') style = self.node(self.defs, 'style', type='text/css')
with io.open(css, encoding='utf-8') as f: with io.open(css, encoding='utf-8') as f:
templ = template( templ = template(
@ -55,6 +64,7 @@ class Svg(object):
style.text = templ style.text = templ
def add_script(self, js): def add_script(self, js):
"""Add the js to the svg"""
script = self.node(self.defs, 'script', type='text/javascript') script = self.node(self.defs, 'script', type='text/javascript')
with io.open(js, encoding='utf-8') as f: with io.open(js, encoding='utf-8') as f:
templ = template( templ = template(
@ -65,6 +75,7 @@ class Svg(object):
script.text = templ script.text = templ
def node(self, parent=None, tag='g', attrib=None, **extras): def node(self, parent=None, tag='g', attrib=None, **extras):
"""Make a new svg node"""
if parent is None: if parent is None:
parent = self.root parent = self.root
attrib = attrib or {} attrib = attrib or {}
@ -80,6 +91,7 @@ class Svg(object):
return etree.SubElement(parent, tag, attrib) return etree.SubElement(parent, tag, attrib)
def transposable_node(self, parent=None, tag='g', attrib=None, **extras): def transposable_node(self, parent=None, tag='g', attrib=None, **extras):
"""Make a new svg node which can be transposed if horizontal"""
if self.graph._horizontal: if self.graph._horizontal:
for key1, key2 in (('x', 'y'), ('width', 'height')): for key1, key2 in (('x', 'y'), ('width', 'height')):
attr1 = extras.get(key1, None) attr1 = extras.get(key1, None)
@ -87,24 +99,23 @@ class Svg(object):
extras[key1], extras[key2] = attr2, attr1 extras[key1], extras[key2] = attr2, attr1
return self.node(parent, tag, attrib, **extras) return self.node(parent, tag, attrib, **extras)
def format(self, xy):
return '%f %f' % xy
def line(self, node, coords, close=False, **kwargs): def line(self, node, coords, close=False, **kwargs):
"""Draw a svg line"""
if len(coords) < 2: if len(coords) < 2:
return return
root = 'M%s L%s Z' if close else 'M%s L%s' root = 'M%s L%s Z' if close else 'M%s L%s'
origin_index = 0 origin_index = 0
while None in coords[origin_index]: while None in coords[origin_index]:
origin_index += 1 origin_index += 1
origin = self.format(coords[origin_index]) origin = coord_format(coords[origin_index])
line = ' '.join([self.format(c) line = ' '.join([coord_format(c)
for c in coords[origin_index + 1:] for c in coords[origin_index + 1:]
if None not in c]) if None not in c])
self.node(node, 'path', self.node(node, 'path',
d=root % (origin, line), **kwargs) d=root % (origin, line), **kwargs)
def _pre_render(self, no_data=False): def pre_render(self, no_data=False):
"""Last things to do before rendering"""
self.add_style(self.graph.base_css or os.path.join( self.add_style(self.graph.base_css or os.path.join(
os.path.dirname(__file__), 'css', 'graph.css')) os.path.dirname(__file__), 'css', 'graph.css'))
self.add_script(self.graph.base_js or os.path.join( self.add_script(self.graph.base_js or os.path.join(
@ -122,6 +133,7 @@ class Svg(object):
no_data.text = self.graph.no_data_text no_data.text = self.graph.no_data_text
def render(self, is_unicode=False): def render(self, is_unicode=False):
"""Last thing to do before rendering"""
svg = etree.tostring( svg = etree.tostring(
self.root, pretty_print=True, self.root, pretty_print=True,
xml_declaration=not self.graph.disable_xml_declaration, xml_declaration=not self.graph.disable_xml_declaration,

35
pygal/util.py

@ -16,6 +16,11 @@
# #
# You should have received a copy of the GNU Lesser General Public License # You should have received a copy of the GNU Lesser General Public License
# along with pygal. If not, see <http://www.gnu.org/licenses/>. # along with pygal. If not, see <http://www.gnu.org/licenses/>.
"""
Various utils
"""
from __future__ import division from __future__ import division
from decimal import Decimal from decimal import Decimal
from math import floor, pi, log, log10 from math import floor, pi, log, log10
@ -23,10 +28,12 @@ ORDERS = u"yzafpnµm kMGTPEZY"
def float_format(number): def float_format(number):
"""Format a float to a precision of 3, without zeroes or dots"""
return ("%.3f" % number).rstrip('0').rstrip('.') return ("%.3f" % number).rstrip('0').rstrip('.')
def humanize(number): def humanize(number):
"""Format a number to engineer scale"""
order = number and int(floor(log(abs(number)) / log(1000))) order = number and int(floor(log(abs(number)) / log(1000)))
human_readable = ORDERS.split(" ")[int(order > 0)] human_readable = ORDERS.split(" ")[int(order > 0)]
if order == 0 or order > len(human_readable): if order == 0 or order > len(human_readable):
@ -42,37 +49,43 @@ def is_major(number):
def round_to_int(number, precision): def round_to_int(number, precision):
"""Round a number to a precision"""
precision = int(precision) precision = int(precision)
rounded = (int(number) + precision / 2) // precision * precision rounded = (int(number) + precision / 2) // precision * precision
return rounded return rounded
def round_to_float(number, precision): def round_to_float(number, precision):
"""Round a float to a precision"""
rounded = Decimal(str(floor((number + precision / 2) // precision)) rounded = Decimal(str(floor((number + precision / 2) // precision))
) * Decimal(str(precision)) ) * Decimal(str(precision))
return float(rounded) return float(rounded)
def round_to_scale(number, precision): def round_to_scale(number, precision):
"""Round a number or a float to a precision"""
if precision < 1: if precision < 1:
return round_to_float(number, precision) return round_to_float(number, precision)
return round_to_int(number, precision) return round_to_int(number, precision)
def cut(list_, index=0): def cut(list_, index=0):
"""Cut a list by index or arg"""
if isinstance(index, int): if isinstance(index, int):
cut = lambda x: x[index] cut_ = lambda x: x[index]
else: else:
cut = lambda x: getattr(x, index) cut_ = lambda x: getattr(x, index)
return map(cut, list_) return map(cut_, list_)
def rad(deg): def rad(degrees):
return pi * deg / 180 """Convert degrees in radiants"""
return pi * degrees / 180
def deg(deg): def deg(radiants):
return 180 * deg / pi """Convert radiants in degrees"""
return 180 * radiants / pi
def _swap_curly(string): def _swap_curly(string):
@ -92,19 +105,25 @@ def template(string, **kwargs):
"""Format a string using double braces""" """Format a string using double braces"""
return _swap_curly(string).format(**kwargs) return _swap_curly(string).format(**kwargs)
def coord_format(xy):
"""Format x y coords to svg"""
return '%f %f' % xy
swap = lambda tuple_: tuple(reversed(tuple_)) swap = lambda tuple_: tuple(reversed(tuple_))
ident = lambda x: x ident = lambda x: x
# Stolen from brownie http://packages.python.org/Brownie/ # Stolen from brownie http://packages.python.org/Brownie/
class cached_property(object): class cached_property(object):
"""Optimize a static property"""
def __init__(self, getter, doc=None): def __init__(self, getter, doc=None):
self.getter = getter self.getter = getter
self.__module__ = getter.__module__ self.__module__ = getter.__module__
self.__name__ = getter.__name__ self.__name__ = getter.__name__
self.__doc__ = doc or getter.__doc__ self.__doc__ = doc or getter.__doc__
def __get__(self, obj, type=None): def __get__(self, obj, type_=None):
if obj is None: if obj is None:
return self return self
value = obj.__dict__[self.__name__] = self.getter(obj) value = obj.__dict__[self.__name__] = self.getter(obj)

1
pygal/view.py

@ -136,6 +136,7 @@ class LogView(View):
self.log10_ymin = log10(self.box.ymin) self.log10_ymin = log10(self.box.ymin)
self.box.fix(False) self.box.fix(False)
# pylint: enable-msg=W0231
def y(self, y): def y(self, y):
"""Project y""" """Project y"""
if y == None or y <= 0: if y == None or y <= 0:

Loading…
Cancel
Save