Skip to content

Commit

Permalink
Fix fileno error on Windows (Serial bus) (#1333)
Browse files Browse the repository at this point in the history
* Add conda-forge badge to readme

* Update fileno method in serial_can.py

Change implemented similar to that made in #1313. This means notifiers will now work with the Serial interface.

* Format serial_test.py with black

* Revert "Add conda-forge badge to readme"

This reverts commit 59d0b3c.
  • Loading branch information
MattWoodhead committed Jun 22, 2022
1 parent cb3d4dc commit ec06452
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 3 deletions.
11 changes: 8 additions & 3 deletions can/interfaces/serial/serial_can.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
See the interface documentation for the format being used.
"""

import io
import logging
import struct
from typing import Any, List, Tuple, Optional
Expand Down Expand Up @@ -212,10 +213,14 @@ def _recv_internal(
raise CanOperationError("could not read from serial") from error

def fileno(self) -> int:
if hasattr(self._ser, "fileno"):
try:
return self._ser.fileno()
# Return an invalid file descriptor on Windows
return -1
except io.UnsupportedOperation:
raise NotImplementedError(
"fileno is not implemented using current CAN bus on this platform"
)
except Exception as exception:
raise CanOperationError("Cannot fetch fileno") from exception

@staticmethod
def _detect_available_configs() -> List[AutoDetectedConfig]:
Expand Down
18 changes: 18 additions & 0 deletions test/serial_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,24 @@ def test_rx_tx_min_timestamp_error(self):
msg = can.Message(timestamp=-1)
self.assertRaises(ValueError, self.bus.send, msg)

def test_when_no_fileno(self):
"""
Tests for the fileno method catching the missing pyserial implementeation on the Windows platform
"""
try:
fileno = self.bus.fileno()
except NotImplementedError:
pass # allow it to be left non-implemented for Windows platform
else:
fileno.__gt__ = (
lambda self, compare: True
) # Current platform implements fileno, so get the mock to respond to a greater than comparison
self.assertIsNotNone(fileno)
self.assertFalse(
fileno == -1
) # forcing the value to -1 is the old way of managing fileno on Windows but it is not compatible with notifiers
self.assertTrue(fileno > 0)


class SimpleSerialTest(unittest.TestCase, SimpleSerialTestBase):
def __init__(self, *args, **kwargs):
Expand Down

0 comments on commit ec06452

Please sign in to comment.