From d60ab23c375f86a74c7ddaa55018f20c9d5c1563 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Kotal?= Date: Mon, 5 Dec 2022 18:06:36 +0100 Subject: [PATCH 1/6] remove duplicate _sock_exact_recv() definition --- adafruit_minimqtt/adafruit_minimqtt.py | 29 -------------------------- 1 file changed, 29 deletions(-) diff --git a/adafruit_minimqtt/adafruit_minimqtt.py b/adafruit_minimqtt/adafruit_minimqtt.py index 00bace2b..1e341af7 100644 --- a/adafruit_minimqtt/adafruit_minimqtt.py +++ b/adafruit_minimqtt/adafruit_minimqtt.py @@ -313,35 +313,6 @@ def __enter__(self): def __exit__(self, exception_type, exception_value, traceback): self.deinit() - def _sock_exact_recv(self, bufsize): - """Reads _exact_ number of bytes from the connected socket. Will only return - string with the exact number of bytes requested. - - The semantics of native socket receive is that it returns no more than the - specified number of bytes (i.e. max size). However, it makes no guarantees in - terms of the minimum size of the buffer, which could be 1 byte. This is a - wrapper for socket recv() to ensure that no less than the expected number of - bytes is returned or trigger a timeout exception. - - :param int bufsize: number of bytes to receive - """ - stamp = time.monotonic() - rc = self._sock.recv(bufsize) - to_read = bufsize - len(rc) - assert to_read >= 0 - read_timeout = self.keep_alive - while to_read > 0: - recv = self._sock.recv(to_read) - to_read -= len(recv) - rc += recv - if time.monotonic() - stamp > read_timeout: - raise MMQTTException( - "Unable to receive {} bytes within {} seconds.".format( - to_read, read_timeout - ) - ) - return rc - def deinit(self): """De-initializes the MQTT client and disconnects from the mqtt broker.""" self.disconnect() From c334c8157dddc06f67b85b9c299b49d0b29f3031 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Kotal?= Date: Mon, 5 Dec 2022 19:43:38 +0100 Subject: [PATCH 2/6] finish partial reads in CPython fixes #131 --- adafruit_minimqtt/adafruit_minimqtt.py | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/adafruit_minimqtt/adafruit_minimqtt.py b/adafruit_minimqtt/adafruit_minimqtt.py index 1e341af7..d0862515 100644 --- a/adafruit_minimqtt/adafruit_minimqtt.py +++ b/adafruit_minimqtt/adafruit_minimqtt.py @@ -956,15 +956,29 @@ def _sock_exact_recv(self, bufsize): bytes is returned or trigger a timeout exception. :param int bufsize: number of bytes to receive - + :return: byte array """ + stamp = time.monotonic() if not self._backwards_compatible_sock: # CPython/Socketpool Impl. rc = bytearray(bufsize) - self._sock.recv_into(rc, bufsize) - else: # ESP32SPI Impl. - stamp = time.monotonic() + mv = memoryview(rc) + recv = self._sock.recv_into(rc, bufsize) + to_read = bufsize - recv + assert to_read >= 0 read_timeout = self.keep_alive + mv = mv[recv:] + while to_read > 0: + recv = self._sock.recv_into(mv, to_read) + to_read -= recv + mv = mv[recv:] + if time.monotonic() - stamp > read_timeout: + raise MMQTTException( + "Unable to receive {} bytes within {} seconds.".format( + to_read, read_timeout + ) + ) + else: # ESP32SPI Impl. # This will timeout with socket timeout (not keepalive timeout) rc = self._sock.recv(bufsize) if not rc: From f0fd46514b5104cd67baaf78c2b96d63d9a921b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Kotal?= Date: Tue, 6 Dec 2022 09:55:42 +0100 Subject: [PATCH 3/6] rename variable for better readability --- adafruit_minimqtt/adafruit_minimqtt.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/adafruit_minimqtt/adafruit_minimqtt.py b/adafruit_minimqtt/adafruit_minimqtt.py index d0862515..0304cae5 100644 --- a/adafruit_minimqtt/adafruit_minimqtt.py +++ b/adafruit_minimqtt/adafruit_minimqtt.py @@ -963,15 +963,15 @@ def _sock_exact_recv(self, bufsize): # CPython/Socketpool Impl. rc = bytearray(bufsize) mv = memoryview(rc) - recv = self._sock.recv_into(rc, bufsize) - to_read = bufsize - recv + recv_len = self._sock.recv_into(rc, bufsize) + to_read = bufsize - recv_len assert to_read >= 0 read_timeout = self.keep_alive - mv = mv[recv:] + mv = mv[recv_len:] while to_read > 0: - recv = self._sock.recv_into(mv, to_read) - to_read -= recv - mv = mv[recv:] + recv_len = self._sock.recv_into(mv, to_read) + to_read -= recv_len + mv = mv[recv_len:] if time.monotonic() - stamp > read_timeout: raise MMQTTException( "Unable to receive {} bytes within {} seconds.".format( From c0a902a26e3e35888a66244394e0863a4088f072 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Kotal?= Date: Wed, 7 Dec 2022 11:19:32 +0100 Subject: [PATCH 4/6] use f-strings for the exceptions pylint will like the code more --- adafruit_minimqtt/adafruit_minimqtt.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/adafruit_minimqtt/adafruit_minimqtt.py b/adafruit_minimqtt/adafruit_minimqtt.py index 0304cae5..5b1cc08e 100644 --- a/adafruit_minimqtt/adafruit_minimqtt.py +++ b/adafruit_minimqtt/adafruit_minimqtt.py @@ -974,9 +974,7 @@ def _sock_exact_recv(self, bufsize): mv = mv[recv_len:] if time.monotonic() - stamp > read_timeout: raise MMQTTException( - "Unable to receive {} bytes within {} seconds.".format( - to_read, read_timeout - ) + f"Unable to receive {to_read} bytes within {read_timeout} seconds." ) else: # ESP32SPI Impl. # This will timeout with socket timeout (not keepalive timeout) @@ -997,9 +995,7 @@ def _sock_exact_recv(self, bufsize): rc += recv if time.monotonic() - stamp > read_timeout: raise MMQTTException( - "Unable to receive {} bytes within {} seconds.".format( - to_read, read_timeout - ) + f"Unable to receive {to_read} bytes within {read_timeout} seconds." ) return rc From 8f517100fc35c59c5b488e9d82ab247ef4db9d26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Kotal?= Date: Thu, 12 Jan 2023 17:50:12 +0100 Subject: [PATCH 5/6] use MMQTTException instead of assert for the negative read length --- adafruit_minimqtt/adafruit_minimqtt.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/adafruit_minimqtt/adafruit_minimqtt.py b/adafruit_minimqtt/adafruit_minimqtt.py index 5b1cc08e..10effeaf 100644 --- a/adafruit_minimqtt/adafruit_minimqtt.py +++ b/adafruit_minimqtt/adafruit_minimqtt.py @@ -965,7 +965,11 @@ def _sock_exact_recv(self, bufsize): mv = memoryview(rc) recv_len = self._sock.recv_into(rc, bufsize) to_read = bufsize - recv_len - assert to_read >= 0 + if to_read < 0: + raise MMQTTException( + f"negative number of bytes to read: " + f"{to_read} = {bufsize} - {recv_len}" + ) read_timeout = self.keep_alive mv = mv[recv_len:] while to_read > 0: From be9c198ddf76f72b746bf2d958102d2c8a7538a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Kotal?= Date: Thu, 12 Jan 2023 17:56:43 +0100 Subject: [PATCH 6/6] try different format --- adafruit_minimqtt/adafruit_minimqtt.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/adafruit_minimqtt/adafruit_minimqtt.py b/adafruit_minimqtt/adafruit_minimqtt.py index 10effeaf..4fa0b90a 100644 --- a/adafruit_minimqtt/adafruit_minimqtt.py +++ b/adafruit_minimqtt/adafruit_minimqtt.py @@ -966,10 +966,7 @@ def _sock_exact_recv(self, bufsize): recv_len = self._sock.recv_into(rc, bufsize) to_read = bufsize - recv_len if to_read < 0: - raise MMQTTException( - f"negative number of bytes to read: " - f"{to_read} = {bufsize} - {recv_len}" - ) + raise MMQTTException(f"negative number of bytes to read: {to_read}") read_timeout = self.keep_alive mv = mv[recv_len:] while to_read > 0: