GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Generate vectorcall code to parse arguments using Argument Clinic · Issue #87613 · python/cpython

Generate vectorcall code to parse arguments using Argument Clinic #87613

New issue
Copy link
New issue
Copy link
Open
Open
Generate vectorcall code to parse arguments using Argument Clinic#87613
Copy link
Assignees
corona10
Labels
interpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)performancePerformance or resource usagePerformance or resource usagetopic-C-APItopic-argument-clinictype-featureA feature request or enhancementA feature request or enhancement

Description

@vstinner
vstinner
opened on Mar 9, 2021
Issue body actions
BPO 43447
Nosy @vstinner, @serhiy-storchaka, @corona10, @erlend-aasland, @kumaraditya303

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 = 'https://github.com/corona10'
closed_at = None
created_at = <Date 2021-03-09.11:34:23.944>
labels = ['expert-C-API', '3.10']
title = 'Generate vectorcall code to parse arguments using Argument Clinic'
updated_at = <Date 2022-03-06.09:38:05.594>
user = 'https://github.com/vstinner'

bugs.python.org fields:

activity = <Date 2022-03-06.09:38:05.594>
actor = 'kumaraditya'
assignee = 'corona10'
closed = False
closed_date = None
closer = None
components = ['C API']
creation = <Date 2021-03-09.11:34:23.944>
creator = 'vstinner'
dependencies = []
files = []
hgrepos = []
issue_num = 43447
keywords = []
message_count = 2.0
messages = ['388354', '389214']
nosy_count = 5.0
nosy_names = ['vstinner', 'serhiy.storchaka', 'corona10', 'erlendaasland', 'kumaraditya']
pr_nums = []
priority = 'normal'
resolution = None
stage = None
status = 'open'
superseder = None
type = None
url = 'https://bugs.python.org/issue43447'
versions = ['Python 3.10']

Linked PRs

  • gh-87613: Argument Clinic vectorcall decorator #145381
  • gh-87613: Use the AC vectorcall for float #158199
  • gh-87613: Use AC vectorcall for float #158201
  • gh-87613: Use AC vectorcall for bytes and bytearray #158891
  • gh-87613: Use AC vectorcall for weakref.ref() #159470
  • gh-87613: Use AC vectorcall for slice() #159471
  • gh-87613: Allow Argument Clinic vectorcall on heap types #160115
  • gh-87613: Use AC and AC vectorcall for bool #160791
  • gh-87613: Use AC and AC vectorcall for filter #160792
  • gh-87613: Name the subclass in Argument Clinic __new__ argument errors #160799
  • gh-87613: Use AC VC for io.BytesIO #160855
  • gh-87613: Reject deprecated parameters in AC VC #160857
  • gh-87613: AC VC add support for *args and use it for zip #160944
  • gh-87613: Pass NULL for an empty **kwargs in Argument Clinic #161382
  • gh-87613: Supprt **kwargs in AC VC and use for xml.etree.ElementTree.Element #161597

Activity

Next
  1. vstinner commented on Mar 9, 2021

    @vstinner
    vstinner
    on Mar 9, 2021
    MemberAuthor
    More actions

    To optimize the creation of objects, a lot of "tp_new" methods are defined twice: once in the legacy way (tp_new slot), once with the new VECTORCALL calling convention (tp_vectorcall slot). My concern is that the VECTORCALL implementation copy/paste most of the code just to parse arguments, whereas the specific code is just a few lines.

    Example with the float type constructor:
    --------------

    static PyObject *
    float_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
    {
        PyObject *return_value = NULL;
        PyObject *x = NULL;
    
        if ((type == &PyFloat_Type) &&
            !_PyArg_NoKeywords("float", kwargs)) {
            goto exit;
        }
        if (!_PyArg_CheckPositional("float", PyTuple_GET_SIZE(args), 0, 1)) {
            goto exit;
        }
        if (PyTuple_GET_SIZE(args) < 1) {
            goto skip_optional;
        }
        x = PyTuple_GET_ITEM(args, 0);
    skip_optional:
        return_value = float_new_impl(type, x);
    
    exit:
        return return_value;
    }
    
    /*[clinic input]
    @classmethod
    float.\_\_new__ as float_new
        x: object(c_default="NULL") = 0
        /
    
    Convert a string or number to a floating point number, if possible.
    [clinic start generated code]*/
    
    static PyObject *
    float_new_impl(PyTypeObject *type, PyObject *x)
    /*[clinic end generated code: output=ccf1e8dc460ba6ba input=f43661b7de03e9d8]*/
    {
        if (type != &PyFloat_Type) {
            if (x == NULL) {
                x = _PyLong_GetZero();
            }
            return float_subtype_new(type, x); /* Wimp out */
        }
    
        if (x == NULL) {
            return PyFloat_FromDouble(0.0);
        }
        /* If it's a string, but not a string subclass, use
           PyFloat_FromString. */
        if (PyUnicode_CheckExact(x))
            return PyFloat_FromString(x);
        return PyNumber_Float(x);
    }
    
    static PyObject *
    float_vectorcall(PyObject *type, PyObject * const*args,
                     size_t nargsf, PyObject *kwnames)
    {
        if (!_PyArg_NoKwnames("float", kwnames)) {
            return NULL;
        }
    
        Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
        if (!_PyArg_CheckPositional("float", nargs, 0, 1)) {
            return NULL;
        }
    
        PyObject *x = nargs >= 1 ? args[0] : NULL;
        return float_new_impl((PyTypeObject *)type, x);
    }

    Here the float_new() function (tp_new slot) is implemented with Argument Clinic: float_new() C code is generated from the [clinic input] DSL: good!

    My concern is that float_vectorcall() code is hand written, it's boring to write and boring to maintain.

    Would it be possible to add a new [clinic input] DSL for vectorcall? I expect something like that:
    --------------

    static PyObject *
    float_vectorcall(PyObject *type, PyObject * const*args,
                     size_t nargsf, PyObject *kwnames)
    {
        if (!_PyArg_NoKwnames("float", kwnames)) {
            return NULL;
        }
    
        Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
        if (!_PyArg_CheckPositional("float", nargs, 0, 1)) {
            return NULL;
        }
    
        PyObject *x = nargs >= 1 ? args[0] : NULL;
        return float_vectorcall_impl(type, x);
    }
    
    static PyObject *
    float_vectorcall_impl(PyObject *type, PyObject *x)
    {
        return float_new_impl((PyTypeObject *)type, x);
    }

    where float_vectorcall() C code would be generated, and float_vectorcall_impl() would be the only part written manually. float_vectorcall_impl() gets a clean API and its body is way simpler to write and to maintain!

  2. vstinner
    added
    3.10 (EOL)end of lifeend of life
    topic-C-API
    on Mar 9, 2021
  3. corona10 commented on Mar 21, 2021

    @corona10
    corona10
    on Mar 21, 2021
    Member
    More actions

    I agree with we should update AC to generate vectorcall.
    I am going to investigate what we can :)

  4. corona10
    assigned
    corona10
    on Apr 6, 2021
  5. ezio-melotti
    transferred this issue fromon Apr 10, 2022
  6. serhiy-storchaka
    added
    topic-argument-clinic
    on Apr 30, 2022
  7. vstinner commented on Nov 3, 2022

    @vstinner
    vstinner
    on Nov 3, 2022
    MemberAuthor
    More actions

    I don't have the bandwidth to work on this issue, so I just close it.

  8. vstinner
    closed this as completedon Nov 3, 2022
  9. erlend-aasland
    reopened this on Aug 17, 2023
  10. erlend-aasland
    added
    type-featureA feature request or enhancementA feature request or enhancement
    and removed
    3.10 (EOL)end of lifeend of life
    on Aug 17, 2023
  11. 93 remaining items

  12. cmaloney
    added 7 commits that reference this issue on Oct 28, 2026

    pythongh-87613: Reuse the positional parser for AC **kwargs

    32e22af

    pythongh-87613: Merge the inline AC vectorcall paths

    027746f

    pythongh-87613: Pick the AC **kwargs no-positional check with the con…

    9845c78

    pythongh-87613: Declare the AC keyword parser locals in the conventio…

    2e4eff2

    pythongh-87613: Warn on deprecated keywords passed to an AC vectorcall

    4999b50

    pythongh-87613: Build the AC @vectorcall **kwargs dict inline

    2b204b1

    pythongh-87613: zip: Drop tuplesize local

    607ad5a
  13. kumaraditya303
    added a commit that references this issue on Oct 31, 2026

    gh-87613: Use AC vectorcall for slice() (#159471)

    07db3e9
  14. eendebakpt
    added a commit that references this issue on Nov 1, 2026

    gh-87613: Use AC and AC vectorcall for bool (#160791)

    a7c0383
  15. cmaloney
    added 6 commits that reference this issue on Nov 3, 2026

    gh-87613: AC VC add support for *args and use it for zip (#160944)

    6d31270

    gh-87613: Use AC and AC vectorcall for filter (#160792)

    7e3290d

    gh-87613: Pass NULL for an empty **kwargs in Argument Clinic (#161382)

    9ea60a5

    pythongh-87613: Use Argument Clinic vectorcall for xml.etree.ElementT…

    0f32147

    pythongh-87613: Check the attrib copy explicitly in get_attrib_from_k…

    e49ac09

    gh-87613: Use AC VC for io.BytesIO (#160855)

    61fdee3
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

  • @corona10
    corona10

Labels

interpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)performancePerformance or resource usagePerformance or resource usagetopic-C-APItopic-argument-clinictype-featureA feature request or enhancementA feature request or enhancement

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

    You are visitor 01402503 — GeezerVison does not store the pages you look up.
    Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.