Brought CustomConfig.py into more proper shape

- Multi-line documentation for functions and methods
   now has ending triple-double-quotes on an own line,
   as per PEP 257.

 - Added documentation and comments to almost all functions
   and methods.

 - Added stub implementations for getconfig() and getsection()
   inside CustomConfig.ConfigHelperMixin to provide sane
   run-time diagnostics for classes that doesn't implement them.

Signed-off-by: Eygene Ryabinkin <rea@codelabs.ru>
This commit is contained in:
Eygene Ryabinkin 2014-10-05 11:49:08 +04:00
parent 0a569bea3d
commit a1bf8db517
3 changed files with 110 additions and 22 deletions

View File

@ -24,26 +24,46 @@ import re
class CustomConfigParser(SafeConfigParser): class CustomConfigParser(SafeConfigParser):
def getdefault(self, section, option, default, *args, **kwargs): def getdefault(self, section, option, default, *args, **kwargs):
"""Same as config.get, but returns the "default" option if there """
is no such option specified.""" Same as config.get, but returns the value of `default`
if there is no such option specified.
"""
if self.has_option(section, option): if self.has_option(section, option):
return self.get(*(section, option) + args, **kwargs) return self.get(*(section, option) + args, **kwargs)
else: else:
return default return default
def getdefaultint(self, section, option, default, *args, **kwargs): def getdefaultint(self, section, option, default, *args, **kwargs):
"""
Same as config.getint, but returns the value of `default`
if there is no such option specified.
"""
if self.has_option(section, option): if self.has_option(section, option):
return self.getint (*(section, option) + args, **kwargs) return self.getint (*(section, option) + args, **kwargs)
else: else:
return default return default
def getdefaultfloat(self, section, option, default, *args, **kwargs): def getdefaultfloat(self, section, option, default, *args, **kwargs):
"""
Same as config.getfloat, but returns the value of `default`
if there is no such option specified.
"""
if self.has_option(section, option): if self.has_option(section, option):
return self.getfloat(*(section, option) + args, **kwargs) return self.getfloat(*(section, option) + args, **kwargs)
else: else:
return default return default
def getdefaultboolean(self, section, option, default, *args, **kwargs): def getdefaultboolean(self, section, option, default, *args, **kwargs):
"""
Same as config.getboolean, but returns the value of `default`
if there is no such option specified.
"""
if self.has_option(section, option): if self.has_option(section, option):
return self.getboolean(*(section, option) + args, **kwargs) return self.getboolean(*(section, option) + args, **kwargs)
else: else:
@ -63,6 +83,11 @@ class CustomConfigParser(SafeConfigParser):
(separator_re, e)) (separator_re, e))
def getdefaultlist(self, section, option, default, separator_re): def getdefaultlist(self, section, option, default, separator_re):
"""
Same as getlist, but returns the value of `default`
if there is no such option specified.
"""
if self.has_option(section, option): if self.has_option(section, option):
return self.getlist(*(section, option, separator_re)) return self.getlist(*(section, option, separator_re))
else: else:
@ -82,43 +107,78 @@ class CustomConfigParser(SafeConfigParser):
return LocalEval(path) return LocalEval(path)
def getsectionlist(self, key): def getsectionlist(self, key):
"""Returns a list of sections that start with key + " ". That is, """
if key is "Account", returns all section names that start with Returns a list of sections that start with key + " ".
"Account ", but strips off the "Account ". For instance, for
"Account Test", returns "Test"."""
That is, if key is "Account", returns all section names that
start with "Account ", but strips off the "Account ".
For instance, for "Account Test", returns "Test".
"""
key = key + ' ' key = key + ' '
return [x[len(key):] for x in self.sections() \ return [x[len(key):] for x in self.sections() \
if x.startswith(key)] if x.startswith(key)]
def set_if_not_exists(self, section, option, value): def set_if_not_exists(self, section, option, value):
"""Set a value if it does not exist yet """
Set a value if it does not exist yet
This allows to set default if the user has not explicitly This allows to set default if the user has not explicitly
configured anything.""" configured anything.
"""
if not self.has_option(section, option): if not self.has_option(section, option):
self.set(section, option, value) self.set(section, option, value)
def CustomConfigDefault(): def CustomConfigDefault():
"""Just a constant that won't occur anywhere else. """
Just a constant that won't occur anywhere else.
This allows us to differentiate if the user has passed in any This allows us to differentiate if the user has passed in any
default value to the getconf* functions in ConfigHelperMixin default value to the getconf* functions in ConfigHelperMixin
derived classes.""" derived classes.
"""
pass pass
class ConfigHelperMixin:
"""Allow comfortable retrieving of config values pertaining to a section.
If a class inherits from this cls:`ConfigHelperMixin`, it needs
to provide 2 functions: meth:`getconfig` (returning a class ConfigHelperMixin:
ConfigParser object) and meth:`getsection` (returning a string """
which represents the section to look up). All calls to getconf* Allow comfortable retrieving of config values pertaining
will then return the configuration values for the ConfigParser to a section.
object in the specific section."""
If a class inherits from cls:`ConfigHelperMixin`, it needs
to provide 2 functions:
- meth:`getconfig` (returning a CustomConfigParser object)
- and meth:`getsection` (returning a string which represents
the section to look up).
All calls to getconf* will then return the configuration values
for the CustomConfigParser object in the specific section.
"""
def _confighelper_runner(self, option, default, defaultfunc, mainfunc, *args): def _confighelper_runner(self, option, default, defaultfunc, mainfunc, *args):
"""Return config value for getsection()""" """
Return configuration or default value for option
that contains in section identified by getsection().
Arguments:
- option: name of the option to retrieve;
- default: governs which function we will call.
* When CustomConfigDefault is passed, we will call
the mainfunc.
* When any other value is passed, we will call
the defaultfunc and the value of `default` will
be passed as the third argument to this function.
- defaultfunc and mainfunc: processing helpers.
- args: additional trailing arguments that will be passed
to all processing helpers.
"""
lst = [self.getsection(), option] lst = [self.getsection(), option]
if default == CustomConfigDefault: if default == CustomConfigDefault:
return mainfunc(*(lst + list(args))) return mainfunc(*(lst + list(args)))
@ -127,8 +187,32 @@ class ConfigHelperMixin:
return defaultfunc(*(lst + list(args))) return defaultfunc(*(lst + list(args)))
def getconf(self, option, def getconfig(self):
default = CustomConfigDefault): """
Returns CustomConfigParser object that we will use
for all our actions.
Must be overriden in all classes that use this mix-in.
"""
raise NotImplementedError("ConfigHelperMixin.getconfig() "
"is to be overriden")
def getsection(self):
"""
Returns name of configuration section in which our
class keeps its configuration.
Must be overriden in all classes that use this mix-in.
"""
raise NotImplementedError("ConfigHelperMixin.getsection() "
"is to be overriden")
def getconf(self, option, default = CustomConfigDefault):
return self._confighelper_runner(option, default, return self._confighelper_runner(option, default,
self.getconfig().getdefault, self.getconfig().getdefault,
self.getconfig().get) self.getconfig().get)

View File

@ -78,6 +78,7 @@ class Account(CustomConfig.ConfigHelperMixin):
def getlocaleval(self): def getlocaleval(self):
return self.localeval return self.localeval
# Interface from CustomConfig.ConfigHelperMixin
def getconfig(self): def getconfig(self):
return self.config return self.config
@ -90,6 +91,7 @@ class Account(CustomConfig.ConfigHelperMixin):
def getaccountmeta(self): def getaccountmeta(self):
return os.path.join(self.metadatadir, 'Account-' + self.name) return os.path.join(self.metadatadir, 'Account-' + self.name)
# Interface from CustomConfig.ConfigHelperMixin
def getsection(self): def getsection(self):
return 'Account ' + self.getname() return 'Account ' + self.getname()

View File

@ -103,9 +103,11 @@ class BaseRepository(CustomConfig.ConfigHelperMixin, object):
def getmapdir(self): def getmapdir(self):
return self.mapdir return self.mapdir
# Interface from CustomConfig.ConfigHelperMixin
def getsection(self): def getsection(self):
return 'Repository ' + self.name return 'Repository ' + self.name
# Interface from CustomConfig.ConfigHelperMixin
def getconfig(self): def getconfig(self):
return self.config return self.config