docs: def cap(self, subcommand, *args):
          """
          Send a CAP command according to `the spec
          <http://ircv3.atheme.org/specification/capability-negotiation-3.1>`_.
  
          Arguments:
  
              subcommand -- LS, LIST, REQ, ACK, CLEAR, END
              args -- capabilities, if required for given subcommand
  
          Example:
  
              .cap('LS')
              .cap('REQ', 'multi-prefix', 'sasl')
              .cap('END')
          """
          cap_subcommands = set('LS LIST REQ ACK NAK CLEAR END'.split())
          client_subcommands = set(cap_subcommands) - {'NAK'}
          assert subcommand in client_subcommands, "invalid subcommand"
  
          def _multi_parameter(args):
              """
              According to the spec::
  
                  If more than one capability is named, the RFC1459 designated
                  sentinel (:) for a multi-parameter argument must be present.
  
              It's not obvious where the sentinel should be present or if it
              must be omitted for a single parameter, so follow convention and
              only include the sentinel prefixed to the first parameter if more
              than one parameter is present.
              """
              if len(args) > 1:
                  return (':' + args[0],) + args[1:]
              return args
  
          self.send_items('CAP', subcommand, *_multi_parameter(args))