2012-09-03 6 views
9

Betrachten Sie dieses Beispiel:Warum schlägt Popen unter Windows fehl, wenn der Parameter "env" ein Unicode-Objekt enthält?

>>> import subprocess as sp 
>>> sp.Popen("notepad2.exe",env={"PATH":"C:\\users\\guillermo\\smallapps\\bin"}) 
<subprocess.Popen object at 0x030DF430> 
>>> sp.Popen("notepad2.exe",env={"PATH":u"C:\\users\\guillermo\\smallapps\\bin"}) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "C:\Python26\lib\subprocess.py", line 633, in __init__ 
    errread, errwrite) 
File "C:\Python26\lib\subprocess.py", line 842, in _execute_child 
    startupinfo) 
TypeError: environment can only contain strings 

Ich habe den Fehler zu dieser CPython Code zurückverfolgt:

http://hg.python.org/cpython/file/ca54c27a9045/Modules/_winapi.c#l511

ich nicht in der Lage bin zu udnerstand was PyUnicode_Check tut, aber:

http://hg.python.org/cpython/file/26af48f65ef3/Objects/unicodeobject.c#l73

+0

So schlagen Sie mit python 3 wird diesen Fehler Bitte Beratung lösen. Da ich auch diesem Problem gegenüberstehe https://github.com/django-dbbackup/django-dbbackup/issues/147 –

Antwort

11

Wie die Fehlermeldung sagt, die Umwelt t muss nur Zeichenfolgen enthalten. Ihr erster Popen-Aufruf erfüllt diese Bedingung, der zweite jedoch nicht, weil Sie PATH einem Unicode-Objekt zuordnen, das mit der u"..."-Syntax erstellt wurde. Verwenden Sie nur Byte-Strings, wenn Sie die Umgebungsdiagramme Popen angeben, und Sie erhalten diesen Fehler nicht.

Beachten Sie, dass Sie mit dem Python 2.6 arbeiten, so dass der verknüpfte Code nicht tatsächlich gilt, da er von Python 3.3.0 beta2 stammt. PyUnicode_Check überprüft, ob das Objekt ein Unicode-Objekt ist, was in Python 3 Sinn macht, wo die Zeichenfolgen (intern als Unicode-Objekte implementiert) sind. In Python 2.6 verwendet the equivalent line jedoch PyString_Check, wodurch es in Ihrem zweiten Beispiel fehlschlagen würde.

0

Ich hatte eine ähnliche Situation, wenn jupyter Kernel für pyspark konfiguriert: die kernel.json wird als Unicode gelesen und dann verpackt ** Kwargs an Proc = Popen (cmd, ** Kwargs) in der C: \ Anaconda2 übergeben \ Lib \ site-packages \ jupyter_client \ launcher.py

Daher hatte ich die launcher.py wie folgt zu ändern:

try: 
     # Ihor Bobak: fix to convert all env keys and values to str 
     klist = kwargs['env'].keys()[:] 
     for key in klist: 
      value = kwargs['env'][key] 
      if isinstance(key, unicode) or isinstance(value, unicode): 
       newkey = key.encode('ascii','ignore') 
       newvalue = value.encode('ascii','ignore') 
       del kwargs['env'][key] 
       kwargs['env'][newkey] = newvalue 
     # regular code 
     proc = Popen(cmd, **kwargs) 
    except Exception as exc: 
     msg = (
      "Failed to run command:\n{}\n" 
      " PATH={!r}\n" 
      " with kwargs:\n{!r}\n" 
     ) 
Verwandte Themen