diff --git a/modules/bindings/pymod/blast.py b/modules/bindings/pymod/blast.py
index 7ecff08966302dc70d7b8325d9af10d9a50268fd..80409f492957991a942d8e4f13ec9d2fc2f428ad 100644
--- a/modules/bindings/pymod/blast.py
+++ b/modules/bindings/pymod/blast.py
@@ -192,8 +192,9 @@ def BlastVersion(blast_location=None):
     pattern=re.compile(r'\s*Package: blast (\d+\.\d+\.\d+),\s+')
 
   blast_pipe=subprocess.Popen(args, stdout=subprocess.PIPE,
-                              stderr=subprocess.PIPE, universal_newlines=True)
-  lines=blast_pipe.stdout.readlines()
+                              stderr=subprocess.PIPE)
+  stdout, _ = blast_pipe.communicate()
+  lines=stdout.decode().splitlines()
 
   for line in lines:
     m=pattern.match(line)
@@ -264,20 +265,19 @@ def Blast(query, database, gap_open=11, gap_ext=1, matrix='BLOSUM62',
 
   ost.LogInfo('running BLAST (%s)' % ' '.join(args))
   blast_pipe=subprocess.Popen(args, stderr=subprocess.PIPE,
-                              stdout=subprocess.PIPE, stdin=subprocess.PIPE,
-                              universal_newlines=True)
+                              stdout=subprocess.PIPE, stdin=subprocess.PIPE)
   if isinstance(query, str):
-    stdout, stderr=blast_pipe.communicate(query)
+    stdout, stderr=blast_pipe.communicate(query.encode())
   else:
-    stdout, stderr=blast_pipe.communicate(io.SequenceToString(query, 'fasta'))
+    stdout, stderr=blast_pipe.communicate(io.SequenceToString(query, 'fasta').encode())
 
   if len(stderr)>0:
      pattern=re.compile(r'^\[.*\]\s+ERROR:\s+(.*)')
-     lines=stderr.split('\n')
+     lines=stderr.decode().split('\n')
      error_message=pattern.match(lines[0])
      if error_message:
        raise BlastError(error_message.group(1), '\n'.join(lines[1:]))
   if outfmt==0:
-    return ParseBlastOutput(stdout)
+    return ParseBlastOutput(stdout.decode())
   else:
     return stdout
diff --git a/modules/bindings/pymod/cadscore.py b/modules/bindings/pymod/cadscore.py
index 90fa77e4ae61226a12002eeb7dfb86777a01907b..362325c87bed18910ba802240fb941f853eee723 100644
--- a/modules/bindings/pymod/cadscore.py
+++ b/modules/bindings/pymod/cadscore.py
@@ -185,21 +185,18 @@ def _RunCAD(tmp_dir, mode, cad_bin_path, old_regime):
                                                             os.path.join(tmp_dir,
                                                             "cadtemp"))
 
-    ps1=subprocess.Popen(command1, shell=True, stdout=subprocess.PIPE,
-                         universal_newlines=True)
+    ps1=subprocess.Popen(command1, shell=True, stdout=subprocess.PIPE)
     ps1.wait()
-    ps2=subprocess.Popen(command2, shell=True, stdout=subprocess.PIPE,
-                         universal_newlines=True)
-    ps2.wait()
-    lines=ps2.stdout.readlines()
+    ps2=subprocess.Popen(command2, shell=True, stdout=subprocess.PIPE)
+    stdout,_ = ps2.communicate()
+    lines=stdout.decode().splitlines()
     try:
       globalAA=_ParseCADGlobal(lines)
     except:
       raise RuntimeError("CAD calculation failed")
-    ps3=subprocess.Popen(command3, shell=True, stdout=subprocess.PIPE,
-                         universal_newlines=True)
-    ps3.wait()
-    lines=ps3.stdout.readlines()
+    ps3=subprocess.Popen(command3, shell=True, stdout=subprocess.PIPE)
+    stdout,_ = ps3.communicate()
+    lines=stdout.decode().splitlines()
     try:
       localAA=_ParseCADLocal(lines)
     except:
@@ -228,11 +225,10 @@ def _RunCAD(tmp_dir, mode, cad_bin_path, old_regime):
     if old_regime:
       cmd.append("--old-regime")
     cmd = ' '.join(cmd)
-    ps = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE,
-                          universal_newlines=True)
-    ps.wait()
+    ps = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
+    stdout, _ = ps.communicate()
     try:
-      globalAA = _ParseVoronotaGlobal(ps.stdout.readlines())
+      globalAA = _ParseVoronotaGlobal(stdout.decode().splitlines())
     except:
       raise RuntimeError("CAD calculation failed")
     try:
diff --git a/modules/bindings/pymod/clustalw.py b/modules/bindings/pymod/clustalw.py
index 29af869f445f1c1353c2673770048125c507a4fc..7ed4e8259d70868b9d1c66a865a5cd26d220f449 100644
--- a/modules/bindings/pymod/clustalw.py
+++ b/modules/bindings/pymod/clustalw.py
@@ -130,7 +130,7 @@ def ClustalW(seq1, seq2=None, clustalw=None, keep_files=False, nopgap=False,
     command=command+" "+clustalw_option_string  #see useful flags: http://toolkit.tuebingen.mpg.de/clustalw/help_params
 
   ps=subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)
-  ps.stdout.readlines()
+  ps.wait()
   aln=io.LoadAlignment(out)
   
 
diff --git a/modules/bindings/pymod/dssp.py b/modules/bindings/pymod/dssp.py
index a43696c4eefbcd80221a5b01e9e63e9b19e1bab4..b0346878972d2049290c6886b1ac02711a015eeb 100644
--- a/modules/bindings/pymod/dssp.py
+++ b/modules/bindings/pymod/dssp.py
@@ -55,9 +55,8 @@ def _ExecuteDSSP(path, dssp_bin, temp_dir=None):
   if not os.access(dssp_abs_path, os.X_OK):
     raise RuntimeError('"%s" is not executable' % dssp_abs_path)
 
-  ps=subprocess.Popen([dssp_abs_path, path, temp_dssp_path], 
-                      stderr=subprocess.PIPE)
-  err_lines=ps.stderr.readlines()
+  ps=subprocess.Popen([dssp_abs_path, path, temp_dssp_path])
+  ps.wait()
   return temp_dssp_path
 
 
diff --git a/modules/bindings/pymod/hbplus.py b/modules/bindings/pymod/hbplus.py
index 3ca6361a4a0a27cd6c082257bd8bce587d93be78..39b9033597dec4cae75621e2e746f94e57774aee 100644
--- a/modules/bindings/pymod/hbplus.py
+++ b/modules/bindings/pymod/hbplus.py
@@ -63,7 +63,7 @@ def HBondList(ent, hbplus_bin=None):
   full_bin=_LocateHBPlus(hbplus_bin)
   temp_d=tempfile.mkdtemp(prefix='hbplus_')
   hb_proc=subprocess.Popen(full_bin, shell=True, stdout=subprocess.PIPE,
-                           stdin=subprocess.PIPE, universal_newlines=True)
+                           stdin=subprocess.PIPE)
   file_name=os.path.join(temp_d, 'ent.pdb')
   io.SaveEntity(ent, file_name)
   hb_proc.stdin.write('%s\n' % temp_d)
diff --git a/modules/bindings/pymod/hhblits.py b/modules/bindings/pymod/hhblits.py
index 9749507c57c74c519c34c6c923c639f6f4ec2b25..5567dd2296f9c9819d610bb18558668c878f8a14 100644
--- a/modules/bindings/pymod/hhblits.py
+++ b/modules/bindings/pymod/hhblits.py
@@ -568,10 +568,9 @@ class HHblits:
                       (self.hhblits_bin, self.filename, a3m_file, full_nrdb,
                        opt_cmd)
         job = subprocess.Popen(hhblits_cmd, shell=True, cwd=self.working_dir,
-                               stdout=subprocess.PIPE, stderr=subprocess.PIPE,
-                               universal_newlines=True)
+                               stdout=subprocess.PIPE, stderr=subprocess.PIPE)
         sout, _ = job.communicate()
-        lines = sout.splitlines()
+        lines = sout.decode().splitlines()
         for line in lines:
             ost.LogVerbose(line.strip())
         if not os.path.exists(a3m_file):
@@ -589,9 +588,9 @@ class HHblits:
                                         os.environ['PATH'])})
         job = subprocess.Popen(addss_cmd, shell=True, cwd=self.working_dir,
                                env=env, stdout=subprocess.PIPE,
-                               stderr=subprocess.PIPE, universal_newlines=True)
+                               stderr=subprocess.PIPE)
         sout, serr = job.communicate()
-        lines = sout.splitlines()
+        lines = sout.decode().splitlines()
         for line in lines:
             if 'error' in line.lower():
                 ost.LogWarning('Predicting secondary structure for MSA '+
@@ -626,7 +625,7 @@ class HHblits:
         ost.LogVerbose('converting %s to %s' % (a3m_file, hhm_file))
         os.putenv('HHLIB', self.hhlib_dir)
         if subprocess.call('%s -i %s -o %s' % (hhmake, a3m_file, hhm_file),
-                           shell=True, universal_newlines=True):
+                           shell=True):
             raise IOError('could not convert a3m to hhm file')
         return hhm_file
 
@@ -736,14 +735,13 @@ class HHblits:
         ost.LogInfo('searching %s' % database)
         ost.LogVerbose(search_cmd)
         job = subprocess.Popen(search_cmd, shell=True, cwd=self.working_dir,
-                               stdout=subprocess.PIPE, stderr=subprocess.PIPE,
-                               universal_newlines=True)
+                               stdout=subprocess.PIPE, stderr=subprocess.PIPE)
         sout, serr = job.communicate()
         if job.returncode != 0:
-            lines = sout.splitlines()
+            lines = sout.decode().splitlines()
             for line in lines:
                 ost.LogError(line.strip())
-            lines = serr.splitlines()
+            lines = serr.decode().splitlines()
             for line in lines:
                 ost.LogError(line.strip())
             return None
diff --git a/modules/bindings/pymod/ialign.py b/modules/bindings/pymod/ialign.py
index 176a5dbe46360b271f7baf0738f71e4300348e43..aa7105cd61ed1c232f70cf77c642c3299ce1677d 100644
--- a/modules/bindings/pymod/ialign.py
+++ b/modules/bindings/pymod/ialign.py
@@ -141,10 +141,9 @@ def _RuniAlign(ialign, tmp_dir, options={}):
     ialign_path=settings.Locate('ialign.pl', explicit_file_name=ialign)  
     command="\"%s\" \"%s\" \"%s\" %s" % (ialign_path, model1_filename, model2_filename, cmd_opts)
 
-  ps=subprocess.Popen(command, shell=True, stdout=subprocess.PIPE,
-                      universal_newlines=True)
-  ps.wait()
-  lines=ps.stdout.readlines()
+  ps=subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)
+  stdout,_=ps.communicate()
+  lines=stdout.decode().splitlines()
 
   if (len(lines))<22:
     _CleanupFiles(tmp_dir)
diff --git a/modules/bindings/pymod/msms.py b/modules/bindings/pymod/msms.py
index b7d338e507d6b93f120d5fa022c8361cb117d131..38f37008a32ab37bfb8e6b8606b78448c520b870 100644
--- a/modules/bindings/pymod/msms.py
+++ b/modules/bindings/pymod/msms.py
@@ -43,12 +43,11 @@ def GetVersion(msms_exe=None, msms_env=None):
   """
   msms_executable = _GetExecutable(msms_exe, msms_env)
   command = "%s" % (msms_executable)
-  proc = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE,
-                          universal_newlines=True)
+  proc = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)
   stdout_value, stderr_value = proc.communicate()
 
   version = ""
-  for l in stdout_value.splitlines():
+  for l in stdout_value.decode().splitlines():
     if l[0:4]=='MSMS':
       version = l.split(' ')[1]
       return version
@@ -150,16 +149,15 @@ def _RunMSMS(command):
   :returns:                 stdout of MSMS
   :raises:              :class:`CalledProcessError` for non-zero return value
   """
-  proc = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE,
-                          universal_newlines=True)
+  proc = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)
   stdout_value, stderr_value = proc.communicate()
 
   #check for successful completion of msms
   if proc.returncode!=0:
-    print("WARNING: msms error\n", stdout_value)
+    print("WARNING: msms error\n", stdout_value.decode())
     raise MsmsProcessError(proc.returncode, command)
 
-  return stdout_value
+  return stdout_value.decode()
   
 
 
diff --git a/modules/bindings/pymod/naccess.py b/modules/bindings/pymod/naccess.py
index d2592c6b2ac3300201bb18790a918492779d335d..57d1c5740c6621fb7fd85f3320ebde403acaa1c9 100644
--- a/modules/bindings/pymod/naccess.py
+++ b/modules/bindings/pymod/naccess.py
@@ -190,17 +190,18 @@ def _RunACCALL(command, temp_dir, query):
   :returns:        stdout of command
   :exception:      CalledProcessError for non-zero return value
   """
-  proc = subprocess.Popen(command, stdout=subprocess.PIPE,
-                          stderr=subprocess.PIPE, stdin=subprocess.PIPE,
-                          cwd=temp_dir, universal_newlines=True)
-  stdout_value, stderr_value = proc.communicate(query)
+
+  proc = subprocess.Popen(command, cwd=temp_dir, stdout=subprocess.PIPE,
+                          stderr=subprocess.PIPE, stdin=subprocess.PIPE)
+  stdout_value, stderr_value = proc.communicate(query.encode())
 
   # check for successful completion of naccess
   if proc.returncode != 0:
-    LogWarning("WARNING: naccess error\n%s\n%s" % (stdout_value, stderr_value))
+    LogWarning("WARNING: naccess error\n%s\n%s" % (stdout_value.decode(), 
+                                                   stderr_value.decode()))
     raise subprocess.CalledProcessError(proc.returncode, command)
 
-  return stdout_value
+  return stdout_value.decode()
 
 
 def _RunNACCESS(command, temp_dir):
@@ -214,16 +215,16 @@ def _RunNACCESS(command, temp_dir):
   :returns:        stdout of command
   :exception:      CalledProcessError for non-zero return value
   """
-  proc = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE,
-                          cwd=temp_dir, universal_newlines=True)
+  proc = subprocess.Popen(command, cwd=temp_dir, shell=True, 
+                          stdout=subprocess.PIPE)
   stdout_value, stderr_value = proc.communicate()
 
   # check for successful completion of naccess
   if proc.returncode != 0:
-    LogWarning("WARNING: naccess error\n%s" % stdout_value)
+    LogWarning("WARNING: naccess error\n%s" % stdout_value.decode())
     raise subprocess.CalledProcessError(proc.returncode, command)
 
-  return stdout_value
+  return stdout_value.decode()
 
 
 def CalculateSurfaceArea(entity,  radius=1.4,  
diff --git a/modules/bindings/pymod/tmtools.py b/modules/bindings/pymod/tmtools.py
index b91dd6676d32897cd2d880e1a4f91d430fb5cb97..3c1ef12c8499b5f50686ae09f80044668c5242e4 100644
--- a/modules/bindings/pymod/tmtools.py
+++ b/modules/bindings/pymod/tmtools.py
@@ -80,10 +80,9 @@ def _RunTmAlign(tmalign, tmp_dir):
   else:
     tmalign_path=settings.Locate('tmalign', explicit_file_name=tmalign)  
     command="\"%s\" \"%s\" \"%s\" -m \"%s\"" %(tmalign_path, model1_filename, model2_filename, os.path.join(tmp_dir,'matrix.txt'))
-  ps=subprocess.Popen(command, shell=True, stdout=subprocess.PIPE,
-                      universal_newlines=True)
-  ps.wait()
-  lines=ps.stdout.readlines()
+  ps=subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)
+  stdout,_=ps.communicate()
+  lines=stdout.decode().splitlines()
   if (len(lines))<22:
     _CleanupFiles(tmp_dir)
     raise RuntimeError("tmalign superposition failed")
@@ -162,10 +161,9 @@ def _RunTmScore(tmscore, tmp_dir):
     tmscore_path=settings.Locate('tmscore', explicit_file_name=tmscore)
     command="\"%s\" \"%s\" \"%s\"" % (tmscore_path, model1_filename, 
                                       model2_filename)
-  ps=subprocess.Popen(command, shell=True, stdout=subprocess.PIPE,
-                      universal_newlines=True)
-  ps.wait()
-  lines=ps.stdout.readlines()
+  ps=subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)
+  stdout,_=ps.communicate()
+  lines=stdout.decode().splitlines()
   if (len(lines))<22:
     _CleanupFiles(tmp_dir)
     raise RuntimeError("tmscore superposition failed")