docs: def comports(vid_pid=None, include_all=False, check_available=True,
               only_available=False):
      '''
      .. versionchanged:: 0.9
          Add :data:`check_available` keyword argument to optionally check if
          each port is actually available by attempting to open a temporary
          connection.
  
          Add :data:`only_available` keyword argument to only include ports that
          are actually available for connection.
  
      Parameters
      ----------
      vid_pid : str or list, optional
          One or more USB vendor/product IDs to match.
  
          Each USB vendor/product must be in the form ``'<vid>:<pid>'``.
          For example, ``'2341:0010'``.
      include_all : bool, optional
          If ``True``, include all available serial ports, but sort rows such
          that ports matching specified USB vendor/product IDs come first.
  
          If ``False``, only include ports that match specified USB
          vendor/product IDs.
      check_available : bool, optional
          If ``True``, check if each port is actually available by attempting to
          open a temporary connection.
      only_available : bool, optional
          If ``True``, only include ports that are available.
  
      Returns
      -------
      pandas.DataFrame
          Table containing descriptor and hardware ID of each COM port, indexed
          by port (e.g., "COM4").
  
          .. versionchanged:: 0.9
              If :data:`check_available` is ``True``, add an ``available`` column
              to the table indicating whether each port accepted a connection.
      '''
      df_comports = _comports()
  
      # Extract USB product and vendor IDs from `hwid` entries of the form:
      #
      #     FTDIBUS\VID_0403+PID_6001+A60081GEA\0000
      df_hwid = (df_comports.hardware_id.str.lower().str
                 .extract('vid_(?P<vid>[0-9a-f]+)\+pid_(?P<pid>[0-9a-f]+)',
                          expand=True))
      # Extract USB product and vendor IDs from `hwid` entries of the form:
      #
      #     USB VID:PID=16C0:0483 SNR=2145930
      no_id_mask = df_hwid.vid.isnull()
      df_hwid.loc[no_id_mask] = (df_comports.loc[no_id_mask, 'hardware_id']
                                 .str.lower().str
                                 .extract('vid:pid=(?P<vid>[0-9a-f]+):'
                                          '(?P<pid>[0-9a-f]+)', expand=True))
      df_comports = df_comports.join(df_hwid)
  
      if vid_pid is not None:
          if isinstance(vid_pid, six.string_types):
              # Single USB vendor/product ID specified.
              vid_pid = [vid_pid]
  
          # Mark ports that match specified USB vendor/product IDs.
          df_comports['include'] = (df_comports.vid + ':' +
                                    df_comports.pid).isin(map(str.lower,
                                                              vid_pid))
  
          if include_all:
              # All ports should be included, but sort rows such that ports
              # matching specified USB vendor/product IDs come first.
              df_comports = (df_comports.sort_values('include', ascending=False)
                             .drop('include', axis=1))
          else:
              # Only include ports that match specified USB vendor/product IDs.
              df_comports = (df_comports.loc[df_comports.include]
                             .drop('include', axis=1))
  
      if check_available or only_available:
          # Add `available` column indicating whether each port accepted a
          # connection.  A port may not, for example, accept a connection if the
          # port is already open.
          available = []
  
          for name_i, port_info_i in df_comports.iterrows():
              try:
                  connection = serial.Serial(port=name_i)
                  connection.close()
                  available.append(True)
              except serial.SerialException:
                  available.append(False)
          df_comports['available'] = available
          if only_available:
              df_comports = df_comports.loc[df_comports.available]
          if not check_available:
              del df_comports['available']
      return df_comports