code: def run_once(self):
          
          packet = _parse_irc_packet(next(self.lines)) #Get next line from generator
  
          for event_handler in list(self.on_packet_received):
              event_handler(self, packet)
  
          if packet.command == "PRIVMSG":
              if packet.arguments[0].startswith("#"):
                  for event_handler in list(self.on_public_message):
                      event_handler(self, packet.arguments[0], packet.prefix.split("!")[0], packet.arguments[1])
              else:
                  for event_handler in list(self.on_private_message):
                      event_handler(self, packet.prefix.split("!")[0], packet.arguments[1])
          elif packet.command == "PING":
              self.send_line("PONG :{}".format(packet.arguments[0]))
  
              for event_handler in list(self.on_ping):
                  event_handler(self)
          elif packet.command == "433" or packet.command == "437":
              #Command 433 is "Nick in use"
              #Add underscore to the nick
  
              self.set_nick("{}_".format(self.nick))
          elif packet.command == "001":
              for event_handler in list(self.on_welcome):
                  event_handler(self)
          elif packet.command == "JOIN":
              for event_handler in list(self.on_join):
                  event_handler(self, packet.arguments[0], packet.prefix.split("!")[0])
          elif packet.command == "PART":
              for event_handler in list(self.on_leave):
                  event_handler(self, packet.arguments[0], packet.prefix.split("!")[0])
docs: This function runs one iteration of the IRC client. This is called in a loop
          by the run_loop function. It can be called separately, but most of the
          time there is no need to do this.