Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhance Argument Clinic's NoneType return converter to give void #91284

Closed
arhadthedev opened this issue Mar 26, 2022 · 6 comments
Closed

Enhance Argument Clinic's NoneType return converter to give void #91284

arhadthedev opened this issue Mar 26, 2022 · 6 comments
Labels
3.11 only security fixes topic-argument-clinic type-feature A feature request or enhancement

Comments

@arhadthedev
Copy link
Member

BPO 47128
Nosy @larryhastings, @serhiy-storchaka, @arhadthedev
PRs
  • bpo-47128: Enhance Argument Clinic's NoneType return converter to give void #32126
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields:

    assignee = None
    closed_at = <Date 2022-03-27.06:26:32.947>
    created_at = <Date 2022-03-26.12:59:28.016>
    labels = ['type-feature', 'expert-argument-clinic', '3.11']
    title = "Enhance Argument Clinic's NoneType return converter to give `void`"
    updated_at = <Date 2022-03-28.07:34:15.520>
    user = 'https://github.com/arhadthedev'

    bugs.python.org fields:

    activity = <Date 2022-03-28.07:34:15.520>
    actor = 'arhadthedev'
    assignee = 'none'
    closed = True
    closed_date = <Date 2022-03-27.06:26:32.947>
    closer = 'serhiy.storchaka'
    components = ['Argument Clinic']
    creation = <Date 2022-03-26.12:59:28.016>
    creator = 'arhadthedev'
    dependencies = []
    files = []
    hgrepos = []
    issue_num = 47128
    keywords = ['patch']
    message_count = 5.0
    messages = ['416062', '416064', '416066', '416104', '416147']
    nosy_count = 3.0
    nosy_names = ['larry', 'serhiy.storchaka', 'arhadthedev']
    pr_nums = ['32126']
    priority = 'normal'
    resolution = 'rejected'
    stage = 'resolved'
    status = 'closed'
    superseder = None
    type = 'enhancement'
    url = 'https://bugs.python.org/issue47128'
    versions = ['Python 3.11']

    @arhadthedev
    Copy link
    Member Author

    The attached PR makes the following possible (note that the impl has a void return type):

    /*[clinic input]
    _io._IOBase.writelines -> NoneType
        lines: object
        /
    [clinic start generated code]*/
    
        static void
        _io__IOBase_writelines_impl(PyObject *self, PyObject *lines)
        /*[clinic end generated code: output=f3feca36db72dbd1 input=286ba711cb7291ad]*/

    Previously, the return type would be Object * with generated replacement of non-Py_None values to NULL on the other side.

    So now there is no need to track whether NULL or Py_None should be returned. Or should it be Py_RETURN_NONE? Argument Clinic does it by itself returning NULL on errors and PyNone otherwise:

        static PyObject *
        _io__IOBase_writelines(PyObject *self, PyObject *lines)
        {
            PyObject *return_value = NULL;
    
            _io__IOBase_writelines_impl(self, lines);
            if (PyErr_Occurred()) {
                goto exit;
            }
            return_value = Py_None;
            Py_INCREF(Py_None);
    
        exit:
            return return_value;
        }

    @arhadthedev arhadthedev added 3.11 only security fixes topic-argument-clinic type-feature A feature request or enhancement labels Mar 26, 2022
    @serhiy-storchaka
    Copy link
    Member

    The function should return different values for success and error. Functions which do not do this have bad design.

    @arhadthedev
    Copy link
    Member Author

    The function should return different values for success and error

    It does, and a void return type enforces it. Here is the trick:

    An important convention throughout the Python interpreter is the following: when a function fails, it should set an exception condition and return an error value (usually -1 or a NULL pointer).

    Previously, a function could return NULL but forget to call PyErr_*(). With void, however, the function has no other choise but to properly set the error indicator so the Clinic's part will see it and return NULL finishing the convention.

    @serhiy-storchaka
    Copy link
    Member

    It is simpler and faster to return NULL than call PyErr_Occurred(). There is a special macro PY_RETURN_NONE, so there is no problem with returning None either.

    I do not think it would make the code better.

    @arhadthedev
    Copy link
    Member Author

    Actually, you're right. For now, PyErr_Occurred is a GIL lock plus a memory access. While the access is cheap because of a L1 cache hit, the GIL takes its toll in a hot path.

    So I'm closing the PR until GIL removal is done so no performance penalty will be imposed.

    I could use _PyErr_Occurred because "Currently Argument Clinic is considered internal-only for CPython", but it requires extra modifications of the clinic that is undesirable.

    @arhadthedev
    Copy link
    Member Author

    arhadthedev commented Jul 20, 2022

    So I'm closing the PR until GIL removal is done so no performance penalty will be imposed.

    Not relevant anymore; see #32126 (comment).

    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    3.11 only security fixes topic-argument-clinic type-feature A feature request or enhancement
    Projects
    None yet
    Development

    No branches or pull requests

    2 participants