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 <amulhern@redhat.com>
This commit is contained in:
mulhern 2015-12-22 21:39:34 -05:00
parent cf27328d13
commit d75b6d2f2b
1 changed files with 23 additions and 18 deletions

View File

@ -32,6 +32,7 @@ import os as _os
import errno as _errno import errno as _errno
from select import select as _select from select import select as _select
from pyudev import Context as _Context, Monitor as _Monitor, Device as _Device from pyudev import Context as _Context, Monitor as _Monitor, Device as _Device
from pyudev import DeviceNotFoundError
native_implementation = 'udev' 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 device_handle: a device handle returned by open() or open_path().
:param index: the index of the string to get. :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: try:
return None key = _DEVICE_STRINGS[index]
except KeyError:
return None
assert device_handle assert device_handle
stat = _os.fstat(device_handle) stat = _os.fstat(device_handle)
dev = _Device.from_device_number(_Context(), 'char', stat.st_rdev) try:
if dev: dev = _Device.from_device_number(_Context(), 'char', stat.st_rdev)
hid_dev = dev.find_parent('hid') except (DeviceNotFoundError, ValueError):
if hid_dev: return None
assert 'HID_ID' in hid_dev
bus, _ignore, _ignore = hid_dev['HID_ID'].split(':')
if bus == '0003': # USB hid_dev = dev.find_parent('hid')
usb_dev = dev.find_parent('usb', 'usb_device') if hid_dev:
assert usb_dev assert 'HID_ID' in hid_dev
key = _DEVICE_STRINGS[index] bus, _ignore, _ignore = hid_dev['HID_ID'].split(':')
attrs = usb_dev.attributes
if key in attrs:
return attrs[key]
elif bus == '0005': # BLUETOOTH if bus == '0003': # USB
# TODO usb_dev = dev.find_parent('usb', 'usb_device')
pass assert usb_dev
return usb_dev.attributes.get(key)
elif bus == '0005': # BLUETOOTH
# TODO
pass