From d75b6d2f2b8b012dbd1540a97dd73b756fb4d31b Mon Sep 17 00:00:00 2001 From: mulhern Date: Tue, 22 Dec 2015 21:39:34 -0500 Subject: [PATCH] Fix some bugs in udev.get_indexed_string. * from_device_number raises an exception if no device found, rather than returning None. So, instead of checking the result, catch the exception. * Use Attributes.get() method instead of checking containment and using the index operator. This is really the only correct way, see rhbz#1267584. Effect of the changes: Previously, if no device was found this method would raise an exception. Now it returns None instead. Previously this method read the value of the attribute corresponding to key twice, once via 'key in attributes' and again when accessing the key. Now, it just reads it the one time. Reason for noticing all these problems: In pyudev-0.18 the Attributes class is fixed, and no longer has the [] operator or __contains__ method or other methods which require a total mapping. This patch fixes several bugs while simultaneously avoiding these removed operators. Signed-off-by: mulhern --- lib/hidapi/udev.py | 41 +++++++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/lib/hidapi/udev.py b/lib/hidapi/udev.py index 27e1ff12..abcd8113 100644 --- a/lib/hidapi/udev.py +++ b/lib/hidapi/udev.py @@ -32,6 +32,7 @@ import os as _os import errno as _errno from select import select as _select from pyudev import Context as _Context, Monitor as _Monitor, Device as _Device +from pyudev import DeviceNotFoundError native_implementation = 'udev' @@ -338,27 +339,31 @@ def get_indexed_string(device_handle, index): :param device_handle: a device handle returned by open() or open_path(). :param index: the index of the string to get. + :returns: the value corresponding to index, or None if no value found + :rtype: bytes or NoneType """ - if index not in _DEVICE_STRINGS: - return None + try: + key = _DEVICE_STRINGS[index] + except KeyError: + return None assert device_handle stat = _os.fstat(device_handle) - dev = _Device.from_device_number(_Context(), 'char', stat.st_rdev) - if dev: - hid_dev = dev.find_parent('hid') - if hid_dev: - assert 'HID_ID' in hid_dev - bus, _ignore, _ignore = hid_dev['HID_ID'].split(':') + try: + dev = _Device.from_device_number(_Context(), 'char', stat.st_rdev) + except (DeviceNotFoundError, ValueError): + return None - if bus == '0003': # USB - usb_dev = dev.find_parent('usb', 'usb_device') - assert usb_dev - key = _DEVICE_STRINGS[index] - attrs = usb_dev.attributes - if key in attrs: - return attrs[key] + hid_dev = dev.find_parent('hid') + if hid_dev: + assert 'HID_ID' in hid_dev + bus, _ignore, _ignore = hid_dev['HID_ID'].split(':') - elif bus == '0005': # BLUETOOTH - # TODO - pass + if bus == '0003': # USB + usb_dev = dev.find_parent('usb', 'usb_device') + assert usb_dev + return usb_dev.attributes.get(key) + + elif bus == '0005': # BLUETOOTH + # TODO + pass