pygments.rb 0.2.13 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +1 -0
- data/README.md +45 -19
- data/Rakefile +21 -11
- data/bench.rb +15 -48
- data/cache-lexers.rb +8 -0
- data/lexers +0 -0
- data/lib/pygments.rb +3 -6
- data/lib/pygments/mentos.py +343 -0
- data/lib/pygments/popen.rb +383 -0
- data/lib/pygments/version.rb +1 -1
- data/pygments.rb.gemspec +5 -4
- data/test/test_data.c +2581 -0
- data/test/test_data.py +514 -0
- data/test/test_data_generated +2582 -0
- data/test/test_pygments.rb +208 -84
- data/vendor/pygments-main/pygments/lexers/_mapping.py +1 -1
- data/vendor/pygments-main/pygments/lexers/shell.py +1 -1
- data/vendor/simplejson/.gitignore +10 -0
- data/vendor/simplejson/.travis.yml +5 -0
- data/vendor/simplejson/CHANGES.txt +291 -0
- data/vendor/simplejson/LICENSE.txt +19 -0
- data/vendor/simplejson/MANIFEST.in +5 -0
- data/vendor/simplejson/README.rst +19 -0
- data/vendor/simplejson/conf.py +179 -0
- data/vendor/simplejson/index.rst +628 -0
- data/vendor/simplejson/scripts/make_docs.py +18 -0
- data/vendor/simplejson/setup.py +104 -0
- data/vendor/simplejson/simplejson/__init__.py +510 -0
- data/vendor/simplejson/simplejson/_speedups.c +2745 -0
- data/vendor/simplejson/simplejson/decoder.py +425 -0
- data/vendor/simplejson/simplejson/encoder.py +567 -0
- data/vendor/simplejson/simplejson/ordered_dict.py +119 -0
- data/vendor/simplejson/simplejson/scanner.py +77 -0
- data/vendor/simplejson/simplejson/tests/__init__.py +67 -0
- data/vendor/simplejson/simplejson/tests/test_bigint_as_string.py +55 -0
- data/vendor/simplejson/simplejson/tests/test_check_circular.py +30 -0
- data/vendor/simplejson/simplejson/tests/test_decimal.py +66 -0
- data/vendor/simplejson/simplejson/tests/test_decode.py +83 -0
- data/vendor/simplejson/simplejson/tests/test_default.py +9 -0
- data/vendor/simplejson/simplejson/tests/test_dump.py +67 -0
- data/vendor/simplejson/simplejson/tests/test_encode_basestring_ascii.py +46 -0
- data/vendor/simplejson/simplejson/tests/test_encode_for_html.py +32 -0
- data/vendor/simplejson/simplejson/tests/test_errors.py +34 -0
- data/vendor/simplejson/simplejson/tests/test_fail.py +91 -0
- data/vendor/simplejson/simplejson/tests/test_float.py +19 -0
- data/vendor/simplejson/simplejson/tests/test_indent.py +86 -0
- data/vendor/simplejson/simplejson/tests/test_item_sort_key.py +20 -0
- data/vendor/simplejson/simplejson/tests/test_namedtuple.py +121 -0
- data/vendor/simplejson/simplejson/tests/test_pass1.py +76 -0
- data/vendor/simplejson/simplejson/tests/test_pass2.py +14 -0
- data/vendor/simplejson/simplejson/tests/test_pass3.py +20 -0
- data/vendor/simplejson/simplejson/tests/test_recursion.py +67 -0
- data/vendor/simplejson/simplejson/tests/test_scanstring.py +117 -0
- data/vendor/simplejson/simplejson/tests/test_separators.py +42 -0
- data/vendor/simplejson/simplejson/tests/test_speedups.py +20 -0
- data/vendor/simplejson/simplejson/tests/test_tuple.py +49 -0
- data/vendor/simplejson/simplejson/tests/test_unicode.py +109 -0
- data/vendor/simplejson/simplejson/tool.py +39 -0
- metadata +80 -22
- data/ext/extconf.rb +0 -14
- data/ext/pygments.c +0 -466
- data/lib/pygments/c.rb +0 -54
- data/lib/pygments/ffi.rb +0 -155
- data/vendor/.gitignore +0 -1
@@ -0,0 +1,119 @@
|
|
1
|
+
"""Drop-in replacement for collections.OrderedDict by Raymond Hettinger
|
2
|
+
|
3
|
+
http://code.activestate.com/recipes/576693/
|
4
|
+
|
5
|
+
"""
|
6
|
+
from UserDict import DictMixin
|
7
|
+
|
8
|
+
# Modified from original to support Python 2.4, see
|
9
|
+
# http://code.google.com/p/simplejson/issues/detail?id=53
|
10
|
+
try:
|
11
|
+
all
|
12
|
+
except NameError:
|
13
|
+
def all(seq):
|
14
|
+
for elem in seq:
|
15
|
+
if not elem:
|
16
|
+
return False
|
17
|
+
return True
|
18
|
+
|
19
|
+
class OrderedDict(dict, DictMixin):
|
20
|
+
|
21
|
+
def __init__(self, *args, **kwds):
|
22
|
+
if len(args) > 1:
|
23
|
+
raise TypeError('expected at most 1 arguments, got %d' % len(args))
|
24
|
+
try:
|
25
|
+
self.__end
|
26
|
+
except AttributeError:
|
27
|
+
self.clear()
|
28
|
+
self.update(*args, **kwds)
|
29
|
+
|
30
|
+
def clear(self):
|
31
|
+
self.__end = end = []
|
32
|
+
end += [None, end, end] # sentinel node for doubly linked list
|
33
|
+
self.__map = {} # key --> [key, prev, next]
|
34
|
+
dict.clear(self)
|
35
|
+
|
36
|
+
def __setitem__(self, key, value):
|
37
|
+
if key not in self:
|
38
|
+
end = self.__end
|
39
|
+
curr = end[1]
|
40
|
+
curr[2] = end[1] = self.__map[key] = [key, curr, end]
|
41
|
+
dict.__setitem__(self, key, value)
|
42
|
+
|
43
|
+
def __delitem__(self, key):
|
44
|
+
dict.__delitem__(self, key)
|
45
|
+
key, prev, next = self.__map.pop(key)
|
46
|
+
prev[2] = next
|
47
|
+
next[1] = prev
|
48
|
+
|
49
|
+
def __iter__(self):
|
50
|
+
end = self.__end
|
51
|
+
curr = end[2]
|
52
|
+
while curr is not end:
|
53
|
+
yield curr[0]
|
54
|
+
curr = curr[2]
|
55
|
+
|
56
|
+
def __reversed__(self):
|
57
|
+
end = self.__end
|
58
|
+
curr = end[1]
|
59
|
+
while curr is not end:
|
60
|
+
yield curr[0]
|
61
|
+
curr = curr[1]
|
62
|
+
|
63
|
+
def popitem(self, last=True):
|
64
|
+
if not self:
|
65
|
+
raise KeyError('dictionary is empty')
|
66
|
+
# Modified from original to support Python 2.4, see
|
67
|
+
# http://code.google.com/p/simplejson/issues/detail?id=53
|
68
|
+
if last:
|
69
|
+
key = reversed(self).next()
|
70
|
+
else:
|
71
|
+
key = iter(self).next()
|
72
|
+
value = self.pop(key)
|
73
|
+
return key, value
|
74
|
+
|
75
|
+
def __reduce__(self):
|
76
|
+
items = [[k, self[k]] for k in self]
|
77
|
+
tmp = self.__map, self.__end
|
78
|
+
del self.__map, self.__end
|
79
|
+
inst_dict = vars(self).copy()
|
80
|
+
self.__map, self.__end = tmp
|
81
|
+
if inst_dict:
|
82
|
+
return (self.__class__, (items,), inst_dict)
|
83
|
+
return self.__class__, (items,)
|
84
|
+
|
85
|
+
def keys(self):
|
86
|
+
return list(self)
|
87
|
+
|
88
|
+
setdefault = DictMixin.setdefault
|
89
|
+
update = DictMixin.update
|
90
|
+
pop = DictMixin.pop
|
91
|
+
values = DictMixin.values
|
92
|
+
items = DictMixin.items
|
93
|
+
iterkeys = DictMixin.iterkeys
|
94
|
+
itervalues = DictMixin.itervalues
|
95
|
+
iteritems = DictMixin.iteritems
|
96
|
+
|
97
|
+
def __repr__(self):
|
98
|
+
if not self:
|
99
|
+
return '%s()' % (self.__class__.__name__,)
|
100
|
+
return '%s(%r)' % (self.__class__.__name__, self.items())
|
101
|
+
|
102
|
+
def copy(self):
|
103
|
+
return self.__class__(self)
|
104
|
+
|
105
|
+
@classmethod
|
106
|
+
def fromkeys(cls, iterable, value=None):
|
107
|
+
d = cls()
|
108
|
+
for key in iterable:
|
109
|
+
d[key] = value
|
110
|
+
return d
|
111
|
+
|
112
|
+
def __eq__(self, other):
|
113
|
+
if isinstance(other, OrderedDict):
|
114
|
+
return len(self)==len(other) and \
|
115
|
+
all(p==q for p, q in zip(self.items(), other.items()))
|
116
|
+
return dict.__eq__(self, other)
|
117
|
+
|
118
|
+
def __ne__(self, other):
|
119
|
+
return not self == other
|
@@ -0,0 +1,77 @@
|
|
1
|
+
"""JSON token scanner
|
2
|
+
"""
|
3
|
+
import re
|
4
|
+
def _import_c_make_scanner():
|
5
|
+
try:
|
6
|
+
from simplejson._speedups import make_scanner
|
7
|
+
return make_scanner
|
8
|
+
except ImportError:
|
9
|
+
return None
|
10
|
+
c_make_scanner = _import_c_make_scanner()
|
11
|
+
|
12
|
+
__all__ = ['make_scanner']
|
13
|
+
|
14
|
+
NUMBER_RE = re.compile(
|
15
|
+
r'(-?(?:0|[1-9]\d*))(\.\d+)?([eE][-+]?\d+)?',
|
16
|
+
(re.VERBOSE | re.MULTILINE | re.DOTALL))
|
17
|
+
|
18
|
+
def py_make_scanner(context):
|
19
|
+
parse_object = context.parse_object
|
20
|
+
parse_array = context.parse_array
|
21
|
+
parse_string = context.parse_string
|
22
|
+
match_number = NUMBER_RE.match
|
23
|
+
encoding = context.encoding
|
24
|
+
strict = context.strict
|
25
|
+
parse_float = context.parse_float
|
26
|
+
parse_int = context.parse_int
|
27
|
+
parse_constant = context.parse_constant
|
28
|
+
object_hook = context.object_hook
|
29
|
+
object_pairs_hook = context.object_pairs_hook
|
30
|
+
memo = context.memo
|
31
|
+
|
32
|
+
def _scan_once(string, idx):
|
33
|
+
try:
|
34
|
+
nextchar = string[idx]
|
35
|
+
except IndexError:
|
36
|
+
raise StopIteration
|
37
|
+
|
38
|
+
if nextchar == '"':
|
39
|
+
return parse_string(string, idx + 1, encoding, strict)
|
40
|
+
elif nextchar == '{':
|
41
|
+
return parse_object((string, idx + 1), encoding, strict,
|
42
|
+
_scan_once, object_hook, object_pairs_hook, memo)
|
43
|
+
elif nextchar == '[':
|
44
|
+
return parse_array((string, idx + 1), _scan_once)
|
45
|
+
elif nextchar == 'n' and string[idx:idx + 4] == 'null':
|
46
|
+
return None, idx + 4
|
47
|
+
elif nextchar == 't' and string[idx:idx + 4] == 'true':
|
48
|
+
return True, idx + 4
|
49
|
+
elif nextchar == 'f' and string[idx:idx + 5] == 'false':
|
50
|
+
return False, idx + 5
|
51
|
+
|
52
|
+
m = match_number(string, idx)
|
53
|
+
if m is not None:
|
54
|
+
integer, frac, exp = m.groups()
|
55
|
+
if frac or exp:
|
56
|
+
res = parse_float(integer + (frac or '') + (exp or ''))
|
57
|
+
else:
|
58
|
+
res = parse_int(integer)
|
59
|
+
return res, m.end()
|
60
|
+
elif nextchar == 'N' and string[idx:idx + 3] == 'NaN':
|
61
|
+
return parse_constant('NaN'), idx + 3
|
62
|
+
elif nextchar == 'I' and string[idx:idx + 8] == 'Infinity':
|
63
|
+
return parse_constant('Infinity'), idx + 8
|
64
|
+
elif nextchar == '-' and string[idx:idx + 9] == '-Infinity':
|
65
|
+
return parse_constant('-Infinity'), idx + 9
|
66
|
+
else:
|
67
|
+
raise StopIteration
|
68
|
+
|
69
|
+
def scan_once(string, idx):
|
70
|
+
try:
|
71
|
+
return _scan_once(string, idx)
|
72
|
+
finally:
|
73
|
+
memo.clear()
|
74
|
+
|
75
|
+
return scan_once
|
76
|
+
|
77
|
+
make_scanner = c_make_scanner or py_make_scanner
|
@@ -0,0 +1,67 @@
|
|
1
|
+
import unittest
|
2
|
+
import doctest
|
3
|
+
|
4
|
+
|
5
|
+
class OptionalExtensionTestSuite(unittest.TestSuite):
|
6
|
+
def run(self, result):
|
7
|
+
import simplejson
|
8
|
+
run = unittest.TestSuite.run
|
9
|
+
run(self, result)
|
10
|
+
simplejson._toggle_speedups(False)
|
11
|
+
run(self, result)
|
12
|
+
simplejson._toggle_speedups(True)
|
13
|
+
return result
|
14
|
+
|
15
|
+
|
16
|
+
def additional_tests(suite=None):
|
17
|
+
import simplejson
|
18
|
+
import simplejson.encoder
|
19
|
+
import simplejson.decoder
|
20
|
+
if suite is None:
|
21
|
+
suite = unittest.TestSuite()
|
22
|
+
for mod in (simplejson, simplejson.encoder, simplejson.decoder):
|
23
|
+
suite.addTest(doctest.DocTestSuite(mod))
|
24
|
+
suite.addTest(doctest.DocFileSuite('../../index.rst'))
|
25
|
+
return suite
|
26
|
+
|
27
|
+
|
28
|
+
def all_tests_suite():
|
29
|
+
suite = unittest.TestLoader().loadTestsFromNames([
|
30
|
+
'simplejson.tests.test_bigint_as_string',
|
31
|
+
'simplejson.tests.test_check_circular',
|
32
|
+
'simplejson.tests.test_decode',
|
33
|
+
'simplejson.tests.test_default',
|
34
|
+
'simplejson.tests.test_dump',
|
35
|
+
'simplejson.tests.test_encode_basestring_ascii',
|
36
|
+
'simplejson.tests.test_encode_for_html',
|
37
|
+
'simplejson.tests.test_errors',
|
38
|
+
'simplejson.tests.test_fail',
|
39
|
+
'simplejson.tests.test_float',
|
40
|
+
'simplejson.tests.test_indent',
|
41
|
+
'simplejson.tests.test_pass1',
|
42
|
+
'simplejson.tests.test_pass2',
|
43
|
+
'simplejson.tests.test_pass3',
|
44
|
+
'simplejson.tests.test_recursion',
|
45
|
+
'simplejson.tests.test_scanstring',
|
46
|
+
'simplejson.tests.test_separators',
|
47
|
+
'simplejson.tests.test_speedups',
|
48
|
+
'simplejson.tests.test_unicode',
|
49
|
+
'simplejson.tests.test_decimal',
|
50
|
+
'simplejson.tests.test_tuple',
|
51
|
+
'simplejson.tests.test_namedtuple',
|
52
|
+
])
|
53
|
+
suite = additional_tests(suite)
|
54
|
+
return OptionalExtensionTestSuite([suite])
|
55
|
+
|
56
|
+
|
57
|
+
def main():
|
58
|
+
runner = unittest.TextTestRunner()
|
59
|
+
suite = all_tests_suite()
|
60
|
+
raise SystemExit(not runner.run(suite).wasSuccessful())
|
61
|
+
|
62
|
+
|
63
|
+
if __name__ == '__main__':
|
64
|
+
import os
|
65
|
+
import sys
|
66
|
+
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))
|
67
|
+
main()
|
@@ -0,0 +1,55 @@
|
|
1
|
+
from unittest import TestCase
|
2
|
+
|
3
|
+
import simplejson as json
|
4
|
+
|
5
|
+
class TestBigintAsString(TestCase):
|
6
|
+
values = [(200, 200),
|
7
|
+
((2 ** 53) - 1, 9007199254740991),
|
8
|
+
((2 ** 53), '9007199254740992'),
|
9
|
+
((2 ** 53) + 1, '9007199254740993'),
|
10
|
+
(-100, -100),
|
11
|
+
((-2 ** 53), '-9007199254740992'),
|
12
|
+
((-2 ** 53) - 1, '-9007199254740993'),
|
13
|
+
((-2 ** 53) + 1, -9007199254740991)]
|
14
|
+
|
15
|
+
def test_ints(self):
|
16
|
+
for val, expect in self.values:
|
17
|
+
self.assertEquals(
|
18
|
+
val,
|
19
|
+
json.loads(json.dumps(val)))
|
20
|
+
self.assertEquals(
|
21
|
+
expect,
|
22
|
+
json.loads(json.dumps(val, bigint_as_string=True)))
|
23
|
+
|
24
|
+
def test_lists(self):
|
25
|
+
for val, expect in self.values:
|
26
|
+
val = [val, val]
|
27
|
+
expect = [expect, expect]
|
28
|
+
self.assertEquals(
|
29
|
+
val,
|
30
|
+
json.loads(json.dumps(val)))
|
31
|
+
self.assertEquals(
|
32
|
+
expect,
|
33
|
+
json.loads(json.dumps(val, bigint_as_string=True)))
|
34
|
+
|
35
|
+
def test_dicts(self):
|
36
|
+
for val, expect in self.values:
|
37
|
+
val = {'k': val}
|
38
|
+
expect = {'k': expect}
|
39
|
+
self.assertEquals(
|
40
|
+
val,
|
41
|
+
json.loads(json.dumps(val)))
|
42
|
+
self.assertEquals(
|
43
|
+
expect,
|
44
|
+
json.loads(json.dumps(val, bigint_as_string=True)))
|
45
|
+
|
46
|
+
def test_dict_keys(self):
|
47
|
+
for val, _ in self.values:
|
48
|
+
expect = {str(val): 'value'}
|
49
|
+
val = {val: 'value'}
|
50
|
+
self.assertEquals(
|
51
|
+
expect,
|
52
|
+
json.loads(json.dumps(val)))
|
53
|
+
self.assertEquals(
|
54
|
+
expect,
|
55
|
+
json.loads(json.dumps(val, bigint_as_string=True)))
|
@@ -0,0 +1,30 @@
|
|
1
|
+
from unittest import TestCase
|
2
|
+
import simplejson as json
|
3
|
+
|
4
|
+
def default_iterable(obj):
|
5
|
+
return list(obj)
|
6
|
+
|
7
|
+
class TestCheckCircular(TestCase):
|
8
|
+
def test_circular_dict(self):
|
9
|
+
dct = {}
|
10
|
+
dct['a'] = dct
|
11
|
+
self.assertRaises(ValueError, json.dumps, dct)
|
12
|
+
|
13
|
+
def test_circular_list(self):
|
14
|
+
lst = []
|
15
|
+
lst.append(lst)
|
16
|
+
self.assertRaises(ValueError, json.dumps, lst)
|
17
|
+
|
18
|
+
def test_circular_composite(self):
|
19
|
+
dct2 = {}
|
20
|
+
dct2['a'] = []
|
21
|
+
dct2['a'].append(dct2)
|
22
|
+
self.assertRaises(ValueError, json.dumps, dct2)
|
23
|
+
|
24
|
+
def test_circular_default(self):
|
25
|
+
json.dumps([set()], default=default_iterable)
|
26
|
+
self.assertRaises(TypeError, json.dumps, [set()])
|
27
|
+
|
28
|
+
def test_circular_off_default(self):
|
29
|
+
json.dumps([set()], default=default_iterable, check_circular=False)
|
30
|
+
self.assertRaises(TypeError, json.dumps, [set()], check_circular=False)
|
@@ -0,0 +1,66 @@
|
|
1
|
+
import decimal
|
2
|
+
from decimal import Decimal
|
3
|
+
from unittest import TestCase
|
4
|
+
from StringIO import StringIO
|
5
|
+
|
6
|
+
import simplejson as json
|
7
|
+
|
8
|
+
class TestDecimal(TestCase):
|
9
|
+
NUMS = "1.0", "10.00", "1.1", "1234567890.1234567890", "500"
|
10
|
+
def dumps(self, obj, **kw):
|
11
|
+
sio = StringIO()
|
12
|
+
json.dump(obj, sio, **kw)
|
13
|
+
res = json.dumps(obj, **kw)
|
14
|
+
self.assertEquals(res, sio.getvalue())
|
15
|
+
return res
|
16
|
+
|
17
|
+
def loads(self, s, **kw):
|
18
|
+
sio = StringIO(s)
|
19
|
+
res = json.loads(s, **kw)
|
20
|
+
self.assertEquals(res, json.load(sio, **kw))
|
21
|
+
return res
|
22
|
+
|
23
|
+
def test_decimal_encode(self):
|
24
|
+
for d in map(Decimal, self.NUMS):
|
25
|
+
self.assertEquals(self.dumps(d, use_decimal=True), str(d))
|
26
|
+
|
27
|
+
def test_decimal_decode(self):
|
28
|
+
for s in self.NUMS:
|
29
|
+
self.assertEquals(self.loads(s, parse_float=Decimal), Decimal(s))
|
30
|
+
|
31
|
+
def test_decimal_roundtrip(self):
|
32
|
+
for d in map(Decimal, self.NUMS):
|
33
|
+
# The type might not be the same (int and Decimal) but they
|
34
|
+
# should still compare equal.
|
35
|
+
self.assertEquals(
|
36
|
+
self.loads(
|
37
|
+
self.dumps(d, use_decimal=True), parse_float=Decimal),
|
38
|
+
d)
|
39
|
+
self.assertEquals(
|
40
|
+
self.loads(
|
41
|
+
self.dumps([d], use_decimal=True), parse_float=Decimal),
|
42
|
+
[d])
|
43
|
+
|
44
|
+
def test_decimal_defaults(self):
|
45
|
+
d = Decimal('1.1')
|
46
|
+
# use_decimal=True is the default
|
47
|
+
self.assertRaises(TypeError, json.dumps, d, use_decimal=False)
|
48
|
+
self.assertEqual('1.1', json.dumps(d))
|
49
|
+
self.assertEqual('1.1', json.dumps(d, use_decimal=True))
|
50
|
+
self.assertRaises(TypeError, json.dump, d, StringIO(),
|
51
|
+
use_decimal=False)
|
52
|
+
sio = StringIO()
|
53
|
+
json.dump(d, sio)
|
54
|
+
self.assertEqual('1.1', sio.getvalue())
|
55
|
+
sio = StringIO()
|
56
|
+
json.dump(d, sio, use_decimal=True)
|
57
|
+
self.assertEqual('1.1', sio.getvalue())
|
58
|
+
|
59
|
+
def test_decimal_reload(self):
|
60
|
+
# Simulate a subinterpreter that reloads the Python modules but not
|
61
|
+
# the C code https://github.com/simplejson/simplejson/issues/34
|
62
|
+
global Decimal
|
63
|
+
Decimal = reload(decimal).Decimal
|
64
|
+
import simplejson.encoder
|
65
|
+
simplejson.encoder.Decimal = Decimal
|
66
|
+
self.test_decimal_roundtrip()
|
@@ -0,0 +1,83 @@
|
|
1
|
+
import decimal
|
2
|
+
from unittest import TestCase
|
3
|
+
from StringIO import StringIO
|
4
|
+
|
5
|
+
import simplejson as json
|
6
|
+
from simplejson import OrderedDict
|
7
|
+
|
8
|
+
class TestDecode(TestCase):
|
9
|
+
if not hasattr(TestCase, 'assertIs'):
|
10
|
+
def assertIs(self, a, b):
|
11
|
+
self.assertTrue(a is b, '%r is %r' % (a, b))
|
12
|
+
|
13
|
+
def test_decimal(self):
|
14
|
+
rval = json.loads('1.1', parse_float=decimal.Decimal)
|
15
|
+
self.assertTrue(isinstance(rval, decimal.Decimal))
|
16
|
+
self.assertEquals(rval, decimal.Decimal('1.1'))
|
17
|
+
|
18
|
+
def test_float(self):
|
19
|
+
rval = json.loads('1', parse_int=float)
|
20
|
+
self.assertTrue(isinstance(rval, float))
|
21
|
+
self.assertEquals(rval, 1.0)
|
22
|
+
|
23
|
+
def test_decoder_optimizations(self):
|
24
|
+
# Several optimizations were made that skip over calls to
|
25
|
+
# the whitespace regex, so this test is designed to try and
|
26
|
+
# exercise the uncommon cases. The array cases are already covered.
|
27
|
+
rval = json.loads('{ "key" : "value" , "k":"v" }')
|
28
|
+
self.assertEquals(rval, {"key":"value", "k":"v"})
|
29
|
+
|
30
|
+
def test_empty_objects(self):
|
31
|
+
s = '{}'
|
32
|
+
self.assertEqual(json.loads(s), eval(s))
|
33
|
+
s = '[]'
|
34
|
+
self.assertEqual(json.loads(s), eval(s))
|
35
|
+
s = '""'
|
36
|
+
self.assertEqual(json.loads(s), eval(s))
|
37
|
+
|
38
|
+
def test_object_pairs_hook(self):
|
39
|
+
s = '{"xkd":1, "kcw":2, "art":3, "hxm":4, "qrt":5, "pad":6, "hoy":7}'
|
40
|
+
p = [("xkd", 1), ("kcw", 2), ("art", 3), ("hxm", 4),
|
41
|
+
("qrt", 5), ("pad", 6), ("hoy", 7)]
|
42
|
+
self.assertEqual(json.loads(s), eval(s))
|
43
|
+
self.assertEqual(json.loads(s, object_pairs_hook=lambda x: x), p)
|
44
|
+
self.assertEqual(json.load(StringIO(s),
|
45
|
+
object_pairs_hook=lambda x: x), p)
|
46
|
+
od = json.loads(s, object_pairs_hook=OrderedDict)
|
47
|
+
self.assertEqual(od, OrderedDict(p))
|
48
|
+
self.assertEqual(type(od), OrderedDict)
|
49
|
+
# the object_pairs_hook takes priority over the object_hook
|
50
|
+
self.assertEqual(json.loads(s,
|
51
|
+
object_pairs_hook=OrderedDict,
|
52
|
+
object_hook=lambda x: None),
|
53
|
+
OrderedDict(p))
|
54
|
+
|
55
|
+
def check_keys_reuse(self, source, loads):
|
56
|
+
rval = loads(source)
|
57
|
+
(a, b), (c, d) = sorted(rval[0]), sorted(rval[1])
|
58
|
+
self.assertIs(a, c)
|
59
|
+
self.assertIs(b, d)
|
60
|
+
|
61
|
+
def test_keys_reuse_str(self):
|
62
|
+
s = u'[{"a_key": 1, "b_\xe9": 2}, {"a_key": 3, "b_\xe9": 4}]'.encode('utf8')
|
63
|
+
self.check_keys_reuse(s, json.loads)
|
64
|
+
|
65
|
+
def test_keys_reuse_unicode(self):
|
66
|
+
s = u'[{"a_key": 1, "b_\xe9": 2}, {"a_key": 3, "b_\xe9": 4}]'
|
67
|
+
self.check_keys_reuse(s, json.loads)
|
68
|
+
|
69
|
+
def test_empty_strings(self):
|
70
|
+
self.assertEqual(json.loads('""'), "")
|
71
|
+
self.assertEqual(json.loads(u'""'), u"")
|
72
|
+
self.assertEqual(json.loads('[""]'), [""])
|
73
|
+
self.assertEqual(json.loads(u'[""]'), [u""])
|
74
|
+
|
75
|
+
def test_raw_decode(self):
|
76
|
+
cls = json.decoder.JSONDecoder
|
77
|
+
self.assertEqual(
|
78
|
+
({'a': {}}, 9),
|
79
|
+
cls().raw_decode("{\"a\": {}}"))
|
80
|
+
# http://code.google.com/p/simplejson/issues/detail?id=85
|
81
|
+
self.assertEqual(
|
82
|
+
({'a': {}}, 9),
|
83
|
+
cls(object_pairs_hook=dict).raw_decode("{\"a\": {}}"))
|