Commit b8b0f55e authored by Jelte Jansen's avatar Jelte Jansen
Browse files

refactoring;

renamed the DataDefinition class to the much more accurate ModuleSpec
also renamed some ambiguously named functions therein



git-svn-id: svn://bind10.isc.org/svn/bind10/branches/jelte-configuration@833 e5f2f494-b856-4b98-b285-d166d9295462
parent 976107dd
{ {
"data_specification": { "module_spec": {
"module_name": "Auth", "module_name": "Auth",
"config_data": [ "config_data": [
{ "item_name": "default_name", { "item_name": "default_name",
......
...@@ -116,7 +116,7 @@ class BoB: ...@@ -116,7 +116,7 @@ class BoB:
print("[XX] handling new config:") print("[XX] handling new config:")
print(new_config) print(new_config)
errors = [] errors = []
if self.ccs.get_config_data().get_specification().validate(False, new_config, errors): if self.ccs.get_config_spec().get_module_spec().validate(False, new_config, errors):
print("[XX] new config validated") print("[XX] new config validated")
self.ccs.set_config(new_config) self.ccs.set_config(new_config)
answer = isc.config.ccsession.create_answer(0) answer = isc.config.ccsession.create_answer(0)
......
{ {
"data_specification": { "module_spec": {
"module_name": "Boss", "module_name": "Boss",
"config_data": [ "config_data": [
{ {
......
...@@ -188,7 +188,7 @@ class CommandControl(): ...@@ -188,7 +188,7 @@ class CommandControl():
self.config_data = self.get_config_data() self.config_data = self.get_config_data()
def get_cmd_specification(self): def get_cmd_specification(self):
return self.send_command('ConfigManager', 'get_commands') return self.send_command('ConfigManager', 'get_commands_spec')
def get_config_data(self): def get_config_data(self):
return self.send_command('ConfigManager', 'get_config') return self.send_command('ConfigManager', 'get_config')
...@@ -198,7 +198,7 @@ class CommandControl(): ...@@ -198,7 +198,7 @@ class CommandControl():
self.config_data = self.get_config_data() self.config_data = self.get_config_data()
def get_data_specification(self): def get_data_specification(self):
return self.send_command('ConfigManager', 'get_data_spec') return self.send_command('ConfigManager', 'get_module_spec')
def handle_recv_msg(self): def handle_recv_msg(self):
# Handle received message, if 'shutdown' is received, return False # Handle received message, if 'shutdown' is received, return False
......
{ {
"data_specification": { "module_spec": {
"module_name": "ParkingLot", "module_name": "ParkingLot",
"config_data": [ "config_data": [
{ {
......
{ {
"data_specification": { "module_spec": {
"module_name": "ParkingLot", "module_name": "ParkingLot",
"config_data": [ "config_data": [
{ {
......
...@@ -81,7 +81,7 @@ CommandSession::CommandSession(std::string spec_file_name, ...@@ -81,7 +81,7 @@ CommandSession::CommandSession(std::string spec_file_name,
read_data_definition(spec_file_name); read_data_definition(spec_file_name);
sleep(1); sleep(1);
module_name_ = data_definition_.getDefinition()->get("data_specification")->get("module_name")->stringValue(); module_name_ = data_definition_.getDefinition()->get("module_spec")->get("module_name")->stringValue();
config_handler_ = config_handler; config_handler_ = config_handler;
command_handler_ = command_handler; command_handler_ = command_handler;
......
...@@ -141,10 +141,10 @@ check_data_specification(const ElementPtr& spec) { ...@@ -141,10 +141,10 @@ check_data_specification(const ElementPtr& spec) {
static void static void
check_definition(const ElementPtr& def) check_definition(const ElementPtr& def)
{ {
if (!def->contains("data_specification")) { if (!def->contains("module_spec")) {
throw DataDefinitionError("Data specification does not contain data_specification element"); throw DataDefinitionError("Data specification does not contain module_spec element");
} else { } else {
check_data_specification(def->get("data_specification")); check_data_specification(def->get("module_spec"));
} }
} }
...@@ -276,7 +276,7 @@ DataDefinition::validate_spec_list(const ElementPtr spec, const ElementPtr data) ...@@ -276,7 +276,7 @@ DataDefinition::validate_spec_list(const ElementPtr spec, const ElementPtr data)
// form, we should do that in the constructor // form, we should do that in the constructor
bool bool
DataDefinition::validate(const ElementPtr data) { DataDefinition::validate(const ElementPtr data) {
ElementPtr spec = definition->find("data_specification/config_data"); ElementPtr spec = definition->find("module_spec/config_data");
return validate_spec_list(spec, data); return validate_spec_list(spec, data);
} }
...@@ -47,11 +47,11 @@ TEST(DataDefinition, ReadingSpecfiles) { ...@@ -47,11 +47,11 @@ TEST(DataDefinition, ReadingSpecfiles) {
// Tests whether we can open specfiles and if we get the // Tests whether we can open specfiles and if we get the
// right parse errors // right parse errors
DataDefinition dd = DataDefinition(specfile("spec1.spec")); DataDefinition dd = DataDefinition(specfile("spec1.spec"));
EXPECT_EQ(dd.getDefinition()->get("data_specification") EXPECT_EQ(dd.getDefinition()->get("module_spec")
->get("module_name") ->get("module_name")
->stringValue(), "Spec1"); ->stringValue(), "Spec1");
dd = DataDefinition(specfile("spec2.spec")); dd = DataDefinition(specfile("spec2.spec"));
EXPECT_EQ(dd.getDefinition()->get("data_specification") EXPECT_EQ(dd.getDefinition()->get("module_spec")
->get("config_data")->size(), 6); ->get("config_data")->size(), 6);
data_def_error("doesnotexist", data_def_error("doesnotexist",
"Error opening ", "Error opening ",
...@@ -61,7 +61,7 @@ TEST(DataDefinition, ReadingSpecfiles) { ...@@ -61,7 +61,7 @@ TEST(DataDefinition, ReadingSpecfiles) {
std::ifstream file; std::ifstream file;
file.open(specfile("spec1.spec").c_str()); file.open(specfile("spec1.spec").c_str());
dd = DataDefinition(file); dd = DataDefinition(file);
EXPECT_EQ(dd.getDefinition()->get("data_specification") EXPECT_EQ(dd.getDefinition()->get("module_spec")
->get("module_name") ->get("module_name")
->stringValue(), "Spec1"); ->stringValue(), "Spec1");
} }
...@@ -96,7 +96,7 @@ TEST(DataDefinition, SpecfileConfigData) ...@@ -96,7 +96,7 @@ TEST(DataDefinition, SpecfileConfigData)
data_def_error("spec7.spec", data_def_error("spec7.spec",
"module_name missing in {}"); "module_name missing in {}");
data_def_error("spec8.spec", data_def_error("spec8.spec",
"Data specification does not contain data_specification element"); "Data specification does not contain module_spec element");
data_def_error("spec16.spec", data_def_error("spec16.spec",
"config_data is not a list of elements"); "config_data is not a list of elements");
data_def_error("spec21.spec", data_def_error("spec21.spec",
......
...@@ -80,7 +80,7 @@ class CCSession: ...@@ -80,7 +80,7 @@ class CCSession:
config_handler and command_handler are callback functions, config_handler and command_handler are callback functions,
see set_config_handler and set_command_handler for more see set_config_handler and set_command_handler for more
information on their signatures.""" information on their signatures."""
data_definition = isc.config.data_spec_from_file(spec_file_name) data_definition = isc.config.module_spec_from_file(spec_file_name)
self._config_data = isc.config.config_data.ConfigData(data_definition) self._config_data = isc.config.config_data.ConfigData(data_definition)
self._module_name = data_definition.get_module_name() self._module_name = data_definition.get_module_name()
...@@ -121,9 +121,8 @@ class CCSession: ...@@ -121,9 +121,8 @@ class CCSession:
"""Returns the current or non-default configuration""" """Returns the current or non-default configuration"""
return self._config_data.get_full_config() return self._config_data.get_full_config()
def get_config_data(self): def get_module_spec(self):
"""Returns the config_data part of the specification""" return self._config_data.get_module_spec()
return self._config_data
def close(self): def close(self):
"""Close the session to the command channel""" """Close the session to the command channel"""
...@@ -165,7 +164,7 @@ class CCSession: ...@@ -165,7 +164,7 @@ class CCSession:
def __send_spec(self): def __send_spec(self):
"""Sends the data specification to the configuration manager""" """Sends the data specification to the configuration manager"""
print("[XX] send spec for " + self._module_name + " to ConfigManager") print("[XX] send spec for " + self._module_name + " to ConfigManager")
self._session.group_sendmsg({ "data_specification": self._config_data.get_specification().get_definition() }, "ConfigManager") self._session.group_sendmsg({ "module_spec": self._config_data.get_module_spec().get_full_spec() }, "ConfigManager")
answer, env = self._session.group_recvmsg(False) answer, env = self._session.group_recvmsg(False)
print("[XX] got answer from cfgmgr:") print("[XX] got answer from cfgmgr:")
print(answer) print(answer)
...@@ -176,7 +175,7 @@ class CCSession: ...@@ -176,7 +175,7 @@ class CCSession:
answer, env = self._session.group_recvmsg(False) answer, env = self._session.group_recvmsg(False)
rcode, value = parse_answer(answer) rcode, value = parse_answer(answer)
if rcode == 0: if rcode == 0:
if self._config_data.get_specification().validate(False, value): if self._config_data.get_module_spec().validate(False, value):
self._config_data.set_local_config(value); self._config_data.set_local_config(value);
if self._config_handler: if self._config_handler:
self._config_handler(value) self._config_handler(value)
......
...@@ -106,12 +106,12 @@ class ConfigManager: ...@@ -106,12 +106,12 @@ class ConfigManager:
The ability to specify a custom session is for testing purposes The ability to specify a custom session is for testing purposes
and should not be needed for normal usage.""" and should not be needed for normal usage."""
def __init__(self, data_path, session = None): def __init__(self, data_path, session = None):
# remove these and use self.data_specs # remove these and use self.module_specs
#self.commands = {} #self.commands = {}
self.data_definitions = {} self.data_definitions = {}
self.data_path = data_path self.data_path = data_path
self.data_specs = {} self.module_specs = {}
self.config = ConfigManagerData(data_path) self.config = ConfigManagerData(data_path)
if session: if session:
self.cc = session self.cc = session
...@@ -125,38 +125,38 @@ class ConfigManager: ...@@ -125,38 +125,38 @@ class ConfigManager:
"""Notifies the Boss module that the Config Manager is running""" """Notifies the Boss module that the Config Manager is running"""
self.cc.group_sendmsg({"running": "configmanager"}, "Boss") self.cc.group_sendmsg({"running": "configmanager"}, "Boss")
def set_data_spec(self, spec): def set_module_spec(self, spec):
#data_def = isc.config.DataDefinition(spec) #data_def = isc.config.ModuleSpec(spec)
self.data_specs[spec.get_module_name()] = spec self.module_specs[spec.get_module_name()] = spec
def get_data_spec(self, module_name): def get_module_spec(self, module_name):
if module_name in self.data_specs: if module_name in self.module_specs:
return self.data_specs[module_name] return self.module_specs[module_name]
def get_config_data(self, name = None): def get_config_spec(self, name = None):
"""Returns a dict containing 'module_name': config_data for """Returns a dict containing 'module_name': config_data for
all modules. If name is specified, only that module will all modules. If name is specified, only that module will
be included""" be included"""
config_data = {} config_data = {}
if name: if name:
if name in self.data_specs: if name in self.module_specs:
config_data[name] = self.data_specs[name].get_data config_data[name] = self.module_specs[name].get_data
else: else:
for module_name in self.data_specs.keys(): for module_name in self.module_specs.keys():
config_data[module_name] = self.data_specs[module_name].get_config_data() config_data[module_name] = self.module_specs[module_name].get_config_spec()
return config_data return config_data
def get_commands(self, name = None): def get_commands_spec(self, name = None):
"""Returns a dict containing 'module_name': commands_dict for """Returns a dict containing 'module_name': commands_dict for
all modules. If name is specified, only that module will all modules. If name is specified, only that module will
be included""" be included"""
commands = {} commands = {}
if name: if name:
if name in self.data_specs: if name in self.module_specs:
commands[name] = self.data_specs[name].get_commands commands[name] = self.module_specs[name].get_commands_spec
else: else:
for module_name in self.data_specs.keys(): for module_name in self.module_specs.keys():
commands[module_name] = self.data_specs[module_name].get_commands() commands[module_name] = self.module_specs[module_name].get_commands_spec()
return commands return commands
def read_config(self): def read_config(self):
...@@ -173,19 +173,19 @@ class ConfigManager: ...@@ -173,19 +173,19 @@ class ConfigManager:
at the path specificied at init()""" at the path specificied at init()"""
self.config.write_to_file() self.config.write_to_file()
def _handle_get_data_spec(self, cmd): def _handle_get_module_spec(self, cmd):
answer = {} answer = {}
if len(cmd) > 1: if len(cmd) > 1:
if type(cmd[1]) == dict: if type(cmd[1]) == dict:
if 'module_name' in cmd[1] and cmd[1]['module_name'] != '': if 'module_name' in cmd[1] and cmd[1]['module_name'] != '':
module_name = cmd[1]['module_name'] module_name = cmd[1]['module_name']
answer = isc.config.ccsession.create_answer(0, self.get_config_data(module_name)) answer = isc.config.ccsession.create_answer(0, self.get_config_spec(module_name))
else: else:
answer = isc.config.ccsession.create_answer(1, "Bad module_name in get_data_spec command") answer = isc.config.ccsession.create_answer(1, "Bad module_name in get_module_spec command")
else: else:
answer = isc.config.ccsession.create_answer(1, "Bad get_data_spec command, argument not a dict") answer = isc.config.ccsession.create_answer(1, "Bad get_module_spec command, argument not a dict")
else: else:
answer = isc.config.ccsession.create_answer(0, self.get_config_data()) answer = isc.config.ccsession.create_answer(0, self.get_config_spec())
return answer return answer
def _handle_get_config(self, cmd): def _handle_get_config(self, cmd):
...@@ -256,17 +256,17 @@ class ConfigManager: ...@@ -256,17 +256,17 @@ class ConfigManager:
return answer return answer
def _handle_data_specification(self, spec): def _handle_module_spec(self, spec):
# todo: validate? (no direct access to spec as # todo: validate? (no direct access to spec as
# todo: use DataDefinition class # todo: use ModuleSpec class
# todo: error checking (like keyerrors) # todo: error checking (like keyerrors)
answer = {} answer = {}
self.set_data_spec(spec) self.set_module_spec(spec)
# We should make one general 'spec update for module' that # We should make one general 'spec update for module' that
# passes both specification and commands at once # passes both specification and commands at once
self.cc.group_sendmsg({ "specification_update": [ spec.get_module_name(), spec.get_config_data() ] }, "Cmd-Ctrld") self.cc.group_sendmsg({ "specification_update": [ spec.get_module_name(), spec.get_config_spec() ] }, "Cmd-Ctrld")
self.cc.group_sendmsg({ "commands_update": [ spec.get_module_name(), spec.get_commands() ] }, "Cmd-Ctrld") self.cc.group_sendmsg({ "commands_update": [ spec.get_module_name(), spec.get_commands_spec() ] }, "Cmd-Ctrld")
answer = isc.config.ccsession.create_answer(0) answer = isc.config.ccsession.create_answer(0)
return answer return answer
...@@ -276,10 +276,10 @@ class ConfigManager: ...@@ -276,10 +276,10 @@ class ConfigManager:
if "command" in msg: if "command" in msg:
cmd = msg["command"] cmd = msg["command"]
try: try:
if cmd[0] == "get_commands": if cmd[0] == "get_commands_spec":
answer = isc.config.ccsession.create_answer(0, self.get_commands()) answer = isc.config.ccsession.create_answer(0, self.get_commands_spec())
elif cmd[0] == "get_data_spec": elif cmd[0] == "get_module_spec":
answer = self._handle_get_data_spec(cmd) answer = self._handle_get_module_spec(cmd)
elif cmd[0] == "get_config": elif cmd[0] == "get_config":
answer = self._handle_get_config(cmd) answer = self._handle_get_config(cmd)
elif cmd[0] == "set_config": elif cmd[0] == "set_config":
...@@ -293,10 +293,10 @@ class ConfigManager: ...@@ -293,10 +293,10 @@ class ConfigManager:
except IndexError as ie: except IndexError as ie:
answer = isc.config.ccsession.create_answer(1, "Missing argument in command: " + str(ie)) answer = isc.config.ccsession.create_answer(1, "Missing argument in command: " + str(ie))
raise ie raise ie
elif "data_specification" in msg: elif "module_spec" in msg:
try: try:
answer = self._handle_data_specification(isc.config.DataDefinition(msg["data_specification"])) answer = self._handle_module_spec(isc.config.ModuleSpec(msg["module_spec"]))
except isc.config.DataDefinitionError as dde: except isc.config.ModuleSpecError as dde:
answer = isc.config.ccsession.create_answer(1, "Error in data definition: " + str(dde)) answer = isc.config.ccsession.create_answer(1, "Error in data definition: " + str(dde))
elif 'result' in msg: elif 'result' in msg:
# this seems wrong, might start pingpong # this seems wrong, might start pingpong
......
...@@ -109,10 +109,10 @@ class TestConfigManager(unittest.TestCase): ...@@ -109,10 +109,10 @@ class TestConfigManager(unittest.TestCase):
self.fake_session = FakeCCSession() self.fake_session = FakeCCSession()
self.cm = ConfigManager(self.data_path, self.fake_session) self.cm = ConfigManager(self.data_path, self.fake_session)
self.name = "TestModule" self.name = "TestModule"
self.spec = isc.config.data_spec_from_file(self.data_path + os.sep + "/spec2.spec") self.spec = isc.config.module_spec_from_file(self.data_path + os.sep + "/spec2.spec")
def test_init(self): def test_init(self):
self.assert_(self.cm.data_specs == {}) self.assert_(self.cm.module_specs == {})
self.assert_(self.cm.data_path == self.data_path) self.assert_(self.cm.data_path == self.data_path)
self.assert_(self.cm.config != None) self.assert_(self.cm.config != None)
self.assert_(self.fake_session.has_subscription("ConfigManager")) self.assert_(self.fake_session.has_subscription("ConfigManager"))
...@@ -134,14 +134,14 @@ class TestConfigManager(unittest.TestCase): ...@@ -134,14 +134,14 @@ class TestConfigManager(unittest.TestCase):
self._handle_msg_helper({}, { 'result': [ 1, 'Unknown message format: {}']}) self._handle_msg_helper({}, { 'result': [ 1, 'Unknown message format: {}']})
self._handle_msg_helper("", { 'result': [ 1, 'Unknown message format: ']}) self._handle_msg_helper("", { 'result': [ 1, 'Unknown message format: ']})
self._handle_msg_helper({ "command": [ "badcommand" ] }, { 'result': [ 1, "Unknown command: ['badcommand']"]}) self._handle_msg_helper({ "command": [ "badcommand" ] }, { 'result': [ 1, "Unknown command: ['badcommand']"]})
self._handle_msg_helper({ "command": [ "get_commands" ] }, { 'result': [ 0, {} ]}) self._handle_msg_helper({ "command": [ "get_commands_spec" ] }, { 'result': [ 0, {} ]})
self._handle_msg_helper({ "command": [ "get_data_spec" ] }, { 'result': [ 0, {} ]}) self._handle_msg_helper({ "command": [ "get_module_spec" ] }, { 'result': [ 0, {} ]})
#self._handle_msg_helper({ "command": [ "get_data_spec", { "module_name": "nosuchmodule" } ] }, #self._handle_msg_helper({ "command": [ "get_module_spec", { "module_name": "nosuchmodule" } ] },
# {'result': [1, 'No specification for module nosuchmodule']}) # {'result': [1, 'No specification for module nosuchmodule']})
self._handle_msg_helper({ "command": [ "get_data_spec", 1 ] }, self._handle_msg_helper({ "command": [ "get_module_spec", 1 ] },
{'result': [1, 'Bad get_data_spec command, argument not a dict']}) {'result': [1, 'Bad get_module_spec command, argument not a dict']})
self._handle_msg_helper({ "command": [ "get_data_spec", { } ] }, self._handle_msg_helper({ "command": [ "get_module_spec", { } ] },
{'result': [1, 'Bad module_name in get_data_spec command']}) {'result': [1, 'Bad module_name in get_module_spec command']})
self._handle_msg_helper({ "command": [ "get_config" ] }, { 'result': [ 0, { 'version': 1} ]}) self._handle_msg_helper({ "command": [ "get_config" ] }, { 'result': [ 0, { 'version': 1} ]})
self._handle_msg_helper({ "command": [ "get_config", { "module_name": "nosuchmodule" } ] }, self._handle_msg_helper({ "command": [ "get_config", { "module_name": "nosuchmodule" } ] },
{'result': [0, {}]}) {'result': [0, {}]})
...@@ -174,16 +174,16 @@ class TestConfigManager(unittest.TestCase): ...@@ -174,16 +174,16 @@ class TestConfigManager(unittest.TestCase):
self.assertEqual({'config_update': {'test': 124}}, self.assertEqual({'config_update': {'test': 124}},
self.fake_session.get_message(self.name, None)) self.fake_session.get_message(self.name, None))
self.assertEqual({'version': 1, 'TestModule': {'test': 124}}, self.cm.config.data) self.assertEqual({'version': 1, 'TestModule': {'test': 124}}, self.cm.config.data)
self._handle_msg_helper({ "data_specification": self._handle_msg_helper({ "module_spec":
self.spec.get_definition() self.spec.get_full_spec()
}, },
{'result': [0]}) {'result': [0]})
self._handle_msg_helper({ "data_specification": self._handle_msg_helper({ "module_spec":
{ 'foo': 1 } { 'foo': 1 }
}, },
{'result': [1, 'Error in data definition: no module_name in data_specification']}) {'result': [1, 'Error in data definition: no module_name in module_spec']})
self._handle_msg_helper({ "command": [ "get_data_spec" ] }, { 'result': [ 0, { self.spec.get_module_name(): self.spec.get_config_spec() } ]}) self._handle_msg_helper({ "command": [ "get_module_spec" ] }, { 'result': [ 0, { self.spec.get_module_name(): self.spec.get_config_spec() } ]})
self._handle_msg_helper({ "command": [ "get_commands" ] }, { 'result': [ 0, { self.spec.get_module_name(): self.spec.get_commands() } ]}) self._handle_msg_helper({ "command": [ "get_commands_spec" ] }, { 'result': [ 0, { self.spec.get_module_name(): self.spec.get_commands_spec() } ]})
# re-add this once we have new way to propagate spec changes (1 instead of the current 2 messages) # re-add this once we have new way to propagate spec changes (1 instead of the current 2 messages)
#self.assertEqual(len(self.fake_session.message_queue), 2) #self.assertEqual(len(self.fake_session.message_queue), 2)
# the name here is actually wrong (and hardcoded), but needed in the current version # the name here is actually wrong (and hardcoded), but needed in the current version
......
...@@ -108,9 +108,9 @@ class ConfigData: ...@@ -108,9 +108,9 @@ class ConfigData:
def __init__(self, specification): def __init__(self, specification):
"""Initialize a ConfigData instance. If specification is not """Initialize a ConfigData instance. If specification is not
of type DataDefinition, a ConfigDataError is raised.""" of type ModuleSpec, a ConfigDataError is raised."""
if type(specification) != isc.config.DataDefinition: if type(specification) != isc.config.ModuleSpec:
raise ConfigDataError("specification is of type " + str(type(specification)) + ", not DataDefinition") raise ConfigDataError("specification is of type " + str(type(specification)) + ", not ModuleSpec")
self.specification = specification self.specification = specification
self.data = {} self.data = {}
...@@ -127,14 +127,13 @@ class ConfigData: ...@@ -127,14 +127,13 @@ class ConfigData:
value = isc.cc.data.find_no_exc(self.data, identifier) value = isc.cc.data.find_no_exc(self.data, identifier)
if value: if value:
return value, False return value, False
spec = find_spec(self.specification.get_config_data(), identifier) spec = find_spec(self.specification.get_config_spec(), identifier)
if spec and 'item_default' in spec: if spec and 'item_default' in spec:
return spec['item_default'], True return spec['item_default'], True
return None, False return None, False
def get_specification(self): def get_module_spec(self):
"""Returns the datadefinition""" """Returns the ModuleSpec object associated with this ConfigData"""
print(self.specification)
return self.specification return self.specification
def set_local_config(self, data): def set_local_config(self, data):
...@@ -147,10 +146,10 @@ class ConfigData: ...@@ -147,10 +146,10 @@ class ConfigData:
def get_full_config(self): def get_full_config(self):
items = self.get_item_list(None, True) items = self.get_item_list(None, True)
result = [] result = {}
for item in items: for item in items:
value, default = self.get_value(item) value, default = self.get_value(item)
result.append(item + ": " + str(value)) result[item] = value
return result return result
#def get_identifiers(self): #def get_identifiers(self):
...@@ -174,11 +173,11 @@ class MultiConfigData: ...@@ -174,11 +173,11 @@ class MultiConfigData:
self._local_changes = {}