docs: def create_table_hdu(self, data=None, dtype=None,
                           header=None,
                           names=None, formats=None,
                           units=None, dims=None, extname=None, extver=None,
                           table_type='binary', write_bitcols=False):
          """
          Create a new, empty table extension and reload the hdu list.
  
          There are three ways to do it:
              1) send a numpy dtype, from which the formats in the fits file will
                 be determined.
              2) Send an array in data= keyword.  this is required if you have
                  object fields for writing to variable length columns.
              3) send the names,formats and dims yourself
  
          You can then write data into the new extension using
              fits[extension].write(array)
          If you want to write to a single column
              fits[extension].write_column(array)
          But be careful as the other columns will be left zeroed.
  
          Often you will instead just use write_table to do this all
          atomically.
  
              fits.write_table(recarray)
  
          write_table will create the new table extension for you with the
          appropriate fields.
  
          parameters
          ----------
          dtype: numpy dtype or descriptor, optional
              If you have an array with fields, you can just send arr.dtype.  You
              can also use a list of tuples, e.g. [('x','f8'),('index','i4')] or
              a dictionary representation.
          data: a numpy array with fields, optional
                or a dictionary
  
              An array or dict from which to determine the table definition.  You
              must use this instead of sending a descriptor if you have object
              array fields, as this is the only way to determine the type and max
              size.
  
          names: list of strings, optional
              The list of field names
          formats: list of strings, optional
              The TFORM format strings for each field.
          dims: list of strings, optional
              An optional list of dimension strings for each field.  Should
              match the repeat count for the formats fields. Be careful of
              the order since FITS is more like fortran. See the descr2tabledef
              function.
  
          table_type: string, optional
              Either 'binary' or 'ascii', default 'binary'
              Matching is case-insensitive
          units: list of strings, optional
              An optional list of unit strings for each field.
          extname: string, optional
              An optional extension name.
          extver: integer, optional
              FITS allows multiple extensions to have the same name (extname).
              These extensions can optionally specify an EXTVER version number in
              the header.  Send extver= to set a particular version, which will
              be represented in the header with keyname EXTVER.  The extver must
              be an integer > 0.  If extver is not sent, the first one will be
              selected.  If ext is an integer, the extver is ignored.
          write_bitcols: bool, optional
              Write boolean arrays in the FITS bitcols format, default False
  
          header: FITSHDR, list, dict, optional
              This is only used to determine how many slots to reserve for
              header keywords
  
  
          restrictions
          ------------
          The File must be opened READWRITE
          """
  
          # record this for the TableHDU object
          self.keys['write_bitcols'] = write_bitcols
  
          # can leave as turn
          table_type_int = _extract_table_type(table_type)
  
          if data is not None:
              if isinstance(data, numpy.ndarray):
                  names, formats, dims = array2tabledef(
                      data, table_type=table_type, write_bitcols=write_bitcols)
              elif isinstance(data, (list, dict)):
                  names, formats, dims = collection2tabledef(
                      data, names=names, table_type=table_type,
                      write_bitcols=write_bitcols)
              else:
                  raise ValueError(
                      "data must be an ndarray with fields or a dict")
          elif dtype is not None:
              dtype = numpy.dtype(dtype)
              names, formats, dims = descr2tabledef(
                  dtype.
                  descr,
                  write_bitcols=write_bitcols,
                  table_type=table_type,
              )
          else:
              if names is None or formats is None:
                  raise ValueError(
                      "send either dtype=, data=, or names= and formats=")
  
              if not isinstance(names, list) or not isinstance(formats, list):
                  raise ValueError("names and formats should be lists")
              if len(names) != len(formats):
                  raise ValueError("names and formats must be same length")
  
              if dims is not None:
                  if not isinstance(dims, list):
                      raise ValueError("dims should be a list")
                  if len(dims) != len(names):
                      raise ValueError("names and dims must be same length")
  
          if units is not None:
              if not isinstance(units, list):
                  raise ValueError("units should be a list")
              if len(units) != len(names):
                  raise ValueError("names and units must be same length")
  
          if extname is None:
              # will be ignored
              extname = ""
          else:
              if not isstring(extname):
                  raise ValueError("extension name must be a string")
              extname = mks(extname)
  
          if extname is not None and extver is not None:
              extver = check_extver(extver)
          if extver is None:
              # will be ignored
              extver = 0
          if extname is None:
              # will be ignored
              extname = ""
  
          if header is not None:
              nkeys = len(header)
          else:
              nkeys = 0
  
          # note we can create extname in the c code for tables, but not images
          self._FITS.create_table_hdu(table_type_int, nkeys,
                                      names, formats, tunit=units, tdim=dims,
                                      extname=extname, extver=extver)
  
          # don't rebuild the whole list unless this is the first hdu
          # to be created
          self.update_hdu_list(rebuild=False)