-
Notifications
You must be signed in to change notification settings - Fork 670
Make Device hashable again #376
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Commit 251dbc1 ("core: implement Device.__eq__") had the side effect of making Device objects unhashable, so they could no longer be included in a set(). This was a regression from v1.1.1. Add a corresponding __hash__() method so that Device objects are hashable again. Fixes eblot/pyftdi#256
|
The pyftdi code and comments after the call that raises that exception makes me worry that we may instead need to remove if sys.platform == 'win32':
# ugly kludge for a boring OS:
# on Windows, the USB stack may enumerate the very same
# devices several times: a real device with N interface
# appears also as N device with as single interface.
# We only keep the "device" that declares the most
# interface count and discard the "virtual" ones.
filtered_devs = dict()
for dev in devs:
vid = dev.idVendor
pid = dev.idProduct
ifc = max([cfg.bNumInterfaces for cfg in dev])
k = (vid, pid, dev.bus, dev.address)
if k not in filtered_devs:
filtered_devs[k] = dev
else:
fdev = filtered_devs[k]
fifc = max([cfg.bNumInterfaces for cfg in fdev])
if fifc < ifc:
filtered_devs[k] = dev
devs = set(filtered_devs.values())—https://github.com/eblot/pyftdi/blob/845bc7944fe1/pyftdi/usbtools.py#L615-L635 The notable part is that, apparently, multiple |
|
Pinging @mcuee: have you seen this behavior on libusb and Windows (or any other platform)? |
|
By default Windows will enumerate different interfaces of a USB composite device as different devices. That is one of the major challenges for libusb Windows backend. Sometimes we actually have to asked the user to use WinUSB to replace the USB Composite Device parent driver (usbccgp.sys). |
|
On the other hand, at one particular run (without hotplug), I believe libusb_get_port_numbers() for a device should be unique. With hotplug that is another story since libusb does not support hotplug under Windows. Example: I purposely use different drivers for the two interfaces of FT2232H (USB Composite), one with libusbk driver and one with WinUSB driver, and the parent device is using usbccgp.sys. Still libusb lists it as one device. https://github.com/libusb/libusb/blob/master/examples/listdevs.c |
|
As for the pyftdi issue, yes I can reproduce the issue. |
|
With the proposed fix, the issue goes away. |
|
Same report here. eblot/pyftdi#257 |
That makes sense (within a given bus), and it seems to also hold for Will give it a couple of days before releasing 1.2.1, just in case someone reports another problem with And thanks again @mcuee. |
UsbTools in PyFtdi needs a major overhaul as it is too complex and dates back when earlier versions of PyUSB/libusb enumeration were very slow and were lacking useful features. I need to tackle with this rework "soon", as other features such as index-based selection is awful and buggy. Meanwhile I've disabled compatibility with PyUSB 1.2.0+ (and will restore support whenever 1.2.1 gets released). |
|
Thanks for the additional context. Oh, and I just released 1.2.1. |
|
pyftdi v0.53.3 has just been tagged and available on PyPI. |
Commit 251dbc1 (core: implement
Device.__eq__") had the side effect of makingDeviceobjects unhashable, so they could no longer be included in aset(). This was a regression from v1.1.1. Add a corresponding__hash__()method so that Device objects are hashable again.Fixes eblot/pyftdi#256