Popen.communicate () lanza UnicodeDecodeError

Tengo este codigo

def __executeCommand(self, command: str, input: str = None) -> str: p = sub.Popen(command, stdout=sub.PIPE, stderr=sub.PIPE, stdin=sub.PIPE, universal_newlines=True) p.stdin.write(input) output, error = p.communicate() if (len(errors) > 0): raise EnvironmentError("Could not generate the key: " + error) elif (p.returncode != 0): raise EnvironmentError("Could not generate the key. Return Value: " + p.returncode) return output 

Y obtengo un error UnicodeDecode en la línea de output, error = p.communicate() :

 Traceback (most recent call last): File "C:\Python34\lib\threading.py", line 921, in _bootstrap_inner self.run() File "C:\Python34\lib\threading.py", line 869, in run self._target(*self._args, **self._kwargs) File "C:\Python34\lib\subprocess.py", line 1170, in _readerthread buffer.append(fh.read()) File "C:\Python34\lib\encodings\cp1252.py", line 23, in decode return codecs.charmap_decode(input,self.errors,decoding_table)[0] UnicodeDecodeError: 'charmap' codec can't decode byte 0x81 in position 27: character maps to  

¿Cómo puedo arreglar esto?

univeral_newlines=True habilita el modo de texto. La salida de subproceso (bytes) se decodifica utilizando la encoding de caracteres locale.getpreferredencoding(False) como se menciona en @cdosborn .

Si no funciona, proporcione la encoding real que utiliza el command . Y / o especifique el controlador de errores como 'ignore' , 'surrogateescape' , etc. como parámetro de errors :

 from subprocess import Popen, PIPE def __executeCommand(self, command: str, input: str = None, encoding=None, errors='strict') -> str: text_mode = (encoding is None) with Popen(command, stdout=PIPE, stderr=PIPE, stdin=PIPE, universal_newlines=text_mode) as p: if input is not None and not text_mode: input = input.encode(encoding, errors) # convert to bytes output, err = p.communicate(input) if err or p.returncode != 0: raise EnvironmentError("Could not generate the key. " "Error: {}, Return Value: {}".format( ascii(err), p.returncode)) return output if text_mode else output.decode(encoding, errors) 

La configuración universal_newlines=true da como resultado una encoding adicional que es la fuente de su error.

 def __executeCommand(self, command: str, input: str = None) -> str: p = sub.Popen(command, stdout=sub.PIPE, stderr=sub.PIPE, stdin=sub.PIPE) output, error = p.communicate(input) if (len(errors) > 0): raise EnvironmentError("Could not generate the key: " + error) elif (p.returncode != 0): raise EnvironmentError("Could not generate the key. Return Value: " + p.returncode) return output 

universal_newlines=true da como resultado una encoding basada en la salida de:

python -c 'import locale; print locale.getpreferredencoding()'

Python lanzó un error cuando esperaba que su entrada coincidiera con la encoding anterior, pero en su lugar procesó un byte claramente en una encoding diferente.

Más información sobre python 3.4 universal_newlines aquí .

Si está utilizando Python 3.6 o posterior, puede corregir el error cambiando esta línea:

 p = sub.Popen(command, stdout=sub.PIPE, stderr=sub.PIPE, stdin=sub.PIPE, universal_newlines=True) 

a esto:

 p = sub.Popen(command, stdout=sub.PIPE, stderr=sub.PIPE, stdin=sub.PIPE, encoding="utf-8", universal_newlines=True) 

Usé UTF-8 arriba, pero puedes sustituirlo con cualquier encoding que necesites.