From 2e4bc0ff1c9e59121e715e489a6fc102ada93e15 Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Mon, 2 Aug 2021 18:23:55 +0100 Subject: Use custom integer check to handle large ints larger than 32 bits --- jq.pyx | 16 +++++++++++++--- tests/jq_tests.py | 9 +++++++++ 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/jq.pyx b/jq.pyx index d3f9067..00609a8 100644 --- a/jq.pyx +++ b/jq.pyx @@ -2,6 +2,7 @@ import json import threading from cpython.bytes cimport PyBytes_AsString +from libc.math cimport modf cdef extern from "jv.h": @@ -70,6 +71,7 @@ cdef object _jv_to_python(jv value): cdef jv property_key cdef jv property_value cdef object python_value + cdef double number_value if kind == JV_KIND_INVALID: raise ValueError("Invalid value") @@ -80,10 +82,11 @@ cdef object _jv_to_python(jv value): elif kind == JV_KIND_TRUE: python_value = True elif kind == JV_KIND_NUMBER: - if jv_is_integer(value): - python_value = int(jv_number_value(value)) + number_value = jv_number_value(value) + if _is_integer(number_value): + python_value = int(number_value) else: - python_value = float(jv_number_value(value)) + python_value = number_value elif kind == JV_KIND_STRING: python_value = jv_string_value(value).decode("utf-8") elif kind == JV_KIND_ARRAY: @@ -109,6 +112,13 @@ cdef object _jv_to_python(jv value): return python_value +cdef int _is_integer(double value): + cdef double integral_part + cdef double fractional_part = modf(value, &integral_part) + + return fractional_part == 0 + + def compile(object program, args=None): cdef object program_bytes = program.encode("utf8") return _Program(program_bytes, args=args) diff --git a/tests/jq_tests.py b/tests/jq_tests.py index b5bbbd1..4eab9f7 100644 --- a/tests/jq_tests.py +++ b/tests/jq_tests.py @@ -165,6 +165,15 @@ def test_unicode_strings_can_be_used_as_programs(): ) +def test_returned_integers_larger_than_32_bits_have_int_type(): + program = jq.compile("pow(.; 33)") + + result = program.input(2).first() + + assert_equal(2 ** 33, result) + assert_equal(int, type(result)) + + def test_compiling_with_args_should_set_predefined_variables(): assert_equal( 123, -- cgit v1.2.3