Revision fd0351ae

b/lib/serializer.py
29 29
# C0103: Invalid name, since pylint doesn't see that Dump points to a
30 30
# function and not a constant
31 31

  
32
_OLD_SIMPLEJSON = False
33

  
32 34
try:
33 35
  import json
34 36
except ImportError:
35 37
  # The "json" module was only added in Python 2.6. Earlier versions must use
36 38
  # the separate "simplejson" module.
37 39
  import simplejson as json
40
  _OLD_SIMPLEJSON = True
38 41

  
39 42
import re
43
import logging
40 44

  
41 45
from ganeti import errors
42 46
from ganeti import utils
......
47 51
_RE_EOLSP = re.compile("[ \t]+$", re.MULTILINE)
48 52

  
49 53

  
50
def _GetJsonDumpers(_encoder_class=json.JSONEncoder):
54
class _CustomJsonEncoder(json.JSONEncoder):
55
  if __debug__ and not _OLD_SIMPLEJSON:
56
    try:
57
      _orig_fn = json.JSONEncoder._iterencode_dict
58
    except AttributeError:
59
      raise Exception("Can't override JSONEncoder's '_iterencode_dict'")
60
    else:
61
      def _iterencode_dict(self, data, *args, **kwargs):
62
        for key in data.keys():
63
          if not (key is None or isinstance(key, (basestring, bool))):
64
            raise ValueError("Key '%s' is of disallowed type '%s'" %
65
                             (key, type(key)))
66

  
67
        return self._orig_fn(data, *args, **kwargs)
68

  
69

  
70
def _GetJsonDumpers(_encoder_class=_CustomJsonEncoder):
51 71
  """Returns two JSON functions to serialize data.
52 72

  
53 73
  @rtype: (callable, callable)
b/test/ganeti.serializer_unittest.py
23 23

  
24 24

  
25 25
import unittest
26
import warnings
26 27

  
27 28
from ganeti import serializer
28 29
from ganeti import errors
30
from ganeti import compat
29 31

  
30 32
import testutils
31 33

  
......
107 109
                      serializer.DumpJson(tdata), "mykey")
108 110

  
109 111

  
112
class TestInvalidDictionaryKey(unittest.TestCase):
113
  def _Test(self, data):
114
    if serializer._OLD_SIMPLEJSON:
115
      # Using old "simplejson", can't really test
116
      warnings.warn("This test requires Python 2.6 or above to function"
117
                    " correctly")
118
      self.assertTrue(serializer.DumpJson(data))
119
    else:
120
      self.assertRaises(ValueError, serializer.DumpJson, data)
121

  
122
  def test(self):
123
    for value in [123, 1.1, -1, -9492.1123, -3234e-4]:
124
      self._Test({value: ""})
125

  
126
  def testAllowed(self):
127
    for value in ["", "Hello World", None, True, False]:
128
      self.assertTrue(serializer.DumpJson({value: ""}))
129

  
130

  
110 131
if __name__ == '__main__':
111 132
  testutils.GanetiTestProgram()

Also available in: Unified diff