wIndex is the interface number to be claimed only for standard request types. For example Silicon Labs cp2103 defines a vendor control transfer to set some GPIO pins though wIndex parameter (se AN571 page 17).
This removes the DeprecationWarning that warns that tostring() is obsolete when running with Python 3.2+
When dispose is called after the device is diconnected, release_interface might fail (see commit 5e9ef15), then the interface stays in the claimed interfaces set. When the device is destroyed, its __del__ method will call dispose again and, since the interface is still marked as claimed, a new call to release_interface will be made with an invalid device handle, causing a segmentation fault. We fix that by always removing the interface from the claimed set. closes #89.
At object destruction, claimed interfaces are released. If the device is disconnected, the call to release_interface may fail and raise an exception. closes #84.
If the device is disconnected when a isochronous transfer is ongoing, it might raise an exception in the callback and the 'callback done' signaling flag is never set. This causes the program to hang forever. We move the error handling to the caller function, after the callback returns. In this way, the exception is raised in the main thread and client software is notified about the exceptional situation. closes #85.
libusb_strerror returns a string containing the error message for the given error code. When the function is not available, we fallback to our own internal error code mapping strategy. closes #69.
Starting with (C)Python 3.4, the GC features "Safe object finalization" , which doesn't work nicely with pyusb's object structure. Required globals / modules may already have been deleted (set to None) when an object's __del__() method gets called , which randomly breaks libusb calls etc. when calling sys.exit(). Use the atexit module to solve this (indirectly via weakref.finalize()). This commit adds a class that takes care of object finalization. Classes/objects can adopt this functionality by inheriting AutoFinalizedObject and renaming their __del__() method to _finalize_object(). Shouldn't break existing use cases, but adds a few layers of indirection. A __del__() call gets processed as follows: __del__() -> finalize() -> [...] -> _do_finalize_object() -> _finalize_object() All methods in this call chain are provided by AutoFinalizedObject, derived classes should override the no-op _finalize_object() method. The "[...]" part depends on the python version: * < 3.4: <nothing> * >= 3.4: _finalizer() -> _do_finalize_object_ref()
Legacy module has no explicity resource cleanup functions, so we free allocated resources in the __del__ method.