Browse Source

Add some docstring and repr the config key with their doc

pull/242/head
Florian Mounier 9 years ago
parent
commit
37697fe0e5
  1. 15
      pygal/__init__.py
  2. 20
      pygal/colors.py
  3. 46
      pygal/config.py

15
pygal/__init__.py

@ -17,7 +17,10 @@
# You should have received a copy of the GNU Lesser General Public License
# along with pygal. If not, see <http://www.gnu.org/licenses/>.
"""
Pygal - A python svg graph plotting library
Main pygal package
This package holds all available charts in pygal, the Config class
and the maps extensions namespace module.
"""
@ -73,16 +76,26 @@ CHARTS = list(CHARTS_BY_NAME.values())
class PluginImportFixer(object):
"""Allow external map plugins to be imported from pygal.maps package.
It is a ``sys.meta_path`` loader.
"""
def __init__(self):
pass
def find_module(self, fullname, path=None):
"""This method says if the module to load can be loaded by
the load_module function, that is here if it is a ``pygal.maps.*``
module.
"""
if fullname.startswith('pygal.maps.') and hasattr(
maps, fullname.split('.')[2]):
return self
return None
def load_module(self, name):
"""Loads the ``pygal.maps.name`` module from
the previously loaded plugin"""
if name not in sys.modules:
sys.modules[name] = getattr(maps, name.split('.')[2])
return sys.modules[name]

20
pygal/colors.py

@ -17,19 +17,23 @@
# You should have received a copy of the GNU Lesser General Public License
# along with pygal. If not, see <http://www.gnu.org/licenses/>.
"""
Color utils
This package is an utility package oriented on color alteration.
This is used by the :py:mod:`pygal.style` package to generate
parametric styles.
"""
from __future__ import division
def normalize_float(f):
"""Round float errors"""
if abs(f - round(f)) < .0000000000001:
return round(f)
return f
def rgb_to_hsl(r, g, b):
"""Convert a color in r, g, b to a color in h, s, l"""
r /= 255
g /= 255
b /= 255
@ -57,6 +61,7 @@ def rgb_to_hsl(r, g, b):
def hsl_to_rgb(h, s, l):
"""Convert a color in h, s, l to a color in r, g, b"""
h /= 360
s /= 100
l /= 100
@ -80,6 +85,10 @@ def hsl_to_rgb(h, s, l):
def parse_color(color):
"""Take any css color definition and give back a tuple containing the
r, g, b, a values along with a type which can be: #rgb, #rgba, #rrggbb,
#rrggbbaa, rgb, rgba
"""
r = g = b = a = type = None
if color.startswith('#'):
color = color[1:]
@ -110,6 +119,9 @@ def parse_color(color):
def unparse_color(r, g, b, a, type):
"""Take the r, g, b, a color values and give back
a type css color string. This is the inverse function of parse_color"""
if type == '#rgb':
# Don't lose precision on rgb shortcut
if r % 17 == 0 and g % 17 == 0 and b % 17 == 0:
@ -148,26 +160,32 @@ def _adjust(hsl, attribute, percent):
def adjust(color, attribute, percent):
"""Adjust an attribute of color by a percent"""
r, g, b, a, type = parse_color(color)
r, g, b = hsl_to_rgb(*_adjust(rgb_to_hsl(r, g, b), attribute, percent))
return unparse_color(r, g, b, a, type)
def rotate(color, percent):
"""Rotates a color by changing its hue value by percent"""
return adjust(color, 0, percent)
def saturate(color, percent):
"""Saturate a color by increasing its saturation by percent"""
return adjust(color, 1, percent)
def desaturate(color, percent):
"""Desaturate a color by decreasing its saturation by percent"""
return adjust(color, 1, -percent)
def lighten(color, percent):
"""Lighten a color by increasing its lightness by percent"""
return adjust(color, 2, percent)
def darken(color, percent):
"""Darken a color by decreasing its lightness by percent"""
return adjust(color, 2, -percent)

46
pygal/config.py

@ -18,7 +18,7 @@
# along with pygal. If not, see <http://www.gnu.org/licenses/>.
"""
Config module with all options
Config module holding all options and their default values.
"""
from copy import deepcopy
from pygal.style import Style, DefaultStyle
@ -29,6 +29,16 @@ CONFIG_ITEMS = []
class Key(object):
"""
Represents a config parameter.
A config parameter has a name, a default value, a type,
a category, a documentation, an optional longer documentatation
and an optional subtype for list style option.
Most of these informations are used in cabaret to auto generate
forms representing these options.
"""
_categories = []
@ -48,27 +58,46 @@ class Key(object):
CONFIG_ITEMS.append(self)
def __repr__(self):
return """
Type: %s%s     
Default: %r     
%s%s
""" % (
self.type.__name__,
(' of %s' % self.subtype.__name__) if self.subtype else '',
self.value,
self.doc,
(' %s' % self.subdoc) if self.subdoc else ''
)
@property
def is_boolean(self):
"""Return `True` if this parameter is a boolean"""
return self.type == bool
@property
def is_numeric(self):
"""Return `True` if this parameter is numeric (int or float)"""
return self.type in (int, float)
@property
def is_string(self):
"""Return `True` if this parameter is a string"""
return self.type == str
@property
def is_dict(self):
"""Return `True` if this parameter is a mapping"""
return self.type == dict
@property
def is_list(self):
"""Return `True` if this parameter is a list"""
return self.type == list
def coerce(self, value):
"""Cast a string into this key type"""
if self.type == Style:
return value
elif self.type == list:
@ -91,14 +120,24 @@ class Key(object):
class MetaConfig(type):
"""
Metaclass for configs. Used to get the key name and set it on the value.
"""
def __new__(mcs, classname, bases, classdict):
for k, v in classdict.items():
if isinstance(v, Key):
v.name = k
return type.__new__(mcs, classname, bases, classdict)
class BaseConfig(MetaConfig('ConfigBase', (object,), {})):
"""
This class holds the common method for configs.
A config object can be instanciated with keyword arguments and
updated on call with keyword arguments.
"""
def __init__(self, **kwargs):
"""Can be instanciated with config kwargs"""
@ -120,11 +159,13 @@ class BaseConfig(MetaConfig('ConfigBase', (object,), {})):
self._update(kwargs)
def _update(self, kwargs):
"""Updates the config with the given dictionary"""
self.__dict__.update(
dict([(k, v) for (k, v) in kwargs.items()
if not k.startswith('_') and k in dir(self)]))
def to_dict(self):
"""Export a JSON serializable dictionary of the config"""
config = {}
for attr in dir(self):
if not attr.startswith('__'):
@ -136,10 +177,13 @@ class BaseConfig(MetaConfig('ConfigBase', (object,), {})):
return config
def copy(self):
"""Copy this config object into another"""
return deepcopy(self)
class CommonConfig(BaseConfig):
"""Class holding options used in both chart and serie configuration"""
stroke = Key(
True, bool, "Look",
"Line dots (set it to false to get a scatter plot)")

Loading…
Cancel
Save