def sys_number(self): """ The trailing number of the :attr:`sys_name` as unicode string, or ``None``, if the device has no trailing number in its name. .. note:: The number is returned as unicode string to preserve the exact format of the number, especially any leading zeros: >>> from pyudev import Context, Device >>> context = Context() >>> device = Device.from_path(context, '/sys/devices/LNXSYSTM:00') >>> device.sys_number u'00' To work with numbers, explicitly convert them to ints: >>> int(device.sys_number) 0 .. versionadded:: 0.11 """ number = libudev.udev_device_get_sysnum(self) if number is not None: return ensure_unicode_string(number)
def action(self): """ The device event action as string, or ``None``, if this device was not received from a :class:`Monitor`. Usual actions are: ``'add'`` A device has been added (e.g. a USB device was plugged in) ``'remove'`` A device has been removed (e.g. a USB device was unplugged) ``'change'`` Something about the device changed (e.g. a device property) ``'online'`` The device is online now ``'offline'`` The device is offline now .. warning:: Though the actions listed above are the most common, this property *may* return other values, too, so be prepared to handle unknown actions! .. versionadded:: 0.16 """ action = libudev.udev_device_get_action(self) if action: return ensure_unicode_string(action)
def device_path(self): """ The device directory path defaulting to ``/dev`` as unicode string. This can be overridden in the udev configuration. """ return ensure_unicode_string(self._libudev.udev_get_dev_path(self))
def sys_path(self): """ Absolute path of this device in ``sysfs`` including the ``sysfs`` mount point as unicode string. """ return ensure_unicode_string( self._libudev.udev_device_get_syspath(self))
def udev_version(): """ Get the version of the underlying udev library. udev doesn't use a standard major-minor versioning scheme, but instead labels releases with a single consecutive number. Consequently, the version number returned by this function is a single integer, and not a tuple (like for instance the interpreter version in :data:`sys.version_info`). As libudev itself does not provide a function to query the version number, this function calls the ``udevadm`` utilitiy, so be prepared to catch :exc:`~exceptions.EnvironmentError` and :exc:`~subprocess.CalledProcessError` if you call this function. Return the version number as single integer. Raise :exc:`~exceptions.ValueError`, if the version number retrieved from udev could not be converted to an integer. Raise :exc:`~exceptions.EnvironmentError`, if ``udevadm`` was not found, or could not be executed. Raise :exc:`subprocess.CalledProcessError`, if ``udevadm`` returned a non-zero exit code. On Python 2.7 or newer, the ``output`` attribute of this exception is correctly set. .. versionadded:: 0.8 """ output = ensure_unicode_string(check_output(['udevadm', '--version'])) return int(output.strip())
def action(self): """ The device event action as string, or ``None``, if this device was not received from a :class:`Monitor`. Usual actions are: ``'add'`` A device has been added (e.g. a USB device was plugged in) ``'remove'`` A device has been removed (e.g. a USB device was unplugged) ``'change'`` Something about the device changed (e.g. a device property) ``'online'`` The device is online now ``'offline'`` The device is offline now .. warning:: Though the actions listed above are the most common, this property *may* return other values, too, so be prepared to handle unknown actions! .. versionadded:: 0.16 """ action = self._libudev.udev_device_get_action(self) return ensure_unicode_string(action) if action is not None else None
def device_links(self): """ An iterator, which yields the absolute paths (including the device directory, see :attr:`Context.device_path`) of all symbolic links pointing to the :attr:`device_node` of this device. The paths are unicode strings. UDev can create symlinks to the original device node (see :attr:`device_node`) inside the device directory. This is often used to assign a constant, fixed device node to devices like removeable media, which technically do not have a constant device node, or to map a single device into multiple device hierarchies. The property provides access to all such symbolic links, which were created by UDev for this device. .. warning:: Links are not necessarily resolved by :meth:`Device.from_device_file()`. Hence do *not* rely on ``Device.from_device_file(context, link).device_path == device.device_path`` from any ``link`` in ``device.device_links``. """ devlinks = libudev.udev_device_get_devlinks_list_entry(self) for name, _ in udev_list_iterate(devlinks): yield ensure_unicode_string(name)
def device_path(self): """ The device directory path defaulting to ``/dev`` as unicode string. """ if hasattr(self._libudev, 'udev_get_dev_path'): return ensure_unicode_string(self._libudev.udev_get_dev_path(self)) return '/dev' # Fixed path since udev 183
def receive_device(self): """ Receive a single device from the monitor. The caller must make sure, that there are events available in the event queue. The call blocks, until a device is available. If a device was available, return ``(action, device)``. ``device`` is the :class:`Device` object describing the device. ``action`` is a string describing the action. udev informs about the following actions: ``'add'`` A device has been added (e.g. a USB device was plugged in) ``'remove'`` A device has been removed (e.g. a USB device was unplugged) ``'change'`` Something about the device changed (e.g. a device property) ``'move'`` The device was renamed, moved, or re-parented Raise :exc:`~exceptions.EnvironmentError`, if no device could be read. """ try: device_p = self._libudev.udev_monitor_receive_device(self) except EnvironmentError: self._reraise_with_socket_path() if not device_p: raise EnvironmentError('Could not receive device') action = ensure_unicode_string( self._libudev.udev_device_get_action(device_p)) return action, Device(self.context, device_p)
def receive_device(self): """ Receive a single device from the monitor. The caller must make sure, that there are events available in the event queue. The call blocks, until a device is available. If a device was available, return ``(action, device)``. ``device`` is the :class:`Device` object describing the device. ``action`` is a string describing the action. udev informs about the following actions: ``'add'`` A device has been added (e.g. a USB device was plugged in) ``'remove'`` A device has been removed (e.g. a USB device was unplugged) ``'change'`` Something about the device changed (e.g. a device property) ``'move'`` The device was renamed, moved, or re-parented Raise :exc:`~exceptions.EnvironmentError`, if no device could be read. """ try: device_p = libudev.udev_monitor_receive_device(self) except EnvironmentError: self._reraise_with_socket_path() if not device_p: raise EnvironmentError('Could not receive device') action = ensure_unicode_string( libudev.udev_device_get_action(device_p)) return action, Device(self.context, device_p)
def sys_path(self): """ The ``sysfs`` mount point defaulting to ``/sys'`` as unicode string. """ if hasattr(self._libudev, 'udev_get_sys_path'): return ensure_unicode_string(self._libudev.udev_get_sys_path(self)) return '/sys' # Fixed path since udev 183
def device_path(self): """ The device directory path defaulting to ``/dev`` as unicode string. This can be overridden in the udev configuration. """ return ensure_unicode_string(libudev.udev_get_dev_path(self))
def sys_path(self): """ The ``sysfs`` mount point defaulting to ``/sys'`` as unicode string. The mount point can be overwritten using the environment variable :envvar:`SYSFS_PATH`. Use this for testing purposes. """ return ensure_unicode_string(libudev.udev_get_sys_path(self))
def sys_path(self): """ The ``sysfs`` mount point defaulting to ``/sys'`` as unicode string. The mount point can be overwritten using the environment variable :envvar:`SYSFS_PATH`. Use this for testing purposes. """ return ensure_unicode_string(self._libudev.udev_get_sys_path(self))
def subsystem(self): """ Name of the subsystem this device is part of as unicode string. :returns: name of subsystem if found, else None :rtype: unicode string or NoneType """ subsys = self._libudev.udev_device_get_subsystem(self) return None if subsys is None else ensure_unicode_string(subsys)
def __iter__(self): """ Iterate over all tags. Yield each tag as unicode string. """ tags = libudev.udev_device_get_tags_list_entry(self.device) for tag, _ in udev_list_iterate(tags): yield ensure_unicode_string(tag)
def driver(self): """ The driver name as unicode string, or ``None``, if there is no driver for this device. .. versionadded:: 0.5 """ driver = self._libudev.udev_device_get_driver(self) return ensure_unicode_string(driver) if driver else None
def driver(self): """ The driver name as unicode string, or ``None``, if there is no driver for this device. .. versionadded:: 0.5 """ driver = self._libudev.udev_device_get_driver(self) return ensure_unicode_string(driver) if driver is not None else None
def sys_path(self): """ The ``sysfs`` mount point defaulting to ``/sys'`` as unicode string. """ if hasattr(self._libudev, 'udev_get_sys_path'): return ensure_unicode_string(self._libudev.udev_get_sys_path(self)) else: # Fixed path since udev 183 return '/sys'
def device_path(self): """ The device directory path defaulting to ``/dev`` as unicode string. """ if hasattr(self._libudev, 'udev_get_dev_path'): return ensure_unicode_string(self._libudev.udev_get_dev_path(self)) else: # Fixed path since udev 183 return '/dev'
def device_path(self): """ Kernel device path as unicode string. This path uniquely identifies a single device. Unlike :attr:`sys_path`, this path does not contain the ``sysfs`` mount point. However, the path is absolute and starts with a slash ``'/'``. """ return ensure_unicode_string(libudev.udev_device_get_devpath(self))
def __iter__(self): """ Iterate over the names of all properties defined for this device. Return a generator yielding the names of all properties of this device as unicode strings. """ properties = libudev.udev_device_get_properties_list_entry(self) for name, _ in udev_list_iterate(properties): yield ensure_unicode_string(name)
def run_path(self): """ The run runtime directory path defaulting to ``/run`` as unicode string. .. udevversion:: 167 .. versionadded:: 0.10 """ return ensure_unicode_string(self._libudev.udev_get_run_path(self))
def run_path(self): """ The run runtime directory path defaulting to ``/run`` as unicode string. .. udevversion:: 167 .. versionadded:: 0.10 """ return ensure_unicode_string(libudev.udev_get_run_path(self))
def asstring(self, attribute): """ Get the given ``attribute`` for the device as unicode string. :param attribute: the key for an attribute value :type attribute: unicode or byte string :returns: the value corresponding to ``attribute``, as unicode :rtype: unicode :raises KeyError: if no value found for ``attribute`` :raises UnicodeDecodeError: if value is not convertible """ return ensure_unicode_string(self._get(attribute))
def _get_attributes(self): if hasattr(self._libudev, 'udev_device_get_sysattr_list_entry'): attrs = self._libudev.udev_device_get_sysattr_list_entry( self.device) for attribute, _ in udev_list_iterate(self._libudev, attrs): yield ensure_unicode_string(attribute) else: sys_path = self.device.sys_path for filename in os.listdir(sys_path): filepath = os.path.join(sys_path, filename) if _is_attribute_file(filepath): yield filename
def run_path(self): """ The run runtime directory path defaulting to ``/run`` as unicode string. .. udevversion:: 167 .. versionadded:: 0.10 """ if hasattr(self._libudev, 'udev_get_run_path'): return ensure_unicode_string(self._libudev.udev_get_run_path(self)) else: return '/run/udev'
def run_path(self): """ The run runtime directory path defaulting to ``/run`` as unicode string. .. udevversion:: 167 .. versionadded:: 0.10 """ if hasattr(libudev, 'udev_get_run_path'): return ensure_unicode_string(libudev.udev_get_run_path(self)) else: return '/run/udev'
def device_node(self): """ Absolute path to the device node of this device as unicode string or ``None``, if this device doesn't have a device node. The path includes the device directory (see :attr:`Context.device_path`). This path always points to the actual device node associated with this device, and never to any symbolic links to this device node. See :attr:`device_links` to get a list of symbolic links to this device node. """ node = libudev.udev_device_get_devnode(self) if node: return ensure_unicode_string(node)
def asstring(self, attribute): """ Get the given ``atribute`` for the device as unicode string. Depending on the content of the attribute, this may or may not work. Be prepared to catch :exc:`~exceptions.UnicodeDecodeError`. ``attribute`` is a unicode or byte string containing the name of the attribute. Return the attribute value as byte string. Raise a :exc:`~exceptions.KeyError`, if the given attribute is not defined for this device, or :exc:`~exceptions.UnicodeDecodeError`, if the content of the attribute cannot be decoded into a unicode string. """ return ensure_unicode_string(self[attribute])
def __getitem__(self, property): """ Get the given ``property`` from this device. ``property`` is a unicode or byte string containing the name of the property. Return the property value as unicode string, or raise a :exc:`~exceptions.KeyError`, if the given property is not defined for this device. """ value = libudev.udev_device_get_property_value( self, ensure_byte_string(property)) if value is None: raise KeyError(property) return ensure_unicode_string(value)
def device_links(self): """ An iterator, which yields the absolute paths (including the device directory, see :attr:`Context.device_path`) of all symbolic links pointing to the :attr:`device_node` of this device. The paths are unicode strings. UDev can create symlinks to the original device node (see :attr:`device_node`) inside the device directory. This is often used to assign a constant, fixed device node to devices like removeable media, which technically do not have a constant device node, or to map a single device into multiple device hierarchies. The property provides access to all such symbolic links, which were created by UDev for this device. """ devlinks = self._libudev.udev_device_get_devlinks_list_entry(self) for name, _ in udev_list_iterate(self._libudev, devlinks): yield ensure_unicode_string(name)
def device_node(self): """ Absolute path to the device node of this device as unicode string or ``None``, if this device doesn't have a device node. The path includes the device directory (see :attr:`Context.device_path`). This path always points to the actual device node associated with this device, and never to any symbolic links to this device node. See :attr:`device_links` to get a list of symbolic links to this device node. .. warning:: For devices created with :meth:`from_device_file()`, the value of this property is not necessary equal to the ``filename`` given to :meth:`from_device_file()`. """ node = self._libudev.udev_device_get_devnode(self) return ensure_unicode_string(node) if node is not None else None
def device_type(self): """ Device type as unicode string, or ``None``, if the device type is unknown. >>> context = Context() >>> for device in context.list_devices(subsystem='net'): ... '{0} - {1}'.format(device.sys_name, device.device_type or 'ethernet') ... u'eth0 - ethernet' u'wlan0 - wlan' u'lo - ethernet' u'vboxnet0 - ethernet' .. versionadded:: 0.10 """ device_type = libudev.udev_device_get_devtype(self) if device_type is not None: return ensure_unicode_string(device_type)
def device_node(self): """ Absolute path to the device node of this device as unicode string or ``None``, if this device doesn't have a device node. The path includes the device directory (see :attr:`Context.device_path`). This path always points to the actual device node associated with this device, and never to any symbolic links to this device node. See :attr:`device_links` to get a list of symbolic links to this device node. .. warning:: For devices created with :meth:`from_device_file()`, the value of this property is not necessary equal to the ``filename`` given to :meth:`from_device_file()`. """ node = self._libudev.udev_device_get_devnode(self) return ensure_unicode_string(node) if node else None
def device_type(self): """ Device type as unicode string, or ``None``, if the device type is unknown. >>> context = Context() >>> for device in context.list_devices(subsystem='net'): ... '{0} - {1}'.format(device.sys_name, device.device_type or 'ethernet') ... u'eth0 - ethernet' u'wlan0 - wlan' u'lo - ethernet' u'vboxnet0 - ethernet' .. versionadded:: 0.10 """ device_type = self._libudev.udev_device_get_devtype(self) if device_type is not None: return ensure_unicode_string(device_type)
def available_attributes(self): """ Yield the ``available`` attributes for the device. It is not guaranteed that a key in this list will have a value. It is not guaranteed that a key not in this list will not have a value. It is guaranteed that the keys in this list are the keys that libudev considers to be "available" attributes. If libudev version does not define udev_device_get_sysattr_list_entry() yields nothing. See rhbz#1267584. """ if not hasattr(self._libudev, 'udev_device_get_sysattr_list_entry'): return # pragma: no cover attrs = self._libudev.udev_device_get_sysattr_list_entry(self.device) for attribute, _ in udev_list_iterate(self._libudev, attrs): yield ensure_unicode_string(attribute)
def _attributes(self): attrs = libudev.udev_device_get_sysattr_list_entry(self.device) for attribute, _ in udev_list_iterate(attrs): yield ensure_unicode_string(attribute)
def sys_name(self): """ Device file name inside ``sysfs`` as unicode string. """ return ensure_unicode_string(libudev.udev_device_get_sysname(self))
def test_ensure_unicode_string(): assert pytest.is_unicode_string( _util.ensure_unicode_string(b'hello world')) assert _util.ensure_unicode_string(b'hello world') == 'hello world' hello = 'hello world' assert _util.ensure_unicode_string(hello) is hello
def test_ensure_unicode_string_none(): with pytest.raises(AttributeError): _util.ensure_unicode_string(None)
def subsystem(self): """ Name of the subsystem this device is part of as unicode string. """ return ensure_unicode_string(libudev.udev_device_get_subsystem(self))
def test_ensure_unicode_string(): assert is_unicode_string(_util.ensure_unicode_string(b'hello world')) assert _util.ensure_unicode_string(b'hello world') == 'hello world' hello = 'hello world' assert _util.ensure_unicode_string(hello) is hello