/usr/lib/python3/dist-packages/pyutilib/component/config/configuration.py is in python3-pyutilib 5.3.5-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 | # _________________________________________________________________________
#
# PyUtilib: A Python utility library.
# Copyright (c) 2008 Sandia Corporation.
# This software is distributed under the BSD License.
# Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
# the U.S. Government retains certain rights in this software.
# _________________________________________________________________________
"""
This package defines the Configuration class, which provides a generic interface for reading/writing configuration files. This class uses a simple
model for configuration data:
section -> option -> value
A key role of this class is to support initialization of Option objects.
"""
from pyutilib.component.core import *
from pyutilib.component.config.options import *
import os.path
class ConfigurationError(PluginError):
"""Exception raised when a value in the configuration file is not valid."""
class IConfiguration(Interface):
"""Define an interface for classes that are used by Configuration to
read/write configuration data."""
def load(self, filename):
"""Returns a list of tuples: [ (section,option,value) ]"""
def save(self, filename, config):
"""Save configuration information to the specified file."""
class Configuration(Plugin):
"""This class manages configuration data. Further, this configuration
I/O is coordinated with Option objects. When configuration data is read
in, associated Option plugins are populated. Similarly, when
configuration data is writen, the configuration data is taken from
Option data."""
def __init__(self, filename=None, parser="ConfigParser"):
"""Constructor.
@param filename - The associated configuration file.
@param parser - Specify the name of the parser used to
read/write configuration files.
"""
self.parser_type = "Configuration_ConfigParser"
self.filename = filename
#
# Define extension points
#
self.parsers = ExtensionPoint(IConfiguration)
self.option_plugins = ExtensionPoint(IOption)
self.option_data_plugin = ExtensionPoint(IOptionDataProvider)
self.pathoption_plugins = ExtensionPoint(IFileOption)
self.postconfig_actions = ExtensionPoint(IUpdatedOptionsAction)
self.clear()
def clear(self):
"""Clear local data."""
self.config = []
self.data = {}
self.section = []
def __contains__(self, name):
"""Return whether the configuration contains a section of the given
name.
"""
return name in self.data
def __getitem__(self, name):
"""Return the configuration section with the specified name."""
if name not in self.data:
raise ConfigurationError("No section "+name+" in data")
return self.data[name]
def sections(self):
"""Returns the names of all sections in the configuration data."""
return list(self.data.keys())
def load(self, filename=None):
"""Load configuration from a file."""
if len(self.parsers) == 0: #pragma:nocover
raise ConfigurationError("No IConfiguration parsers are registered")
if not filename is None:
self.filename = filename
if self.filename is None:
raise ConfigurationError("Cannot load without a filename")
for option in self.pathoption_plugins:
option.set_dir(os.path.dirname(self.filename))
#
# By default, we simply take the first parser
#
self.config = self.parsers.service(self.parser_type).load(self.filename)
self.data = {}
self.section = []
for (s,o,v) in self.config:
if not s in self.data:
self.section.append(s)
self.data[s] = {}
if not o in self.data[s]:
self.data[s][o] = []
self.data[s][o].append(v)
#
# Iterate through all sections, in the order they were
# loaded. Load data for extensions that match each section name.
#
for sec in self.section:
#
# Find the option_plugins that match this section
#
plugins = []
for plugin in self.option_plugins:
if plugin.matches_section(sec):
plugins.append(plugin)
for option in self.data[sec]:
flag = False
for plugin in plugins:
if plugin.matches_name(option):
flag = plugin.load(option, self.data[sec][option]) or flag
if not flag:
raise ConfigurationError("Problem loading file %r. Option %r in section %r is not recognized!" % (self.filename, option,sec))
#
# Finalize the configuration process
#
for plugin in self.postconfig_actions:
plugin.reset_after_updates()
def save(self, filename=None):
"""Save configuration to a file."""
if not filename is None:
self.filename = filename
if self.filename is None:
raise ConfigurationError("Cannot save without a filename")
#
# Setup the list of tuples
#
self.clear()
self.data = self.option_data_plugin.service().get_data()
self.section = list(self.data.keys())
self.section.sort()
flag=False
header = "\nNote: the following configuration options have been omitted because their\nvalue is 'None':\n"
for sec in self.section:
plugins = []
for plugin in self.option_plugins:
if plugin.matches_section(sec):
plugins.append(plugin)
#
options = list(self.data[sec].keys())
options.sort()
for option in options:
for plugin in plugins:
if plugin.matches_name(option):
if not self.data[sec][option] is None:
val = self.data[sec][option]
self.config.append( (sec,option,val) )
else:
flag=True
header = header + " section=%r option=%r\n" % (sec,option)
break
if flag:
header = header + "\n"
else:
header = None
#
# Write config file
#
self.parsers.service(self.parser_type).save(self.filename, self.config, header)
def pprint(self):
"""Print a simple summary of the configuration data."""
text = ""
for (s,o,v) in self.config:
text += "[%s] %s = %s\n" % (s,o,v)
print(text)
def summarize(self):
"""Summarize options"""
tmp = {}
for option in self.option_plugins:
tmp.setdefault(option.section, {})[option.name] = option
keys = list(tmp.keys())
keys.sort()
for key in keys:
print("["+key+"]")
print("")
okeys = list(tmp[key].keys())
okeys.sort()
for okey in okeys:
print(" Option: "+tmp[key][okey].name)
print(" Type: "+tmp[key][okey].__class__.__name__)
print(" Default: "+tmp[key][okey].default_str())
print(" Doc: "+tmp[key][okey].__doc__)
print("")
print("")
|