NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
PyPI · #3986 most downloaded on PyPI
A libudev binding
Last release 6 days ago
28 Sep 2026
Release timing varies
gaps range from 2 weeks to 3.5 years
Nearly every release is documented
notes for 31 of 32 stable releases
Nothing withdrawn
no release was ever pulled
16 years old
35 releases · first in 2010
Recommended development release: Fedora 44
Recommended development release: Fedora 44
Use the returned error code for udev_monitor functions: https://github.com/pyudev/pyudev/issues/548 https://github.com/pyudev/pyudev/pull/549
Remove PyQt4 support: https://github.com/pyudev/pyudev/issues/533 https://github.com/pyudev/pyudev/pull/534
Require at least Python 3.10: https://github.com/pyudev/pyudev/pull/561
Use exclusively pyproject.toml for project metadata: https://github.com/pyudev/pyudev/pull/560
docs: clarify binary nature of sysfs attributes: https://github.com/pyudev/pyudev/pull/542
Remove last vestiges of Python 2: https://github.com/pyudev/pyudev/pull/555 https://github.com/pyudev/pyudev/pull/545 https://github.com/pyudev/pyudev/pull/544
Tidies and Maintenance: https://github.com/pyudev/pyudev/pull/559 https://github.com/pyudev/pyudev/pull/554 https://github.com/pyudev/pyudev/pull/553 https://github.com/pyudev/pyudev/pull/551 https://github.com/pyudev/pyudev/pull/547 https://github.com/pyudev/pyudev/pull/546 https://github.com/pyudev/pyudev/pull/541 https://github.com/pyudev/pyudev/pull/540 https://github.com/pyudev/pyudev/pull/539 https://github.com/pyudev/pyudev/pull/538 https://github.com/pyudev/pyudev/pull/537 https://github.com/pyudev/pyudev/pull/536 https://github.com/pyudev/pyudev/pull/535 https://github.com/pyudev/pyudev/pull/531 https://github.com/pyudev/pyudev/pull/530
One column per quarter.
"pyudev version 0.24.4"
"pyudev version 0.24.4"
Recommended development release: Fedora 41
Add device attributes unset(): https://github.com/pyudev/pyudev/pull/525
Remove license classifier deprecated by PEP 639: https://github.com/pyudev/pyudev/pull/522
Tidies and Maintenance: https://github.com/pyudev/pyudev/pull/529 https://github.com/pyudev/pyudev/pull/528 https://github.com/pyudev/pyudev/pull/526 https://github.com/pyudev/pyudev/pull/524 https://github.com/pyudev/pyudev/pull/521 https://github.com/pyudev/pyudev/pull/520 https://github.com/pyudev/pyudev/pull/518 https://github.com/pyudev/pyudev/pull/512 https://github.com/pyudev/pyudev/pull/511
"pyudev version 0.24.3"
"pyudev version 0.24.3"
Recommended development release: Fedora 37
Recommended development release: Fedora 37
Add support for PySide6: https://github.com/pyudev/pyudev/pull/487
Add missing 'priority' argument for GLib.to_add_watch() https://github.com/pyudev/pyudev/pull/479
Tidies and Maintenance: https://github.com/pyudev/pyudev/pull/486 https://github.com/pyudev/pyudev/pull/485 https://github.com/pyudev/pyudev/pull/484 https://github.com/pyudev/pyudev/pull/481 https://github.com/pyudev/pyudev/pull/480 https://github.com/pyudev/pyudev/pull/477 https://github.com/pyudev/pyudev/pull/474
Recommended development release: Fedora 36
Recommended development release: Fedora 36
Remove a bunch of Python 2 code: https://github.com/pyudev/pyudev/pull/468 https://github.com/pyudev/pyudev/pull/460 https://github.com/pyudev/pyudev/pull/455 https://github.com/pyudev/pyudev/pull/358
Tidies and Maintenance: https://github.com/pyudev/pyudev/pull/471 https://github.com/pyudev/pyudev/pull/466 https://github.com/pyudev/pyudev/pull/465 https://github.com/pyudev/pyudev/pull/464 https://github.com/pyudev/pyudev/pull/462 https://github.com/pyudev/pyudev/pull/461 https://github.com/pyudev/pyudev/pull/459 https://github.com/pyudev/pyudev/pull/458 https://github.com/pyudev/pyudev/pull/456 https://github.com/pyudev/pyudev/pull/454 https://github.com/pyudev/pyudev/pull/447 https://github.com/pyudev/pyudev/pull/445
Recommended development release: Fedora 35
Recommended development release: Fedora 35
New release: 0.23.2: https://github.com/pyudev/pyudev/pull/444
Tidies and Maintenance: https://github.com/pyudev/pyudev/pull/445 https://github.com/pyudev/pyudev/pull/443 https://github.com/pyudev/pyudev/pull/442
Recommended development release: Fedora 34
Recommended development release: Fedora 34
Update to version 0.23.1: https://github.com/pyudev/pyudev/pull/440
Check for existence of _hasattr attribute in Context.__del__ method: https://github.com/pyudev/pyudev/issues/421 https://github.com/pyudev/pyudev/pull/439
Tidies and Maintenance: https://github.com/pyudev/pyudev/pull/438
Recommended development release: Fedora 34
Recommended development release: Fedora 34
Update to version 0.23.0: https://github.com/pyudev/pyudev/pull/427
Officially drop support for Python 2: https://github.com/pyudev/pyudev/pull/414
Remove external mock dependency: https://github.com/pyudev/pyudev/pull/409
Enable GLib unit tests: https://github.com/pyudev/pyudev/pull/400
Switch to new style gi.repository.GLib imports: https://github.com/pyudev/pyudev/pull/399
Tidies and Maintenance: https://github.com/pyudev/pyudev/pull/432 https://github.com/pyudev/pyudev/pull/430 https://github.com/pyudev/pyudev/pull/429 https://github.com/pyudev/pyudev/pull/428 https://github.com/pyudev/pyudev/pull/424 https://github.com/pyudev/pyudev/pull/423 https://github.com/pyudev/pyudev/pull/418 https://github.com/pyudev/pyudev/pull/415 https://github.com/pyudev/pyudev/pull/413
Nothing published for this version
Add a six-enabled move for collections move imports: https://github.com/pyudev/pyudev/pull/386
Add a six-enabled move for collections move imports: https://github.com/pyudev/pyudev/pull/386
Fix any newly introduced pylint errors
Numerous improvements or updates to the test infrastructure
A number of test updates
Require yapf 0.21.0 for Python formatting
Various documentation fixes and updates
Nothing published for this version
Deprecate use of Device object as mapping from udev property names to values.
Deprecate use of Device object as mapping from udev property names to values.
Add a Properties class and a Device.properties() method for udev properties.
Fix places where Device object was incorrectly used in a boolean context.
Return an empty string, not None, if the property value is an empty string.
Exceptions re-raised from libudev calls now have a message string.
Insert a warning about using a Device in a boolean context in docs.
Infrastructure for vagrant tests is removed.
Various internal refactorings.
Extensive test improvements.
Numerous documentation fixes.
No longer use deprecated Device.from_sys_path() method.
Remove parsing code added in previous release.
No longer do CI for Python 2.6.
Eliminate all wildcard imports and __all__ statements.
No longer use deprecated Device.from_sys_path() method.
Minor pylint induced changes.
Documentation fixes.
Add DeprecationWarnings to deprecated Device methods.
Restore raising KeyError by Attributes.as* methods when attribute not found.
Explicitly require six module.
Never raise a DeviceNotFoundError when iterating over a device enumeration.
Device.subsystem() now returns None if device has no subsystem.
Add DeprecationWarnings to deprecated Device methods.
Replace "/" with "!" in Device.from_name() sys_name parameter.
Add some unstable classes for parsing some kinds of values.
Make version info more like Python's including micro numbers and levels.
Refactor some internal modules into subdirectories.
Work on tests and reproducers.
Nothing published for this version
Nothing published for this version
Device.from_* methods are deprecated, uses Devices.from_* methods instead
DeviceNotFoundError is no longer a subtype of LookupError
Added support for pyqt5 monitor observer
Added discover module, which looks up a device on limited information
Attributes class no longer extends Mapping, extends object instead
Attributes class no longer inherits [] operator, Mapping methods
Attributes class objects are no longer iterable
Attributes.available_attributes property added
Attributes.get() method, with usual semantics, defined
Device.from_* methods are deprecated, uses Devices.from_* methods instead
Device.from_device_file() now raises DeviceNotFoundByFileError
Device.from_device_number() now raises DeviceNotFoundByNumberError
Devices.from_interface_index() method added
Devices.from_kernel_device() method added
Numerous testing infrastructure changes
Add a wrapper function to retry interruptible system calls.
#52: Remove global libudev object
#57: Really start the monitor on pyudev.Monitor.poll()
#60: Do not use select.select to avoid hitting its file descriptor limit
#58: Force non-blocking IO in pyudev.Monitor to avoid blocking on receiving the device
#63: Set proper flags on pipe fds.
#65: Handle irregular polling events properly.
#50: Add pyudev.wx.MonitorObserver and deprecate pyudev.wx.WxUDevMonitorObserver
#50: Add pyudev.glib.MonitorObserver and deprecate pyudev.glib.GUDevMonitorObserver
#50: Add pyudev.pyqt4.MonitorObserver and deprecate pyudev.pyqt4.QUDevMonitorObserver
#50: Add pyudev.pyside.MonitorObserver and deprecate pyudev.pyside.QUDevMonitorObserver
Add a wrapper function to retry interruptible system calls.
- #53: Fix source distribution - #54: Fix typo in test
#53: Fix source distribution
#54: Fix typo in test
Deprecate pyudev.Device.traverse() in favor of pyudev.Device.ancestors.
Remove pyudev.Monitor.from_socket.
Deprecate pyudev.Device.traverse() in favor of pyudev.Device.ancestors.
#47: Deprecate pyudev.Monitor.receive_device in favor of pyudev.Monitor.poll.
#47: Deprecate pyudev.Monitor.enable_receiving in favor of pyudev.Monitor.start.
#47: Deprecate pyudev.Monitor.__iter__ in favor of explicit looping or pyudev.MonitorObserver.
#49: Deprecate event_handler to pyudev.MonitorObserver in favour of callback argument.
#46: Continuously test pyudev on Travis-CI.
Add pyudev.Device.ancestors.
Add pyudev.Device.action.
#10: Add pyudev.Device.sequence_number.
#47: Add pyudev.Monitor.poll.
#47: Add pyudev.Monitor.started.
#49: Add callback argument to pyudev.Monitor.
pyudev.Monitor.start can be called repeatedly.
#45: Get rid of 2to3
#43: Fix test failures on Python 2.6
Fix signature in declaration of udev_monitor_set_receive_buffer_size.
#44: Test wrapped signatures with help of gccxml.
Fix compatibility with udev 183 and newer in pyudev.Context.
pyudev.MonitorObserver.stop can be called from the observer thread.
errno.EINVAL from underlying libudev functions causes ~exceptions.ValueError instead of ~exceptions.EnvironmentError.
#20: Add ~pyudev.Monitor.remove_filter().
#40: Add user guide to the documentation.
#39: Add pyudev.Device.from_device_file().
errno.EINVAL from underlying libudev functions causes ~exceptions.ValueError instead of ~exceptions.EnvironmentError.
pyudev.MonitorObserver calls pyudev.Monitor.enable_receiving() when started.
#20: pyudev.Monitor.filter_by() and pyudev.Monitor.filter_by_tag() can be called after pyudev.Monitor.enable_receiving().
Host documentation at http://pyudev.readthedocs.org (thanks to the readthedocs.org team for this service)
Host documentation at http://pyudev.readthedocs.org (thanks to the readthedocs.org team for this service)
#37: Add pyudev.wx.WxUDevMonitorObserver for wxPython (thanks to Tobias Eberle).
Add pyudev.MonitorObserver.
Add pyudev.glib.GUDevMonitorObserver.enabled, pyudev.pyqt4.QUDevMonitorObserver.enabled and pyudev.pyside.QUDevMonitorObserver.enabled.
Add pyudev.Enumerator.match_parent.
#36: Add pyudev.Monitor.set_receive_buffer_size (thanks to Rémi Rérolle).
Add pyudev.Enumerator.match_parent.
Add parent keyword argument to pyudev.Enumerator.match().
#31: Add pyudev.Enumerator.match_attribute.
Add nomatch argument to pyudev.Enumerator.match_subsystem and pyudev.Enumerator.match_attribute.
Remove pyudev.Enumerator.match_children in favour of pyudev.Enumerator.match_parent.
#34: pyudev.Device.tags returns a pyudev.Tags object.
pyudev.Device.children requires udev version 172 now
Fix license header in pyudev._compat.
#32: Fix memory leak.
#33: Fix Python 3 support for pyudev.glib.
Fix license header in pyudev._compat.
- #30: Add pyudev.Device.sys_number. - #29: Add pyudev.Device.from_device_number - #29: Add pyudev.Device.device_number. - Support PyPy.
#30: Add pyudev.Device.sys_number.
#29: Add pyudev.Device.from_device_number
#29: Add pyudev.Device.device_number.
Support PyPy.
pyudev.Context, pyudev.Enumerator, pyudev.Device and pyudev.Monitor can directly be passed to ctypes-wrapped functions.
Add pyudev.__version_info__
Add pyudev.Device.device_type
pyudev.Context, pyudev.Enumerator, pyudev.Device and pyudev.Monitor can directly be passed to ctypes-wrapped functions.
#24: Add pyudev.Context.run_path.
Add pyudev.Context.log_priority.
#21: Add pyudev.Device.find_parent.
#22: Add pyudev.Monitor.filter_by_tag.
Add pyudev.Context.log_priority.
Improve error reporting, if libudev is missing.
Add keyword arguments to pyudev.Context.list_devices().
#16: Add pyudev.Enumerator.match.
Add keyword arguments to pyudev.Context.list_devices().
#19: Add pyudev.Enumerator.match_sys_name.
#18: Add pyudev.udev_version().
#17: Add pyudev.Device.is_initialized.
#17: Add pyudev.Device.time_since_initialized.
#17: Add pyudev.Enumerator.match_is_initialized
Fix support for earlier releases of udev.
Document minimum udev version for all affected attributes.
- #15: Add pyudev.glib.GUDevMonitorObserver.
#15: Add pyudev.glib.GUDevMonitorObserver.
Fix licence headers in source files.
#8: Add pyudev.Device.tags.
#8: Add pyudev.Enumerator.match_tag.
#11: Add pyudev.Device.from_environment
#5: Add pyudev.pyside
#14: Remove apipkg dependency.
#14: Require explicit import of pyudev.pyqt4.
Fix licence headers in source files.
Rename pyudev.NoSuchDeviceError to pyudev.DeviceNotFoundError.
Support Python 3.
#6: Add pyudev.Device.attributes (thanks to Daniel Lazzari).
#6: Add pyudev.Attributes (thanks to Daniel Lazzari).
#7: pyudev.Device.context and pyudev.Monitor.context are part of the public API.
#9: Add pyudev.Device.driver.
#12: Add pyudev.Device.from_name.
Rename pyudev.NoSuchDeviceError to pyudev.DeviceNotFoundError.
pyudev.Device.from_sys_path raises pyudev.DeviceNotFoundAtPathError.
#13: Fix ~exceptions.AttributeError in pyudev.Device.device_node.
Improve and extend documentation.
Add more tests.
pyudev.Device.from_sys_path raises pyudev.NoSuchDeviceError.
#3: Rename udev to pyudev.
#3: Rename qudev to pyudev.pyqt4.
Add pyudev.Device.from_path.
pyudev.Device.from_sys_path raises pyudev.NoSuchDeviceError.
pyudev.Monitor.receive_device raises ~exceptions.EnvironmentError.
errno, strerror and filename attributes of ~exceptions.EnvironmentError exceptions have meaningful content.
Fix ~exceptions.NameError in pyudev.Monitor.from_socket
subsystem argument to pyudev.Monitor.filter_by is mandatory.
Delete underlying C objects if pyudev.Device is garbage-collected.
Fix broken signal emitting in pyudev.pyqt4.QUDevMonitorObserver.
Raise ~exceptions.TypeError if udev.Device are compared with >, >=, < or <=.
#1: Fix documentation to reflect the actual behaviour of the underlying API
Raise ~exceptions.TypeError if udev.Device are compared with >, >=, < or <=.
Add udev.Enumerator.match_children.
Add udev.Device.children.
Add qudev.QUDevMonitorObserver.deviceChanged.
Add qudev.QUDevMonitorObserver.deviceMoved.
Remove type magic in udev.Device.__getitem__.
Add udev.Monitor.
Add udev.Device.asbool.
Add udev.Device.asint.
Remove type magic in udev.Device.__getitem__.
Add qudev.
- Initial release. - Add udev.Context. - Add udev.Device. - Add udev.Enumerator.
Initial release.
Add udev.Context.
Add udev.Device.
Add udev.Enumerator.
Your coding agent can read these notes before it upgrades. Set up the MCP server →