From a30c5a5828b2f447387d8635021f9736822b7290 Mon Sep 17 00:00:00 2001 From: foamyguy Date: Sat, 10 Jun 2023 17:43:44 -0500 Subject: [PATCH 1/4] remove backwards compatibility --- adafruit_requests.py | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/adafruit_requests.py b/adafruit_requests.py index a0276f0..f253b8c 100644 --- a/adafruit_requests.py +++ b/adafruit_requests.py @@ -188,8 +188,6 @@ def __init__(self, sock: SocketType, session: Optional["Session"] = None) -> Non self._remaining = None self._chunked = False - self._backwards_compatible = not hasattr(sock, "recv_into") - http = self._readto(b" ") if not http: if session: @@ -217,12 +215,6 @@ def __exit__( self.close() def _recv_into(self, buf: bytearray, size: int = 0) -> int: - if self._backwards_compatible: - size = len(buf) if size == 0 else size - b = self.socket.recv(size) - read_size = len(b) - buf[:read_size] = b - return read_size return cast("SupportsRecvInto", self.socket).recv_into(buf, size) def _readto(self, stop: bytes) -> bytearray: @@ -763,6 +755,7 @@ def __init__(self, socket: CircuitPythonSocketType, tls_mode: int) -> None: self.send = socket.send self.recv = socket.recv self.close = socket.close + self.recv_into = socket.recv_into def connect(self, address: Tuple[str, int]) -> None: """connect wrapper to add non-standard mode parameter""" From b151039d16ee9e44398cdebe470bb4c67b34180d Mon Sep 17 00:00:00 2001 From: foamyguy Date: Mon, 26 Jun 2023 16:35:16 -0500 Subject: [PATCH 2/4] remove legacy tests --- tests/legacy_mocket.py | 47 ---------- tests/legacy_test.py | 208 ----------------------------------------- 2 files changed, 255 deletions(-) delete mode 100644 tests/legacy_mocket.py delete mode 100644 tests/legacy_test.py diff --git a/tests/legacy_mocket.py b/tests/legacy_mocket.py deleted file mode 100644 index 17bf209..0000000 --- a/tests/legacy_mocket.py +++ /dev/null @@ -1,47 +0,0 @@ -# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries -# -# SPDX-License-Identifier: Unlicense - -""" Mock for Legacy Socket """ - -from unittest import mock - -SOCK_STREAM = 0 - -set_interface = mock.Mock() -interface = mock.MagicMock() -getaddrinfo = mock.Mock() -socket = mock.Mock() - - -class Mocket: # pylint: disable=too-few-public-methods - """Mock Socket""" - - def __init__(self, response): - self.settimeout = mock.Mock() - self.close = mock.Mock() - self.connect = mock.Mock() - self.send = mock.Mock(side_effect=self._send) - self.readline = mock.Mock(side_effect=self._readline) - self.recv = mock.Mock(side_effect=self._recv) - self.fail_next_send = False - self._response = response - self._position = 0 - - def _send(self, data): # pylint: disable=unused-argument - if self.fail_next_send: - self.fail_next_send = False - raise RuntimeError("Send failed") - - def _readline(self): - i = self._response.find(b"\r\n", self._position) - response = self._response[self._position : i + 2] - self._position = i + 2 - return response - - def _recv(self, count): - end = self._position + count - response = self._response[self._position : end] - self._position = end - print(response) - return response diff --git a/tests/legacy_test.py b/tests/legacy_test.py deleted file mode 100644 index cba604d..0000000 --- a/tests/legacy_test.py +++ /dev/null @@ -1,208 +0,0 @@ -# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries -# -# SPDX-License-Identifier: Unlicense - -""" Legacy Tests """ - -from unittest import mock -import json -import legacy_mocket as mocket -import adafruit_requests - -IP = "1.2.3.4" -HOST = "httpbin.org" -RESPONSE = {"Date": "July 25, 2019"} -ENCODED = json.dumps(RESPONSE).encode("utf-8") -HEADERS = "HTTP/1.0 200 OK\r\nContent-Length: {}\r\n\r\n".format(len(ENCODED)).encode( - "utf-8" -) - - -def test_get_json(): - mocket.getaddrinfo.return_value = ((None, None, None, None, (IP, 80)),) - sock = mocket.Mocket(HEADERS + ENCODED) - mocket.socket.return_value = sock - - adafruit_requests.set_socket(mocket, mocket.interface) - response = adafruit_requests.get("http://" + HOST + "/get") - - sock.connect.assert_called_once_with((IP, 80)) - assert response.json() == RESPONSE - response.close() - - -def test_tls_mode(): - mocket.getaddrinfo.return_value = ((None, None, None, None, (IP, 80)),) - sock = mocket.Mocket(HEADERS + ENCODED) - mocket.socket.return_value = sock - - adafruit_requests.set_socket(mocket, mocket.interface) - response = adafruit_requests.get("https://" + HOST + "/get") - - sock.connect.assert_called_once_with((HOST, 443), mocket.interface.TLS_MODE) - assert response.json() == RESPONSE - response.close() - - -def test_post_string(): - mocket.getaddrinfo.return_value = ((None, None, None, None, (IP, 80)),) - sock = mocket.Mocket(HEADERS + ENCODED) - mocket.socket.return_value = sock - - adafruit_requests.set_socket(mocket, mocket.interface) - data = "31F" - response = adafruit_requests.post("http://" + HOST + "/post", data=data) - sock.connect.assert_called_once_with((IP, 80)) - sock.send.assert_called_with(b"31F") - response.close() - - -def test_second_tls_send_fails(): - mocket.getaddrinfo.return_value = ((None, None, None, None, (IP, 80)),) - sock = mocket.Mocket(HEADERS + ENCODED) - sock2 = mocket.Mocket(HEADERS + ENCODED) - mocket.socket.call_count = 0 # Reset call count - mocket.socket.side_effect = [sock, sock2] - - adafruit_requests.set_socket(mocket, mocket.interface) - response = adafruit_requests.get("https://" + HOST + "/testwifi/index.html") - - sock.send.assert_has_calls( - [ - mock.call(b"testwifi/index.html"), - ] - ) - - sock.send.assert_has_calls( - [ - mock.call(b"Host: "), - mock.call(HOST.encode("utf-8")), - mock.call(b"\r\n"), - ] - ) - assert response.text == str(ENCODED, "utf-8") - - sock.fail_next_send = True - adafruit_requests.get("https://" + HOST + "/get2") - - sock.connect.assert_called_once_with((HOST, 443), mocket.interface.TLS_MODE) - sock2.connect.assert_called_once_with((HOST, 443), mocket.interface.TLS_MODE) - # Make sure that the socket is closed after send fails. - sock.close.assert_called_once() - assert sock2.close.call_count == 0 - assert mocket.socket.call_count == 2 - - -def test_second_send_fails(): - mocket.getaddrinfo.return_value = ((None, None, None, None, (IP, 80)),) - sock = mocket.Mocket(HEADERS + ENCODED) - sock2 = mocket.Mocket(HEADERS + ENCODED) - mocket.socket.call_count = 0 # Reset call count - mocket.socket.side_effect = [sock, sock2] - - adafruit_requests.set_socket(mocket, mocket.interface) - response = adafruit_requests.get("http://" + HOST + "/testwifi/index.html") - - sock.send.assert_has_calls( - [ - mock.call(b"testwifi/index.html"), - ] - ) - - sock.send.assert_has_calls( - [ - mock.call(b"Host: "), - mock.call(HOST.encode("utf-8")), - mock.call(b"\r\n"), - ] - ) - assert response.text == str(ENCODED, "utf-8") - - sock.fail_next_send = True - adafruit_requests.get("http://" + HOST + "/get2") - - sock.connect.assert_called_once_with((IP, 80)) - sock2.connect.assert_called_once_with((IP, 80)) - # Make sure that the socket is closed after send fails. - sock.close.assert_called_once() - assert sock2.close.call_count == 0 - assert mocket.socket.call_count == 2 - - -def test_first_read_fails(): - mocket.getaddrinfo.return_value = ((None, None, None, None, (IP, 80)),) - sock = mocket.Mocket(b"") - sock2 = mocket.Mocket(HEADERS + ENCODED) - mocket.socket.call_count = 0 # Reset call count - mocket.socket.side_effect = [sock, sock2] - - adafruit_requests.set_socket(mocket, mocket.interface) - adafruit_requests.get("http://" + HOST + "/testwifi/index.html") - - sock.send.assert_has_calls( - [ - mock.call(b"testwifi/index.html"), - ] - ) - - sock.send.assert_has_calls( - [ - mock.call(b"Host: "), - mock.call(HOST.encode("utf-8")), - mock.call(b"\r\n"), - ] - ) - - sock2.send.assert_has_calls( - [ - mock.call(b"Host: "), - mock.call(HOST.encode("utf-8")), - mock.call(b"\r\n"), - ] - ) - - sock.connect.assert_called_once_with((IP, 80)) - sock2.connect.assert_called_once_with((IP, 80)) - # Make sure that the socket is closed after the first receive fails. - sock.close.assert_called_once() - assert mocket.socket.call_count == 2 - - -def test_second_tls_connect_fails(): - mocket.getaddrinfo.return_value = ((None, None, None, None, (IP, 80)),) - sock = mocket.Mocket(HEADERS + ENCODED) - sock2 = mocket.Mocket(HEADERS + ENCODED) - sock3 = mocket.Mocket(HEADERS + ENCODED) - mocket.socket.call_count = 0 # Reset call count - mocket.socket.side_effect = [sock, sock2, sock3] - sock2.connect.side_effect = RuntimeError("error connecting") - - adafruit_requests.set_socket(mocket, mocket.interface) - response = adafruit_requests.get("https://" + HOST + "/testwifi/index.html") - - sock.send.assert_has_calls( - [ - mock.call(b"testwifi/index.html"), - ] - ) - - sock.send.assert_has_calls( - [ - mock.call(b"Host: "), - mock.call(HOST.encode("utf-8")), - mock.call(b"\r\n"), - ] - ) - assert response.text == str(ENCODED, "utf-8") - - host2 = "test.adafruit.com" - response = adafruit_requests.get("https://" + host2 + "/get2") - - sock.connect.assert_called_once_with((HOST, 443), mocket.interface.TLS_MODE) - sock2.connect.assert_called_once_with((host2, 443), mocket.interface.TLS_MODE) - sock3.connect.assert_called_once_with((host2, 443), mocket.interface.TLS_MODE) - # Make sure that the socket is closed after send fails. - sock.close.assert_called_once() - sock2.close.assert_called_once() - assert sock3.close.call_count == 0 - assert mocket.socket.call_count == 3 From f4478ceb1d958a9e28f321b7be424df0b315e90e Mon Sep 17 00:00:00 2001 From: foamyguy Date: Tue, 27 Jun 2023 18:44:22 -0500 Subject: [PATCH 3/4] remove cast to support recv_into --- adafruit_requests.py | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/adafruit_requests.py b/adafruit_requests.py index f253b8c..a015f61 100644 --- a/adafruit_requests.py +++ b/adafruit_requests.py @@ -41,16 +41,10 @@ import json as json_module -if sys.implementation.name == "circuitpython": - - def cast(_t, value): - """No-op shim for the typing.cast() function which is not available in CircuitPython.""" - return value - -else: +if not sys.implementation.name == "circuitpython": from ssl import SSLContext from types import ModuleType, TracebackType - from typing import Any, Dict, Optional, Tuple, Type, Union, cast + from typing import Any, Dict, Optional, Tuple, Type, Union try: from typing import Protocol @@ -215,7 +209,7 @@ def __exit__( self.close() def _recv_into(self, buf: bytearray, size: int = 0) -> int: - return cast("SupportsRecvInto", self.socket).recv_into(buf, size) + return self.socket.recv_into(buf, size) def _readto(self, stop: bytes) -> bytearray: buf = self._receive_buffer From c5e1a4ce53f8bf6c909ce748a6a8266a9c341fa5 Mon Sep 17 00:00:00 2001 From: foamyguy Date: Tue, 27 Jun 2023 18:47:38 -0500 Subject: [PATCH 4/4] remove LegacyCircuitPythonSocketType --- adafruit_requests.py | 9 --------- 1 file changed, 9 deletions(-) diff --git a/adafruit_requests.py b/adafruit_requests.py index a015f61..363abb4 100644 --- a/adafruit_requests.py +++ b/adafruit_requests.py @@ -77,14 +77,6 @@ def connect( kwarg optionally may indicate SSL or not, depending on the underlying interface. """ - class LegacyCircuitPythonSocketType(CommonCircuitPythonSocketType, Protocol): - """Describes the structure a legacy CircuitPython socket type must have.""" - - def recv(self, bufsize: int = ...) -> bytes: - """Receive data from the socket. The return value is a bytes object representing - the data received. The maximum amount of data to be received at once is specified - by bufsize.""" - class SupportsRecvWithFlags(Protocol): """Describes a type that posseses a socket recv() method supporting the flags kwarg.""" @@ -122,7 +114,6 @@ def connect(self, address: Union[Tuple[Any, ...], str, bytes]) -> None: """Connect to a remote socket at the provided address.""" SocketType = Union[ - LegacyCircuitPythonSocketType, CircuitPythonSocketType, StandardPythonSocketType, ]