2017-02-13 1 views
1

говорит это только о PyModule_Create: функция инициализацииЯвляется ли PyObject * возвращенным PyModule_Create «заимствованным» или «приобретенным»?

Модуль может создать и вернуть объект модуля непосредственно. Это называется «инициализацией однофазной», и использует одну из следующих двух функций модуля создания:

PyObject* PyModule_Create(PyModuleDef *def)

  • Создать новый объект модуля, учитывая определение в четкости. Это ведет себя как PyModule_Create2() с module_api_version установлено в PYTHON_API_VERSION.
  • ...

Перед тем как он будет возвращен из в функции инициализации, результирующий объект модуль обычно заполняется с использованием функций, таких как PyModule_AddObject().

Также PyModule_Create нет в списке от this question. Это предполагает, что соблюдается обычное поведение, а именно, как ожидается, вызывающий абонент «получит» ссылку на возвращаемый PyObject*.

Но все же из этого блога python3porting поста, он имеет следующий пример: «линия А»

static PyObject * 
moduleinit(void) 
{ 
    MOD_DEF(m, "themodulename", 
      "This is the module docstring", 
    module_methods) 

    if (m == NULL) 
     return NULL; 

    if (PyModule_AddObject(m, "hookable", 
     (PyObject *)&hookabletype) < 0) 
     return NULL;       /* line A */ 

    return m; 
} 

бы не просочиться ссылку для этого кода пути? Какова правильная семантика использования и собственности PyModule_Create?

ответ

4

Этот фрагмент кода просто не правильно управляет ссылками. Помимо обнаруженной утечки, она также забывает Py_INCREF(&hookabletype), несмотря на то, что PyModule_AddObject steals a reference to the value.

Как обычно, если не указано иное, PyModule_Create возвращает новую ссылку, а не заимствованную ссылку.

+0

хорошо, это имеет смысл. Поэтому в случае, когда вам нужно сигнализировать ошибку загрузки модуля *, но * 'PyModule_Create' уже удалось, требуется' Py_DECREF (m) '? – greatwolf

+0

@ greatwolf: Да. – user2357112

Смежные вопросы