Как я узнаю, почему импорт не удался с PyImportModule? - PullRequest
4 голосов
/ 09 июня 2011

У меня есть этот код в приложении C, которое встраивает Python (2.7.1):

{
PyObject *user_dict;
PyObject *user_func;
PyObject *result;
PyObject *header_tuple;
PyObject *original_recipients;
PyObject *working_recipients;

if (!Py_IsInitialized())
    {
    Py_Initialize();
    }

if (!expy_exim_dict)
    {
    PyObject *module = Py_InitModule(expy_exim_module, expy_exim_methods); /* Borrowed reference */
    Py_INCREF(module);                                 /* convert to New reference */
    expy_exim_dict = PyModule_GetDict(module);         /* Borrowed reference */
    Py_INCREF(expy_exim_dict);                         /* convert to New reference */
    }

if (!expy_user_module)
    {
    if (expy_path_add)
        {
        PyObject *sys_module;
        PyObject *sys_dict;
        PyObject *sys_path;
        PyObject *add_value;

        sys_module = PyImport_ImportModule("sys");  /* New Reference */
        if (!sys_module)
            {
            PyErr_Clear();
            *return_text = "Internal error, can't import Python sys module";
            log_write(0, LOG_REJECT, "Couldn't import Python 'sys' module");
            return PYTHON_FAILURE_RETURN;
            }

        sys_dict = PyModule_GetDict(sys_module);               /* Borrowed Reference, never fails */
        sys_path = PyMapping_GetItemString(sys_dict, "path");  /* New reference */

        if (!sys_path || (!PyList_Check(sys_path)))
            {
            PyErr_Clear();  /* in case sys_path was NULL, harmless otherwise */
            *return_text = "Internal error, sys.path doesn't exist or isn't a list";
            log_write(0, LOG_REJECT, "expy: Python sys.path doesn't exist or isn't a list");
            return PYTHON_FAILURE_RETURN;
            }

        add_value = PyString_FromString(expy_path_add);  /* New reference */
        if (!add_value)
            {
            PyErr_Clear();
            log_write(0, LOG_PANIC, "expy: Failed to create Python string from [%s]", expy_path_add);
            return PYTHON_FAILURE_RETURN;
            }

        if (PyList_Append(sys_path, add_value))
            {
            PyErr_Clear();
            log_write(0, LOG_PANIC, "expy: Failed to append [%s] to Python sys.path", expy_path_add);
            }

        Py_DECREF(add_value);
        Py_DECREF(sys_path);
        Py_DECREF(sys_module);
        }

    expy_user_module = PyImport_ImportModule(expy_scan_module);  /* New Reference */

    if (!expy_user_module)
        {
        PyErr_Clear();
        /* Handle error */
        }
    }

При сбое PyImport_ImportModule возвращается значение NULL. Как я могу узнать , почему не удалось импортировать? (например, при импорте работ модуля находите вне встраивания).

(Код является частью py-exim-localscan , и я хочу добавить дополнительную информацию о сбоях в тех редких случаях, когда они происходят).

1 Ответ

5 голосов
/ 09 июня 2011

Вы делаете это, глядя на исключение, которое было поднято. В настоящее время вы стираете исключение (это то, что делает PyErr_Clear()). Не делайте этого, а вместо этого распечатываете трассировку или проверяете объект исключения. См. http://docs.python.org/c-api/exceptions.html для получения информации о том, как сделать это из кода C, но обычно лучшая идея - просто позволить распространению исключения.

...