Skip to content

RecursionError when unpickling message object #804

@fpetry

Description

@fpetry

Python 3.7.5
python-can 3.3.2

To hand over messages to another process I intended to use multiprocessing.JoinableQueue.
I stumbled over a RecursionError and tracked it down to the pickleing that is used to serialize the objects (see example code).

The error occurs when calling loads() on the serialized message.

I'm not a python expert and found some clues regarding the __getattr__ method. Maybe a custom __getattr__ method is needed for the message objects?

Is there another way to hand over the emssage objects to another process?

#!/usr/bin/env python3
import can
import logging
import pickle

class CanReader():
    """
    Reads messages from a configured can bus and puts them into a queue for further processing
    """

    def __init__(self):
        LOG_FORMAT = '%(asctime)s:%(threadName)s:%(levelname)s: %(message)s'
        logging.basicConfig(format=LOG_FORMAT, level=logging.INFO)


    def run(self):
        can.rc['interface'] = 'socketcan_ctypes'
        can.rc['channel'] = "vcan0"

        can_bus = can.interface.Bus()

        try:
            for can_msg in can_bus:
                if can_msg is  None:
                    continue

                pick = pickle.dumps(can_msg)
                logging.info("pickled")
                unpick = pickle.loads(pick)
                logging.info("unpickled")

        except KeyboardInterrupt:
            logging.error("KeyboardInterrupt - Stopping CanReader")

        return

if __name__ == "__main__":
    canReader = CanReader()
    canReader.run()

Console output:

/usr/bin/python3.7 /XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/SerializationTest.py
2020-04-02 13:35:59,352:MainThread:INFO: Created a socket
2020-04-02 13:35:59,389:MainThread:INFO: pickled
Traceback (most recent call last):
  File "/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/SerializationTest.py", line 39, in <module>
    canReader.run()
  File "/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/SerializationTest.py", line 29, in run
    unpick = pickle.loads(pick)
  File "/home/XXXXXX/.local/lib/python3.7/site-packages/can/message.py", line 59, in __getattr__
    return self._dict[key]
  File "/home/XXXXXX/.local/lib/python3.7/site-packages/can/message.py", line 59, in __getattr__
    return self._dict[key]
  File "/home/XXXXXX/.local/lib/python3.7/site-packages/can/message.py", line 59, in __getattr__
    return self._dict[key]
  [Previous line repeated 494 more times]
  File "/home/XXXXXX/.local/lib/python3.7/site-packages/can/message.py", line 58, in __getattr__
    warnings.warn("Custom attributes of messages are deprecated and will be removed in 4.0", DeprecationWarning)
RecursionError: maximum recursion depth exceeded while calling a Python object

Process finished with exit code 1

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions