2020
2121from pygridgain .constants import *
2222from pygridgain .exceptions import ParseError
23+
2324from .base import GridGainDataType
2425from .internal import AnyDataObject , infer_from_python
2526from .type_codes import *
2627from .type_ids import *
2728from .type_names import *
29+ from .null_object import Null
2830
2931
3032__all__ = [
@@ -68,8 +70,13 @@ def build_header(cls):
6870
6971 @classmethod
7072 def parse (cls , client : 'Client' ):
73+ tc_type = client .recv (ctypes .sizeof (ctypes .c_byte ))
74+
75+ if tc_type == TC_NULL :
76+ return Null .build_c_type (), tc_type
77+
7178 header_class = cls .build_header ()
72- buffer = client .recv (ctypes .sizeof (header_class ))
79+ buffer = tc_type + client .recv (ctypes .sizeof (header_class ) - len ( tc_type ))
7380 header = header_class .from_buffer_copy (buffer )
7481 fields = []
7582
@@ -91,7 +98,10 @@ def parse(cls, client: 'Client'):
9198 @classmethod
9299 def to_python (cls , ctype_object , * args , ** kwargs ):
93100 result = []
94- for i in range (ctype_object .length ):
101+ length = getattr (ctype_object , "length" , None )
102+ if length is None :
103+ return None
104+ for i in range (length ):
95105 result .append (
96106 AnyDataObject .to_python (
97107 getattr (ctype_object , 'element_{}' .format (i )),
@@ -102,6 +112,9 @@ def to_python(cls, ctype_object, *args, **kwargs):
102112
103113 @classmethod
104114 def from_python (cls , value ):
115+ if value is None :
116+ return Null .from_python ()
117+
105118 type_or_id , value = value
106119 header_class = cls .build_header ()
107120 header = header_class ()
@@ -150,8 +163,13 @@ def build_header(cls):
150163
151164 @classmethod
152165 def parse (cls , client : 'Client' ):
166+ tc_type = client .recv (ctypes .sizeof (ctypes .c_byte ))
167+
168+ if tc_type == TC_NULL :
169+ return Null .build_c_type (), tc_type
170+
153171 header_class = cls .build_header ()
154- buffer = client .recv (ctypes .sizeof (header_class ))
172+ buffer = tc_type + client .recv (ctypes .sizeof (header_class ) - len ( tc_type ))
155173 header = header_class .from_buffer_copy (buffer )
156174
157175 final_class = type (
@@ -243,8 +261,13 @@ def build_header(cls):
243261
244262 @classmethod
245263 def parse (cls , client : 'Client' ):
264+ tc_type = client .recv (ctypes .sizeof (ctypes .c_byte ))
265+
266+ if tc_type == TC_NULL :
267+ return Null .build_c_type (), tc_type
268+
246269 header_class = cls .build_header ()
247- buffer = client .recv (ctypes .sizeof (header_class ))
270+ buffer = tc_type + client .recv (ctypes .sizeof (header_class ) - len ( tc_type ))
248271 header = header_class .from_buffer_copy (buffer )
249272 fields = []
250273
@@ -266,7 +289,10 @@ def parse(cls, client: 'Client'):
266289 @classmethod
267290 def to_python (cls , ctype_object , * args , ** kwargs ):
268291 result = []
269- for i in range (ctype_object .length ):
292+ length = getattr (ctype_object , "length" , None )
293+ if length is None :
294+ return None
295+ for i in range (length ):
270296 result .append (
271297 AnyDataObject .to_python (
272298 getattr (ctype_object , 'element_{}' .format (i )),
@@ -277,6 +303,9 @@ def to_python(cls, ctype_object, *args, **kwargs):
277303
278304 @classmethod
279305 def from_python (cls , value ):
306+ if value is None :
307+ return Null .from_python ()
308+
280309 type_or_id , value = value
281310 header_class = cls .build_header ()
282311 header = header_class ()
@@ -330,8 +359,13 @@ def build_header(cls):
330359
331360 @classmethod
332361 def parse (cls , client : 'Client' ):
362+ tc_type = client .recv (ctypes .sizeof (ctypes .c_byte ))
363+
364+ if tc_type == TC_NULL :
365+ return Null .build_c_type (), tc_type
366+
333367 header_class = cls .build_header ()
334- buffer = client .recv (ctypes .sizeof (header_class ))
368+ buffer = tc_type + client .recv (ctypes .sizeof (header_class ) - len ( tc_type ))
335369 header = header_class .from_buffer_copy (buffer )
336370 fields = []
337371
@@ -420,12 +454,18 @@ def build_header(cls):
420454
421455 @classmethod
422456 def to_python (cls , ctype_object , * args , ** kwargs ):
457+ type = getattr (ctype_object , "type" , None )
458+ if type is None :
459+ return None
423460 return ctype_object .type , super ().to_python (
424461 ctype_object , * args , ** kwargs
425462 )
426463
427464 @classmethod
428465 def from_python (cls , value ):
466+ if value is None :
467+ return Null .from_python ()
468+
429469 type_id , value = value
430470 return super ().from_python (value , type_id )
431471
@@ -539,9 +579,13 @@ def get_dataclass(conn: 'Connection', header) -> OrderedDict:
539579 @classmethod
540580 def parse (cls , client : 'Client' ):
541581 from pygridgain .datatypes import Struct
582+ tc_type = client .recv (ctypes .sizeof (ctypes .c_byte ))
583+
584+ if tc_type == TC_NULL :
585+ return Null .build_c_type (), tc_type
542586
543587 header_class = cls .build_header ()
544- buffer = client .recv (ctypes .sizeof (header_class ))
588+ buffer = tc_type + client .recv (ctypes .sizeof (header_class ) - len ( tc_type ))
545589 header = header_class .from_buffer_copy (buffer )
546590
547591 # ignore full schema, always retrieve fields' types and order
@@ -572,14 +616,17 @@ def parse(cls, client: 'Client'):
572616
573617 @classmethod
574618 def to_python (cls , ctype_object , client : 'Client' = None , * args , ** kwargs ):
619+ type_id = getattr (ctype_object , "type_id" , None )
620+ if type_id is None :
621+ return None
575622
576623 if not client :
577624 raise ParseError (
578- 'Can not query binary type {}' .format (ctype_object . type_id )
625+ 'Can not query binary type {}' .format (type_id )
579626 )
580627
581628 data_class = client .query_binary_type (
582- ctype_object . type_id ,
629+ type_id ,
583630 ctype_object .schema_id
584631 )
585632 result = data_class ()
@@ -596,6 +643,8 @@ def to_python(cls, ctype_object, client: 'Client' = None, *args, **kwargs):
596643
597644 @classmethod
598645 def from_python (cls , value : object ):
646+ if value is None :
647+ return Null .from_python ()
599648
600649 if getattr (value , '_buffer' , None ) is None :
601650 client = cls .find_client ()
0 commit comments