Путь Python с не-латинским-1 PYTHONHOME

В моем случае я включил Python в свое приложение. Когда путь моего приложения содержит символ не-латинского-1, Py_Initialize вызывает exit (1) внутри (дополнительная информация позже).

Итак, я проверил, может ли это воспроизвести с помощью стандартного исполняемого файла интерпретатора.

Python-2.7.x на Windows, похоже, не работает, когда путь PYTHONHOME содержит символ за пределами латинской кодировки. Проблема в том, что сайт модуля не может быть найден и импортирован. Поскольку умлауты, похоже, работают, каково фактическое ограничение здесь? Поддерживается ли только латинский-1? Почему он работает на OSX?

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

Любые идеи?

Фон:

Я еще не прошел код, но Python 2.6 и Python 2.7 также ведут себя по-разному, когда сайт недоступен. Py 2.6 просто печатает сообщение, Py 2.7 отклоняется для запуска.

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);
    }
    ...
}

Python 2.7: https://github.com/enthought/Python-2.7.3/blob/master/Python/pythonrun.c#L725

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

Ответ 1

Я думаю, что проблема в том, что внутри Python2 обрабатывает все как байтовые строки в кодировке платформы, которая является (в западной Европе) CP1252 вариантом латинского-1. Поэтому не удивительно, что он не может правильно обработать путь PYTHONHOME, содержащий другие символы

Но, когда я был моложе, я привык к добрым старым 8.3 форматам файлов MS/DOS...

Я все еще вижу (и использую их) в окне Windows 7 с DIR /X в окне консоли (CMD.EXE). Этот формат использует только символы верхнего регистра ASCII и tilda (~), поэтому его можно использовать в качестве обходного пути: просто объявите путь 8.3 в переменной окружения PYTHONHOME и запустите python с этим пулом 8.3.

Кстати, для PYTHONHOME рекомендуется использовать путь, который не содержит ни специальных символов, ни пространственных пространств. Он может работать, но это может вызвать проблемы с другими модулями.

Ответ 2

Глядя на PyImport_ImportModule функция version 2.7 дает следующее определение:

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

При просмотре PyImport_ImportModule функция версия 3.5 дает то же самое, кроме

pname = PyUnicode_FromString(name);

вместо

pname = PyString_FromString(name);

Вы можете посмотреть код PyString_FromString и код для PyUnicode_FromString, но кажется ясным, что python 2 не использует unicode и python 3, но я не смог найти, как/где именно это приводит к описанному вами поведению.

Функция PyImport_Import(module_name) (версия 2.7) использует только module_name так:

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

передача ответственности...