You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by is...@apache.org on 2021/01/27 21:00:21 UTC

[ignite-python-thin-client] branch master updated: IGNITE-14057 Support big-endian systems

This is an automated email from the ASF dual-hosted git repository.

isapego pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite-python-thin-client.git


The following commit(s) were added to refs/heads/master by this push:
     new 18d32bb  IGNITE-14057 Support big-endian systems
18d32bb is described below

commit 18d32bb76a030f6aea6ed66dc3e403d096a42023
Author: Pavel Tupitsyn <pt...@apache.org>
AuthorDate: Wed Jan 27 23:59:05 2021 +0300

    IGNITE-14057 Support big-endian systems
    
    Fix primitives decoding on big-endian architectures. This closes #7
---
 pyignite/api/binary.py                  |  2 +-
 pyignite/datatypes/internal.py          |  2 +-
 pyignite/datatypes/primitive.py         | 44 +++++++++++++++++++++++++++------
 pyignite/datatypes/primitive_objects.py |  7 +++++-
 pyignite/queries/response.py            |  2 +-
 tests/test_binary.py                    |  2 +-
 6 files changed, 47 insertions(+), 12 deletions(-)

diff --git a/pyignite/api/binary.py b/pyignite/api/binary.py
index 1d63b49..722001a 100644
--- a/pyignite/api/binary.py
+++ b/pyignite/api/binary.py
@@ -86,7 +86,7 @@ def get_binary_type(
     if result.status != 0:
         return result
     result.value = {
-        'type_exists': response.type_exists
+        'type_exists': Bool.to_python(response.type_exists)
     }
     if hasattr(response, 'body'):
         result.value.update(body_struct.to_python(response.body))
diff --git a/pyignite/datatypes/internal.py b/pyignite/datatypes/internal.py
index 9fd5d64..9f23ec6 100644
--- a/pyignite/datatypes/internal.py
+++ b/pyignite/datatypes/internal.py
@@ -204,7 +204,7 @@ class Struct:
 
     def parse(
         self, client: 'Client'
-    ) -> Tuple[ctypes.BigEndianStructure, bytes]:
+    ) -> Tuple[ctypes.LittleEndianStructure, bytes]:
         buffer = b''
         fields = []
         values = {}
diff --git a/pyignite/datatypes/primitive.py b/pyignite/datatypes/primitive.py
index 23d070d..d549fda 100644
--- a/pyignite/datatypes/primitive.py
+++ b/pyignite/datatypes/primitive.py
@@ -14,6 +14,8 @@
 # limitations under the License.
 
 import ctypes
+import struct
+import sys
 
 from pyignite.constants import *
 from .base import IgniteDataType
@@ -48,13 +50,9 @@ class Primitive(IgniteDataType):
     def parse(cls, client: 'Client'):
         return cls.c_type, client.recv(ctypes.sizeof(cls.c_type))
 
-    @staticmethod
-    def to_python(ctype_object, *args, **kwargs):
-        return ctype_object
-
     @classmethod
-    def from_python(cls, value):
-        return bytes(cls.c_type(value))
+    def to_python(cls, ctype_object, *args, **kwargs):
+        return ctype_object
 
 
 class Byte(Primitive):
@@ -62,36 +60,60 @@ class Byte(Primitive):
     _type_id = TYPE_BYTE
     c_type = ctypes.c_byte
 
+    @classmethod
+    def from_python(cls, value):
+        return struct.pack("<b", value)
+
 
 class Short(Primitive):
     _type_name = NAME_SHORT
     _type_id = TYPE_SHORT
     c_type = ctypes.c_short
 
+    @classmethod
+    def from_python(cls, value):
+        return struct.pack("<h", value)
+
 
 class Int(Primitive):
     _type_name = NAME_INT
     _type_id = TYPE_INT
     c_type = ctypes.c_int
 
+    @classmethod
+    def from_python(cls, value):
+        return struct.pack("<i", value)
+
 
 class Long(Primitive):
     _type_name = NAME_LONG
     _type_id = TYPE_LONG
     c_type = ctypes.c_longlong
 
+    @classmethod
+    def from_python(cls, value):
+        return struct.pack("<q", value)
+
 
 class Float(Primitive):
     _type_name = NAME_FLOAT
     _type_id = TYPE_FLOAT
     c_type = ctypes.c_float
 
+    @classmethod
+    def from_python(cls, value):
+        return struct.pack("<f", value)
+
 
 class Double(Primitive):
     _type_name = NAME_DOUBLE
     _type_id = TYPE_DOUBLE
     c_type = ctypes.c_double
 
+    @classmethod
+    def from_python(cls, value):
+        return struct.pack("<d", value)
+
 
 class Char(Primitive):
     _type_name = NAME_CHAR
@@ -122,4 +144,12 @@ class Char(Primitive):
 class Bool(Primitive):
     _type_name = NAME_BOOLEAN
     _type_id = TYPE_BOOLEAN
-    c_type = ctypes.c_bool
+    c_type = ctypes.c_byte  # Use c_byte because c_bool throws endianness conversion error on BE systems.
+
+    @classmethod
+    def to_python(cls, ctype_object, *args, **kwargs):
+        return ctype_object != 0
+
+    @classmethod
+    def from_python(cls, value):
+        return struct.pack("<b", 1 if value else 0)
diff --git a/pyignite/datatypes/primitive_objects.py b/pyignite/datatypes/primitive_objects.py
index 0bd0ec6..033ac9e 100644
--- a/pyignite/datatypes/primitive_objects.py
+++ b/pyignite/datatypes/primitive_objects.py
@@ -207,7 +207,7 @@ class CharObject(DataObject):
 class BoolObject(DataObject):
     _type_name = NAME_BOOLEAN
     _type_id = TYPE_BOOLEAN
-    c_type = ctypes.c_bool
+    c_type = ctypes.c_byte  # Use c_byte because c_bool throws endianness conversion error on BE systems.
     type_code = TC_BOOL
     pythonic = bool
     default = False
@@ -215,3 +215,8 @@ class BoolObject(DataObject):
     @staticmethod
     def hashcode(value: bool, *args, **kwargs) -> int:
         return 1231 if value else 1237
+
+    @classmethod
+    def to_python(cls, ctype_object, *args, **kwargs):
+        return ctype_object.value != 0
+
diff --git a/pyignite/queries/response.py b/pyignite/queries/response.py
index 6003959..05a519a 100644
--- a/pyignite/queries/response.py
+++ b/pyignite/queries/response.py
@@ -179,7 +179,7 @@ class SQLResponse(Response):
         )
         fields += body_class._fields_ + [
             ('data', data_class),
-            ('more', ctypes.c_bool),
+            ('more', ctypes.c_byte),
         ]
 
     def _create_parse_result(self, conn: Connection, header_class, fields: list, buffer: bytearray):
diff --git a/tests/test_binary.py b/tests/test_binary.py
index 1c051f0..5190a6a 100644
--- a/tests/test_binary.py
+++ b/tests/test_binary.py
@@ -225,7 +225,7 @@ def test_nested_binary_objects(client):
 
 def test_add_schema_to_binary_object(client):
 
-    migrate_cache = client.create_cache('migrate_binary')
+    migrate_cache = client.get_or_create_cache('migrate_binary')
 
     class MyBinaryType(
         metaclass=GenericObjectMeta,