2016-05-19 28 views
10

Nel mio caso ho incorporato Python nella mia applicazione. Quando il percorso della mia applicazione contiene un carattere non latin-1 Py_Initialize chiamate exit (1) internamente (ulteriori informazioni successivamente).Python con percorso PYTHONHOME non latin-1

Quindi ho controllato se è possibile riprodurre questo con l'eseguibile dell'interprete standard.

Python-2.7.x su Windows non sembra funzionare quando il percorso di PYTHONHOME contiene un carattere al di fuori del set di caratteri latin-1. Il problema è che il modulo del sito non è stato trovato e importato. Dal momento che le dieresi sembrano funzionare, qual è il vero limite qui? È supportato solo Latin-1? Perché funziona su OSX allora?

C:\Users\ъ\Python27\python.exe // fails to start (KOI8-R) 
     ^
C:\Users\ġ\Python27\python.exe // fails to start (latin-3) 
     ^
C:\Users\ä\Python27\python.exe // works fine (latin-1) 
     ^

Qualche idea?

Background:

Non ho fatto un passo attraverso il codice ancora, ma Python 2.6 e Python 2.7 anche comportarsi in modo diverso quando sito non è disponibile. Py 2.6 stampa semplicemente un messaggio, Py 2.7 rifiuta di iniziare.

static void 
initsite(void) 
{ 
    PyObject *m; 
    m = PyImport_ImportModule("site"); 
    if (m == NULL) { 
     ... 

     // Python 2.7 and later 
     exit(1); 

     // Python 2.6 and prior 
     PyFile_WriteString("'import site' failed; traceback:\n", f); 
    } 
    ... 
} 

pitone 2,7: https://github.com/enthought/Python-2.7.3/blob/master/Python/pythonrun.c#L725

pitone 2.6: https://github.com/python-git/python/blob/master/Python/pythonrun.c#L705

+1

Hai provato a usare Python 3, invece? Hanno ridimensionato la gestione Unicode, ed è molto più pulito. La mia raccomandazione è in realtà di usare 3 ogni volta che puoi, e 2 solo se devi. –

+0

In Python 3 (dovrebbe) funzionare/i, sì. Devo stare con Python 2 perché questa è la versione che abbiamo incorporato nel nostro software, ma questo cambierà in futuro. – HelloWorld

+0

Puoi approfondire come hai "incorporato" Python nella tua app? chiamandolo da C/C++? qual è il meccanismo che usi? E hai impostato il PYTHONHOME? se sì, come lo si imposta? Come nota a margine, il comportamento di OS FS rispetto ai percorsi unicode varia un po 'su Windows, Mac e Linux/POSIX. E il modo di affrontare questo in CPython 2 ha bisogno di un po 'di giocherellare a volte ... Anche se ho lottato con esso alcune volte con successo –

risposta

2

Credo che il problema è che internamente, python2 elabora tutto come stringhe di byte nella codifica sistema piattaforma che è (in Europa occidentale) CP1252 una variante di Latin-1. Così ther è una sorpresa che non può elaborare correttamente un percorso PYTHONHOME contenente altri personaggi

Ma, quando ero più giovane, ero abituato al buon vecchio 8.3 formato dei file di MS/DOS ...

posso ancora vedere (e usarli) in una scatola di Windows 7 con DIR /X in una finestra di console (CMD.EXE). Questo formato usa solo caratteri maiuscoli ASCII e tilda (~), quindi può essere usato come soluzione temporanea: basta dichiarare il percorso 8.3 nella variabile d'ambiente PYTHONHOME e avviare python con quel percorso 8.3.

BTW, è consigliabile che PYTHONHOME utilizzi un percorso che non contenga caratteri speciali, spazi di nore.Potrebbe funzionare, ma potrebbe causare problemi con altri moduli

+1

Sarei totalmente d'accordo sul fatto che funzionerebbe su un Windows russo perché avere la codepage di sistema corrispondente (supponiamo che sia CP125 ** 1 **). Ma lì fallisce pure. – HelloWorld

+0

Solo per completezza: la codepage della console è 866 per un sistema operativo russo – HelloWorld

+0

Se mancano 8,3 nomi, verificare se sono disabilitati: 'query comportamento fsutil Disable8dot3 C:'. Si noti che l'attivazione dei nomi 8.3 avrà effetto solo sui nuovi file creati successivamente, non sui file esistenti. Si potrebbe anche provare a usare 'mklink' per creare un hard link solo ASCII, un collegamento simbolico o una giunzione. – eryksun

2

Guardando il PyImport_ImportModule function version 2.7 dà questa definizione:

PyObject * 
PyImport_ImportModule(const char *name) 
{ 
    PyObject *pname; 
    PyObject *result; 

    pname = PyString_FromString(name); 
    if (pname == NULL) 
     return NULL; 
    result = PyImport_Import(pname); 
    Py_DECREF(pname); 
    return result; 
} 

Guardando il PyImport_ImportModule function version 3.5 dà lo stesso se non con

pname = PyUnicode_FromString(name); 

invece di

pname = PyString_FromString(name); 

Puoi guardare un t the code for PyString_FromString e the code for PyUnicode_FromString ma sembra chiaro che Python 2 non usi Unicode e Python 3, ma non sono stato in grado di scoprire come/dove esattamente ciò porta al comportamento che descrivi.

L'PyImport_Import(module_name) function (version 2.7) utilizza solo module_name in questo modo:

r = PyObject_CallFunction(import, "OOOOi", module_name, globals, 
          globals, silly_list, 0, NULL); 

passando la responsabilità ...

+0

Solo alcuni aspetti FYI: Python 2 fa Unicode, ma la gestione Unicode è stata completamente rifatta per Python 3. Python 2 usava un metodo di decodifica "best guess", e se indovinava male, si scatenava l'inferno. Python 3 tratta le stringhe Uncode come stringhe e codifica Unicode come array di byte, costringendoti a gestire esplicitamente la conversione se necessario. –

+0

Mi aspetto che il problema si sia verificato da qualche parte in ** PyImport_Import **. Immagino che la ricerca di directory con caratteri Unicode nel loro percorso fallisca. Come accennato, non ho eseguito il debug però. Almeno latin-1 è ancora supportato in questa fase. – HelloWorld