docs: def guess_codec(file, errors="strict", require_char=False):
      """Look at file contents and guess its correct encoding.
  
      File must be open in binary mode and positioned at offset 0. If BOM
      record is present then it is assumed to be UTF-8 or UTF-16 encoded
      file. GEDCOM header is searched for CHAR record and encoding name
      is extracted from it, if BOM record is present then CHAR record
      must match BOM-defined encoding.
  
      :param file: File object, must be open in binary mode.
      :param str errors: Controls error handling behavior during string
          decoding, accepts same values as standard `codecs.decode` method.
      :param bool require_char: If True then exception is thrown if CHAR
          record is not found in a header, if False and CHAR is not in the
          header then codec determined from BOM or "gedcom" is returned.
      :returns: Tuple (codec_name, bom_size)
      :raises: :py:class:`CodecError` when codec name in file is unknown or
          when codec name in file contradicts codec determined from BOM.
      :raises: :py:class:`UnicodeDecodeError` when codec fails to decode
          input lines and `errors` is set to "strict" (default).
      """
  
      # mapping of gedcom character set specifiers to Python encoding names
      gedcom_char_to_codec = {
          'ansel': 'gedcom',
      }
  
      # check BOM first
      bom_codec = check_bom(file)
      bom_size = file.tell()
      codec = bom_codec or 'gedcom'
  
      # scan header until CHAR or end of header
      while True:
  
          # this stops at '\n'
          line = file.readline()
          if not line:
              raise IOError("Unexpected EOF while reading GEDCOM header")
  
          # do not decode bytes to strings here, reason is that some
          # stupid apps split CONC record at byte level (in middle of
          # of multi-byte characters). This implies that we can only
          # work with encodings that have ASCII as single-byte subset.
  
          line = line.lstrip().rstrip(b"\r\n")
          words = line.split()
  
          if len(words) >= 2 and words[0] == b"0" and words[1] != b"HEAD":
              # past header but have not seen CHAR
              if require_char:
                  raise CodecError("GEDCOM header does not have CHAR record")
              else:
                  break
          elif len(words) >= 3 and words[0] == b"1" and words[1] == b"CHAR":
              try:
                  encoding = words[2].decode(codec, errors)
                  encoding = gedcom_char_to_codec.get(encoding.lower(),
                                                      encoding.lower())
                  new_codec = codecs.lookup(encoding).name
              except LookupError:
                  raise CodecError("Unknown codec name {0}".format(encoding))
              if bom_codec is None:
                  codec = new_codec
              elif new_codec != bom_codec:
                  raise CodecError("CHAR codec {0} is different from BOM "
                                   "codec {1}".format(new_codec, bom_codec))
              break
  
      return codec, bom_size