]> git.phdru.name Git - bookmarks_db.git/blobdiff - subproc.py
Fix(Robot): Stop splitting and un-splitting URLs
[bookmarks_db.git] / subproc.py
index 886dc4727a32f7c956ef255fbb00361916c9b996..37cb253d71d9e9c2ac910029876bbba63b21c5fe 100755 (executable)
@@ -1,4 +1,4 @@
-#! /usr/bin/env python
+#! /usr/bin/env python3
 
 """Run a subprocess and communicate with it via stdin, stdout, and stderr.
 
@@ -49,7 +49,6 @@ __version__ = "Revision: 2.0 "
 import os
 import select
 import signal
-import string
 import sys
 import time
 
@@ -81,7 +80,7 @@ class Subprocess:
     the subprocess stderr stream."""
 
     pid = 0
-    cmd = ''
+    cmd = b''
     expire_noisily = 1                  # Announce subproc destruction?
     pipefiles = []
     readbuf = 0                         # fork will assign to be a readbuf obj
@@ -101,7 +100,7 @@ class Subprocess:
         """Fork a subprocess with designated COMMAND (default, self.cmd)."""
         if cmd:
             self.cmd = cmd
-        cmd = string.split(self.cmd)
+        cmd = self.cmd.split()
         pRc, cWp = os.pipe()            # parent-read-child, child-write-parent
         cRp, pWc = os.pipe()            # child-read-parent, parent-write-child
         pRe, cWe = os.pipe()            # parent-read-error, child-write-error
@@ -141,7 +140,7 @@ class Subprocess:
         else:           ### PARENT ### noqa: E262
             # Connect to the child's file descriptors, using our customized
             # fdopen:
-            self.toChild = os.fdopen(pWc, 'w')
+            self.toChild = os.fdopen(pWc, 'wb')
             self.toChild_fdlist = [pWc]
             self.readbuf = ReadBuf(pRc)
             self.errbuf = ReadBuf(pRe)
@@ -185,9 +184,9 @@ class Subprocess:
             # XXX Can write-buffer full be handled better??
             raise IOError("write to %s blocked" % self)                 # ===>
 
-    def writeline(self, line=''):
+    def writeline(self, line=b''):
         """Write STRING, with added newline termination, to subprocess."""
-        self.write(line + '\n')
+        self.write(line + b'\n')
 
     ### Get output from subprocess ### noqa: E266
 
@@ -221,7 +220,7 @@ class Subprocess:
         """Read N chars, or all pending if no N specified."""
         if n is None:
             return self.readPendingChars()
-        got = ''
+        got = b''
         while n:
             got0 = self.readPendingChars(n)
             got = got + got0
@@ -385,7 +384,7 @@ class ReadBuf:
             raise ValueError
         self.fd = fd
         self.eof = 0                    # May be set with stuff still in .buf
-        self.buf = ''
+        self.buf = b''
         self.chunkSize = maxChunkSize   # Biggest read chunk, default 1024.
 
     def fileno(self):
@@ -399,7 +398,7 @@ class ReadBuf:
             return self.buf[0]                                          # ===>
 
         if self.eof:
-            return ''                                                   # ===>
+            return b''                                                   # ===>
 
         sel = select.select([self.fd], [], [self.fd], 0)
         if sel[2]:
@@ -408,7 +407,7 @@ class ReadBuf:
             self.buf = os.read(self.fd, self.chunkSize)                 # ===>
             return self.buf[0]          # Assume select don't lie.
         else:
-            return ''                                                 # ===>
+            return b''                                                 # ===>
 
     def readPendingChar(self):
         """Consume first character of unconsumed output from file, or empty
@@ -419,7 +418,7 @@ class ReadBuf:
             return got                                                  # ===>
 
         if self.eof:
-            return ''                                                   # ===>
+            return b''                                                   # ===>
 
         sel = select.select([self.fd], [], [self.fd], 0)
         if sel[2]:
@@ -427,23 +426,23 @@ class ReadBuf:
         if sel[0]:
             return os.read(self.fd, 1)                                  # ===>
         else:
-            return ''                                                 # ===>
+            return b''                                                 # ===>
 
     def readPendingChars(self, max=None):
         """Consume uncomsumed output from FILE, or empty string if nothing
         pending."""
 
-        got = ""
+        got = b""
         if self.buf:
-            if (max > 0) and (len(self.buf) > max):
+            if max and (len(self.buf) > max):
                 got = self.buf[0:max]
                 self.buf = self.buf[max:]
             else:
-                got, self.buf = self.buf, ''
+                got, self.buf = self.buf, b''
             return got
 
         if self.eof:
-            return ''
+            return b''
 
         sel = select.select([self.fd], [], [self.fd], 0)
         if sel[2]:
@@ -452,7 +451,7 @@ class ReadBuf:
             got = got + os.read(self.fd, self.chunkSize)
             if max == 0:
                 self.buf = got
-                return ''
+                return b''
             elif max is None:
                 return got
             elif len(got) > max:
@@ -461,7 +460,7 @@ class ReadBuf:
             else:
                 return got
         else:
-            return ''
+            return b''
 
     def readPendingLine(self, block=0):
         """Return pending output from FILE, up to first newline (inclusive).
@@ -472,15 +471,15 @@ class ReadBuf:
         any newline."""
 
         if self.buf:
-            to = string.find(self.buf, '\n')
+            to = self.buf.find(b'\n')
             if to != -1:
                 got, self.buf = self.buf[:to+1], self.buf[to+1:]
                 return got                                              # ===>
-            got, self.buf = self.buf, ''
+            got, self.buf = self.buf, b''
         else:
             if self.eof:
-                return ''                                               # ===>
-            got = ''
+                return b''                                               # ===>
+            got = b''
 
         # Herein, 'got' contains the (former) contents of the buffer, and it
         # doesn't include a newline.
@@ -493,14 +492,14 @@ class ReadBuf:
             if sel[0]:
                 got = got + os.read(self.fd, self.chunkSize)
 
-            to = string.find(got, '\n')
+            to = got.find(b'\n')
             if to != -1:
                 got, self.buf = got[:to+1], got[to+1:]
                 return got                                              # ===>
             if not block:
                 return got                                              # ===>
             if self.eof:
-                self.buf = ''           # this is how an ordinary file acts...
+                self.buf = b''           # this is how an ordinary file acts...
                 return got
             # otherwise - no newline, blocking requested, no eof - loop. # ==^
 
@@ -531,7 +530,7 @@ class RecordFile:
     def write_record(self, s):
         "Write so self.read knows exactly how much to read."
         f = self.__dict__['file']
-        f.write("%s\n%s" % (len(s), s))
+        f.write(b"%d\n%s" % (len(s), s))
         if hasattr(f, 'flush'):
             f.flush()
 
@@ -541,14 +540,14 @@ class RecordFile:
         line = f.readline()[:-1]
         if line:
             try:
-                l = string.atoi(line)
+                _l = int(line)
             except ValueError:
                 raise IOError(("corrupt %s file structure"
                                % self.__class__.__name__))
-            return f.read(l)
+            return f.read(_l)
         else:
             # EOF.
-            return ''
+            return b''
 
     def __getattr__(self, attr):
         """Implement characteristic file object attributes."""
@@ -610,7 +609,7 @@ class Ph:
 
         self.clear()
 
-        self.proc.writeline('query ' + q)
+        self.proc.writeline(b'query ' + q)
         got = []
         it = {}
         while 1:
@@ -627,9 +626,8 @@ class Ph:
                 raise ValueError("ph failed match: '%s'" % response)    # ===>
             for line in response:
                 # convert to a dict:
-                line = string.splitfields(line, ':')
-                it[string.strip(line[0])] = (
-                    string.strip(string.join(line[1:])))
+                line = line.split(b':')
+                it[line.strip([0])] = (b''.join(line[1:])).strip()
 
     def getreply(self):
         """Consume next response from ph, returning list of lines or string
@@ -643,20 +641,20 @@ class Ph:
         nextChar = self.proc.waitForPendingChar(60)
         if not nextChar:
             raise SubprocessError('ph subprocess not responding')       # ===>
-        elif nextChar == '-':
+        elif nextChar == b'-':
             # dashed line - discard it, and continue reading:
             self.proc.readline()
             return self.getreply()                                      # ===>
-        elif nextChar == 'p':
+        elif nextChar == b'p':
             # 'ph> ' prompt - don't think we should hit this, but what the hay:
             return ''                                                   # ===>
-        elif nextChar in '0123456789':
+        elif nextChar in b'0123456789':
             # Error notice - we're currently assuming single line errors:
             return self.proc.readline()[:-1]                            # ===>
-        elif nextChar in ' \t':
+        elif nextChar in b' \t':
             # Get content, up to next dashed line:
             got = []
-            while nextChar != '-' and nextChar != '':
+            while nextChar != b'-' and nextChar != b'':
                 got.append(self.proc.readline()[:-1])
                 nextChar = self.proc.peekPendingChar()
             return got
@@ -670,13 +668,13 @@ class Ph:
         pause = .5
         maxIter = 10        # 5 seconds to clear
         iterations = 0
-        got = ''
-        self.proc.write('')
+        got = b''
+        self.proc.write(b'')
         while iterations < maxIter:
             got = got + self.proc.readPendingChars()
             # Strip out all but the last incomplete line:
-            got = string.splitfields(got, '\n')[-1]
-            if got == 'ph> ':
+            got = got.split(b'\n')[-1]
+            if got == b'ph> ':
                 return    # Ok.                             ===>
             time.sleep(pause)
         raise SubprocessError('ph not responding within %s secs' %
@@ -699,14 +697,14 @@ def test(p=0):
     p = Subprocess('cat', 1)            # set to expire noisily...
     print(p)
     print('\tWrite, then read, two newline-teriminated lines, using readline:')
-    p.write('first full line written\n')
-    p.write('second.\n')
+    p.write(b'first full line written\n')
+    p.write(b'second.\n')
     print(repr(p.readline()))
     print(repr(p.readline()))
     print('\tThree lines, last sans newline, read using combination:')
-    p.write('first\n')
-    p.write('second\n')
-    p.write('third, (no cr)')
+    p.write(b'first\n')
+    p.write(b'second\n')
+    p.write(b'third, (no cr)')
     print('\tFirst line via readline:')
     print(repr(p.readline()))
     print('\tRest via readPendingChars:')
@@ -716,7 +714,7 @@ def test(p=0):
         print('\t** Stop seems to have failed!')
     else:
         print('\tWriting line while subprocess is paused...')
-        p.write('written while subprocess paused\n')
+        p.write(b'written while subprocess paused\n')
         print('\tNonblocking read of paused subprocess (should be empty):')
         print(p.readPendingChars())
         print('\tContinuing subprocess (verbose):')