unable to instantiate Message() with string data

Issue #83 new
umläute created an issue

the following fails:

$ python3
>>> import can
>>> can.message.Message(data="foo")

giving the (not so helpful) response:

 Couldn't create message from 'data' (<class 'str'>)
 Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
   File "/usr/lib/python3/dist-packages/can/message.py", line 36, in __init__
     self.dlc = len(self.data)
 AttributeError: 'Message' object has no attribute 'data'

Message should of course have an attribute data, but the assignment self.data = bytearray(data) failed (for strings, on Python3), which goes unnoticed since the failure is caught and logged.

maybe it would be better to replace the init code with

    self.data = bytearray()
    self.dlc = 0
    if data is not None:
        try:
            self.data = bytearray(data)
        except TypeError:
            logger.error("Couldn't create message from %r (%r)", data, type(data))

https://bitbucket.org/hardbyte/python-can/src/0d04bee9b55e1dc7a27dc96f90b2f65fb790f12f/can/message.py?at=default&fileviewer=file-view-default#message.py-26:33

Comments (6)

  1. Christian Sandberg

    I don't see a reason why this would not raise an exception. The message is unusable either way.

  2. umläute reporter

    then the exception should be more meaningful. alternatively, the Message should be documented

  3. Travis Travelstead

    Here are my thoughts.

    I think you should be using can.Message() and not can.message.Message()

    CAN does not deal with strings and characters so trying to use them will only cause issues. Stick with bytes, lists and tuples.

    When involving Strings you need to start worrying about encoding of the string. You can get away with this by converting to bytearray using UTF-8 (which is basically ASCII). bytearray([source[, encoding[, errors]]])

    I agree that most exceptions should not be hidden, but from my experience with CAN is that sometimes they just happen during normal use and you have to catch them. For example a temporary wiring issue causing CAN send/recv failures. I cannot have this crash my application so I catch them, but because the frequency I do not log them as they would fill up too quickly. I would just test with the python-can logging active until you get more comfortable.

  4. Log in to comment