Commit 4c14965f authored by Guido Trotter's avatar Guido Trotter

ConfigObject.ToDict() only export non-None values

The method is changed to a normal loop, to avoid calling getattr()
twice. Also __getstate__ is changed to just use ToDict() by default.

This should also make __getstate__ work for objects which have to
override the ToDict function because they contain other objects.

__setstate__ is probably still broken in this case, but so it was
before, and it's not used inside our code, so I'll pretend not to have
noticed, as there is no "nice" way to fix it, without overriding it all
over the place :(

Some unittests are added as a bonus, to make sure we behave well.
Signed-off-by: default avatarGuido Trotter <ultrotter@google.com>
Reviewed-by: default avatarIustin Pop <iustin@google.com>
parent f9780ccd
......@@ -231,6 +231,7 @@ dist_TESTS = \
test/ganeti.hooks_unittest.py \
test/ganeti.http_unittest.py \
test/ganeti.locking_unittest.py \
test/ganeti.objects_unittest.py \
test/ganeti.rapi.resources_unittest.py \
test/ganeti.serializer_unittest.py \
test/ganeti.ssh_unittest.py \
......
......@@ -104,13 +104,6 @@ class ConfigObject(object):
raise KeyError(key)
setattr(self, key, value)
def __getstate__(self):
state = {}
for name in self.__slots__:
if hasattr(self, name):
state[name] = getattr(self, name)
return state
def __setstate__(self, state):
for name in state:
if name in self.__slots__:
......@@ -126,7 +119,14 @@ class ConfigObject(object):
make sure all objects returned are only standard python types.
"""
return dict([(k, getattr(self, k, None)) for k in self.__slots__])
result = {}
for name in self.__slots__:
value = getattr(self, name, None)
if value is not None:
result[name] = value
return result
__getstate__ = ToDict
@classmethod
def FromDict(cls, val):
......
#!/usr/bin/python
#
# Copyright (C) 2006, 2007, 2008 Google Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 0.0510-1301, USA.
"""Script for unittesting the objects module"""
import unittest
from ganeti import objects
class SimpleObject(objects.ConfigObject):
__slots__ = ['a', 'b']
class TestDictState(unittest.TestCase):
"""Simple dict tansformation tests"""
def testSimpleObjectToDict(self):
o1 = SimpleObject(a='1')
self.assertEquals(o1.ToDict(), {'a': '1'})
self.assertEquals(o1.__getstate__(), {'a': '1'})
self.assertEquals(o1.__getstate__(), o1.ToDict())
o1.a = 2
o1.b = 5
self.assertEquals(o1.ToDict(), {'a': 2, 'b': 5})
o2 = SimpleObject.FromDict(o1.ToDict())
self.assertEquals(o1.ToDict(), {'a': 2, 'b': 5})
if __name__ == '__main__':
unittest.main()
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment