docs: def coverage(self):
          """
          If there is a .coverage file available, this will attempt to form a DataFrame with that information in it, which
          will contain the columns:
  
           * filename
           * lines_covered
           * total_lines
           * coverage
  
          If it can't be found or parsed, an empty DataFrame of that form will be returned.
  
          :return: DataFrame
          """
  
          if not self.has_coverage():
              return DataFrame(columns=['filename', 'lines_covered', 'total_lines', 'coverage'])
  
          with open(self.git_dir + os.sep + '.coverage', 'r') as f:
              blob = f.read()
              blob = blob.split('!')[2]
              cov = json.loads(blob)
  
          ds = []
          for filename in cov['lines'].keys():
              idx = 0
              try:
                  with open(filename, 'r') as f:
                      for idx, _ in enumerate(f):
                          pass
              except FileNotFoundError as e:
                  if self.verbose:
                      warnings.warn('Could not find file %s for coverage' % (filename, ))
  
              num_lines = idx + 1
  
              try:
                  short_filename = filename.split(self.git_dir + os.sep)[1]
                  ds.append([short_filename, len(cov['lines'][filename]), num_lines])
              except IndexError as e:
                  if self.verbose:
                      warnings.warn('Could not find file %s for coverage' % (filename, ))
  
          df = DataFrame(ds, columns=['filename', 'lines_covered', 'total_lines'])
          df['coverage'] = df['lines_covered'] / df['total_lines']
  
          return df