Пример #1
0
def test_endless_recursion():
    # See #12051
    def hook(o):
        """With ujson this will keep adding another list."""
        return [o]

    with pytest.raises((RecursionError, OverflowError)):
        sd_ujson.dumps(5j, pre_encode_hook=hook)
Пример #2
0
def test_encode_dict_key_ref_counting():
    import gc

    gc.collect()
    key = "key"
    data = {key: "abc"}
    ref_count = sys.getrefcount(key)
    sd_ujson.dumps(data)
    assert ref_count == sys.getrefcount(key)
Пример #3
0
def test_ints():
	for num in [1, 1 << 32]:
		assert sd_ujson.dumps(num) == str(num)
		assert int(sd_ujson.dumps(num)) == num
	
	with pytest.raises(OverflowError):
		num = 1 << 64
		assert sd_ujson.dumps(num) == str(num)
		assert int(sd_ujson.dumps(num)) == num
Пример #4
0
def test_encode_dict_values_ref_counting():
    import gc

    gc.collect()
    value = ["abc"]
    data = {"1": value}
    ref_count = sys.getrefcount(value)
    sd_ujson.dumps(data)
    assert ref_count == sys.getrefcount(value)
Пример #5
0
def test_highly_nested_objects_encoding():
    # See #12051
    l, d = [], {}
    for x in range(100000):
        l, d = [l], {'k': d}
    with pytest.raises((RecursionError, OverflowError)):
        sd_ujson.dumps(l)
    with pytest.raises((RecursionError, OverflowError)):
        sd_ujson.dumps(d)
Пример #6
0
def test_allow_nan():
	for val in (float('inf'), float('-inf'), float('nan')):
		out = sd_ujson.dumps([val])
		if val == val:  # inf
			assert sd_ujson.loads(out) == [val]
		else:  # nan
			res = sd_ujson.loads(out)
			assert len(res) == 1
			assert res[0] != res[0]
		with pytest.raises(ValueError):
			sd_ujson.dumps([val], allow_nan=False)
Пример #7
0
def test_encode_truefalse():
    assert sd_ujson.dumps({
        True: False,
        False: True
    }, sort_keys=True) == ('{"false": true, "true": false}')
    assert sd_ujson.dumps({
        2: 3.0,
        4.0: 5,
        False: 1,
        6: True
    }, sort_keys=True) == ('{"false": 1, "2": 3.0, "4.0": 5, "6": true}')
Пример #8
0
def test_multiple_files():
	from .glossia import thorn
	from .glossia import talon
	
	# Test that we get the expected output when encoding a Decimal
	assert sd_ujson.dumps(Decimal(1)) == '"1"'
	
	# Test that we get the expected output when encoding a Fraction
	assert sd_ujson.dumps(Fraction(2, 3)) == '"2/3"'
	
	# Cleanup
	sd_ujson.encoders.unregister(Decimal)
	sd_ujson.encoders.unregister(Fraction)
Пример #9
0
def test_non_string_keys_dict():
	import sys
	
	data = {'a': 1, (1, 2): 2}
	
	# TODO:
	if sys.version_info.major >= 3 and sys.version_info.minor > 6:
		match_string = "keys must be str, int, float, bool or None, not tuple"
	else:
		match_string = "keys must be a string"

	with pytest.raises(TypeError, match=match_string):
		sd_ujson.dumps(data)
Пример #10
0
def test_fraction_str():
	# Create and register a custom encoder for Fraction that turns it into a str
	@sd_ujson.encoders.register(Fraction)
	def encode_fraction_str(obj):
		return str(obj)
	
	assert sd_ujson.dumps(Fraction(13, 10)) == '"13/10"'
	assert sd_ujson.dumps(Fraction(3, 4)) == '"3/4"'
	assert sd_ujson.dumps(Fraction(9, 11)) == '"9/11"'
	assert sd_ujson.dumps(Fraction(140, 144)) == '"35/36"'
	assert sd_ujson.dumps(Fraction(2, 7)) == '"2/7"'
	
	# Cleanup
	sd_ujson.encoders.unregister(Fraction)
Пример #11
0
def test_fraction_float():
	# Create and register a custom encoder for Fraction that turns it into a float
	@sd_ujson.encoders.register(Fraction)
	def encode_fraction_float(obj):
		return float(obj)
	
	assert sd_ujson.dumps(Fraction(13, 10)) == "1.3"
	assert sd_ujson.dumps(Fraction(3, 4)) == "0.75"
	assert sd_ujson.dumps(Fraction(9, 11)) == "0.8181818181818182"
	assert sd_ujson.dumps(Fraction(140, 144)) == "0.9722222222222222"
	assert sd_ujson.dumps(Fraction(2, 7)) == "0.2857142857142857"
	
	# Cleanup
	sd_ujson.encoders.unregister(Fraction)
Пример #12
0
def test_dictrecursion():
    x = {}
    x["test"] = x
    try:
        sd_ujson.dumps(x)
    except (ValueError, OverflowError):
        pass
    else:
        pytest.fail(
            "didn't raise ValueError or OverflowError on dict recursion")
    x = {}
    y = {"a": x, "b": x}
    # ensure that the marker is cleared
    sd_ujson.dumps(x)
Пример #13
0
def test_bytes_decode():
    for encoding, bom in [
        ('utf-8', codecs.BOM_UTF8),
        ('utf-16be', codecs.BOM_UTF16_BE),
        ('utf-16le', codecs.BOM_UTF16_LE),
        ('utf-32be', codecs.BOM_UTF32_BE),
        ('utf-32le', codecs.BOM_UTF32_LE),
    ]:
        data = ["a\xb5\u20ac\U0001d120"]
        encoded = sd_ujson.dumps(data).encode(encoding)
        print(data, encoded)
        assert sd_ujson.loads(bom + encoded) == data
        assert sd_ujson.loads(encoded) == data
    with pytest.raises(UnicodeDecodeError):
        sd_ujson.loads(b'["\x80"]')
    # RFC-7159 and ECMA-404 extend JSON to allow documents that
    # consist of only a string, which can present a special case
    # not covered by the encoding detection patterns specified in
    # RFC-4627 for utf-16-le (XX 00 XX 00).
    assert sd_ujson.loads('"\u2600"'.encode('utf-16-le')) == '\u2600'
    # Encoding detection for small (<4) bytes objects
    # is implemented as a special case. RFC-7159 and ECMA-404
    # allow single codepoint JSON documents which are only two
    # bytes in utf-16 encodings w/o BOM.
    assert sd_ujson.loads(b'5\x00') == 5
    assert sd_ujson.loads(b'\x007') == 7
    assert sd_ujson.loads(b'57') == 57
Пример #14
0
def test_encode_mutated():
    a = [object()] * 10

    def crasher(obj):
        del a[-1]

    assert sd_ujson.dumps(a,
                          default=crasher) == '[null, null, null, null, null]'
Пример #15
0
def test_encode_symbols():
    s = "\u273f\u2661\u273f"  # Рю┐РЎАРю┐
    encoded = sd_ujson.dumps(s)
    encoded_json = sdjson.dumps(s)
    assert len(encoded) == len(s) * 6 + 2  # 6 characters + quotes
    assert encoded == encoded_json
    decoded = sd_ujson.loads(encoded)
    assert s == decoded

    # sd_ujson outputs an UTF-8 encoded str object
    encoded = sd_ujson.dumps(s, ensure_ascii=False)

    # json outputs an unicode object
    encoded_json = sdjson.dumps(s, ensure_ascii=False)
    assert len(encoded) == len(s) + 2  # original length + quotes
    assert encoded == encoded_json
    decoded = sd_ujson.loads(encoded)
    assert s == decoded
Пример #16
0
def test_time_float():
	# Create and register a custom encoder for time that turns it into a float
	@sd_ujson.encoders.register(time)
	def encode_date_float(obj):
		return int(timedelta(hours=obj.hour, minutes=obj.minute, seconds=obj.second).total_seconds())
	
	assert sd_ujson.dumps(time(9, 10, 11)) == "33011"
	
	# Cleanup
	sd_ujson.encoders.unregister(time)
Пример #17
0
def test_time_str():
	# Create and register a custom encoder for time that turns it into a str
	@sd_ujson.encoders.register(time)
	def encode_time_str(obj):
		return f"{obj:%H:%M:%S}"
	
	assert sd_ujson.dumps(time(9, 10, 11)) == '"09:10:11"'
	
	# Cleanup
	sd_ujson.encoders.unregister(time)
Пример #18
0
def test_datetime_tuple():
	# Create and register a custom encoder for datetime that turns it into a timetuple
	@sd_ujson.encoders.register(datetime)
	def encode_datetime_tuple(obj):
		return obj.timetuple()
	
	assert sd_ujson.dumps(datetime(1945, 5, 8, 19, 20)) == nospace('[1945, 5, 8, 19, 20, 0, 1, 128, -1]')
	
	# Cleanup
	sd_ujson.encoders.unregister(datetime)
Пример #19
0
def test_decimal_str():
	# Create and register a custom encoder for Decimal that turns it into a str
	@sd_ujson.encoders.register(Decimal)
	def encode_decimal_str(obj):
		return str(obj)
	
	assert sd_ujson.dumps(Decimal(str(12.3456))) == '"12.3456"'
	
	# Cleanup
	sd_ujson.encoders.unregister(Decimal)
Пример #20
0
def test_time_tuple():
	# Create and register a custom encoder for time that turns it into a timetuple
	@sd_ujson.encoders.register(time)
	def encode_time_tuple(obj):
		return obj.hour, obj.minute, obj.second
	
	assert sd_ujson.dumps(time(9, 10, 11)) == nospace('[9, 10, 11]')
	
	# Cleanup
	sd_ujson.encoders.unregister(time)
Пример #21
0
def test_datetime_float():
	# Create and register a custom encoder for datetime that turns it into a float
	@sd_ujson.encoders.register(datetime)
	def encode_datetime_float(obj):
		return obj.timestamp()

	assert sd_ujson.dumps(datetime(1945, 5, 8, 19, 20, tzinfo=pytz.UTC)) == "-777876000.0"

	# Cleanup
	sd_ujson.encoders.unregister(datetime)
Пример #22
0
def test_parse_pass_2():
    # from http://json.org/JSON_checker/test/pass2.json
    JSON = r'''
    [[[[[[[[[[[[[[[[[[["Not too deep"]]]]]]]]]]]]]]]]]]]
    '''

    # test in/out equivalence and parsing
    res = sd_ujson.loads(JSON)
    out = sd_ujson.dumps(res)
    assert res == sd_ujson.loads(out)
Пример #23
0
def test_datetime_str():
	# Create and register a custom encoder for datetime that turns it into a str
	@sd_ujson.encoders.register(datetime)
	def encode_datetime_str(obj):
		return f"{obj:%Y/%-m/%-d %H:%M}"
	
	assert sd_ujson.dumps(datetime(1945, 5, 8, 19, 20)) == '"1945/5/8 19:20"'
	
	# Cleanup
	sd_ujson.encoders.unregister(datetime)
Пример #24
0
def test_custom_class():
    # Create and register the custom encoders
    # In this example we create three separate encoders even though all three classes
    #  actually share a common subclass. In real usage they might not be.
    @sd_ujson.encoders.register(Character)
    def encode_character(obj):
        return dict(obj)

    @sd_ujson.encoders.register(Cheese)
    def encode_cheese(obj):
        return dict(obj)

    @sd_ujson.encoders.register(Shop)
    def encode_shop(obj):
        return dict(obj)

    # Create instances of classes
    runny_camembert = Cheese("Camembert", ["Very runny"])
    shopkeeper = Character("Mr Wensleydale", "Michael Palin")
    customer = Character("The Customer", "John Cleese")
    cheese_shop = Shop(
        "The National Cheese Emporium",
        address="""12 Some Street
Some Town
England""",
        staff=[shopkeeper],
        customers=[customer],
        current_stock=[runny_camembert],
        music=False,
        dancing=False,
    )

    expected_json = (
        '{"name": "The National Cheese Emporium", "address": "12 Some Street\\n'
        'Some Town\\nEngland", "open": true, "music": false, "dancing": false, '
        '"staff": [{"name": "Mr Wensleydale", "actor": "Michael Palin", "armed": false}], '
        '"customers": [{"name": "The Customer", "actor": "John Cleese", "armed": false}], '
        '"current_stock": [{"name": "Camembert", "properties": ["Very runny"]}]}'
    )

    with TemporaryDirectory() as tmpdir:
        tmpfile = pathlib.Path(tmpdir) / "output.json"

        with open(tmpfile, "w") as fp:
            sd_ujson.dump(cheese_shop, fp)

        with open(tmpfile, "r") as fp:
            assert fp.read() == nospace(expected_json)

    assert sd_ujson.dumps(cheese_shop) == nospace(expected_json)

    # Cleanup
    sd_ujson.unregister_encoder(Character)
    sd_ujson.unregister_encoder(Cheese)
    sd_ujson.unregister_encoder(Shop)
Пример #25
0
def test_timedelta_float():
	# Create and register a custom encoder for timedelta that turns it into a float
	@sd_ujson.encoders.register(timedelta)
	def encode_timedelta_float(obj):
		return obj.total_seconds()

	start_date = datetime(1945, 5, 8, 19, 20).replace(tzinfo=pytz.utc)
	end_date = datetime(2020, 5, 8, 9, 0).replace(tzinfo=pytz.utc)
	delta = end_date - start_date
	assert sd_ujson.dumps(delta) == "2366804400.0"

	# Cleanup
	sd_ujson.encoders.unregister(timedelta)
Пример #26
0
def test_overloading():

    # Create and register a custom encoder
    @sd_ujson.encoders.register(Decimal)
    def encoder_1(obj):
        return "Result from first registration"

    # Test that we get the expected output from the first encoder
    assert sd_ujson.dumps(Decimal(1)) == '"Result from first registration"'

    # Create and register a new custom encoder that overloads the previous one
    @sd_ujson.encoders.register(Decimal)
    def encoder_2(obj):
        return "Result from second registration"

    # Test that we get the expected output from the second encoder
    assert sd_ujson.dumps(Decimal(2)) == '"Result from second registration"'

    print(sd_ujson.encoders.registry.items())

    # Cleanup
    sd_ujson.encoders.unregister(Decimal)
Пример #27
0
def test_separators():
    h = [['blorpie'], ['whoops'], [], 'd-shtaeou', 'd-nthiouh', 'i-vhbjkhnth',
         {
             'nifty': 87
         }, {
             'field': 'yes',
             'morefield': False
         }]

    expect = textwrap.dedent("""\
    [
      [
        "blorpie"
      ] ,
      [
        "whoops"
      ] ,
      [] ,
      "d-shtaeou" ,
      "d-nthiouh" ,
      "i-vhbjkhnth" ,
      {
        "nifty" : 87
      } ,
      {
        "field" : "yes" ,
        "morefield" : false
      }
    ]""")

    d1 = sd_ujson.dumps(h)
    d2 = sd_ujson.dumps(h, indent=2, sort_keys=True, separators=(' ,', ' : '))

    h1 = sd_ujson.loads(d1)
    h2 = sd_ujson.loads(d2)

    assert h1 == h
    assert h2 == h
    assert d2 == expect
Пример #28
0
def test_illegal_separators():
    h = {1: 2, 3: 4}
    with pytest.raises(TypeError):
        sd_ujson.dumps(h, separators=(b', ', ': '))
    with pytest.raises(TypeError):
        sd_ujson.dumps(h, separators=(', ', b': '))
    with pytest.raises(TypeError):
        sd_ujson.dumps(h, separators=(b', ', b': '))
Пример #29
0
def test_encode_unicode_bmp():
    s = "\U0001f42e\U0001f42e\U0001F42D\U0001F42D"  # ­Ъљ«­Ъљ«­ЪљГ­ЪљГ
    encoded = sd_ujson.dumps(s)
    encoded_json = sdjson.dumps(s)

    if len(s) == 4:
        assert len(encoded) == len(s) * 12 + 2
    else:
        assert len(encoded) == len(s) * 6 + 2

    assert encoded == encoded_json
    decoded = sd_ujson.loads(encoded)
    assert s == decoded

    # sd_ujson outputs an UTF-8 encoded str object
    encoded = sd_ujson.dumps(s, ensure_ascii=False)

    # json outputs an unicode object
    encoded_json = sdjson.dumps(s, ensure_ascii=False)
    assert len(encoded) == len(s) + 2  # original length + quotes
    assert encoded == encoded_json
    decoded = sd_ujson.loads(encoded)
    assert s == decoded
Пример #30
0
def test_encode_null_character():
    test_input = "31337 \x00 1337"
    output = sd_ujson.encode(test_input)
    assert test_input == sdjson.loads(output)
    assert output == sdjson.dumps(test_input)
    assert test_input == sd_ujson.decode(output)

    test_input = "\x00"
    output = sd_ujson.encode(test_input)
    assert test_input == sdjson.loads(output)
    assert output == sdjson.dumps(test_input)
    assert test_input == sd_ujson.decode(output)

    assert '"  \\u0000\\r\\n "' == sd_ujson.dumps("  \u0000\r\n ")