Skip to content

Commit 7f26fc4

Browse files
committed
docs: add typing in packet.py
1 parent a19a5a5 commit 7f26fc4

File tree

1 file changed

+65
-66
lines changed

1 file changed

+65
-66
lines changed

Diff for: pymysqlreplication/packet.py

+65-66
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import struct
44

55
from pymysqlreplication import constants, event, row_event
6+
from typing import List, Tuple, Any, Dict, Optional, Union
67

78
# Constants from PyMYSQL source code
89
NULL_COLUMN = 251
@@ -36,24 +37,24 @@
3637
JSONB_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

5354
class 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

Comments
 (0)