summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2021-08-02 18:23:55 +0100
committerMichael Williamson <mike@zwobble.org>2021-08-02 18:24:56 +0100
commit2e4bc0ff1c9e59121e715e489a6fc102ada93e15 (patch)
treed8e4ac7c5f630d2654d3cc93bc539f176dcbd589
parent337c0f8baf77a59f9054eefc07460fffe91702ce (diff)
Use custom integer check to handle large ints larger than 32 bits
-rw-r--r--jq.pyx16
-rw-r--r--tests/jq_tests.py9
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,