docs: def run(self, ds, skip_checks, *checker_names):
          """
          Runs this CheckSuite on the dataset with all the passed Checker instances.
  
          Returns a dictionary mapping checker names to a 2-tuple of their grouped scores and errors/exceptions while running checks.
          """
  
          ret_val = {}
          checkers = self._get_valid_checkers(ds, checker_names)
  
          if skip_checks is not None:
              skip_check_dict = CheckSuite._process_skip_checks(skip_checks)
          else:
              skip_check_dict = defaultdict(lambda: None)
  
          if len(checkers) == 0:
              print("No valid checkers found for tests '{}'".format(",".join(checker_names)))
  
          for checker_name, checker_class in checkers:
  
              checker = checker_class() # instantiate a Checker object
              checker.setup(ds)         # setup method to prep
  
              checks = self._get_checks(checker, skip_check_dict)
              vals = []
              errs = {}   # check method name -> (exc, traceback)
  
              for c, max_level in checks:
                  try:
                      vals.extend(self._run_check(c, ds, max_level))
                  except Exception as e:
                      errs[c.__func__.__name__] = (e, sys.exc_info()[2])
  
              # score the results we got back
              groups = self.scores(vals)
  
              ret_val[checker_name] = groups, errs
  
          return ret_val