1647 lines
55 KiB
Python
1647 lines
55 KiB
Python
|
# -*- coding: utf-8 -*-
|
||
|
|
||
|
try:
|
||
|
import json
|
||
|
except ImportError:
|
||
|
import simplejson as json
|
||
|
import math
|
||
|
import pytz
|
||
|
import pytest
|
||
|
import time
|
||
|
import datetime
|
||
|
import calendar
|
||
|
import re
|
||
|
import decimal
|
||
|
import dateutil
|
||
|
from functools import partial
|
||
|
from pandas.compat import range, zip, StringIO, u
|
||
|
import pandas._libs.json as ujson
|
||
|
import pandas.compat as compat
|
||
|
|
||
|
import numpy as np
|
||
|
from pandas import DataFrame, Series, Index, NaT, DatetimeIndex
|
||
|
import pandas.util.testing as tm
|
||
|
|
||
|
|
||
|
json_unicode = (json.dumps if compat.PY3
|
||
|
else partial(json.dumps, encoding="utf-8"))
|
||
|
|
||
|
|
||
|
class TestUltraJSONTests(object):
|
||
|
|
||
|
@pytest.mark.skipif(compat.is_platform_32bit(),
|
||
|
reason="not compliant on 32-bit, xref #15865")
|
||
|
def test_encodeDecimal(self):
|
||
|
sut = decimal.Decimal("1337.1337")
|
||
|
encoded = ujson.encode(sut, double_precision=15)
|
||
|
decoded = ujson.decode(encoded)
|
||
|
assert decoded == 1337.1337
|
||
|
|
||
|
sut = decimal.Decimal("0.95")
|
||
|
encoded = ujson.encode(sut, double_precision=1)
|
||
|
assert encoded == "1.0"
|
||
|
decoded = ujson.decode(encoded)
|
||
|
assert decoded == 1.0
|
||
|
|
||
|
sut = decimal.Decimal("0.94")
|
||
|
encoded = ujson.encode(sut, double_precision=1)
|
||
|
assert encoded == "0.9"
|
||
|
decoded = ujson.decode(encoded)
|
||
|
assert decoded == 0.9
|
||
|
|
||
|
sut = decimal.Decimal("1.95")
|
||
|
encoded = ujson.encode(sut, double_precision=1)
|
||
|
assert encoded == "2.0"
|
||
|
decoded = ujson.decode(encoded)
|
||
|
assert decoded == 2.0
|
||
|
|
||
|
sut = decimal.Decimal("-1.95")
|
||
|
encoded = ujson.encode(sut, double_precision=1)
|
||
|
assert encoded == "-2.0"
|
||
|
decoded = ujson.decode(encoded)
|
||
|
assert decoded == -2.0
|
||
|
|
||
|
sut = decimal.Decimal("0.995")
|
||
|
encoded = ujson.encode(sut, double_precision=2)
|
||
|
assert encoded == "1.0"
|
||
|
decoded = ujson.decode(encoded)
|
||
|
assert decoded == 1.0
|
||
|
|
||
|
sut = decimal.Decimal("0.9995")
|
||
|
encoded = ujson.encode(sut, double_precision=3)
|
||
|
assert encoded == "1.0"
|
||
|
decoded = ujson.decode(encoded)
|
||
|
assert decoded == 1.0
|
||
|
|
||
|
sut = decimal.Decimal("0.99999999999999944")
|
||
|
encoded = ujson.encode(sut, double_precision=15)
|
||
|
assert encoded == "1.0"
|
||
|
decoded = ujson.decode(encoded)
|
||
|
assert decoded == 1.0
|
||
|
|
||
|
def test_encodeStringConversion(self):
|
||
|
input = "A string \\ / \b \f \n \r \t </script> &"
|
||
|
not_html_encoded = ('"A string \\\\ \\/ \\b \\f \\n '
|
||
|
'\\r \\t <\\/script> &"')
|
||
|
html_encoded = ('"A string \\\\ \\/ \\b \\f \\n \\r \\t '
|
||
|
'\\u003c\\/script\\u003e \\u0026"')
|
||
|
|
||
|
def helper(expected_output, **encode_kwargs):
|
||
|
output = ujson.encode(input, **encode_kwargs)
|
||
|
assert input == json.loads(output)
|
||
|
assert output == expected_output
|
||
|
assert input == ujson.decode(output)
|
||
|
|
||
|
# Default behavior assumes encode_html_chars=False.
|
||
|
helper(not_html_encoded, ensure_ascii=True)
|
||
|
helper(not_html_encoded, ensure_ascii=False)
|
||
|
|
||
|
# Make sure explicit encode_html_chars=False works.
|
||
|
helper(not_html_encoded, ensure_ascii=True, encode_html_chars=False)
|
||
|
helper(not_html_encoded, ensure_ascii=False, encode_html_chars=False)
|
||
|
|
||
|
# Make sure explicit encode_html_chars=True does the encoding.
|
||
|
helper(html_encoded, ensure_ascii=True, encode_html_chars=True)
|
||
|
helper(html_encoded, ensure_ascii=False, encode_html_chars=True)
|
||
|
|
||
|
def test_doubleLongIssue(self):
|
||
|
sut = {u('a'): -4342969734183514}
|
||
|
encoded = json.dumps(sut)
|
||
|
decoded = json.loads(encoded)
|
||
|
assert sut == decoded
|
||
|
encoded = ujson.encode(sut, double_precision=15)
|
||
|
decoded = ujson.decode(encoded)
|
||
|
assert sut == decoded
|
||
|
|
||
|
def test_doubleLongDecimalIssue(self):
|
||
|
sut = {u('a'): -12345678901234.56789012}
|
||
|
encoded = json.dumps(sut)
|
||
|
decoded = json.loads(encoded)
|
||
|
assert sut == decoded
|
||
|
encoded = ujson.encode(sut, double_precision=15)
|
||
|
decoded = ujson.decode(encoded)
|
||
|
assert sut == decoded
|
||
|
|
||
|
def test_encodeNonCLocale(self):
|
||
|
import locale
|
||
|
savedlocale = locale.getlocale(locale.LC_NUMERIC)
|
||
|
try:
|
||
|
locale.setlocale(locale.LC_NUMERIC, 'it_IT.UTF-8')
|
||
|
except:
|
||
|
try:
|
||
|
locale.setlocale(locale.LC_NUMERIC, 'Italian_Italy')
|
||
|
except:
|
||
|
pytest.skip('Could not set locale for testing')
|
||
|
assert ujson.loads(ujson.dumps(4.78e60)) == 4.78e60
|
||
|
assert ujson.loads('4.78', precise_float=True) == 4.78
|
||
|
locale.setlocale(locale.LC_NUMERIC, savedlocale)
|
||
|
|
||
|
def test_encodeDecodeLongDecimal(self):
|
||
|
sut = {u('a'): -528656961.4399388}
|
||
|
encoded = ujson.dumps(sut, double_precision=15)
|
||
|
ujson.decode(encoded)
|
||
|
|
||
|
def test_decimalDecodeTestPrecise(self):
|
||
|
sut = {u('a'): 4.56}
|
||
|
encoded = ujson.encode(sut)
|
||
|
decoded = ujson.decode(encoded, precise_float=True)
|
||
|
assert sut == decoded
|
||
|
|
||
|
@pytest.mark.skipif(compat.is_platform_windows() and not compat.PY3,
|
||
|
reason="buggy on win-64 for py2")
|
||
|
def test_encodeDoubleTinyExponential(self):
|
||
|
num = 1e-40
|
||
|
assert num == ujson.decode(ujson.encode(num))
|
||
|
num = 1e-100
|
||
|
assert num == ujson.decode(ujson.encode(num))
|
||
|
num = -1e-45
|
||
|
assert num == ujson.decode(ujson.encode(num))
|
||
|
num = -1e-145
|
||
|
assert np.allclose(num, ujson.decode(ujson.encode(num)))
|
||
|
|
||
|
def test_encodeDictWithUnicodeKeys(self):
|
||
|
input = {u("key1"): u("value1"), u("key1"):
|
||
|
u("value1"), u("key1"): u("value1"),
|
||
|
u("key1"): u("value1"), u("key1"):
|
||
|
u("value1"), u("key1"): u("value1")}
|
||
|
output = ujson.encode(input)
|
||
|
|
||
|
input = {u("بن"): u("value1"), u("بن"): u("value1"),
|
||
|
u("بن"): u("value1"), u("بن"): u("value1"),
|
||
|
u("بن"): u("value1"), u("بن"): u("value1"),
|
||
|
u("بن"): u("value1")}
|
||
|
output = ujson.encode(input) # noqa
|
||
|
|
||
|
def test_encodeDoubleConversion(self):
|
||
|
input = math.pi
|
||
|
output = ujson.encode(input)
|
||
|
assert round(input, 5) == round(json.loads(output), 5)
|
||
|
assert round(input, 5) == round(ujson.decode(output), 5)
|
||
|
|
||
|
def test_encodeWithDecimal(self):
|
||
|
input = 1.0
|
||
|
output = ujson.encode(input)
|
||
|
assert output == "1.0"
|
||
|
|
||
|
def test_encodeDoubleNegConversion(self):
|
||
|
input = -math.pi
|
||
|
output = ujson.encode(input)
|
||
|
|
||
|
assert round(input, 5) == round(json.loads(output), 5)
|
||
|
assert round(input, 5) == round(ujson.decode(output), 5)
|
||
|
|
||
|
def test_encodeArrayOfNestedArrays(self):
|
||
|
input = [[[[]]]] * 20
|
||
|
output = ujson.encode(input)
|
||
|
assert input == json.loads(output)
|
||
|
# assert output == json.dumps(input)
|
||
|
assert input == ujson.decode(output)
|
||
|
input = np.array(input)
|
||
|
tm.assert_numpy_array_equal(input, ujson.decode(
|
||
|
output, numpy=True, dtype=input.dtype))
|
||
|
|
||
|
def test_encodeArrayOfDoubles(self):
|
||
|
input = [31337.31337, 31337.31337, 31337.31337, 31337.31337] * 10
|
||
|
output = ujson.encode(input)
|
||
|
assert input == json.loads(output)
|
||
|
# assert output == json.dumps(input)
|
||
|
assert input == ujson.decode(output)
|
||
|
tm.assert_numpy_array_equal(
|
||
|
np.array(input), ujson.decode(output, numpy=True))
|
||
|
|
||
|
def test_doublePrecisionTest(self):
|
||
|
input = 30.012345678901234
|
||
|
output = ujson.encode(input, double_precision=15)
|
||
|
assert input == json.loads(output)
|
||
|
assert input == ujson.decode(output)
|
||
|
|
||
|
output = ujson.encode(input, double_precision=9)
|
||
|
assert round(input, 9) == json.loads(output)
|
||
|
assert round(input, 9) == ujson.decode(output)
|
||
|
|
||
|
output = ujson.encode(input, double_precision=3)
|
||
|
assert round(input, 3) == json.loads(output)
|
||
|
assert round(input, 3) == ujson.decode(output)
|
||
|
|
||
|
def test_invalidDoublePrecision(self):
|
||
|
input = 30.12345678901234567890
|
||
|
|
||
|
pytest.raises(ValueError, ujson.encode, input, double_precision=20)
|
||
|
pytest.raises(ValueError, ujson.encode, input, double_precision=-1)
|
||
|
|
||
|
# will throw typeError
|
||
|
pytest.raises(TypeError, ujson.encode, input, double_precision='9')
|
||
|
# will throw typeError
|
||
|
pytest.raises(TypeError, ujson.encode,
|
||
|
input, double_precision=None)
|
||
|
|
||
|
def test_encodeStringConversion2(self):
|
||
|
input = "A string \\ / \b \f \n \r \t"
|
||
|
output = ujson.encode(input)
|
||
|
assert input == json.loads(output)
|
||
|
assert output == '"A string \\\\ \\/ \\b \\f \\n \\r \\t"'
|
||
|
assert input == ujson.decode(output)
|
||
|
pass
|
||
|
|
||
|
def test_decodeUnicodeConversion(self):
|
||
|
pass
|
||
|
|
||
|
def test_encodeUnicodeConversion1(self):
|
||
|
input = "Räksmörgås اسامة بن محمد بن عوض بن لادن"
|
||
|
enc = ujson.encode(input)
|
||
|
dec = ujson.decode(enc)
|
||
|
assert enc == json_unicode(input)
|
||
|
assert dec == json.loads(enc)
|
||
|
|
||
|
def test_encodeControlEscaping(self):
|
||
|
input = "\x19"
|
||
|
enc = ujson.encode(input)
|
||
|
dec = ujson.decode(enc)
|
||
|
assert input == dec
|
||
|
assert enc == json_unicode(input)
|
||
|
|
||
|
def test_encodeUnicodeConversion2(self):
|
||
|
input = "\xe6\x97\xa5\xd1\x88"
|
||
|
enc = ujson.encode(input)
|
||
|
dec = ujson.decode(enc)
|
||
|
assert enc == json_unicode(input)
|
||
|
assert dec == json.loads(enc)
|
||
|
|
||
|
def test_encodeUnicodeSurrogatePair(self):
|
||
|
input = "\xf0\x90\x8d\x86"
|
||
|
enc = ujson.encode(input)
|
||
|
dec = ujson.decode(enc)
|
||
|
|
||
|
assert enc == json_unicode(input)
|
||
|
assert dec == json.loads(enc)
|
||
|
|
||
|
def test_encodeUnicode4BytesUTF8(self):
|
||
|
input = "\xf0\x91\x80\xb0TRAILINGNORMAL"
|
||
|
enc = ujson.encode(input)
|
||
|
dec = ujson.decode(enc)
|
||
|
|
||
|
assert enc == json_unicode(input)
|
||
|
assert dec == json.loads(enc)
|
||
|
|
||
|
def test_encodeUnicode4BytesUTF8Highest(self):
|
||
|
input = "\xf3\xbf\xbf\xbfTRAILINGNORMAL"
|
||
|
enc = ujson.encode(input)
|
||
|
|
||
|
dec = ujson.decode(enc)
|
||
|
|
||
|
assert enc == json_unicode(input)
|
||
|
assert dec == json.loads(enc)
|
||
|
|
||
|
def test_encodeArrayInArray(self):
|
||
|
input = [[[[]]]]
|
||
|
output = ujson.encode(input)
|
||
|
|
||
|
assert input == json.loads(output)
|
||
|
assert output == json.dumps(input)
|
||
|
assert input == ujson.decode(output)
|
||
|
tm.assert_numpy_array_equal(
|
||
|
np.array(input), ujson.decode(output, numpy=True))
|
||
|
pass
|
||
|
|
||
|
def test_encodeIntConversion(self):
|
||
|
input = 31337
|
||
|
output = ujson.encode(input)
|
||
|
assert input == json.loads(output)
|
||
|
assert output == json.dumps(input)
|
||
|
assert input == ujson.decode(output)
|
||
|
pass
|
||
|
|
||
|
def test_encodeIntNegConversion(self):
|
||
|
input = -31337
|
||
|
output = ujson.encode(input)
|
||
|
assert input == json.loads(output)
|
||
|
assert output == json.dumps(input)
|
||
|
assert input == ujson.decode(output)
|
||
|
pass
|
||
|
|
||
|
def test_encodeLongNegConversion(self):
|
||
|
input = -9223372036854775808
|
||
|
output = ujson.encode(input)
|
||
|
|
||
|
assert input == json.loads(output)
|
||
|
assert output == json.dumps(input)
|
||
|
assert input == ujson.decode(output)
|
||
|
|
||
|
def test_encodeListConversion(self):
|
||
|
input = [1, 2, 3, 4]
|
||
|
output = ujson.encode(input)
|
||
|
assert input == json.loads(output)
|
||
|
assert input == ujson.decode(output)
|
||
|
tm.assert_numpy_array_equal(
|
||
|
np.array(input), ujson.decode(output, numpy=True))
|
||
|
pass
|
||
|
|
||
|
def test_encodeDictConversion(self):
|
||
|
input = {"k1": 1, "k2": 2, "k3": 3, "k4": 4}
|
||
|
output = ujson.encode(input) # noqa
|
||
|
assert input == json.loads(output)
|
||
|
assert input == ujson.decode(output)
|
||
|
assert input == ujson.decode(output)
|
||
|
pass
|
||
|
|
||
|
def test_encodeNoneConversion(self):
|
||
|
input = None
|
||
|
output = ujson.encode(input)
|
||
|
assert input == json.loads(output)
|
||
|
assert output == json.dumps(input)
|
||
|
assert input == ujson.decode(output)
|
||
|
pass
|
||
|
|
||
|
def test_encodeTrueConversion(self):
|
||
|
input = True
|
||
|
output = ujson.encode(input)
|
||
|
assert input == json.loads(output)
|
||
|
assert output == json.dumps(input)
|
||
|
assert input == ujson.decode(output)
|
||
|
pass
|
||
|
|
||
|
def test_encodeFalseConversion(self):
|
||
|
input = False
|
||
|
output = ujson.encode(input)
|
||
|
assert input == json.loads(output)
|
||
|
assert output == json.dumps(input)
|
||
|
assert input == ujson.decode(output)
|
||
|
|
||
|
def test_encodeDatetimeConversion(self):
|
||
|
ts = time.time()
|
||
|
input = datetime.datetime.fromtimestamp(ts)
|
||
|
output = ujson.encode(input, date_unit='s')
|
||
|
expected = calendar.timegm(input.utctimetuple())
|
||
|
assert int(expected) == json.loads(output)
|
||
|
assert int(expected) == ujson.decode(output)
|
||
|
|
||
|
def test_encodeDateConversion(self):
|
||
|
ts = time.time()
|
||
|
input = datetime.date.fromtimestamp(ts)
|
||
|
|
||
|
output = ujson.encode(input, date_unit='s')
|
||
|
tup = (input.year, input.month, input.day, 0, 0, 0)
|
||
|
|
||
|
expected = calendar.timegm(tup)
|
||
|
assert int(expected) == json.loads(output)
|
||
|
assert int(expected) == ujson.decode(output)
|
||
|
|
||
|
def test_encodeTimeConversion(self):
|
||
|
tests = [
|
||
|
datetime.time(),
|
||
|
datetime.time(1, 2, 3),
|
||
|
datetime.time(10, 12, 15, 343243),
|
||
|
]
|
||
|
for test in tests:
|
||
|
output = ujson.encode(test)
|
||
|
expected = '"{iso}"'.format(iso=test.isoformat())
|
||
|
assert expected == output
|
||
|
|
||
|
def test_encodeTimeConversion_pytz(self):
|
||
|
# see gh-11473: to_json segfaults with timezone-aware datetimes
|
||
|
test = datetime.time(10, 12, 15, 343243, pytz.utc)
|
||
|
output = ujson.encode(test)
|
||
|
expected = '"{iso}"'.format(iso=test.isoformat())
|
||
|
assert expected == output
|
||
|
|
||
|
def test_encodeTimeConversion_dateutil(self):
|
||
|
# see gh-11473: to_json segfaults with timezone-aware datetimes
|
||
|
test = datetime.time(10, 12, 15, 343243, dateutil.tz.tzutc())
|
||
|
output = ujson.encode(test)
|
||
|
expected = '"{iso}"'.format(iso=test.isoformat())
|
||
|
assert expected == output
|
||
|
|
||
|
def test_nat(self):
|
||
|
input = NaT
|
||
|
assert ujson.encode(input) == 'null', "Expected null"
|
||
|
|
||
|
def test_npy_nat(self):
|
||
|
from distutils.version import LooseVersion
|
||
|
if LooseVersion(np.__version__) < LooseVersion('1.7.0'):
|
||
|
pytest.skip("numpy version < 1.7.0, is "
|
||
|
"{0}".format(np.__version__))
|
||
|
|
||
|
input = np.datetime64('NaT')
|
||
|
assert ujson.encode(input) == 'null', "Expected null"
|
||
|
|
||
|
def test_datetime_units(self):
|
||
|
from pandas._libs.tslib import Timestamp
|
||
|
|
||
|
val = datetime.datetime(2013, 8, 17, 21, 17, 12, 215504)
|
||
|
stamp = Timestamp(val)
|
||
|
|
||
|
roundtrip = ujson.decode(ujson.encode(val, date_unit='s'))
|
||
|
assert roundtrip == stamp.value // 10**9
|
||
|
|
||
|
roundtrip = ujson.decode(ujson.encode(val, date_unit='ms'))
|
||
|
assert roundtrip == stamp.value // 10**6
|
||
|
|
||
|
roundtrip = ujson.decode(ujson.encode(val, date_unit='us'))
|
||
|
assert roundtrip == stamp.value // 10**3
|
||
|
|
||
|
roundtrip = ujson.decode(ujson.encode(val, date_unit='ns'))
|
||
|
assert roundtrip == stamp.value
|
||
|
|
||
|
pytest.raises(ValueError, ujson.encode, val, date_unit='foo')
|
||
|
|
||
|
def test_encodeToUTF8(self):
|
||
|
input = "\xe6\x97\xa5\xd1\x88"
|
||
|
enc = ujson.encode(input, ensure_ascii=False)
|
||
|
dec = ujson.decode(enc)
|
||
|
assert enc == json_unicode(input, ensure_ascii=False)
|
||
|
assert dec == json.loads(enc)
|
||
|
|
||
|
def test_decodeFromUnicode(self):
|
||
|
input = u("{\"obj\": 31337}")
|
||
|
dec1 = ujson.decode(input)
|
||
|
dec2 = ujson.decode(str(input))
|
||
|
assert dec1 == dec2
|
||
|
|
||
|
def test_encodeRecursionMax(self):
|
||
|
# 8 is the max recursion depth
|
||
|
|
||
|
class O2(object):
|
||
|
member = 0
|
||
|
pass
|
||
|
|
||
|
class O1(object):
|
||
|
member = 0
|
||
|
pass
|
||
|
|
||
|
input = O1()
|
||
|
input.member = O2()
|
||
|
input.member.member = input
|
||
|
|
||
|
try:
|
||
|
output = ujson.encode(input) # noqa
|
||
|
assert False, "Expected overflow exception"
|
||
|
except(OverflowError):
|
||
|
pass
|
||
|
|
||
|
def test_encodeDoubleNan(self):
|
||
|
input = np.nan
|
||
|
assert ujson.encode(input) == 'null', "Expected null"
|
||
|
|
||
|
def test_encodeDoubleInf(self):
|
||
|
input = np.inf
|
||
|
assert ujson.encode(input) == 'null', "Expected null"
|
||
|
|
||
|
def test_encodeDoubleNegInf(self):
|
||
|
input = -np.inf
|
||
|
assert ujson.encode(input) == 'null', "Expected null"
|
||
|
|
||
|
def test_decodeJibberish(self):
|
||
|
input = "fdsa sda v9sa fdsa"
|
||
|
try:
|
||
|
ujson.decode(input)
|
||
|
assert False, "Expected exception!"
|
||
|
except(ValueError):
|
||
|
return
|
||
|
assert False, "Wrong exception"
|
||
|
|
||
|
def test_decodeBrokenArrayStart(self):
|
||
|
input = "["
|
||
|
try:
|
||
|
ujson.decode(input)
|
||
|
assert False, "Expected exception!"
|
||
|
except(ValueError):
|
||
|
return
|
||
|
assert False, "Wrong exception"
|
||
|
|
||
|
def test_decodeBrokenObjectStart(self):
|
||
|
input = "{"
|
||
|
try:
|
||
|
ujson.decode(input)
|
||
|
assert False, "Expected exception!"
|
||
|
except(ValueError):
|
||
|
return
|
||
|
assert False, "Wrong exception"
|
||
|
|
||
|
def test_decodeBrokenArrayEnd(self):
|
||
|
input = "]"
|
||
|
try:
|
||
|
ujson.decode(input)
|
||
|
assert False, "Expected exception!"
|
||
|
except(ValueError):
|
||
|
return
|
||
|
assert False, "Wrong exception"
|
||
|
|
||
|
def test_decodeArrayDepthTooBig(self):
|
||
|
input = '[' * (1024 * 1024)
|
||
|
try:
|
||
|
ujson.decode(input)
|
||
|
assert False, "Expected exception!"
|
||
|
except(ValueError):
|
||
|
return
|
||
|
assert False, "Wrong exception"
|
||
|
|
||
|
def test_decodeBrokenObjectEnd(self):
|
||
|
input = "}"
|
||
|
try:
|
||
|
ujson.decode(input)
|
||
|
assert False, "Expected exception!"
|
||
|
except(ValueError):
|
||
|
return
|
||
|
assert False, "Wrong exception"
|
||
|
|
||
|
def test_decodeObjectDepthTooBig(self):
|
||
|
input = '{' * (1024 * 1024)
|
||
|
try:
|
||
|
ujson.decode(input)
|
||
|
assert False, "Expected exception!"
|
||
|
except(ValueError):
|
||
|
return
|
||
|
assert False, "Wrong exception"
|
||
|
|
||
|
def test_decodeStringUnterminated(self):
|
||
|
input = "\"TESTING"
|
||
|
try:
|
||
|
ujson.decode(input)
|
||
|
assert False, "Expected exception!"
|
||
|
except(ValueError):
|
||
|
return
|
||
|
assert False, "Wrong exception"
|
||
|
|
||
|
def test_decodeStringUntermEscapeSequence(self):
|
||
|
input = "\"TESTING\\\""
|
||
|
try:
|
||
|
ujson.decode(input)
|
||
|
assert False, "Expected exception!"
|
||
|
except(ValueError):
|
||
|
return
|
||
|
assert False, "Wrong exception"
|
||
|
|
||
|
def test_decodeStringBadEscape(self):
|
||
|
input = "\"TESTING\\\""
|
||
|
try:
|
||
|
ujson.decode(input)
|
||
|
assert False, "Expected exception!"
|
||
|
except(ValueError):
|
||
|
return
|
||
|
assert False, "Wrong exception"
|
||
|
|
||
|
def test_decodeTrueBroken(self):
|
||
|
input = "tru"
|
||
|
try:
|
||
|
ujson.decode(input)
|
||
|
assert False, "Expected exception!"
|
||
|
except(ValueError):
|
||
|
return
|
||
|
assert False, "Wrong exception"
|
||
|
|
||
|
def test_decodeFalseBroken(self):
|
||
|
input = "fa"
|
||
|
try:
|
||
|
ujson.decode(input)
|
||
|
assert False, "Expected exception!"
|
||
|
except(ValueError):
|
||
|
return
|
||
|
assert False, "Wrong exception"
|
||
|
|
||
|
def test_decodeNullBroken(self):
|
||
|
input = "n"
|
||
|
try:
|
||
|
ujson.decode(input)
|
||
|
assert False, "Expected exception!"
|
||
|
except(ValueError):
|
||
|
return
|
||
|
assert False, "Wrong exception"
|
||
|
|
||
|
def test_decodeBrokenDictKeyTypeLeakTest(self):
|
||
|
input = '{{1337:""}}'
|
||
|
for x in range(1000):
|
||
|
try:
|
||
|
ujson.decode(input)
|
||
|
assert False, "Expected exception!"
|
||
|
except ValueError:
|
||
|
continue
|
||
|
|
||
|
assert False, "Wrong exception"
|
||
|
|
||
|
def test_decodeBrokenDictLeakTest(self):
|
||
|
input = '{{"key":"}'
|
||
|
for x in range(1000):
|
||
|
try:
|
||
|
ujson.decode(input)
|
||
|
assert False, "Expected exception!"
|
||
|
except(ValueError):
|
||
|
continue
|
||
|
|
||
|
assert False, "Wrong exception"
|
||
|
|
||
|
def test_decodeBrokenListLeakTest(self):
|
||
|
input = '[[[true'
|
||
|
for x in range(1000):
|
||
|
try:
|
||
|
ujson.decode(input)
|
||
|
assert False, "Expected exception!"
|
||
|
except(ValueError):
|
||
|
continue
|
||
|
|
||
|
assert False, "Wrong exception"
|
||
|
|
||
|
def test_decodeDictWithNoKey(self):
|
||
|
input = "{{{{31337}}}}"
|
||
|
try:
|
||
|
ujson.decode(input)
|
||
|
assert False, "Expected exception!"
|
||
|
except(ValueError):
|
||
|
return
|
||
|
|
||
|
assert False, "Wrong exception"
|
||
|
|
||
|
def test_decodeDictWithNoColonOrValue(self):
|
||
|
input = "{{{{\"key\"}}}}"
|
||
|
try:
|
||
|
ujson.decode(input)
|
||
|
assert False, "Expected exception!"
|
||
|
except(ValueError):
|
||
|
return
|
||
|
|
||
|
assert False, "Wrong exception"
|
||
|
|
||
|
def test_decodeDictWithNoValue(self):
|
||
|
input = "{{{{\"key\":}}}}"
|
||
|
try:
|
||
|
ujson.decode(input)
|
||
|
assert False, "Expected exception!"
|
||
|
except(ValueError):
|
||
|
return
|
||
|
|
||
|
assert False, "Wrong exception"
|
||
|
|
||
|
def test_decodeNumericIntPos(self):
|
||
|
input = "31337"
|
||
|
assert 31337 == ujson.decode(input)
|
||
|
|
||
|
def test_decodeNumericIntNeg(self):
|
||
|
input = "-31337"
|
||
|
assert -31337 == ujson.decode(input)
|
||
|
|
||
|
@pytest.mark.skipif(compat.PY3, reason="only PY2")
|
||
|
def test_encodeUnicode4BytesUTF8Fail(self):
|
||
|
input = "\xfd\xbf\xbf\xbf\xbf\xbf"
|
||
|
try:
|
||
|
enc = ujson.encode(input) # noqa
|
||
|
assert False, "Expected exception"
|
||
|
except OverflowError:
|
||
|
pass
|
||
|
|
||
|
def test_encodeNullCharacter(self):
|
||
|
input = "31337 \x00 1337"
|
||
|
output = ujson.encode(input)
|
||
|
assert input == json.loads(output)
|
||
|
assert output == json.dumps(input)
|
||
|
assert input == ujson.decode(output)
|
||
|
|
||
|
input = "\x00"
|
||
|
output = ujson.encode(input)
|
||
|
assert input == json.loads(output)
|
||
|
assert output == json.dumps(input)
|
||
|
assert input == ujson.decode(output)
|
||
|
|
||
|
assert '" \\u0000\\r\\n "' == ujson.dumps(u(" \u0000\r\n "))
|
||
|
pass
|
||
|
|
||
|
def test_decodeNullCharacter(self):
|
||
|
input = "\"31337 \\u0000 31337\""
|
||
|
assert ujson.decode(input) == json.loads(input)
|
||
|
|
||
|
def test_encodeListLongConversion(self):
|
||
|
input = [9223372036854775807, 9223372036854775807, 9223372036854775807,
|
||
|
9223372036854775807, 9223372036854775807, 9223372036854775807]
|
||
|
output = ujson.encode(input)
|
||
|
assert input == json.loads(output)
|
||
|
assert input == ujson.decode(output)
|
||
|
tm.assert_numpy_array_equal(np.array(input),
|
||
|
ujson.decode(output, numpy=True,
|
||
|
dtype=np.int64))
|
||
|
pass
|
||
|
|
||
|
def test_encodeLongConversion(self):
|
||
|
input = 9223372036854775807
|
||
|
output = ujson.encode(input)
|
||
|
assert input == json.loads(output)
|
||
|
assert output == json.dumps(input)
|
||
|
assert input == ujson.decode(output)
|
||
|
pass
|
||
|
|
||
|
def test_numericIntExp(self):
|
||
|
input = "1337E40"
|
||
|
output = ujson.decode(input)
|
||
|
assert output == json.loads(input)
|
||
|
|
||
|
def test_numericIntFrcExp(self):
|
||
|
input = "1.337E40"
|
||
|
output = ujson.decode(input)
|
||
|
tm.assert_almost_equal(output, json.loads(input))
|
||
|
|
||
|
def test_decodeNumericIntExpEPLUS(self):
|
||
|
input = "1337E+9"
|
||
|
output = ujson.decode(input)
|
||
|
tm.assert_almost_equal(output, json.loads(input))
|
||
|
|
||
|
def test_decodeNumericIntExpePLUS(self):
|
||
|
input = "1.337e+40"
|
||
|
output = ujson.decode(input)
|
||
|
tm.assert_almost_equal(output, json.loads(input))
|
||
|
|
||
|
def test_decodeNumericIntExpE(self):
|
||
|
input = "1337E40"
|
||
|
output = ujson.decode(input)
|
||
|
tm.assert_almost_equal(output, json.loads(input))
|
||
|
|
||
|
def test_decodeNumericIntExpe(self):
|
||
|
input = "1337e40"
|
||
|
output = ujson.decode(input)
|
||
|
tm.assert_almost_equal(output, json.loads(input))
|
||
|
|
||
|
def test_decodeNumericIntExpEMinus(self):
|
||
|
input = "1.337E-4"
|
||
|
output = ujson.decode(input)
|
||
|
tm.assert_almost_equal(output, json.loads(input))
|
||
|
|
||
|
def test_decodeNumericIntExpeMinus(self):
|
||
|
input = "1.337e-4"
|
||
|
output = ujson.decode(input)
|
||
|
tm.assert_almost_equal(output, json.loads(input))
|
||
|
|
||
|
def test_dumpToFile(self):
|
||
|
f = StringIO()
|
||
|
ujson.dump([1, 2, 3], f)
|
||
|
assert "[1,2,3]" == f.getvalue()
|
||
|
|
||
|
def test_dumpToFileLikeObject(self):
|
||
|
class FileLike(object):
|
||
|
|
||
|
def __init__(self):
|
||
|
self.bytes = ''
|
||
|
|
||
|
def write(self, bytes):
|
||
|
self.bytes += bytes
|
||
|
f = FileLike()
|
||
|
ujson.dump([1, 2, 3], f)
|
||
|
assert "[1,2,3]" == f.bytes
|
||
|
|
||
|
def test_dumpFileArgsError(self):
|
||
|
try:
|
||
|
ujson.dump([], '')
|
||
|
except TypeError:
|
||
|
pass
|
||
|
else:
|
||
|
assert False, 'expected TypeError'
|
||
|
|
||
|
def test_loadFile(self):
|
||
|
f = StringIO("[1,2,3,4]")
|
||
|
assert [1, 2, 3, 4] == ujson.load(f)
|
||
|
|
||
|
f = StringIO("[1,2,3,4]")
|
||
|
tm.assert_numpy_array_equal(
|
||
|
np.array([1, 2, 3, 4]), ujson.load(f, numpy=True))
|
||
|
|
||
|
def test_loadFileLikeObject(self):
|
||
|
class FileLike(object):
|
||
|
|
||
|
def read(self):
|
||
|
try:
|
||
|
self.end
|
||
|
except AttributeError:
|
||
|
self.end = True
|
||
|
return "[1,2,3,4]"
|
||
|
f = FileLike()
|
||
|
assert [1, 2, 3, 4] == ujson.load(f)
|
||
|
|
||
|
f = FileLike()
|
||
|
tm.assert_numpy_array_equal(
|
||
|
np.array([1, 2, 3, 4]), ujson.load(f, numpy=True))
|
||
|
|
||
|
def test_loadFileArgsError(self):
|
||
|
try:
|
||
|
ujson.load("[]")
|
||
|
except TypeError:
|
||
|
pass
|
||
|
else:
|
||
|
assert False, "expected TypeError"
|
||
|
|
||
|
def test_version(self):
|
||
|
assert re.match(r'^\d+\.\d+(\.\d+)?$', ujson.__version__), \
|
||
|
"ujson.__version__ must be a string like '1.4.0'"
|
||
|
|
||
|
def test_encodeNumericOverflow(self):
|
||
|
try:
|
||
|
ujson.encode(12839128391289382193812939)
|
||
|
except OverflowError:
|
||
|
pass
|
||
|
else:
|
||
|
assert False, "expected OverflowError"
|
||
|
|
||
|
def test_encodeNumericOverflowNested(self):
|
||
|
for n in range(0, 100):
|
||
|
class Nested(object):
|
||
|
x = 12839128391289382193812939
|
||
|
|
||
|
nested = Nested()
|
||
|
|
||
|
try:
|
||
|
ujson.encode(nested)
|
||
|
except OverflowError:
|
||
|
pass
|
||
|
else:
|
||
|
assert False, "expected OverflowError"
|
||
|
|
||
|
def test_decodeNumberWith32bitSignBit(self):
|
||
|
# Test that numbers that fit within 32 bits but would have the
|
||
|
# sign bit set (2**31 <= x < 2**32) are decoded properly.
|
||
|
boundary1 = 2**31 # noqa
|
||
|
boundary2 = 2**32 # noqa
|
||
|
docs = (
|
||
|
'{"id": 3590016419}',
|
||
|
'{{"id": {low}}}'.format(low=2**31),
|
||
|
'{{"id": {high}}}'.format(high=2**32),
|
||
|
'{{"id": {one_less}}}'.format(one_less=(2**32) - 1),
|
||
|
)
|
||
|
results = (3590016419, 2**31, 2**32, 2**32 - 1)
|
||
|
for doc, result in zip(docs, results):
|
||
|
assert ujson.decode(doc)['id'] == result
|
||
|
|
||
|
def test_encodeBigEscape(self):
|
||
|
for x in range(10):
|
||
|
if compat.PY3:
|
||
|
base = '\u00e5'.encode('utf-8')
|
||
|
else:
|
||
|
base = "\xc3\xa5"
|
||
|
input = base * 1024 * 1024 * 2
|
||
|
output = ujson.encode(input) # noqa
|
||
|
|
||
|
def test_decodeBigEscape(self):
|
||
|
for x in range(10):
|
||
|
if compat.PY3:
|
||
|
base = '\u00e5'.encode('utf-8')
|
||
|
else:
|
||
|
base = "\xc3\xa5"
|
||
|
quote = compat.str_to_bytes("\"")
|
||
|
input = quote + (base * 1024 * 1024 * 2) + quote
|
||
|
output = ujson.decode(input) # noqa
|
||
|
|
||
|
def test_toDict(self):
|
||
|
d = {u("key"): 31337}
|
||
|
|
||
|
class DictTest(object):
|
||
|
|
||
|
def toDict(self):
|
||
|
return d
|
||
|
|
||
|
o = DictTest()
|
||
|
output = ujson.encode(o)
|
||
|
dec = ujson.decode(output)
|
||
|
assert dec == d
|
||
|
|
||
|
def test_defaultHandler(self):
|
||
|
|
||
|
class _TestObject(object):
|
||
|
|
||
|
def __init__(self, val):
|
||
|
self.val = val
|
||
|
|
||
|
@property
|
||
|
def recursive_attr(self):
|
||
|
return _TestObject("recursive_attr")
|
||
|
|
||
|
def __str__(self):
|
||
|
return str(self.val)
|
||
|
|
||
|
pytest.raises(OverflowError, ujson.encode, _TestObject("foo"))
|
||
|
assert '"foo"' == ujson.encode(_TestObject("foo"),
|
||
|
default_handler=str)
|
||
|
|
||
|
def my_handler(obj):
|
||
|
return "foobar"
|
||
|
|
||
|
assert '"foobar"' == ujson.encode(_TestObject("foo"),
|
||
|
default_handler=my_handler)
|
||
|
|
||
|
def my_handler_raises(obj):
|
||
|
raise TypeError("I raise for anything")
|
||
|
|
||
|
with tm.assert_raises_regex(TypeError, "I raise for anything"):
|
||
|
ujson.encode(_TestObject("foo"), default_handler=my_handler_raises)
|
||
|
|
||
|
def my_int_handler(obj):
|
||
|
return 42
|
||
|
|
||
|
assert ujson.decode(ujson.encode(
|
||
|
_TestObject("foo"), default_handler=my_int_handler)) == 42
|
||
|
|
||
|
def my_obj_handler(obj):
|
||
|
return datetime.datetime(2013, 2, 3)
|
||
|
|
||
|
assert (ujson.decode(ujson.encode(datetime.datetime(2013, 2, 3))) ==
|
||
|
ujson.decode(ujson.encode(_TestObject("foo"),
|
||
|
default_handler=my_obj_handler)))
|
||
|
|
||
|
l = [_TestObject("foo"), _TestObject("bar")]
|
||
|
assert (json.loads(json.dumps(l, default=str)) ==
|
||
|
ujson.decode(ujson.encode(l, default_handler=str)))
|
||
|
|
||
|
|
||
|
class TestNumpyJSONTests(object):
|
||
|
|
||
|
def test_Bool(self):
|
||
|
b = np.bool(True)
|
||
|
assert ujson.decode(ujson.encode(b)) == b
|
||
|
|
||
|
def test_BoolArray(self):
|
||
|
inpt = np.array([True, False, True, True, False, True, False, False],
|
||
|
dtype=np.bool)
|
||
|
outp = np.array(ujson.decode(ujson.encode(inpt)), dtype=np.bool)
|
||
|
tm.assert_numpy_array_equal(inpt, outp)
|
||
|
|
||
|
def test_Int(self):
|
||
|
num = np.int(2562010)
|
||
|
assert np.int(ujson.decode(ujson.encode(num))) == num
|
||
|
|
||
|
num = np.int8(127)
|
||
|
assert np.int8(ujson.decode(ujson.encode(num))) == num
|
||
|
|
||
|
num = np.int16(2562010)
|
||
|
assert np.int16(ujson.decode(ujson.encode(num))) == num
|
||
|
|
||
|
num = np.int32(2562010)
|
||
|
assert np.int32(ujson.decode(ujson.encode(num))) == num
|
||
|
|
||
|
num = np.int64(2562010)
|
||
|
assert np.int64(ujson.decode(ujson.encode(num))) == num
|
||
|
|
||
|
num = np.uint8(255)
|
||
|
assert np.uint8(ujson.decode(ujson.encode(num))) == num
|
||
|
|
||
|
num = np.uint16(2562010)
|
||
|
assert np.uint16(ujson.decode(ujson.encode(num))) == num
|
||
|
|
||
|
num = np.uint32(2562010)
|
||
|
assert np.uint32(ujson.decode(ujson.encode(num))) == num
|
||
|
|
||
|
num = np.uint64(2562010)
|
||
|
assert np.uint64(ujson.decode(ujson.encode(num))) == num
|
||
|
|
||
|
def test_IntArray(self):
|
||
|
arr = np.arange(100, dtype=np.int)
|
||
|
dtypes = (np.int, np.int8, np.int16, np.int32, np.int64,
|
||
|
np.uint, np.uint8, np.uint16, np.uint32, np.uint64)
|
||
|
for dtype in dtypes:
|
||
|
inpt = arr.astype(dtype)
|
||
|
outp = np.array(ujson.decode(ujson.encode(inpt)), dtype=dtype)
|
||
|
tm.assert_numpy_array_equal(inpt, outp)
|
||
|
|
||
|
def test_IntMax(self):
|
||
|
num = np.int(np.iinfo(np.int).max)
|
||
|
assert np.int(ujson.decode(ujson.encode(num))) == num
|
||
|
|
||
|
num = np.int8(np.iinfo(np.int8).max)
|
||
|
assert np.int8(ujson.decode(ujson.encode(num))) == num
|
||
|
|
||
|
num = np.int16(np.iinfo(np.int16).max)
|
||
|
assert np.int16(ujson.decode(ujson.encode(num))) == num
|
||
|
|
||
|
num = np.int32(np.iinfo(np.int32).max)
|
||
|
assert np.int32(ujson.decode(ujson.encode(num))) == num
|
||
|
|
||
|
num = np.uint8(np.iinfo(np.uint8).max)
|
||
|
assert np.uint8(ujson.decode(ujson.encode(num))) == num
|
||
|
|
||
|
num = np.uint16(np.iinfo(np.uint16).max)
|
||
|
assert np.uint16(ujson.decode(ujson.encode(num))) == num
|
||
|
|
||
|
num = np.uint32(np.iinfo(np.uint32).max)
|
||
|
assert np.uint32(ujson.decode(ujson.encode(num))) == num
|
||
|
|
||
|
if not compat.is_platform_32bit():
|
||
|
num = np.int64(np.iinfo(np.int64).max)
|
||
|
assert np.int64(ujson.decode(ujson.encode(num))) == num
|
||
|
|
||
|
# uint64 max will always overflow as it's encoded to signed
|
||
|
num = np.uint64(np.iinfo(np.int64).max)
|
||
|
assert np.uint64(ujson.decode(ujson.encode(num))) == num
|
||
|
|
||
|
def test_Float(self):
|
||
|
num = np.float(256.2013)
|
||
|
assert np.float(ujson.decode(ujson.encode(num))) == num
|
||
|
|
||
|
num = np.float32(256.2013)
|
||
|
assert np.float32(ujson.decode(ujson.encode(num))) == num
|
||
|
|
||
|
num = np.float64(256.2013)
|
||
|
assert np.float64(ujson.decode(ujson.encode(num))) == num
|
||
|
|
||
|
def test_FloatArray(self):
|
||
|
arr = np.arange(12.5, 185.72, 1.7322, dtype=np.float)
|
||
|
dtypes = (np.float, np.float32, np.float64)
|
||
|
|
||
|
for dtype in dtypes:
|
||
|
inpt = arr.astype(dtype)
|
||
|
outp = np.array(ujson.decode(ujson.encode(
|
||
|
inpt, double_precision=15)), dtype=dtype)
|
||
|
tm.assert_almost_equal(inpt, outp)
|
||
|
|
||
|
def test_FloatMax(self):
|
||
|
num = np.float(np.finfo(np.float).max / 10)
|
||
|
tm.assert_almost_equal(np.float(ujson.decode(
|
||
|
ujson.encode(num, double_precision=15))), num, 15)
|
||
|
|
||
|
num = np.float32(np.finfo(np.float32).max / 10)
|
||
|
tm.assert_almost_equal(np.float32(ujson.decode(
|
||
|
ujson.encode(num, double_precision=15))), num, 15)
|
||
|
|
||
|
num = np.float64(np.finfo(np.float64).max / 10)
|
||
|
tm.assert_almost_equal(np.float64(ujson.decode(
|
||
|
ujson.encode(num, double_precision=15))), num, 15)
|
||
|
|
||
|
def test_Arrays(self):
|
||
|
arr = np.arange(100)
|
||
|
|
||
|
arr = arr.reshape((10, 10))
|
||
|
tm.assert_numpy_array_equal(
|
||
|
np.array(ujson.decode(ujson.encode(arr))), arr)
|
||
|
tm.assert_numpy_array_equal(ujson.decode(
|
||
|
ujson.encode(arr), numpy=True), arr)
|
||
|
|
||
|
arr = arr.reshape((5, 5, 4))
|
||
|
tm.assert_numpy_array_equal(
|
||
|
np.array(ujson.decode(ujson.encode(arr))), arr)
|
||
|
tm.assert_numpy_array_equal(ujson.decode(
|
||
|
ujson.encode(arr), numpy=True), arr)
|
||
|
|
||
|
arr = arr.reshape((100, 1))
|
||
|
tm.assert_numpy_array_equal(
|
||
|
np.array(ujson.decode(ujson.encode(arr))), arr)
|
||
|
tm.assert_numpy_array_equal(ujson.decode(
|
||
|
ujson.encode(arr), numpy=True), arr)
|
||
|
|
||
|
arr = np.arange(96)
|
||
|
arr = arr.reshape((2, 2, 2, 2, 3, 2))
|
||
|
tm.assert_numpy_array_equal(
|
||
|
np.array(ujson.decode(ujson.encode(arr))), arr)
|
||
|
tm.assert_numpy_array_equal(ujson.decode(
|
||
|
ujson.encode(arr), numpy=True), arr)
|
||
|
|
||
|
l = ['a', list(), dict(), dict(), list(),
|
||
|
42, 97.8, ['a', 'b'], {'key': 'val'}]
|
||
|
arr = np.array(l)
|
||
|
tm.assert_numpy_array_equal(
|
||
|
np.array(ujson.decode(ujson.encode(arr))), arr)
|
||
|
|
||
|
arr = np.arange(100.202, 200.202, 1, dtype=np.float32)
|
||
|
arr = arr.reshape((5, 5, 4))
|
||
|
outp = np.array(ujson.decode(ujson.encode(arr)), dtype=np.float32)
|
||
|
tm.assert_almost_equal(arr, outp)
|
||
|
outp = ujson.decode(ujson.encode(arr), numpy=True, dtype=np.float32)
|
||
|
tm.assert_almost_equal(arr, outp)
|
||
|
|
||
|
def test_OdArray(self):
|
||
|
def will_raise():
|
||
|
ujson.encode(np.array(1))
|
||
|
|
||
|
pytest.raises(TypeError, will_raise)
|
||
|
|
||
|
def test_ArrayNumpyExcept(self):
|
||
|
|
||
|
input = ujson.dumps([42, {}, 'a'])
|
||
|
try:
|
||
|
ujson.decode(input, numpy=True)
|
||
|
assert False, "Expected exception!"
|
||
|
except(TypeError):
|
||
|
pass
|
||
|
except:
|
||
|
assert False, "Wrong exception"
|
||
|
|
||
|
input = ujson.dumps(['a', 'b', [], 'c'])
|
||
|
try:
|
||
|
ujson.decode(input, numpy=True)
|
||
|
assert False, "Expected exception!"
|
||
|
except(ValueError):
|
||
|
pass
|
||
|
except:
|
||
|
assert False, "Wrong exception"
|
||
|
|
||
|
input = ujson.dumps([['a'], 42])
|
||
|
try:
|
||
|
ujson.decode(input, numpy=True)
|
||
|
assert False, "Expected exception!"
|
||
|
except(ValueError):
|
||
|
pass
|
||
|
except:
|
||
|
assert False, "Wrong exception"
|
||
|
|
||
|
input = ujson.dumps([42, ['a'], 42])
|
||
|
try:
|
||
|
ujson.decode(input, numpy=True)
|
||
|
assert False, "Expected exception!"
|
||
|
except(ValueError):
|
||
|
pass
|
||
|
except:
|
||
|
assert False, "Wrong exception"
|
||
|
|
||
|
input = ujson.dumps([{}, []])
|
||
|
try:
|
||
|
ujson.decode(input, numpy=True)
|
||
|
assert False, "Expected exception!"
|
||
|
except(ValueError):
|
||
|
pass
|
||
|
except:
|
||
|
assert False, "Wrong exception"
|
||
|
|
||
|
input = ujson.dumps([42, None])
|
||
|
try:
|
||
|
ujson.decode(input, numpy=True)
|
||
|
assert False, "Expected exception!"
|
||
|
except(TypeError):
|
||
|
pass
|
||
|
except:
|
||
|
assert False, "Wrong exception"
|
||
|
|
||
|
input = ujson.dumps([{'a': 'b'}])
|
||
|
try:
|
||
|
ujson.decode(input, numpy=True, labelled=True)
|
||
|
assert False, "Expected exception!"
|
||
|
except(ValueError):
|
||
|
pass
|
||
|
except:
|
||
|
assert False, "Wrong exception"
|
||
|
|
||
|
input = ujson.dumps({'a': {'b': {'c': 42}}})
|
||
|
try:
|
||
|
ujson.decode(input, numpy=True, labelled=True)
|
||
|
assert False, "Expected exception!"
|
||
|
except(ValueError):
|
||
|
pass
|
||
|
except:
|
||
|
assert False, "Wrong exception"
|
||
|
|
||
|
input = ujson.dumps([{'a': 42, 'b': 23}, {'c': 17}])
|
||
|
try:
|
||
|
ujson.decode(input, numpy=True, labelled=True)
|
||
|
assert False, "Expected exception!"
|
||
|
except(ValueError):
|
||
|
pass
|
||
|
except:
|
||
|
assert False, "Wrong exception"
|
||
|
|
||
|
def test_ArrayNumpyLabelled(self):
|
||
|
input = {'a': []}
|
||
|
output = ujson.loads(ujson.dumps(input), numpy=True, labelled=True)
|
||
|
assert (np.empty((1, 0)) == output[0]).all()
|
||
|
assert (np.array(['a']) == output[1]).all()
|
||
|
assert output[2] is None
|
||
|
|
||
|
input = [{'a': 42}]
|
||
|
output = ujson.loads(ujson.dumps(input), numpy=True, labelled=True)
|
||
|
assert (np.array([42]) == output[0]).all()
|
||
|
assert output[1] is None
|
||
|
assert (np.array([u('a')]) == output[2]).all()
|
||
|
|
||
|
# Write out the dump explicitly so there is no dependency on iteration
|
||
|
# order GH10837
|
||
|
input_dumps = ('[{"a": 42, "b":31}, {"a": 24, "c": 99}, '
|
||
|
'{"a": 2.4, "b": 78}]')
|
||
|
output = ujson.loads(input_dumps, numpy=True, labelled=True)
|
||
|
expectedvals = np.array(
|
||
|
[42, 31, 24, 99, 2.4, 78], dtype=int).reshape((3, 2))
|
||
|
assert (expectedvals == output[0]).all()
|
||
|
assert output[1] is None
|
||
|
assert (np.array([u('a'), 'b']) == output[2]).all()
|
||
|
|
||
|
input_dumps = ('{"1": {"a": 42, "b":31}, "2": {"a": 24, "c": 99}, '
|
||
|
'"3": {"a": 2.4, "b": 78}}')
|
||
|
output = ujson.loads(input_dumps, numpy=True, labelled=True)
|
||
|
expectedvals = np.array(
|
||
|
[42, 31, 24, 99, 2.4, 78], dtype=int).reshape((3, 2))
|
||
|
assert (expectedvals == output[0]).all()
|
||
|
assert (np.array(['1', '2', '3']) == output[1]).all()
|
||
|
assert (np.array(['a', 'b']) == output[2]).all()
|
||
|
|
||
|
|
||
|
class TestPandasJSONTests(object):
|
||
|
|
||
|
def test_DataFrame(self):
|
||
|
df = DataFrame([[1, 2, 3], [4, 5, 6]], index=[
|
||
|
'a', 'b'], columns=['x', 'y', 'z'])
|
||
|
|
||
|
# column indexed
|
||
|
outp = DataFrame(ujson.decode(ujson.encode(df)))
|
||
|
assert (df == outp).values.all()
|
||
|
tm.assert_index_equal(df.columns, outp.columns)
|
||
|
tm.assert_index_equal(df.index, outp.index)
|
||
|
|
||
|
dec = _clean_dict(ujson.decode(ujson.encode(df, orient="split")))
|
||
|
outp = DataFrame(**dec)
|
||
|
assert (df == outp).values.all()
|
||
|
tm.assert_index_equal(df.columns, outp.columns)
|
||
|
tm.assert_index_equal(df.index, outp.index)
|
||
|
|
||
|
outp = DataFrame(ujson.decode(ujson.encode(df, orient="records")))
|
||
|
outp.index = df.index
|
||
|
assert (df == outp).values.all()
|
||
|
tm.assert_index_equal(df.columns, outp.columns)
|
||
|
|
||
|
outp = DataFrame(ujson.decode(ujson.encode(df, orient="values")))
|
||
|
outp.index = df.index
|
||
|
assert (df.values == outp.values).all()
|
||
|
|
||
|
outp = DataFrame(ujson.decode(ujson.encode(df, orient="index")))
|
||
|
assert (df.transpose() == outp).values.all()
|
||
|
tm.assert_index_equal(df.transpose().columns, outp.columns)
|
||
|
tm.assert_index_equal(df.transpose().index, outp.index)
|
||
|
|
||
|
def test_DataFrameNumpy(self):
|
||
|
df = DataFrame([[1, 2, 3], [4, 5, 6]], index=[
|
||
|
'a', 'b'], columns=['x', 'y', 'z'])
|
||
|
|
||
|
# column indexed
|
||
|
outp = DataFrame(ujson.decode(ujson.encode(df), numpy=True))
|
||
|
assert (df == outp).values.all()
|
||
|
tm.assert_index_equal(df.columns, outp.columns)
|
||
|
tm.assert_index_equal(df.index, outp.index)
|
||
|
|
||
|
dec = _clean_dict(ujson.decode(ujson.encode(df, orient="split"),
|
||
|
numpy=True))
|
||
|
outp = DataFrame(**dec)
|
||
|
assert (df == outp).values.all()
|
||
|
tm.assert_index_equal(df.columns, outp.columns)
|
||
|
tm.assert_index_equal(df.index, outp.index)
|
||
|
|
||
|
outp = DataFrame(ujson.decode(ujson.encode(df, orient="index"),
|
||
|
numpy=True))
|
||
|
assert (df.transpose() == outp).values.all()
|
||
|
tm.assert_index_equal(df.transpose().columns, outp.columns)
|
||
|
tm.assert_index_equal(df.transpose().index, outp.index)
|
||
|
|
||
|
def test_DataFrameNested(self):
|
||
|
df = DataFrame([[1, 2, 3], [4, 5, 6]], index=[
|
||
|
'a', 'b'], columns=['x', 'y', 'z'])
|
||
|
|
||
|
nested = {'df1': df, 'df2': df.copy()}
|
||
|
|
||
|
exp = {'df1': ujson.decode(ujson.encode(df)),
|
||
|
'df2': ujson.decode(ujson.encode(df))}
|
||
|
assert ujson.decode(ujson.encode(nested)) == exp
|
||
|
|
||
|
exp = {'df1': ujson.decode(ujson.encode(df, orient="index")),
|
||
|
'df2': ujson.decode(ujson.encode(df, orient="index"))}
|
||
|
assert ujson.decode(ujson.encode(nested, orient="index")) == exp
|
||
|
|
||
|
exp = {'df1': ujson.decode(ujson.encode(df, orient="records")),
|
||
|
'df2': ujson.decode(ujson.encode(df, orient="records"))}
|
||
|
assert ujson.decode(ujson.encode(nested, orient="records")) == exp
|
||
|
|
||
|
exp = {'df1': ujson.decode(ujson.encode(df, orient="values")),
|
||
|
'df2': ujson.decode(ujson.encode(df, orient="values"))}
|
||
|
assert ujson.decode(ujson.encode(nested, orient="values")) == exp
|
||
|
|
||
|
exp = {'df1': ujson.decode(ujson.encode(df, orient="split")),
|
||
|
'df2': ujson.decode(ujson.encode(df, orient="split"))}
|
||
|
assert ujson.decode(ujson.encode(nested, orient="split")) == exp
|
||
|
|
||
|
def test_DataFrameNumpyLabelled(self):
|
||
|
df = DataFrame([[1, 2, 3], [4, 5, 6]], index=[
|
||
|
'a', 'b'], columns=['x', 'y', 'z'])
|
||
|
|
||
|
# column indexed
|
||
|
outp = DataFrame(*ujson.decode(ujson.encode(df),
|
||
|
numpy=True, labelled=True))
|
||
|
assert (df.T == outp).values.all()
|
||
|
tm.assert_index_equal(df.T.columns, outp.columns)
|
||
|
tm.assert_index_equal(df.T.index, outp.index)
|
||
|
|
||
|
outp = DataFrame(*ujson.decode(ujson.encode(df, orient="records"),
|
||
|
numpy=True, labelled=True))
|
||
|
outp.index = df.index
|
||
|
assert (df == outp).values.all()
|
||
|
tm.assert_index_equal(df.columns, outp.columns)
|
||
|
|
||
|
outp = DataFrame(*ujson.decode(ujson.encode(df, orient="index"),
|
||
|
numpy=True, labelled=True))
|
||
|
assert (df == outp).values.all()
|
||
|
tm.assert_index_equal(df.columns, outp.columns)
|
||
|
tm.assert_index_equal(df.index, outp.index)
|
||
|
|
||
|
def test_Series(self):
|
||
|
s = Series([10, 20, 30, 40, 50, 60], name="series",
|
||
|
index=[6, 7, 8, 9, 10, 15]).sort_values()
|
||
|
|
||
|
# column indexed
|
||
|
outp = Series(ujson.decode(ujson.encode(s))).sort_values()
|
||
|
exp = Series([10, 20, 30, 40, 50, 60],
|
||
|
index=['6', '7', '8', '9', '10', '15'])
|
||
|
tm.assert_series_equal(outp, exp)
|
||
|
|
||
|
outp = Series(ujson.decode(ujson.encode(s), numpy=True)).sort_values()
|
||
|
tm.assert_series_equal(outp, exp)
|
||
|
|
||
|
dec = _clean_dict(ujson.decode(ujson.encode(s, orient="split")))
|
||
|
outp = Series(**dec)
|
||
|
tm.assert_series_equal(outp, s)
|
||
|
|
||
|
dec = _clean_dict(ujson.decode(ujson.encode(s, orient="split"),
|
||
|
numpy=True))
|
||
|
outp = Series(**dec)
|
||
|
|
||
|
exp_np = Series(np.array([10, 20, 30, 40, 50, 60]))
|
||
|
exp_pd = Series([10, 20, 30, 40, 50, 60])
|
||
|
outp = Series(ujson.decode(ujson.encode(s, orient="records"),
|
||
|
numpy=True))
|
||
|
tm.assert_series_equal(outp, exp_np)
|
||
|
|
||
|
outp = Series(ujson.decode(ujson.encode(s, orient="records")))
|
||
|
exp = Series([10, 20, 30, 40, 50, 60])
|
||
|
tm.assert_series_equal(outp, exp_pd)
|
||
|
|
||
|
outp = Series(ujson.decode(ujson.encode(s, orient="values"),
|
||
|
numpy=True))
|
||
|
tm.assert_series_equal(outp, exp_np)
|
||
|
|
||
|
outp = Series(ujson.decode(ujson.encode(s, orient="values")))
|
||
|
tm.assert_series_equal(outp, exp_pd)
|
||
|
|
||
|
outp = Series(ujson.decode(ujson.encode(
|
||
|
s, orient="index"))).sort_values()
|
||
|
exp = Series([10, 20, 30, 40, 50, 60],
|
||
|
index=['6', '7', '8', '9', '10', '15'])
|
||
|
tm.assert_series_equal(outp, exp)
|
||
|
|
||
|
outp = Series(ujson.decode(ujson.encode(
|
||
|
s, orient="index"), numpy=True)).sort_values()
|
||
|
tm.assert_series_equal(outp, exp)
|
||
|
|
||
|
def test_SeriesNested(self):
|
||
|
s = Series([10, 20, 30, 40, 50, 60], name="series",
|
||
|
index=[6, 7, 8, 9, 10, 15]).sort_values()
|
||
|
|
||
|
nested = {'s1': s, 's2': s.copy()}
|
||
|
|
||
|
exp = {'s1': ujson.decode(ujson.encode(s)),
|
||
|
's2': ujson.decode(ujson.encode(s))}
|
||
|
assert ujson.decode(ujson.encode(nested)) == exp
|
||
|
|
||
|
exp = {'s1': ujson.decode(ujson.encode(s, orient="split")),
|
||
|
's2': ujson.decode(ujson.encode(s, orient="split"))}
|
||
|
assert ujson.decode(ujson.encode(nested, orient="split")) == exp
|
||
|
|
||
|
exp = {'s1': ujson.decode(ujson.encode(s, orient="records")),
|
||
|
's2': ujson.decode(ujson.encode(s, orient="records"))}
|
||
|
assert ujson.decode(ujson.encode(nested, orient="records")) == exp
|
||
|
|
||
|
exp = {'s1': ujson.decode(ujson.encode(s, orient="values")),
|
||
|
's2': ujson.decode(ujson.encode(s, orient="values"))}
|
||
|
assert ujson.decode(ujson.encode(nested, orient="values")) == exp
|
||
|
|
||
|
exp = {'s1': ujson.decode(ujson.encode(s, orient="index")),
|
||
|
's2': ujson.decode(ujson.encode(s, orient="index"))}
|
||
|
assert ujson.decode(ujson.encode(nested, orient="index")) == exp
|
||
|
|
||
|
def test_Index(self):
|
||
|
i = Index([23, 45, 18, 98, 43, 11], name="index")
|
||
|
|
||
|
# column indexed
|
||
|
outp = Index(ujson.decode(ujson.encode(i)), name='index')
|
||
|
tm.assert_index_equal(i, outp)
|
||
|
|
||
|
outp = Index(ujson.decode(ujson.encode(i), numpy=True), name='index')
|
||
|
tm.assert_index_equal(i, outp)
|
||
|
|
||
|
dec = _clean_dict(ujson.decode(ujson.encode(i, orient="split")))
|
||
|
outp = Index(**dec)
|
||
|
tm.assert_index_equal(i, outp)
|
||
|
assert i.name == outp.name
|
||
|
|
||
|
dec = _clean_dict(ujson.decode(ujson.encode(i, orient="split"),
|
||
|
numpy=True))
|
||
|
outp = Index(**dec)
|
||
|
tm.assert_index_equal(i, outp)
|
||
|
assert i.name == outp.name
|
||
|
|
||
|
outp = Index(ujson.decode(ujson.encode(i, orient="values")),
|
||
|
name='index')
|
||
|
tm.assert_index_equal(i, outp)
|
||
|
|
||
|
outp = Index(ujson.decode(ujson.encode(i, orient="values"),
|
||
|
numpy=True), name='index')
|
||
|
tm.assert_index_equal(i, outp)
|
||
|
|
||
|
outp = Index(ujson.decode(ujson.encode(i, orient="records")),
|
||
|
name='index')
|
||
|
tm.assert_index_equal(i, outp)
|
||
|
|
||
|
outp = Index(ujson.decode(ujson.encode(i, orient="records"),
|
||
|
numpy=True), name='index')
|
||
|
tm.assert_index_equal(i, outp)
|
||
|
|
||
|
outp = Index(ujson.decode(ujson.encode(i, orient="index")),
|
||
|
name='index')
|
||
|
tm.assert_index_equal(i, outp)
|
||
|
|
||
|
outp = Index(ujson.decode(ujson.encode(i, orient="index"),
|
||
|
numpy=True), name='index')
|
||
|
tm.assert_index_equal(i, outp)
|
||
|
|
||
|
def test_datetimeindex(self):
|
||
|
from pandas.core.indexes.datetimes import date_range
|
||
|
|
||
|
rng = date_range('1/1/2000', periods=20)
|
||
|
|
||
|
encoded = ujson.encode(rng, date_unit='ns')
|
||
|
decoded = DatetimeIndex(np.array(ujson.decode(encoded)))
|
||
|
|
||
|
tm.assert_index_equal(rng, decoded)
|
||
|
|
||
|
ts = Series(np.random.randn(len(rng)), index=rng)
|
||
|
decoded = Series(ujson.decode(ujson.encode(ts, date_unit='ns')))
|
||
|
idx_values = decoded.index.values.astype(np.int64)
|
||
|
decoded.index = DatetimeIndex(idx_values)
|
||
|
tm.assert_series_equal(ts, decoded)
|
||
|
|
||
|
def test_decodeArrayTrailingCommaFail(self):
|
||
|
input = "[31337,]"
|
||
|
try:
|
||
|
ujson.decode(input)
|
||
|
except ValueError:
|
||
|
pass
|
||
|
else:
|
||
|
assert False, "expected ValueError"
|
||
|
|
||
|
def test_decodeArrayLeadingCommaFail(self):
|
||
|
input = "[,31337]"
|
||
|
try:
|
||
|
ujson.decode(input)
|
||
|
except ValueError:
|
||
|
pass
|
||
|
else:
|
||
|
assert False, "expected ValueError"
|
||
|
|
||
|
def test_decodeArrayOnlyCommaFail(self):
|
||
|
input = "[,]"
|
||
|
try:
|
||
|
ujson.decode(input)
|
||
|
except ValueError:
|
||
|
pass
|
||
|
else:
|
||
|
assert False, "expected ValueError"
|
||
|
|
||
|
def test_decodeArrayUnmatchedBracketFail(self):
|
||
|
input = "[]]"
|
||
|
try:
|
||
|
ujson.decode(input)
|
||
|
except ValueError:
|
||
|
pass
|
||
|
else:
|
||
|
assert False, "expected ValueError"
|
||
|
|
||
|
def test_decodeArrayEmpty(self):
|
||
|
input = "[]"
|
||
|
ujson.decode(input)
|
||
|
|
||
|
def test_decodeArrayOneItem(self):
|
||
|
input = "[31337]"
|
||
|
ujson.decode(input)
|
||
|
|
||
|
def test_decodeBigValue(self):
|
||
|
input = "9223372036854775807"
|
||
|
ujson.decode(input)
|
||
|
|
||
|
def test_decodeSmallValue(self):
|
||
|
input = "-9223372036854775808"
|
||
|
ujson.decode(input)
|
||
|
|
||
|
def test_decodeTooBigValue(self):
|
||
|
try:
|
||
|
input = "9223372036854775808"
|
||
|
ujson.decode(input)
|
||
|
except ValueError:
|
||
|
pass
|
||
|
else:
|
||
|
assert False, "expected ValueError"
|
||
|
|
||
|
def test_decodeTooSmallValue(self):
|
||
|
try:
|
||
|
input = "-90223372036854775809"
|
||
|
ujson.decode(input)
|
||
|
except ValueError:
|
||
|
pass
|
||
|
else:
|
||
|
assert False, "expected ValueError"
|
||
|
|
||
|
def test_decodeVeryTooBigValue(self):
|
||
|
try:
|
||
|
input = "9223372036854775808"
|
||
|
ujson.decode(input)
|
||
|
except ValueError:
|
||
|
pass
|
||
|
else:
|
||
|
assert False, "expected ValueError"
|
||
|
|
||
|
def test_decodeVeryTooSmallValue(self):
|
||
|
try:
|
||
|
input = "-90223372036854775809"
|
||
|
ujson.decode(input)
|
||
|
except ValueError:
|
||
|
pass
|
||
|
else:
|
||
|
assert False, "expected ValueError"
|
||
|
|
||
|
def test_decodeWithTrailingWhitespaces(self):
|
||
|
input = "{}\n\t "
|
||
|
ujson.decode(input)
|
||
|
|
||
|
def test_decodeWithTrailingNonWhitespaces(self):
|
||
|
try:
|
||
|
input = "{}\n\t a"
|
||
|
ujson.decode(input)
|
||
|
except ValueError:
|
||
|
pass
|
||
|
else:
|
||
|
assert False, "expected ValueError"
|
||
|
|
||
|
def test_decodeArrayWithBigInt(self):
|
||
|
try:
|
||
|
ujson.loads('[18446098363113800555]')
|
||
|
except ValueError:
|
||
|
pass
|
||
|
else:
|
||
|
assert False, "expected ValueError"
|
||
|
|
||
|
def test_decodeArrayFaultyUnicode(self):
|
||
|
try:
|
||
|
ujson.loads('[18446098363113800555]')
|
||
|
except ValueError:
|
||
|
pass
|
||
|
else:
|
||
|
assert False, "expected ValueError"
|
||
|
|
||
|
def test_decodeFloatingPointAdditionalTests(self):
|
||
|
places = 15
|
||
|
|
||
|
tm.assert_almost_equal(-1.1234567893,
|
||
|
ujson.loads("-1.1234567893"),
|
||
|
check_less_precise=places)
|
||
|
tm.assert_almost_equal(-1.234567893,
|
||
|
ujson.loads("-1.234567893"),
|
||
|
check_less_precise=places)
|
||
|
tm.assert_almost_equal(-1.34567893,
|
||
|
ujson.loads("-1.34567893"),
|
||
|
check_less_precise=places)
|
||
|
tm.assert_almost_equal(-1.4567893,
|
||
|
ujson.loads("-1.4567893"),
|
||
|
check_less_precise=places)
|
||
|
tm.assert_almost_equal(-1.567893,
|
||
|
ujson.loads("-1.567893"),
|
||
|
check_less_precise=places)
|
||
|
tm.assert_almost_equal(-1.67893,
|
||
|
ujson.loads("-1.67893"),
|
||
|
check_less_precise=places)
|
||
|
tm.assert_almost_equal(-1.7893, ujson.loads("-1.7893"),
|
||
|
check_less_precise=places)
|
||
|
tm.assert_almost_equal(-1.893, ujson.loads("-1.893"),
|
||
|
check_less_precise=places)
|
||
|
tm.assert_almost_equal(-1.3, ujson.loads("-1.3"),
|
||
|
check_less_precise=places)
|
||
|
|
||
|
tm.assert_almost_equal(1.1234567893, ujson.loads(
|
||
|
"1.1234567893"), check_less_precise=places)
|
||
|
tm.assert_almost_equal(1.234567893, ujson.loads(
|
||
|
"1.234567893"), check_less_precise=places)
|
||
|
tm.assert_almost_equal(
|
||
|
1.34567893, ujson.loads("1.34567893"), check_less_precise=places)
|
||
|
tm.assert_almost_equal(
|
||
|
1.4567893, ujson.loads("1.4567893"), check_less_precise=places)
|
||
|
tm.assert_almost_equal(
|
||
|
1.567893, ujson.loads("1.567893"), check_less_precise=places)
|
||
|
tm.assert_almost_equal(1.67893, ujson.loads("1.67893"),
|
||
|
check_less_precise=places)
|
||
|
tm.assert_almost_equal(1.7893, ujson.loads("1.7893"),
|
||
|
check_less_precise=places)
|
||
|
tm.assert_almost_equal(1.893, ujson.loads("1.893"),
|
||
|
check_less_precise=places)
|
||
|
tm.assert_almost_equal(1.3, ujson.loads("1.3"),
|
||
|
check_less_precise=places)
|
||
|
|
||
|
def test_encodeBigSet(self):
|
||
|
s = set()
|
||
|
for x in range(0, 100000):
|
||
|
s.add(x)
|
||
|
ujson.encode(s)
|
||
|
|
||
|
def test_encodeEmptySet(self):
|
||
|
s = set()
|
||
|
assert "[]" == ujson.encode(s)
|
||
|
|
||
|
def test_encodeSet(self):
|
||
|
s = set([1, 2, 3, 4, 5, 6, 7, 8, 9])
|
||
|
enc = ujson.encode(s)
|
||
|
dec = ujson.decode(enc)
|
||
|
|
||
|
for v in dec:
|
||
|
assert v in s
|
||
|
|
||
|
|
||
|
def _clean_dict(d):
|
||
|
return {str(k): v for k, v in compat.iteritems(d)}
|