Repository: pyocd/pyocd
Issue: Picoprobe: exception raised when UID is specified but no Picoprobe is connected

The symptom of this bug is the following `AttributeError` exception raised when a probe UID is specified but there is not a Picoprobe connected to USB.

```
0000616:CRITICAL:__main__:uncaught exception: 'NoneType' object has no attribute 'serial_number'
Traceback (most recent call last):
  File "/Volumes/projects/pyOCD-flit/pyocd/__main__.py", line 402, in run
    self._COMMANDS[self._args.cmd](self)
  File "/Volumes/projects/pyOCD-flit/pyocd/__main__.py", line 808, in do_commander
    PyOCDCommander(self._args, cmds).run()
  File "/Volumes/projects/pyOCD-flit/pyocd/commands/commander.py", line 65, in run
    if not self.connect():
  File "/Volumes/projects/pyOCD-flit/pyocd/commands/commander.py", line 164, in connect
    probe = ConnectHelper.choose_probe(
  File "/Volumes/projects/pyOCD-flit/pyocd/core/helpers.py", line 138, in choose_probe
    allProbes = ConnectHelper.get_all_connected_probes(blocking=blocking, unique_id=unique_id)
  File "/Volumes/projects/pyOCD-flit/pyocd/core/helpers.py", line 82, in get_all_connected_probes
    allProbes = DebugProbeAggregator.get_all_connected_probes(unique_id=unique_id)
  File "/Volumes/projects/pyOCD-flit/pyocd/probe/aggregator.py", line 58, in get_all_connected_probes
    probe = cls.get_probe_with_id(unique_id, is_explicit)
  File "/Volumes/projects/pyOCD-flit/pyocd/probe/picoprobe.py", line 339, in get_probe_with_id
    probe = PicoLink.enumerate_picoprobes(unique_id)
  File "/Volumes/projects/pyOCD-flit/pyocd/probe/picoprobe.py", line 110, in enumerate_picoprobes
    return PicoLink(core.find(custom_match=FindPicoprobe(uid)))
  File "/Volumes/projects/pyOCD-flit/pyocd/probe/picoprobe.py", line 59, in __init__
    self._probe_id = dev.serial_number
AttributeError: 'NoneType' object has no attribute 'serial_number'
```

Changed files:
pyocd/probe/picoprobe.py

diff --git a/pyocd/probe/picoprobe.py b/pyocd/probe/picoprobe.py
index 15a1a10b..d48995a6 100644
--- a/pyocd/probe/picoprobe.py
+++ b/pyocd/probe/picoprobe.py
@@ -23,6 +23,7 @@ from usb import core, util
 import platform
 import errno
 import logging
+from typing import List
 
 from .debug_probe import DebugProbe
 from ..core import exceptions
@@ -101,13 +102,10 @@ class PicoLink(object):
         self._rd_ep = None
 
     @classmethod
-    def enumerate_picoprobes(cls, uid=None):
+    def enumerate_picoprobes(cls, uid=None) -> List["PicoLink"]:
         """! @brief Find and return all Picoprobes """
         # Use a custom matcher to make sure the probe is a Picoprobe and accessible.
-        if uid is None:
-            return [PicoLink(probe) for probe in core.find(find_all=True, custom_match=FindPicoprobe(uid))]
-        else:
-            return PicoLink(core.find(custom_match=FindPicoprobe(uid)))
+        return [PicoLink(probe) for probe in core.find(find_all=True, custom_match=FindPicoprobe(uid))]
 
     def q_read_bits(self, bits):
         """! @brief Queue a read request for 'bits' bits to the probe """
@@ -336,9 +334,9 @@ class Picoprobe(DebugProbe):
 
     @ classmethod
     def get_probe_with_id(cls, unique_id, is_explicit=False):
-        probe = PicoLink.enumerate_picoprobes(unique_id)
-        if probe is not None:
-            return cls(probe)
+        probes = PicoLink.enumerate_picoprobes(unique_id)
+        if probes:
+            return cls(probes[0])
 
     def __init__(self, picolink):
         super(Picoprobe, self).__init__()