This is an automated email from the ASF dual-hosted git repository. isapego pushed a commit to branch ignite-13735 in repository https://gitbox.apache.org/repos/asf/ignite-python-thin-client.git
commit ed6de34e9f43310a8f04bff3353d4db9d6a6fbc9 Author: Dmitry Melnichuk <[email protected]> AuthorDate: Mon Oct 22 18:25:31 2018 +0300 IGNITE-9950 Python: Fixes for Decimal data type This closes #5041 --- pyignite/datatypes/standard.py | 34 +++++++++++++++++++++++++--------- setup.py | 2 +- 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/pyignite/datatypes/standard.py b/pyignite/datatypes/standard.py index 6109c7a..5f3af74 100644 --- a/pyignite/datatypes/standard.py +++ b/pyignite/datatypes/standard.py @@ -16,6 +16,7 @@ import ctypes from datetime import date, datetime, time, timedelta import decimal +from math import ceil import uuid from pyignite.constants import * @@ -163,7 +164,7 @@ class DecimalObject: { '_pack_': 1, '_fields_': [ - ('data', ctypes.c_char * header.length), + ('data', ctypes.c_ubyte * header.length), ], } ) @@ -179,12 +180,18 @@ class DecimalObject: return None sign = 1 if ctype_object.data[0] & 0x80 else 0 - data = bytes([ctype_object.data[0] & 0x7f]) + ctype_object.data[1:] - result = decimal.Decimal(data.decode(PROTOCOL_STRING_ENCODING)) + data = ctype_object.data[1:] + data.insert(0, ctype_object.data[0] & 0x7f) + # decode n-byte integer + result = sum([ + [x for x in reversed(data)][i] * 0x100 ** i for i in + range(len(data)) + ]) # apply scale result = ( result - * decimal.Decimal('10') ** decimal.Decimal(ctype_object.scale) + / decimal.Decimal('10') + ** decimal.Decimal(ctype_object.scale) ) if sign: # apply sign @@ -197,12 +204,20 @@ class DecimalObject: return Null.from_python() sign, digits, scale = value.normalize().as_tuple() - data = bytearray([ord('0') + digit for digit in digits]) + integer = int(''.join([str(d) for d in digits])) + # calculate number of bytes (at least one, and not forget the sign bit) + length = ceil((integer.bit_length() + 1)/8) + # write byte string + data = [] + for i in range(length): + digit = integer % 0x100 + integer //= 0x100 + data.insert(0, digit) + # apply sign if sign: data[0] |= 0x80 else: data[0] &= 0x7f - length = len(digits) header_class = cls.build_c_header() data_class = type( cls.__name__, @@ -210,7 +225,7 @@ class DecimalObject: { '_pack_': 1, '_fields_': [ - ('data', ctypes.c_char * length), + ('data', ctypes.c_ubyte * length), ], } ) @@ -220,8 +235,9 @@ class DecimalObject: byteorder=PROTOCOL_BYTE_ORDER ) data_object.length = length - data_object.scale = scale - data_object.data = bytes(data) + data_object.scale = -scale + for i in range(length): + data_object.data[i] = data[i] return bytes(data_object) diff --git a/setup.py b/setup.py index 5d14dae..7419c97 100644 --- a/setup.py +++ b/setup.py @@ -65,7 +65,7 @@ for section in requirement_sections: if is_a_requirement(line): requirements[section].append(line) -with open('README.md', 'r') as readme_file: +with open('README.md', 'r', encoding='utf-8') as readme_file: long_description = readme_file.read() setuptools.setup(
