docs: def encode(self):
          """Encode the packet's buffer from the instance variables."""
          tftpassert(self.filename, "filename required in initial packet")
          tftpassert(self.mode, "mode required in initial packet")
          # Make sure filename and mode are bytestrings.
          filename = self.filename
          mode = self.mode
          if not isinstance(filename, bytes):
              filename = filename.encode('ascii')
          if not isinstance(self.mode, bytes):
              mode = mode.encode('ascii')
  
          ptype = None
          if self.opcode == 1: ptype = "RRQ"
          else:                ptype = "WRQ"
          log.debug("Encoding %s packet, filename = %s, mode = %s",
              ptype, filename, mode)
          for key in self.options:
              log.debug("    Option %s = %s", key, self.options[key])
  
          fmt = b"!H"
          fmt += b"%dsx" % len(filename)
          if mode == b"octet":
              fmt += b"5sx"
          else:
              raise AssertionError("Unsupported mode: %s" % mode)
          # Add options. Note that the options list must be bytes.
          options_list = []
          if len(list(self.options.keys())) > 0:
              log.debug("there are options to encode")
              for key in self.options:
                  # Populate the option name
                  name = key
                  if not isinstance(name, bytes):
                      name = name.encode('ascii')
                  options_list.append(name)
                  fmt += b"%dsx" % len(name)
                  # Populate the option value
                  value = self.options[key]
                  # Work with all strings.
                  if isinstance(value, int):
                      value = str(value)
                  if not isinstance(value, bytes):
                      value = value.encode('ascii')
                  options_list.append(value)
                  fmt += b"%dsx" % len(value)
  
          log.debug("fmt is %s", fmt)
          log.debug("options_list is %s", options_list)
          log.debug("size of struct is %d", struct.calcsize(fmt))
          
          self.buffer = struct.pack(fmt,
                                    self.opcode,
                                    filename,
                                    mode,
                                    *options_list)
  
          log.debug("buffer is %s", repr(self.buffer))
          return self