From 8b329d7bfd42c6619a1e274bac805f61c64aee63 Mon Sep 17 00:00:00 2001
From: David Runge <dave@sleepmap.de>
Date: Fri, 11 Feb 2022 12:04:52 +0100
Subject: [PATCH] Make the use of libusb-package optional

Attempt to import libusb-package's `find()` function, else fall back to
using pyusb's `find()` function.
This allows to use pyusb by just removing the project's requirement on
libusb-package, as python-pyusb and libusb packaging go hand-in-hand on
Linux distributions.
---
 pyocd/probe/picoprobe.py                              |  7 +++++--
 pyocd/probe/pydapaccess/interface/pyusb_backend.py    | 10 +++++++---
 pyocd/probe/pydapaccess/interface/pyusb_v2_backend.py | 10 +++++++---
 pyocd/probe/stlink/usb.py                             |  7 +++++--
 4 files changed, 24 insertions(+), 10 deletions(-)

diff --git a/pyocd/probe/picoprobe.py b/pyocd/probe/picoprobe.py
index c8df7a35e..ec4605b42 100644
--- a/pyocd/probe/picoprobe.py
+++ b/pyocd/probe/picoprobe.py
@@ -19,7 +19,10 @@
 
 from time import sleep
 from usb import core, util
-import libusb_package
+try:
+    from libusb_package import find as usb_find
+except ImportError:
+    from usb.core import find as usb_find
 
 import platform
 import errno
@@ -108,7 +111,7 @@ def enumerate_picoprobes(cls, uid=None) -> List["PicoLink"]:
         """@brief Find and return all Picoprobes """
         try:
             # Use a custom matcher to make sure the probe is a Picoprobe and accessible.
-            return [PicoLink(probe) for probe in libusb_package.find(find_all=True, custom_match=FindPicoprobe(uid))]
+            return [PicoLink(probe) for probe in usb_find(find_all=True, custom_match=FindPicoprobe(uid))]
         except core.NoBackendError:
             show_no_libusb_warning()
             return []
diff --git a/pyocd/probe/pydapaccess/interface/pyusb_backend.py b/pyocd/probe/pydapaccess/interface/pyusb_backend.py
index 904869400..567b50a5b 100644
--- a/pyocd/probe/pydapaccess/interface/pyusb_backend.py
+++ b/pyocd/probe/pydapaccess/interface/pyusb_backend.py
@@ -41,14 +41,18 @@
 TRACE.setLevel(logging.CRITICAL)
 
 try:
-    import libusb_package
     import usb.core
     import usb.util
+    try:
+        from libusb_package import find as usb_find
+    except ImportError:
+        from usb.core import find as usb_find
 except ImportError:
     IS_AVAILABLE = False
 else:
     IS_AVAILABLE = True
 
+
 class PyUSB(Interface):
     """@brief CMSIS-DAP USB interface class using pyusb for the backend."""
 
@@ -81,7 +85,7 @@ def open(self):
         assert self.closed is True
 
         # Get device handle
-        dev = libusb_package.find(custom_match=FindDap(self.serial_number))
+        dev = usb_find(custom_match=FindDap(self.serial_number))
         if dev is None:
             raise DAPAccessIntf.DeviceError(f"Probe {self.serial_number} not found")
 
@@ -180,7 +184,7 @@ def get_all_connected_interfaces():
         """
         # find all cmsis-dap devices
         try:
-            all_devices = libusb_package.find(find_all=True, custom_match=FindDap())
+            all_devices = usb_find(find_all=True, custom_match=FindDap())
         except usb.core.NoBackendError:
             if not PyUSB.did_show_no_libusb_warning:
                 LOG.warning("CMSIS-DAPv1 probes may not be detected because no libusb library was found.")
diff --git a/pyocd/probe/pydapaccess/interface/pyusb_v2_backend.py b/pyocd/probe/pydapaccess/interface/pyusb_v2_backend.py
index 145497f28..7e443ecd9 100644
--- a/pyocd/probe/pydapaccess/interface/pyusb_v2_backend.py
+++ b/pyocd/probe/pydapaccess/interface/pyusb_v2_backend.py
@@ -40,14 +40,18 @@
 TRACE.setLevel(logging.CRITICAL)
 
 try:
-    import libusb_package
     import usb.core
     import usb.util
+    try:
+        from libusb_package import find as usb_find
+    except ImportError:
+        from usb.core import find as usb_find
 except ImportError:
     IS_AVAILABLE = False
 else:
     IS_AVAILABLE = True
 
+
 class PyUSBv2(Interface):
     """@brief CMSIS-DAPv2 interface using pyUSB."""
 
@@ -95,7 +99,7 @@ def open(self):
         assert self.closed is True
 
         # Get device handle
-        dev = libusb_package.find(custom_match=HasCmsisDapv2Interface(self.serial_number))
+        dev = usb_find(custom_match=HasCmsisDapv2Interface(self.serial_number))
         if dev is None:
             raise DAPAccessIntf.DeviceError(f"Probe {self.serial_number} not found")
 
@@ -204,7 +208,7 @@ def get_all_connected_interfaces():
         """@brief Returns all the connected devices with a CMSIS-DAPv2 interface."""
         # find all cmsis-dap devices
         try:
-            all_devices = libusb_package.find(find_all=True, custom_match=HasCmsisDapv2Interface())
+            all_devices = usb_find(find_all=True, custom_match=HasCmsisDapv2Interface())
         except usb.core.NoBackendError:
             common.show_no_libusb_warning()
             return []
diff --git a/pyocd/probe/stlink/usb.py b/pyocd/probe/stlink/usb.py
index ae7fe4dba..c3b6e0404 100644
--- a/pyocd/probe/stlink/usb.py
+++ b/pyocd/probe/stlink/usb.py
@@ -15,7 +15,10 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import libusb_package
+try:
+    from libusb_package import find as usb_find
+except ImportError:
+    from usb.core import find as usb_find
 import usb.core
 import usb.util
 import logging
@@ -101,7 +104,7 @@ def _usb_match(cls, dev):
     @classmethod
     def get_all_connected_devices(cls):
         try:
-            devices = libusb_package.find(find_all=True, custom_match=cls._usb_match)
+            devices = usb_find(find_all=True, custom_match=cls._usb_match)
         except usb.core.NoBackendError:
             common.show_no_libusb_warning()
             return []
