title: "AttributeError" What am I doing wrong here?
body: <p>I'm developing a server monitoring utility in Python that I want to work on everything from macOS to Haiku. It's split into a client that connects to and queries multiple servers. Right now I'm testing the client on a macOS host with the server running on Debian in a Parallels VM. However, I didn't commit the new changes I made that <em>did</em> work to GitHub, and then made some changes that broke the whole thing. I'm only going to include the parts of my code that are relevant.</p>
  
  <p>This is from the client.</p>
  
  <pre><code>def getServerInfoByName(serverName):
      serverIndex = serverNames.index(serverName)
      serverAddress = serverAddressList[serverIndex]
      serverPort = serverPorts[serverIndex]
      serverUsername = serverUsernames[serverIndex]
      return serverAddress, serverPort, serverUsername
  
  
  
  for server in serverNames:
      try:
          if server != None:
              serverInfo = getServerInfoByName(server)
              exec(server + "Socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)")
              exec(server + "Socket.connect(('" + serverInfo[0] + "', " + serverInfo[1] + "))")
  
      except ConnectionRefusedError:
          print("Could not establish a connection to " + server + ".")
          print(divider)
          sys.exit()
  
  
  
  
  def clientLoop():
      sys.stdout.write(termcolors.BLUE + "-&gt; " + termcolors.ENDC)
      commandInput = input()
      splitCommand = commandInput.split(' ')
      whichServer = splitCommand[0]
  
      if splitCommand[0] == "exit":
          sys.exit()
  
      # Insert new one word client commands here
  
      elif len(splitCommand) &lt; 2:
          print("Not enough arguments")
          print(divider)
          clientLoop()
  
      elif splitCommand[1] == "ssh":
          serverInfo = getServerInfoByName(whichServer)
          os.system("ssh " + serverInfo[2] + "@" + serverInfo[0])
          print(divider)
          clientLoop()
  
      # Insert new external commands above here (if any, perhaps FTP in the 
      # future).
      # NOTE: Must be recursive or else we'll crash with an IndexError
      # TODO: Possibly just catch the exception and use that to restart the 
      # function
  
      else:
          whichServer = splitCommand[0]
          commandToServer = splitCommand[1]
          exec(whichServer + "Socket.send(commandToServer.encode('utf-8'))")
  
          response = exec(whichServer + "Socket.recv(1024)")
          print(response.decode('utf-8'))
          print(divider)
          clientLoop()
  
  clientLoop()
  </code></pre>
  
  <p>And this is from the server.</p>
  
  <pre><code>### Start the server
  
  try:
      incomingSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
      incomingSocket.bind((address, port))
  
  except OSError:
      print("The configured address is already in use.")
      print("The problem should solve itself in a few seconds.")
      print("Otherwise, make sure no other services are using")
      print("the configured address.")
      sys.exit()
  
  incomingSocket.listen(1)
  
  ### Main loop for the server
  while True:
  
      clientSocket, clientAddress = incomingSocket.accept()
      incomingCommand = clientSocket.recv(1024)
      command = incomingCommand.decode('utf-8')
  
      if command != None:
          if command == "os":
              clientSocket.send(osinfo[0].encode('utf-8'))
  
          elif command == "hostname":
              clientSocket.send(osinfo[1].encode('utf-8'))
  
          elif command == "kernel":
              clientSocket.send(osinfo[2].encode('utf-8'))
  
          elif command == "arch":
              clientSocket.send(osinfo[3].encode('utf-8'))
  
          elif command == "cpu":
              cpuOverall = getOverall()
              cpuOverallMessage = "Overall CPU usage: " + str(cpuOverall) + "%"
              clientSocket.send(cpuOverallMessage.encode('utf-8'))
  
          elif command == "stopserver":
              incomingSocket.close()
              clientSocket.close()
              sys.exit()
  
          else:
              clientSocket.send("Invalid command".encode('utf-8'))
  </code></pre>
  
  <p>Any time I try to send a command to the server, the client crashes with <code>AttributeError: 'NoneType' object has no attribute 'decode'</code> as soon as it tries to decode the response from the server. Eventually I want to encrypt the sockets with AES but I can't do that if it doesn't even work in plain text.</p>