pytestpython-3.7socketcan

AttributeError: object has no attribute thrown even though an attribute is implicitly given


Not sure why the following code throws the error AttributeError: 'CANManager' object has no attribute bus:

class CANManager():
  def __init__(self, name="can0", bitrate=500000, data_bitrate=2000000, fd=False):
    self.bus_name = name
    self.connect(fd)

  def connect(self, fd: bool):
    if fd is False:
      self.bus = can.interface.Bus(channel=self.bus_name, bustype='socketcan')
    elif fd is True:
      self.bus = can.interface.Bus(channel=self.bus_name, bustype='socketcan')
    return True

The self.connect(fd) should initialize bus in the constructor, shouldn't it?


Solution

  • There is nothing wrong with the above class.

    The issue was that the fixture using this class was getting the fd boolean value from pytest.ini; which was set to the string "False":

    @pytest.fixture(scope="session")
    def can0(options, pytestconfig):
      logging.getLogger('can').setLevel(logging.WARNING)
      can_manager = CANManager(name=options.get('can_a'), 
                               bitrate=int(options.get('can_a_bitrate')),
                               fd=bool(options.get('can_fd_enable')))
    
        yield can_manager
        
        can_manager.disconnect()
    

    So as shown above the fd parameter needed to be cast as a fd=bool(options.get('can_fd_enable')) so that the if statements in the connect definitions could be triggered. Python by default uses type declaration string so setting this variable in pytest.ini

    can_fd_enable = False

    Is setting it to the string False