Merge pull request #380 from CZerta/configparser_default_delimiter
Default delimiters errors, inline comments
This commit is contained in:
commit
e1045f2d1d
10 changed files with 85 additions and 68 deletions
|
|
@ -11,7 +11,9 @@ class GlobalConfigTestCase(unittest.TestCase):
|
|||
def setUpClass(cls):
|
||||
cls.test_dir = tempfile.mkdtemp()
|
||||
with open(cls.test_dir + '/test_config','w') as f:
|
||||
f.write('test_option = hello\ntest_bool = 1\ntest_size = 12MB\n'\
|
||||
f.write('test_option = hello #this is comment\ntest_bool = 1\ntest_size = 12MB\n'\
|
||||
+ '/sys/bus/pci/devices/0000:00:02.0/power/control=auto\n'\
|
||||
+ '/sys/bus/pci/devices/0000:04:00.0/power/control=auto\n'\
|
||||
+ 'false_bool=0\n'\
|
||||
+ consts.CFG_LOG_FILE_COUNT + " = " + str(consts.CFG_DEF_LOG_FILE_COUNT) + "1\n")
|
||||
|
||||
|
|
@ -20,6 +22,7 @@ class GlobalConfigTestCase(unittest.TestCase):
|
|||
|
||||
def test_get(self):
|
||||
self.assertEqual(self._global_config.get('test_option'), 'hello')
|
||||
self.assertEqual(self._global_config.get('/sys/bus/pci/devices/0000:00:02.0/power/control'), 'auto')
|
||||
|
||||
def test_get_bool(self):
|
||||
self.assertTrue(self._global_config.get_bool('test_bool'))
|
||||
|
|
|
|||
|
|
@ -28,13 +28,7 @@ import importlib
|
|||
|
||||
import tuned.consts as consts
|
||||
import tuned.logs
|
||||
try:
|
||||
from configparser import ConfigParser, Error
|
||||
from io import StringIO
|
||||
except ImportError:
|
||||
# python2.7 support, remove RHEL-7 support end
|
||||
from ConfigParser import ConfigParser, Error
|
||||
from StringIO import StringIO
|
||||
from tuned.utils.config_parser import ConfigParser, Error
|
||||
from tuned.exceptions import TunedException
|
||||
from tuned.utils.global_config import GlobalConfig
|
||||
|
||||
|
|
@ -82,10 +76,10 @@ class GuiPluginLoader():
|
|||
"""
|
||||
|
||||
try:
|
||||
config_parser = ConfigParser()
|
||||
config_parser = ConfigParser(delimiters=('='), inline_comment_prefixes=('#'))
|
||||
config_parser.optionxform = str
|
||||
with open(file_name) as f:
|
||||
config_parser.readfp(StringIO("[" + consts.MAGIC_HEADER_NAME + "]\n" + f.read()))
|
||||
config_parser.read_string("[" + consts.MAGIC_HEADER_NAME + "]\n" + f.read(), file_name)
|
||||
config, functions = GlobalConfig.get_global_config_spec()
|
||||
for option in config_parser.options(consts.MAGIC_HEADER_NAME):
|
||||
if option in config:
|
||||
|
|
|
|||
|
|
@ -25,13 +25,7 @@ Created on Mar 13, 2014
|
|||
'''
|
||||
|
||||
import os
|
||||
try:
|
||||
from configparser import ConfigParser, Error
|
||||
from io import StringIO
|
||||
except ImportError:
|
||||
# python2.7 support, remove RHEL-7 support end
|
||||
from ConfigParser import ConfigParser, Error
|
||||
from StringIO import StringIO
|
||||
from tuned.utils.config_parser import ConfigParser, Error
|
||||
import subprocess
|
||||
import json
|
||||
import sys
|
||||
|
|
@ -68,9 +62,9 @@ class GuiProfileLoader(object):
|
|||
|
||||
if profilePath == tuned.consts.LOAD_DIRECTORIES[1]:
|
||||
file_path = profilePath + '/' + profile_name + '/' + tuned.consts.PROFILE_FILE
|
||||
config_parser = ConfigParser()
|
||||
config_parser = ConfigParser(delimiters=('='), inline_comment_prefixes=('#'))
|
||||
config_parser.optionxform = str
|
||||
config_parser.readfp(StringIO(config))
|
||||
config_parser.read_string(config)
|
||||
|
||||
config_obj = {
|
||||
'main': collections.OrderedDict(),
|
||||
|
|
@ -90,11 +84,11 @@ class GuiProfileLoader(object):
|
|||
|
||||
def load_profile_config(self, profile_name, path):
|
||||
conf_path = path + '/' + profile_name + '/' + tuned.consts.PROFILE_FILE
|
||||
config = ConfigParser()
|
||||
config = ConfigParser(delimiters=('='), inline_comment_prefixes=('#'))
|
||||
config.optionxform = str
|
||||
profile_config = collections.OrderedDict()
|
||||
with open(conf_path) as f:
|
||||
config.readfp(f)
|
||||
config.read_file(f, conf_path)
|
||||
for s in config.sections():
|
||||
profile_config[s] = collections.OrderedDict()
|
||||
for o in config.options(s):
|
||||
|
|
|
|||
|
|
@ -1,11 +1,7 @@
|
|||
import os
|
||||
import sys
|
||||
import json
|
||||
try:
|
||||
from configparser import ConfigParser
|
||||
except ImportError:
|
||||
# python2.7 support, remove RHEL-7 support end
|
||||
from ConfigParser import ConfigParser
|
||||
from tuned.utils.config_parser import ConfigParser
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
@ -15,7 +11,7 @@ if __name__ == "__main__":
|
|||
if not os.path.exists(profile_dict['filename']):
|
||||
os.makedirs(os.path.dirname(profile_dict['filename']))
|
||||
|
||||
profile_configobj = ConfigParser()
|
||||
profile_configobj = ConfigParser(delimiters=('='), inline_comment_prefixes=('#'))
|
||||
profile_configobj.optionxform = str
|
||||
for section, options in profile_dict['main'].items():
|
||||
profile_configobj.add_section(section)
|
||||
|
|
|
|||
|
|
@ -1,10 +1,6 @@
|
|||
import tuned.profiles.profile
|
||||
import tuned.profiles.variables
|
||||
try:
|
||||
from configparser import ConfigParser, Error
|
||||
except ImportError:
|
||||
# python2.7 support, remove RHEL-7 support end
|
||||
from ConfigParser import ConfigParser, Error
|
||||
from tuned.utils.config_parser import ConfigParser, Error
|
||||
import tuned.consts as consts
|
||||
import os.path
|
||||
import collections
|
||||
|
|
@ -100,10 +96,10 @@ class Loader(object):
|
|||
|
||||
def _load_config_data(self, file_name):
|
||||
try:
|
||||
config_obj = ConfigParser()
|
||||
config_obj = ConfigParser(delimiters=('='), inline_comment_prefixes=('#'))
|
||||
config_obj.optionxform=str
|
||||
with open(file_name) as f:
|
||||
config_obj.readfp(f)
|
||||
config_obj.read_file(f, file_name)
|
||||
except Error as e:
|
||||
raise InvalidProfileException("Cannot parse '%s'." % file_name, e)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +1,6 @@
|
|||
import os
|
||||
import tuned.consts as consts
|
||||
try:
|
||||
from configparser import ConfigParser, Error
|
||||
from io import StringIO
|
||||
except ImportError:
|
||||
# python2.7 support, remove RHEL-7 support end
|
||||
from ConfigParser import ConfigParser, Error
|
||||
from StringIO import StringIO
|
||||
from tuned.utils.config_parser import ConfigParser, Error
|
||||
|
||||
class Locator(object):
|
||||
"""
|
||||
|
|
@ -61,10 +55,10 @@ class Locator(object):
|
|||
if config_file is None:
|
||||
return None
|
||||
try:
|
||||
config = ConfigParser()
|
||||
config = ConfigParser(delimiters=('='), inline_comment_prefixes=('#'), allow_no_value=True)
|
||||
config.optionxform = str
|
||||
with open(config_file) as f:
|
||||
config.readfp(StringIO("[" + consts.MAGIC_HEADER_NAME + "]\n" + f.read()))
|
||||
config.read_string("[" + consts.MAGIC_HEADER_NAME + "]\n" + f.read())
|
||||
return config
|
||||
except (IOError, OSError, Error) as e:
|
||||
return None
|
||||
|
|
|
|||
|
|
@ -4,13 +4,7 @@ import tuned.logs
|
|||
from .functions import functions as functions
|
||||
import tuned.consts as consts
|
||||
from tuned.utils.commands import commands
|
||||
try:
|
||||
from configparser import ConfigParser, Error
|
||||
from io import StringIO
|
||||
except ImportError:
|
||||
# python2.7 support, remove RHEL-7 support end
|
||||
from ConfigParser import ConfigParser, Error
|
||||
from StringIO import StringIO
|
||||
from tuned.utils.config_parser import ConfigParser, Error
|
||||
|
||||
log = tuned.logs.get()
|
||||
|
||||
|
|
@ -51,10 +45,10 @@ class Variables():
|
|||
log.error("unable to find variables_file: '%s'" % filename)
|
||||
return
|
||||
try:
|
||||
config = ConfigParser()
|
||||
config = ConfigParser(delimiters=('='), inline_comment_prefixes=('#'), allow_no_value=True)
|
||||
config.optionxform = str
|
||||
with open(filename) as f:
|
||||
config.readfp(StringIO("[" + consts.MAGIC_HEADER_NAME + "]\n" + f.read()))
|
||||
config.read_string("[" + consts.MAGIC_HEADER_NAME + "]\n" + f.read(), filename)
|
||||
except Error:
|
||||
log.error("error parsing variables_file: '%s'" % filename)
|
||||
return
|
||||
|
|
|
|||
56
tuned/utils/config_parser.py
Normal file
56
tuned/utils/config_parser.py
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
# ConfigParser wrapper providing compatibility layer for python 2.7/3
|
||||
|
||||
try:
|
||||
python3 = True
|
||||
import configparser as cp
|
||||
except ImportError:
|
||||
python3 = False
|
||||
import ConfigParser as cp
|
||||
from StringIO import StringIO
|
||||
import re
|
||||
|
||||
class Error(cp.Error):
|
||||
pass
|
||||
|
||||
if python3:
|
||||
|
||||
class ConfigParser(cp.ConfigParser):
|
||||
pass
|
||||
|
||||
else:
|
||||
|
||||
class ConfigParser(cp.ConfigParser):
|
||||
|
||||
def __init__(self, delimiters=None, inline_comment_prefixes=None, strict=True, *args, **kwargs):
|
||||
delims = "".join(list(delimiters))
|
||||
# REs taken from the python-2.7 ConfigParser
|
||||
self.OPTCRE = re.compile(
|
||||
r'(?P<option>[^' + delims + '\s][^' + delims + ']*)'
|
||||
r'\s*(?P<vi>[' + delims + '])\s*'
|
||||
r'(?P<value>.*)$'
|
||||
)
|
||||
self.OPTCRE_NV = re.compile(
|
||||
r'(?P<option>[^' + delims + '\s][^' + delims + ']*)'
|
||||
r'\s*(?:'
|
||||
r'(?P<vi>[' + delims + '])\s*'
|
||||
r'(?P<value>.*))?$'
|
||||
)
|
||||
cp.ConfigParser.__init__(self, *args, **kwargs)
|
||||
self._inline_comment_prefixes = inline_comment_prefixes or []
|
||||
self._re = re.compile("\s+(%s).*" % ")|(".join(list(self._inline_comment_prefixes)))
|
||||
|
||||
def read_string(self, string, source="<string>"):
|
||||
sfile = StringIO(string)
|
||||
self.read_file(sfile, source)
|
||||
|
||||
def readfp(self, fp, filename=None):
|
||||
cp.ConfigParser.readfp(self, fp, filename)
|
||||
# remove inline comments
|
||||
all_sections = [self._defaults]
|
||||
all_sections.extend(self._sections.values())
|
||||
for options in all_sections:
|
||||
for name, val in options.items():
|
||||
options[name] = self._re.sub("", val)
|
||||
|
||||
def read_file(self, f, source="<???>"):
|
||||
self.readfp(f, source)
|
||||
|
|
@ -1,11 +1,5 @@
|
|||
import tuned.logs
|
||||
try:
|
||||
from configparser import ConfigParser, Error
|
||||
from io import StringIO
|
||||
except ImportError:
|
||||
# python2.7 support, remove RHEL-7 support end
|
||||
from ConfigParser import ConfigParser, Error
|
||||
from StringIO import StringIO
|
||||
from tuned.utils.config_parser import ConfigParser, Error
|
||||
from tuned.exceptions import TunedException
|
||||
import tuned.consts as consts
|
||||
from tuned.utils.commands import commands
|
||||
|
|
@ -45,10 +39,10 @@ class GlobalConfig():
|
|||
"""
|
||||
log.debug("reading and parsing global configuration file '%s'" % file_name)
|
||||
try:
|
||||
config_parser = ConfigParser()
|
||||
config_parser = ConfigParser(delimiters=('='), inline_comment_prefixes=('#'))
|
||||
config_parser.optionxform = str
|
||||
with open(file_name) as f:
|
||||
config_parser.readfp(StringIO("[" + consts.MAGIC_HEADER_NAME + "]\n" + f.read()))
|
||||
config_parser.read_string("[" + consts.MAGIC_HEADER_NAME + "]\n" + f.read(), file_name)
|
||||
self._cfg, _global_config_func = self.get_global_config_spec()
|
||||
for option in config_parser.options(consts.MAGIC_HEADER_NAME):
|
||||
if option in self._cfg:
|
||||
|
|
|
|||
|
|
@ -3,11 +3,7 @@ import re
|
|||
import errno
|
||||
import procfs
|
||||
import subprocess
|
||||
try:
|
||||
from configparser import ConfigParser, Error
|
||||
except ImportError:
|
||||
# python2.7 support, remove RHEL-7 support end
|
||||
from ConfigParser import ConfigParser, Error
|
||||
from tuned.utils.config_parser import ConfigParser, Error
|
||||
|
||||
try:
|
||||
import syspurpose.files
|
||||
|
|
@ -63,10 +59,10 @@ class ProfileRecommender:
|
|||
try:
|
||||
if not os.path.isfile(fname):
|
||||
return None
|
||||
config = ConfigParser()
|
||||
config = ConfigParser(delimiters=('='), inline_comment_prefixes=('#'))
|
||||
config.optionxform = str
|
||||
with open(fname) as f:
|
||||
config.readfp(f)
|
||||
config.read_file(f, fname)
|
||||
for section in config.sections():
|
||||
match = True
|
||||
for option in config.options(section):
|
||||
|
|
|
|||
Loading…
Reference in a new issue