--- bin/hatop.orig	2019-12-09 21:46:21 UTC
+++ bin/hatop
@@ -404,7 +404,7 @@ class Socket:
         data = self._socket.recv(HAPROXY_CLI_BUFSIZE)
         if not data:
             raise SocketError('error while waiting for prompt')
-        return data
+        return data.decode()
 
     def connect(self):
         # Initialize socket connection
@@ -414,16 +414,16 @@ class Socket:
         # Enter the interactive socket mode. This requires HAProxy 1.4+ and
         # allows us to error out early if connected to an older version.
         try:
-            self.send('prompt')
+            self.send(b'prompt')
             self.wait()
-            self.send('set timeout cli %d' % HAPROXY_CLI_TIMEOUT)
+            self.send(b'set timeout cli %d' % HAPROXY_CLI_TIMEOUT)
             self.wait()
         except SocketError:
             raise SocketError('error while initializing interactive mode')
 
     def close(self):
         try:
-            self.send('quit')
+            self.send(b'quit')
         except:
             pass
         try:
@@ -432,7 +432,7 @@ class Socket:
             pass
 
     def send(self, cmdline):
-        self._socket.sendall('%s\n' % cmdline)
+        self._socket.sendall(b'%s\n' % cmdline)
 
     def wait(self):
         # Wait for the prompt and discard data.
@@ -495,7 +495,7 @@ class SocketData:
                 raise ValueError('invalid proxy filter: %s' % filter)
 
         # Convert proxy filters into more efficient stat filters
-        self.socket.send('show stat')
+        self.socket.send(b'show stat')
         pxstat, pxcount, svcount = parse_stat(self.socket.recv())
 
         proxy_iid_map = {} # {pxname: iid, ...}
@@ -514,11 +514,11 @@ class SocketData:
                 raise RuntimeError('proxy not found: %s' % pxname)
 
         # Register filters
-        for iid in proxy_iid_map.itervalues():
+        for iid in proxy_iid_map.values():
             self._filters.add((iid, -1, -1))
 
     def update_info(self):
-        self.socket.send('show info')
+        self.socket.send(b'show info')
         iterable = self.socket.recv()
         self.info = parse_info(iterable)
 
@@ -535,7 +535,7 @@ class SocketData:
 
         if self._filters:
             for filter in self._filters:
-                self.socket.send('show stat %d %d %d' % filter)
+                self.socket.send(b'show stat %d %d %d' % filter)
                 filter_stat, filter_pxcount, filter_svcount = \
                         parse_stat(self.socket.recv())
 
@@ -546,7 +546,7 @@ class SocketData:
                 self.svcount += filter_svcount
                 self.stat.update(filter_stat)
         else:
-            self.socket.send('show stat')
+            self.socket.send(b'show stat')
             self.stat, self.pxcount, self.svcount = \
                     parse_stat(self.socket.recv())
 
@@ -716,7 +716,7 @@ class ScreenCLI:
         self.ibuf = list(self.ihist[-1])
         self.mvend()
 
-    def next(self):
+    def __next__(self):
         if len(self.ihist) == 0:
             return
         self.ihist.rotate(-1)
@@ -854,7 +854,7 @@ class ScreenCLI:
     def execute_cmdline(self, cmdline):
         self.obuf.append('* %s' % time.ctime())
         self.obuf.append('> %s' % cmdline)
-        self.screen.data.socket.send(cmdline)
+        self.screen.data.socket.send(cmdline.encode())
         self.obuf.extend(self.screen.data.socket.recv())
         self.update_screenlines()
 
@@ -1087,7 +1087,7 @@ class Screen:
         self.data.update_info()
         try:
             self.data.update_stat()
-        except RuntimeWarning, x:
+        except RuntimeWarning as x:
             self.exceptions.append(x)
 
     def update_bars(self):
@@ -1438,19 +1438,19 @@ class StatusBar:
 # ------------------------------------------------------------------------- #
 
 def human_seconds(numeric):
-    for minval, prefix in sorted(PREFIX_TIME.items(), reverse=True):
+    for minval, prefix in sorted(list(PREFIX_TIME.items()), reverse=True):
         if (numeric/minval):
             return '%d%s' % (numeric/minval, prefix)
     return '%ds' % numeric
 
 def human_metric(numeric):
-    for minval, prefix in sorted(PREFIX_METRIC.items(), reverse=True):
+    for minval, prefix in sorted(list(PREFIX_METRIC.items()), reverse=True):
         if (numeric/minval):
             return '%d%s' % (numeric/minval, prefix)
     return str(numeric)
 
 def human_binary(numeric):
-    for minval, prefix in sorted(PREFIX_BINARY.items(), reverse=True):
+    for minval, prefix in sorted(list(PREFIX_BINARY.items()), reverse=True):
         if (numeric/minval):
             return '%.2f%s' % (float(numeric)/float(minval), prefix)
     return '%dB' % numeric
@@ -1683,20 +1683,20 @@ def parse_info(iterable):
         line = line.strip()
         if not line:
             continue
-        for key, regexp in HAPROXY_INFO_RE.iteritems():
+        for key, regexp in HAPROXY_INFO_RE.items():
             match = regexp.match(line)
             if match:
                 info[key] = match.group('value')
                 break
 
-    for key in HAPROXY_INFO_RE.iterkeys():
+    for key in HAPROXY_INFO_RE.keys():
         if not key in info:
             raise RuntimeError('missing "%s" in info data' % key)
 
     return info
 
 def get_idx(field):
-    return filter(lambda x: x[1][1] == field, HAPROXY_STAT_CSV)[0][0]
+    return [x for x in HAPROXY_STAT_CSV if x[1][1] == field][0][0]
 
 def get_width(width, xmax, ncols, idx):
     # distribute excess space evenly from left to right
@@ -1709,7 +1709,7 @@ def get_width(width, xmax, ncols, idx):
             if idx < (xdiff - (xdiff / ncols) * ncols):
                 width += 1 # compensate rounding
             width = width + xdiff / ncols
-    return width
+    return int(width)
 
 def get_cell(width, align, value):
     s = str(value)
@@ -1732,7 +1732,7 @@ def get_head(mode):
 def get_screenlines(stat):
     screenlines = []
 
-    for iid, svstats in stat.iteritems():
+    for iid, svstats in stat.items():
         lines = []
 
         try:
@@ -1774,11 +1774,11 @@ def get_screenline(mode, stat):
         value = stat[column.name]
 
         for filter in column.filters['always']:
-            value = filter(value)
+            value = list(filter(value))
 
         if len(str(value)) > column.width:
             for filter in column.filters['ondemand']:
-                value = filter(value)
+                value = list(filter(value))
 
         value = str(value)
         value = trim(value, column.width)
@@ -2099,7 +2099,7 @@ def mainloop(screen, interval):
             elif c == curses.KEY_UP:
                 screen.cli.prev()
             elif c == curses.KEY_DOWN:
-                screen.cli.next()
+                next(screen.cli)
 
             # output history
             elif c == curses.KEY_PPAGE:
@@ -2202,21 +2202,21 @@ if __name__ == '__main__':
                     break
                 except KeyboardInterrupt:
                     break
-                except CursesError, e:
+                except CursesError as e:
                     screen.reset()
                     log('curses error: %s, restarting...' % e)
                     time.sleep(1)
                     screen.recover()
 
-        except ValueError, e:
+        except ValueError as e:
             screen.reset()
             log('value error: %s' % e)
             sys.exit(1)
-        except RuntimeError, e:
+        except RuntimeError as e:
             screen.reset()
             log('runtime error: %s' % e)
             sys.exit(1)
-        except SocketError, e:
+        except SocketError as e:
             screen.reset()
             log('socket error: %s' % e)
             sys.exit(2)
