docs: def parse(self, args=None):
          """Parse textual keywords as described by this class’s attributes, and update
          this instance’s attributes with the parsed values. *args* is a list of
          strings; if ``None``, it defaults to ``sys.argv[1:]``. Returns *self*
          for convenience. Raises :exc:`KwargvError` if invalid keywords are
          encountered.
  
          See also :meth:`ParseKeywords.parse_or_die`.
  
          """
          if args is None:
              import sys
              args = sys.argv[1:]
  
          seen = set()
  
          for arg in args:
              t = arg.split('=', 1)
              if len(t) < 2:
                  raise KwargvError('don\'t know what to do with argument "%s"', arg)
  
              kw, val = t
              ki = self._kwinfos.get(kw)
  
              if ki is None:
                  raise KwargvError('unrecognized keyword argument "%s"', kw)
  
              if not len(val):
                  raise KwargvError('empty value for keyword argument "%s"', kw)
  
              try:
                  pval = ki.parser(val)
              except ParseError as e :
                  raise KwargvError('cannot parse value "%s" for keyword '
                                    'argument "%s": %s', val, kw, e)
              except Exception as e:
                  if ki.printexc:
                      raise KwargvError('cannot parse value "%s" for keyword '
                                        'argument "%s": %s', val, kw, e)
                  raise KwargvError('cannot parse value "%s" for keyword '
                                    'argument "%s"', val, kw)
  
              if ki.maxvals is not None and len(pval) > ki.maxvals:
                  raise KwargvError('keyword argument "%s" may have at most %d'
                                    ' values, but got %s ("%s")', kw,
                                    ki.maxvals, len(pval), val)
  
              if ki.scale is not None:
                  pval = pval * ki.scale
  
              if ki.fixupfunc is not None:
                  pval = ki.fixupfunc(pval)
  
              if ki.repeatable:
                  # We can't just unilaterally append to the preexisting
                  # list, since if we did that starting with the default value
                  # we'd mutate the default list.
                  cur = self.get(ki._attrname)
                  if not len(cur):
                      pval = [pval]
                  else:
                      cur.append(pval)
                      pval = cur
  
              seen.add(kw)
              self.set_one(ki._attrname, pval)
  
          for kw, ki in six.iteritems(self._kwinfos):
              if kw not in seen:
                  if ki.required:
                      raise KwargvError('required keyword argument "%s" was not provided', kw)
  
                  # If there's a fixup, process it even if the keyword wasn't
                  # provided. This lets code use "interesting" defaults with
                  # types that you might prefer to use when launching a task
                  # programmatically; e.g. a default output stream that is
                  # `sys.stdout`, not "-".
                  if ki.fixupfunc is not None:
                      self.set_one(ki._attrname, ki.fixupfunc(None))
  
          return self