docs: def lineage(self, tax_id=None, tax_name=None):
          """Public method for returning a lineage; includes tax_name and rank
  
          """
  
          if not bool(tax_id) ^ bool(tax_name):
              msg = 'Exactly one of tax_id and tax_name may be provided.'
              raise ValueError(msg)
  
          if tax_name:
              tax_id, primary_name, is_primary = self.primary_from_name(tax_name)
          else:
              primary_name = None
  
          # assumes stable ordering of lineage from root --> leaf
          lintups = self._get_lineage(tax_id)
          ldict = dict(lintups)
  
          ldict['tax_id'] = tax_id
          try:
              # parent is second to last element, except for root
              __, ldict['parent_id'] = lintups[-2]
          except IndexError:
              ldict['parent_id'] = None
  
          ldict['rank'], __ = lintups[-1]  # this taxon is last element in lineage
          ldict['tax_name'] = primary_name or self.primary_from_id(tax_id)
  
          return ldict