Package mvpa :: Package base :: Module config

[hide private]
[frames] | no frames]

# Source Code for Module mvpa.base.config

      1  # emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*-
      2  # vi: set ft=python sts=4 ts=4 sw=4 et:
      3  ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ##
      4  #
      5  #   See COPYING file distributed along with the PyMVPA package for the
      6  #   copyright and license terms.
      7  #
      8  ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ##
      9  """Registry-like monster"""
     10
     11  __docformat__ = 'restructuredtext'
     12
     13  from ConfigParser import SafeConfigParser
     14  import os.path
     15
     16
     17 -class ConfigManager(SafeConfigParser):
     18      """Central configuration registry for PyMVPA.
     19
     20      The purpose of this class is to collect all configurable settings used by
     21      various parts of PyMVPA. It is fairly simple and does only little more
     22      than the standard Python ConfigParser. Like ConfigParser it is blind to the
     23      data that it stores, i.e. not type checking is performed.
     24
     25      Configuration files (INI syntax) in multiple location are passed when the
     26      class is instanciated or whenever `Config.reload()` is called later on.
     27      By default it looks for a config file named `pymvpa.cfg` in the current
     28      directory and `.pymvpa.cfg` in the user's home directory. Morever, the
     29      constructor takes an optional argument with a list of additional file names
     30      to parse.
     31
     32      In addition to configuration files, this class also looks for special
     33      environment variables to read settings from. Names of such variables have to
     34      start with `MVPA_` following by the an optional section name and the
     35      variable name itself ('_' as delimiter). If no section name is provided,
     36      the variables will be associated with section `general`. Some examples::
     37
     38          MVPA_VERBOSE=1
     39
     40      will become::
     41
     42          [general]
     43          verbose = 1
     44
     45      However, `MVPA_VERBOSE_OUTPUT=stdout` becomes::
     46
     47          [verbose]
     48          output = stdout
     49
     50      Any lenght of variable name as allowed, e.g. MVPA_SEC1_LONG_VARIABLE_NAME=1
     51      becomes::
     52
     53          [sec1]
     54          long variable name = 1
     55
     56      Settings from custom configuration files (specified by the constructor
     57      argument) have the highest priority and override settings found in the
     58      current directory. They in turn override user-specific settings and finally
     59      the content of any `MVPA_*` environment variables overrides all settings
     60      read from any file.
     61      """
     62
     63      # things we want to count on to be available
     64      _DEFAULTS = {'general':
     65                    {
     66                      'verbose': '1',
     67                    }
     68                  }
     69
     70
     71 -    def __init__(self, filenames=None):
     72          """Initialization reads settings from config files and env. variables.
     73
     74          :Parameters:
     75            filenames: list of filenames
     76          """
     77          SafeConfigParser.__init__(self)
     78
     79          # store additional config file names
     80          if not filenames is None:
     81              self.__cfg_filenames = filenames
     82          else:
     83              self.__cfg_filenames = []
     84
     85          # set critical defaults
     86          for sec, vars in ConfigManager._DEFAULTS.iteritems():
     87              self.add_section(sec)
     88              for key, value in vars.iteritems():
     89                  self.set(sec, key, value)
     90
     91          # now get the setting
     92          self.reload()
     93
     94
     95 -    def reload(self):
     96          """Re-read settings from all configured locations.
     97          """
     98          # listof filenames to parse (custom plus some standard ones)
     99          filenames = self.__cfg_filenames \
    100                      + ['pymvpa.cfg',
    101                         os.path.join(os.path.expanduser('~'), '.pymvpa.cfg')]
    102
    103          # read local and user-specific config
    104          files = self.read(filenames)
    105
    106          # no look for variables in the environment
    107          for var in [v for v in os.environ.keys() if v.startswith('MVPA_')]:
    108              # strip leading 'MVPA_' and lower case entries
    109              svar = var[5:].lower()
    110
    111              # section is next element in name (or 'general' if simple name)
    112              if not svar.count('_'):
    113                  sec = 'general'
    114              else:
    115                  cut = svar.find('_')
    116                  sec = svar[:cut]
    117                  svar = svar[cut + 1:].replace('_', ' ')
    118
    119              # check if section is already known and add it if not
    120              if not self.has_section(sec):
    121                  self.add_section(sec)
    122
    123              # set value
    124              self.set(sec, svar, os.environ[var])
    125
    126
    127 -    def __repr__(self):
    128          """Generate INI file content with current configuration.
    129          """
    130          # make adaptor to use str as file-like (needed for ConfigParser.write()
    131          class file2str(object):
    132              def __init__(self):
    133                  self.__s = ''
    134              def write(self, val):
    135                  self.__s += val
    136              def str(self):
    137                  return self.__s
    138
    139          r = file2str()
    140          self.write(r)
    141
    142          return r.str()
    143
    144
    145 -    def save(self, filename):
    146          """Write current configuration to a file.
    147          """
    148          f = open(filename, 'w')
    149          self.write(f)
    150          f.close()
    151
    152
    153 -    def get(self, section, option, default=None, **kwargs):
    154          """Wrapper around SafeConfigParser.get() with a custom default value.
    155
    156          This method simply wraps the base class method, but adds a `default`
    157          keyword argument. The value of `default` is returned whenever the
    158          config parser does not have the requested option and/or section.
    159          """
    160          if not self.has_option(section, option):
    161              return default
    162
    163          return SafeConfigParser.get(self, section, option, **kwargs)
    164
    165
    166 -    def getboolean(self, section, option, default=None):
    167          """Wrapper around SafeConfigParser.getboolean() with a custom default.
    168
    169          This method simply wraps the base class method, but adds a `default`
    170          keyword argument. The value of `default` is returned whenever the
    171          config parser does not have the requested option and/or section.
    172          """
    173          if not self.has_option(section, option):
    174              if isinstance(default, bool):
    175                  return default
    176              else:
    177                  if default.lower() not in self._boolean_states:
    178                      raise ValueError, 'Not a boolean: %s' % default
    179                  return self._boolean_states[default.lower()]
    180
    181          return SafeConfigParser.getboolean(self, section, option)
    182
    183
    184 -    def getAsDType(self, section, option, dtype, default=None):
    185          """Convenience method to query options with a custom default and type
    186
    187          This method simply wraps the base class method, but adds a `default`
    188          keyword argument. The value of `default` is returned whenever the
    189          config parser does not have the requested option and/or section.
    190
    191          In addition, the returned value is converted into the specified `dtype`.
    192          """
    193          if not self.has_option(section, option):
    194              return default
    195
    196          return SafeConfigParser._get(self, section, dtype, option)
    197