hardbyte / python-can

The can package provides controller area network support for Python developers
https://python-can.readthedocs.io
GNU Lesser General Public License v3.0
1.31k stars 604 forks source link

How to access typing for different CAN bus interface types so Pylance can know which instance attributes exist? #1880

Open ilanbiala opened 1 month ago

ilanbiala commented 1 month ago

Currently instantiating a bus looks something like:

bus: can.bus.BusABC  = can.Bus(channel="can0", can_filters=[...], interface="socketcan", bitrate=250_000)

However, then bus.channel is unknown because it is not defined in can.bus.BusABC, but channel is a defined and used attributed in subclasses such as KvaserBus and SocketcanBus. Is there a more specific type that can be used, or something that exposes the channel argument provided when instantiating a CAN bus?

zariiii9003 commented 2 weeks ago

I think you'd have to do if isinstance(bus, KvaserBus) or if hasattr(bus, "channel") for this. We should probably add a channel property to BusABC,

ilanbiala commented 1 week ago

Yeah, generally I'd rather avoid conditionals to appease Mypy/Pylance, etc. I skimmed through the code and it does seem like BusABC should have channel and that member value could be instantiated by each interface implementation? Only hiccup is that it seems like each implementation could have a different type for channel, e.g. SocketCAN expects channel is a str while Kvaser expects channel is an int.