33import struct
44
55from pymysqlreplication import constants , event , row_event
6+ from typing import List , Tuple , Any , Dict , Optional , Union
67
78# Constants from PyMYSQL source code
89NULL_COLUMN = 251
3637JSONB_LITERAL_FALSE = 0x2
3738
3839
39- def read_offset_or_inline (packet , large ) :
40+ def read_offset_or_inline (packet , large : bool ) -> Tuple [ Any , Any , Any ] :
4041 t = packet .read_uint8 ()
4142
4243 if t in (JSONB_TYPE_LITERAL ,
4344 JSONB_TYPE_INT16 , JSONB_TYPE_UINT16 ):
44- return ( t , None , packet .read_binary_json_type_inlined (t , large ) )
45+ return t , None , packet .read_binary_json_type_inlined (t , large )
4546 if large and t in (JSONB_TYPE_INT32 , JSONB_TYPE_UINT32 ):
46- return ( t , None , packet .read_binary_json_type_inlined (t , large ) )
47+ return t , None , packet .read_binary_json_type_inlined (t , large )
4748
4849 if large :
49- return ( t , packet .read_uint32 (), None )
50- return ( t , packet .read_uint16 (), None )
50+ return t , packet .read_uint32 (), None
51+ return t , packet .read_uint16 (), None
5152
5253
5354class BinLogPacketWrapper (object ):
5455 """
55- Bin Log Packet Wrapper. It uses an existing packet object, and wraps
56- around it, exposing useful variables while still providing access
56+ Bin Log Packet Wrapper uses an existing packet object and wraps around it,
57+ exposing useful variables while still providing access
5758 to the original packet objects variables and methods.
5859 """
5960
@@ -155,7 +156,7 @@ def __init__(self, from_packet, table_map,
155156 if self .event ._processed == False :
156157 self .event = None
157158
158- def read (self , size ) :
159+ def read (self , size : int ) -> Union [ int , bytes ] :
159160 size = int (size )
160161 self .read_bytes += size
161162 if len (self .__data_buffer ) > 0 :
@@ -167,14 +168,15 @@ def read(self, size):
167168 return data + self .packet .read (size - len (data ))
168169 return self .packet .read (size )
169170
170- def unread (self , data ):
171- '''Push again data in data buffer. It's use when you want
172- to extract a bit from a value a let the rest of the code normally
173- read the datas'''
171+ def unread (self , data : str ):
172+ """
173+ Push again data in data buffer.
174+ Use to extract a bit from a value and ensure that the rest of the code reads data normally
175+ """
174176 self .read_bytes -= len (data )
175177 self .__data_buffer += data
176178
177- def advance (self , size ):
179+ def advance (self , size : int ):
178180 size = int (size )
179181 self .read_bytes += size
180182 buffer_len = len (self .__data_buffer )
@@ -185,13 +187,11 @@ def advance(self, size):
185187 else :
186188 self .packet .advance (size )
187189
188- def read_length_coded_binary (self ):
189- """Read a 'Length Coded Binary' number from the data buffer.
190-
190+ def read_length_coded_binary (self ) -> Optional [ str ] :
191+ """
192+ Read a 'Length Coded Binary' number from the data buffer.
191193 Length coded numbers can be anywhere from 1 to 9 bytes depending
192- on the value of the first byte.
193-
194- From PyMYSQL source code
194+ on the value of the first byte. (From PyMYSQL source code)
195195 """
196196 c = struct .unpack ("!B" , self .read (1 ))[0 ]
197197 if c == NULL_COLUMN :
@@ -205,14 +205,12 @@ def read_length_coded_binary(self):
205205 elif c == UNSIGNED_INT64_COLUMN :
206206 return self .unpack_int64 (self .read (UNSIGNED_INT64_LENGTH ))
207207
208- def read_length_coded_string (self ):
209- """Read a 'Length Coded String' from the data buffer.
210-
211- A 'Length Coded String' consists first of a length coded
212- (unsigned, positive) integer represented in 1-9 bytes followed by
213- that many bytes of binary data. (For example "cat" would be "3cat".)
214-
215- From PyMYSQL source code
208+ def read_length_coded_string (self ) -> Optional [str ]:
209+ """
210+ Read a 'Length Coded String' from the data buffer.
211+ A 'Length Coded String' consists first of a length coded (unsigned, positive) integer
212+ represented in 1-9 bytes followed by that many bytes of binary data.
213+ (For example, "cat" would be "3cat". - From PyMYSQL source code)
216214 """
217215 length = self .read_length_coded_binary ()
218216 if length is None :
@@ -226,8 +224,10 @@ def __getattr__(self, key):
226224 raise AttributeError ("%s instance has no attribute '%s'" %
227225 (self .__class__ , key ))
228226
229- def read_int_be_by_size (self , size ):
230- '''Read a big endian integer values based on byte number'''
227+ def read_int_be_by_size (self , size : int ):
228+ """
229+ Read a big endian integer values based on byte number
230+ """
231231 if size == 1 :
232232 return struct .unpack ('>b' , self .read (size ))[0 ]
233233 elif size == 2 :
@@ -241,8 +241,10 @@ def read_int_be_by_size(self, size):
241241 elif size == 8 :
242242 return struct .unpack ('>l' , self .read (size ))[0 ]
243243
244- def read_uint_by_size (self , size ):
245- '''Read a little endian integer values based on byte number'''
244+ def read_uint_by_size (self , size : int ) -> str :
245+ """
246+ Read a little endian integer values based on byte number
247+ """
246248 if size == 1 :
247249 return self .read_uint8 ()
248250 elif size == 2 :
@@ -260,19 +262,18 @@ def read_uint_by_size(self, size):
260262 elif size == 8 :
261263 return self .read_uint64 ()
262264
263- def read_length_coded_pascal_string (self , size ):
264- """Read a string with length coded using pascal style.
265+ def read_length_coded_pascal_string (self , size : int ) -> Union [int , bytes ]:
266+ """
267+ Read a string with length coded using pascal style.
265268 The string start by the size of the string
266269 """
267270 length = self .read_uint_by_size (size )
268271 return self .read (length )
269272
270- def read_variable_length_string (self ):
271- """Read a variable length string where the first 1-5 bytes stores the
272- length of the string.
273-
274- For each byte, the first bit being high indicates another byte must be
275- read.
273+ def read_variable_length_string (self ) -> Union [int , bytes ]:
274+ """
275+ Read a variable length string where the first 1-5 bytes stores the length of the string.
276+ For each byte, the first bit being high indicates another byte must be read.
276277 """
277278 byte = 0x80
278279 length = 0
@@ -283,65 +284,65 @@ def read_variable_length_string(self):
283284 bits_read = bits_read + 7
284285 return self .read (length )
285286
286- def read_int24 (self ):
287+ def read_int24 (self ) -> str :
287288 a , b , c = struct .unpack ("BBB" , self .read (3 ))
288289 res = a | (b << 8 ) | (c << 16 )
289290 if res >= 0x800000 :
290291 res -= 0x1000000
291292 return res
292293
293- def read_int24_be (self ):
294+ def read_int24_be (self ) -> str :
294295 a , b , c = struct .unpack ('BBB' , self .read (3 ))
295296 res = (a << 16 ) | (b << 8 ) | c
296297 if res >= 0x800000 :
297298 res -= 0x1000000
298299 return res
299300
300- def read_uint8 (self ):
301+ def read_uint8 (self ) -> str :
301302 return struct .unpack ('<B' , self .read (1 ))[0 ]
302303
303- def read_int16 (self ):
304+ def read_int16 (self ) -> str :
304305 return struct .unpack ('<h' , self .read (2 ))[0 ]
305306
306- def read_uint16 (self ):
307+ def read_uint16 (self ) -> str :
307308 return struct .unpack ('<H' , self .read (2 ))[0 ]
308309
309- def read_uint24 (self ):
310+ def read_uint24 (self ) -> str :
310311 a , b , c = struct .unpack ("<BBB" , self .read (3 ))
311312 return a + (b << 8 ) + (c << 16 )
312313
313- def read_uint32 (self ):
314+ def read_uint32 (self ) -> str :
314315 return struct .unpack ('<I' , self .read (4 ))[0 ]
315316
316- def read_int32 (self ):
317+ def read_int32 (self ) -> str :
317318 return struct .unpack ('<i' , self .read (4 ))[0 ]
318319
319- def read_uint40 (self ):
320+ def read_uint40 (self ) -> str :
320321 a , b = struct .unpack ("<BI" , self .read (5 ))
321322 return a + (b << 8 )
322323
323- def read_int40_be (self ):
324+ def read_int40_be (self ) -> str :
324325 a , b = struct .unpack (">IB" , self .read (5 ))
325326 return b + (a << 8 )
326327
327- def read_uint48 (self ):
328+ def read_uint48 (self ) -> str :
328329 a , b , c = struct .unpack ("<HHH" , self .read (6 ))
329330 return a + (b << 16 ) + (c << 32 )
330331
331- def read_uint56 (self ):
332+ def read_uint56 (self ) -> str :
332333 a , b , c = struct .unpack ("<BHI" , self .read (7 ))
333334 return a + (b << 8 ) + (c << 24 )
334335
335- def read_uint64 (self ):
336+ def read_uint64 (self ) -> str :
336337 return struct .unpack ('<Q' , self .read (8 ))[0 ]
337338
338- def read_int64 (self ):
339+ def read_int64 (self ) -> str :
339340 return struct .unpack ('<q' , self .read (8 ))[0 ]
340341
341- def unpack_uint16 (self , n ) :
342+ def unpack_uint16 (self , n : bytes ) -> str :
342343 return struct .unpack ('<H' , n [0 :2 ])[0 ]
343344
344- def unpack_int24 (self , n ) :
345+ def unpack_int24 (self , n : bytes ) -> Optional [ str , int ] :
345346 try :
346347 return struct .unpack ('B' , n [0 ])[0 ] \
347348 + (struct .unpack ('B' , n [1 ])[0 ] << 8 ) \
@@ -358,7 +359,7 @@ def unpack_int32(self, n):
358359 except TypeError :
359360 return n [0 ] + (n [1 ] << 8 ) + (n [2 ] << 16 ) + (n [3 ] << 24 )
360361
361- def read_binary_json (self , size ) :
362+ def read_binary_json (self , size : int ) -> Optional [ str ] :
362363 length = self .read_uint_by_size (size )
363364 if length == 0 :
364365 # handle NULL value
@@ -369,7 +370,7 @@ def read_binary_json(self, size):
369370
370371 return self .read_binary_json_type (t , length )
371372
372- def read_binary_json_type (self , t , length ) :
373+ def read_binary_json_type (self , t : bytes , length : int ) -> Optional [ bool , str ] :
373374 large = (t in (JSONB_TYPE_LARGE_OBJECT , JSONB_TYPE_LARGE_ARRAY ))
374375 if t in (JSONB_TYPE_SMALL_OBJECT , JSONB_TYPE_LARGE_OBJECT ):
375376 return self .read_binary_json_object (length - 1 , large )
@@ -402,7 +403,7 @@ def read_binary_json_type(self, t, length):
402403
403404 raise ValueError ('Json type %d is not handled' % t )
404405
405- def read_binary_json_type_inlined (self , t , large ) :
406+ def read_binary_json_type_inlined (self , t : bytes , large : bool ) -> Optional [ bool , str ] :
406407 if t == JSONB_TYPE_LITERAL :
407408 value = self .read_uint32 () if large else self .read_uint16 ()
408409 if value == JSONB_LITERAL_NULL :
@@ -422,7 +423,7 @@ def read_binary_json_type_inlined(self, t, large):
422423
423424 raise ValueError ('Json type %d is not handled' % t )
424425
425- def read_binary_json_object (self , length , large ) :
426+ def read_binary_json_object (self , length : int , large : bool ) -> Dict [ str , str ] :
426427 if large :
427428 elements = self .read_uint32 ()
428429 size = self .read_uint32 ()
@@ -460,7 +461,7 @@ def read_binary_json_object(self, length, large):
460461
461462 return out
462463
463- def read_binary_json_array (self , length , large ) :
464+ def read_binary_json_array (self , length : int , large : bool ) -> List :
464465 if large :
465466 elements = self .read_uint32 ()
466467 size = self .read_uint32 ()
@@ -482,13 +483,11 @@ def _read(x):
482483
483484 return [_read (x ) for x in values_type_offset_inline ]
484485
485- def read_string (self ):
486- """Read a 'Length Coded String' from the data buffer.
487-
486+ def read_string (self ) -> bytes :
487+ """
488+ Read a 'Length Coded String' from the data buffer.
488489 Read __data_buffer until NULL character (0 = \0 = \x00 )
489-
490- Returns:
491- Binary string parsed from __data_buffer
490+ :return string: Binary string parsed from __data_buffer
492491 """
493492 string = b''
494493 while True :
0 commit comments