2012-09-03 5 views
9

Rozważmy następujący przykład:Dlaczego funkcja Popen ulega awarii w systemie Windows, jeśli parametr "env" zawiera obiekt Unicode?

>>> 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 

Mam sięgają błąd do tego kodu CPython:

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

jestem w stanie udnerstand co PyUnicode_Check robi, choć:

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

+0

Więc sugerujesz przy użyciu Pythona 3 będzie rozwiązać ten problem Proszę o poradę. Ponieważ jestem zbyt zajęty tym problemem https://github.com/django-dbbackup/django-dbbackup/issues/147 –

Odpowiedz

11

Jak informuje komunikat o błędzie, środowisko t może zawierać tylko ciągi. Twoje pierwsze wywołanie Popen spełnia ten warunek, ale drugie nie, ponieważ odwzorowujesz PATH na obiekt Unicode utworzony przy użyciu składni u"...". Używaj tylko ciągów bajtów, gdy udostępniasz dyktowanie środowiska do Popen i nie otrzymasz tego błędu.

Pamiętaj, że sądząc po systemie śledzenia, używasz Pythona 2.6, więc kod połączony nie ma zastosowania, ponieważ pochodzi z Python 3.3.0 beta2. PyUnicode_Check sprawdza, czy obiekt jest obiektem unicode, co ma sens w Pythonie 3, gdzie łańcuchy (wewnętrznie zaimplementowane jako) obiekty Unicode. W Pythonie 2.6 jednak the equivalent line używa PyString_Check, co spowodowałoby niepowodzenie w drugim przykładzie.

0

Miałem podobną sytuację, gdy skonfigurowałem jądro jupytera dla pyspark: kernel.json jest odczytywany jako unicode, a następnie pakowany do ** kwargs przekazany do proc = Popen (cmd, ** kwargs) w C: \ Anaconda2 \ Lib \ site-packages \ jupyter_client \ launcher.py

Dlatego musiałem zmodyfikować launcher.py takiego:

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" 
     ) 
Powiązane problemy