Skip to content

Argument Clinic does not increase NoneType refcount when returning NoneType from a function with no parameters #95007

Description

@noamcohen97

Bug report

/*[clinic input]
function -> NoneType
[clinic start generated code]*/

will produce this function:

static PyObject *
function(PyObject *module, PyObject *Py_UNUSED(ignored))
{
    return function_impl(module);
}

while function_impl returns Py_None (as it should, if using NoneType return converter), refcount is not increased.

here is a working example of NoneType return converter:

/*[clinic input]
function -> NoneType

    a: int
    /
[clinic start generated code]*/
static PyObject *
function(PyObject *module, PyObject *arg)
{
    PyObject *return_value = NULL;
    int a;
    PyObject *_return_value;

    a = _PyLong_AsInt(arg);
    if (a == -1 && PyErr_Occurred()) {
        goto exit;
    }
    _return_value = function_impl(module, a);
    if (_return_value != Py_None) {
        goto exit;
    }
    return_value = Py_None;
    Py_INCREF(Py_None);

exit:
    return return_value;
}

Generation also fails when generating a function with a single object parameter.

It seems like the problem is with default_return_converter in clinic.py, being set to True

Activity

  1. added a commit that references this issue on Jul 19, 2022
  2. serhiy-storchaka commented on Jul 19, 2022

    @serhiy-storchaka
    Member

    Good catch. This converter is not used, so the bug was not exposed. And since it has dubious semantic (requires returning a weak reference to None on success), I think that it is better to remove it.

  3. noamcohen97 commented on Jul 19, 2022

    @noamcohen97
    ContributorAuthor

    How about we'll get rid of the callback return value, and use PyErr_Occurred() to chose whether to return NULL or Py_None?

  4. arhadthedev commented on Jul 19, 2022

    @arhadthedev
    Member

    How about we'll get rid of the callback return value, and use PyErr_Occurred() to chose whether to return NULL or Py_None?

    When I did the same in gh-91284, I found that PyErr_Occurred takes GIL. Currently (until nogil is implemented, at least) it's cheaper to deal with PyErr_Occurred only on NULL returned from a callback.

  5. added a commit that references this issue on Jul 20, 2022
  6. added a commit that references this issue on Aug 1, 2022
  7. added a commit that references this issue on Sep 13, 2023
  8. added a commit that references this issue on Sep 26, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions