Thanks for providing pyusb: its support for libusb-1.0 is making my life
much easier by letting me work around the cdc_acm limitations in Linux.
For your consideration: In my application, the Linux kernel driver for
cdc_acm will be loaded automatically when a device is inserted. I don't
want to break that, because other devices need and work with that
interface. So my script needs to detach the kernel driver. However, if
that's already been done, the underlying libusb call returns
LIBUSB_ERROR_NOT_FOUND. I want to ignore that error, but not others that
might arise in the same call.
Under the current handling of usb.core.USBError, the numeric error code is
translated to a backend-specific error string. This makes it inconvenient
to programmatically identify the problem.
In my case, I know I'm using libusb10, so I'd like to be able to write:
try:
rf2500.detach_kernel_driver(0)
except usb.USBError, e:
if e.backend_errno != e.ERROR_NOT_FOUND:
raise
The attached patch allows this. I've only provided it for the libusb10
backend; cursory inspection suggests it's equally trivial for the others.
Some interface choices you might want to revisit if you like this enough to
adopt it:
* I'm not using IOError's existing errno field because the values are not
errno values, so there's a new backend_errno field.
* I've chosen to name the backend-specific class USBError because it's
disambiguated by the module it belongs to.
* Similarly I left the LIBUSB_ prefix off the error codes since they're
contextualized by the class.
* I placed the error codes as class constants rather than module constants
so they're easily to hand for comparisons. If other back ends happen to
use the same name, the user code doesn't need to check which back end was
used.
Peter
From fe752ce370247c12289111b7986a4fd6dac463e2 Mon Sep 17 00:00:00 2001
From: "Peter A. Bigot" <big...@acm.org>
Date: Sat, 17 Sep 2011 18:34:41 -0500
Subject: [PATCH] Provide backend error code as exception attribute
---
usb/backend/libusb10.py | 83 ++++++++++++++++++++++++++--------------------
1 files changed, 47 insertions(+), 36 deletions(-)
diff --git a/usb/backend/libusb10.py b/usb/backend/libusb10.py
index e50fcb9..21da864 100644
--- a/usb/backend/libusb10.py
+++ b/usb/backend/libusb10.py
@@ -33,6 +33,7 @@ import sys
import logging
from usb._debug import methodtrace
import usb._interop as _interop
+import usb.core
__author__ = 'Wander Lairson Costa'
@@ -42,40 +43,51 @@ _logger = logging.getLogger('usb.backend.libusb10')
# libusb.h
-# return codes
-
-_LIBUSB_SUCCESS = 0
-_LIBUSB_ERROR_IO = -1
-_LIBUSB_ERROR_INVALID_PARAM = -2
-_LIBUSB_ERROR_ACCESS = -3
-_LIBUSB_ERROR_NO_DEVICE = -4
-_LIBUSB_ERROR_NOT_FOUND = -5
-_LIBUSB_ERROR_BUSY = -6
-_LIBUSB_ERROR_TIMEOUT = -7
-_LIBUSB_ERROR_OVERFLOW = -8
-_LIBUSB_ERROR_PIPE = -9
-_LIBUSB_ERROR_INTERRUPTED = -10
-_LIBUSB_ERROR_NO_MEM = -11
-_LIBUSB_ERROR_NOT_SUPPORTED = -12
-_LIBUSB_ERROR_OTHER = -99
-
-# map return codes to strings
-_str_error = {
- _LIBUSB_SUCCESS:'Success (no error)',
- _LIBUSB_ERROR_IO:'Input/output error',
- _LIBUSB_ERROR_INVALID_PARAM:'Invalid parameter',
- _LIBUSB_ERROR_ACCESS:'Access denied (insufficient permissions)',
- _LIBUSB_ERROR_NO_DEVICE:'No such device (it may have been disconnected)',
- _LIBUSB_ERROR_NOT_FOUND:'Entity not found',
- _LIBUSB_ERROR_BUSY:'Resource busy',
- _LIBUSB_ERROR_TIMEOUT:'Operation timed out',
- _LIBUSB_ERROR_OVERFLOW:'Overflow',
- _LIBUSB_ERROR_PIPE:'Pipe error',
- _LIBUSB_ERROR_INTERRUPTED:'System call interrupted (perhaps due to signal)',
- _LIBUSB_ERROR_NO_MEM:'Insufficient memory',
- _LIBUSB_ERROR_NOT_SUPPORTED:'Operation not supported or unimplemented on this platform',
- _LIBUSB_ERROR_OTHER:'Unknown error'
-}
+class USBError (usb.core.USBError):
+ r"""Exception class for libusb 1.0 errors.
+
+ Raised when a usb.backend.libusb10 call results in an error."""
+
+ backend_errno = None
+ """The ERROR_* code produced by the call."""
+
+ # return codes
+ SUCCESS = 0
+ ERROR_IO = -1
+ ERROR_INVALID_PARAM = -2
+ ERROR_ACCESS = -3
+ ERROR_NO_DEVICE = -4
+ ERROR_NOT_FOUND = -5
+ ERROR_BUSY = -6
+ ERROR_TIMEOUT = -7
+ ERROR_OVERFLOW = -8
+ ERROR_PIPE = -9
+ ERROR_INTERRUPTED = -10
+ ERROR_NO_MEM = -11
+ ERROR_NOT_SUPPORTED = -12
+ ERROR_OTHER = -99
+
+ # map return codes to strings
+ _str_error = {
+ SUCCESS:'Success (no error)',
+ ERROR_IO:'Input/output error',
+ ERROR_INVALID_PARAM:'Invalid parameter',
+ ERROR_ACCESS:'Access denied (insufficient permissions)',
+ ERROR_NO_DEVICE:'No such device (it may have been disconnected)',
+ ERROR_NOT_FOUND:'Entity not found',
+ ERROR_BUSY:'Resource busy',
+ ERROR_TIMEOUT:'Operation timed out',
+ ERROR_OVERFLOW:'Overflow',
+ ERROR_PIPE:'Pipe error',
+ ERROR_INTERRUPTED:'System call interrupted (perhaps due to signal)',
+ ERROR_NO_MEM:'Insufficient memory',
+ ERROR_NOT_SUPPORTED:'Operation not supported or unimplemented on this platform',
+ ERROR_OTHER:'Unknown error'
+ }
+
+ def __init__ (self, libusb_errno):
+ self.backend_errno = libusb_errno
+ super(usb.core.USBError, self).__init__(self._str_error[libusb_errno])
# Data structures
@@ -353,8 +365,7 @@ def _check(retval):
retval = c_int(retval)
if isinstance(retval, c_int):
if retval.value < 0:
- from usb.core import USBError
- raise USBError(_str_error[retval.value])
+ raise USBError(retval.value)
return retval
# wrap a device
--
1.7.6
------------------------------------------------------------------------------
BlackBerry® DevCon Americas, Oct. 18-20, San Francisco, CA
http://p.sf.net/sfu/rim-devcon-copy2
_______________________________________________
pyusb-users mailing list
pyusb-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/pyusb-users