From f73df21ee9016e8bd926756b6b15c4e791c43c24 Mon Sep 17 00:00:00 2001 From: Aaron Fulton Date: Sat, 14 Feb 2026 12:18:09 +1300 Subject: [PATCH 1/4] Changed slcan serial read routine to be faster and to manage the buffer more cauciously --- can/interfaces/slcan.py | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/can/interfaces/slcan.py b/can/interfaces/slcan.py index 086d9ed32..bd0fe7ec1 100644 --- a/can/interfaces/slcan.py +++ b/can/interfaces/slcan.py @@ -219,16 +219,17 @@ def _read(self, timeout: float | None) -> str | None: # Due to accessing `serialPortOrig.in_waiting` too often will reduce the performance. # We read the `serialPortOrig.in_waiting` only once here. in_waiting = self.serialPortOrig.in_waiting - for _ in range(max(1, in_waiting)): - new_byte = self.serialPortOrig.read(1) - if new_byte: - self._buffer.extend(new_byte) - else: - break - - if new_byte in (self._ERROR, self._OK): - string = self._buffer.decode() - self._buffer.clear() + if in_waiting > 0: + self._buffer.extend(self.serialPortOrig.read(in_waiting)) + else: + byte = self.serialPortOrig.read(1) + if byte: + self._buffer.extend(byte) + + for i in range(len(self._buffer)): + if self._buffer[i] in (self._OK[0], self._ERROR[0]): + string = self._buffer[: i + 1].decode() + del self._buffer[: i + 1] return string if _timeout.expired(): From cd346bde09f253e07aa493efcbed5e6435f1802d Mon Sep 17 00:00:00 2001 From: aaronfultonnz Date: Mon, 16 Feb 2026 14:21:56 +1300 Subject: [PATCH 2/4] As per merge request suggestion Co-authored-by: zariiii9003 <52598363+zariiii9003@users.noreply.github.com> --- can/interfaces/slcan.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/can/interfaces/slcan.py b/can/interfaces/slcan.py index bd0fe7ec1..9139fc11b 100644 --- a/can/interfaces/slcan.py +++ b/can/interfaces/slcan.py @@ -218,7 +218,7 @@ def _read(self, timeout: float | None) -> str | None: while True: # Due to accessing `serialPortOrig.in_waiting` too often will reduce the performance. # We read the `serialPortOrig.in_waiting` only once here. - in_waiting = self.serialPortOrig.in_waiting + size = self.serialPortOrig.in_waiting or 1 if in_waiting > 0: self._buffer.extend(self.serialPortOrig.read(in_waiting)) else: From a82c91dd73333f0c723fc4957b50233638c3eda0 Mon Sep 17 00:00:00 2001 From: aaronfultonnz Date: Mon, 16 Feb 2026 14:24:17 +1300 Subject: [PATCH 3/4] as per merge request suggestion Co-authored-by: zariiii9003 <52598363+zariiii9003@users.noreply.github.com> --- can/interfaces/slcan.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/can/interfaces/slcan.py b/can/interfaces/slcan.py index 9139fc11b..56ad89f23 100644 --- a/can/interfaces/slcan.py +++ b/can/interfaces/slcan.py @@ -226,7 +226,7 @@ def _read(self, timeout: float | None) -> str | None: if byte: self._buffer.extend(byte) - for i in range(len(self._buffer)): + for i, byte in enumerate(self._buffer): if self._buffer[i] in (self._OK[0], self._ERROR[0]): string = self._buffer[: i + 1].decode() del self._buffer[: i + 1] From 7aa164ccfeb97fa28938d48f1d83f1d3f3df4ad6 Mon Sep 17 00:00:00 2001 From: Aaron Fulton Date: Mon, 16 Feb 2026 14:59:52 +1300 Subject: [PATCH 4/4] Simplified slcan serial reading --- can/interfaces/slcan.py | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/can/interfaces/slcan.py b/can/interfaces/slcan.py index 56ad89f23..a6430d4e2 100644 --- a/can/interfaces/slcan.py +++ b/can/interfaces/slcan.py @@ -219,15 +219,10 @@ def _read(self, timeout: float | None) -> str | None: # Due to accessing `serialPortOrig.in_waiting` too often will reduce the performance. # We read the `serialPortOrig.in_waiting` only once here. size = self.serialPortOrig.in_waiting or 1 - if in_waiting > 0: - self._buffer.extend(self.serialPortOrig.read(in_waiting)) - else: - byte = self.serialPortOrig.read(1) - if byte: - self._buffer.extend(byte) + self._buffer.extend(self.serialPortOrig.read(size)) for i, byte in enumerate(self._buffer): - if self._buffer[i] in (self._OK[0], self._ERROR[0]): + if byte in (self._OK[0], self._ERROR[0]): string = self._buffer[: i + 1].decode() del self._buffer[: i + 1] return string