]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
GH-137630: Convert ``_interpqueues`` to use Argument Clinic (#137685)
authorAdam Turner <9087854+AA-Turner@users.noreply.github.com>
Wed, 17 Sep 2025 16:35:00 +0000 (17:35 +0100)
committerGitHub <noreply@github.com>
Wed, 17 Sep 2025 16:35:00 +0000 (17:35 +0100)
Include/internal/pycore_global_objects_fini_generated.h
Include/internal/pycore_global_strings.h
Include/internal/pycore_runtime_init_generated.h
Include/internal/pycore_unicodeobject_generated.h
Modules/_interpqueuesmodule.c
Modules/clinic/_interpqueuesmodule.c.h [new file with mode: 0644]

index 63888eab7b44815220879fc98cc8ff080a1fc7f5..f393537141c076208c34f5a7d262ba251128e1fd 100644 (file)
@@ -933,6 +933,7 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(eager_start));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(effective_ids));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(element_factory));
+    _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(emptyerror));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(encode));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(encoding));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(end));
@@ -958,6 +959,7 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(extra_tokens));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(facility));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(factory));
+    _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(fallback));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(false));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(family));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(fanout));
@@ -990,6 +992,7 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(fromtimestamp));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(fromutc));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(fset));
+    _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(fullerror));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(func));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(future));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(generation));
@@ -1102,6 +1105,7 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(maxevents));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(maxlen));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(maxmem));
+    _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(maxsize));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(maxsplit));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(maxvalue));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(memLevel));
@@ -1200,7 +1204,9 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(protocol));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(ps1));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(ps2));
+    _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(qid));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(query));
+    _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(queuetype));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(quotetabs));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(raw));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(read));
@@ -1326,6 +1332,7 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(tzinfo));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(tzname));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(uid));
+    _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(unboundop));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(unlink));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(unraisablehook));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(updates));
index b863a7c970e3d4ac655121204c789f8d7329ea4d..f4fde6142b9e826346fdaa9dd355da3a3cb9fff1 100644 (file)
@@ -424,6 +424,7 @@ struct _Py_global_strings {
         STRUCT_FOR_ID(eager_start)
         STRUCT_FOR_ID(effective_ids)
         STRUCT_FOR_ID(element_factory)
+        STRUCT_FOR_ID(emptyerror)
         STRUCT_FOR_ID(encode)
         STRUCT_FOR_ID(encoding)
         STRUCT_FOR_ID(end)
@@ -449,6 +450,7 @@ struct _Py_global_strings {
         STRUCT_FOR_ID(extra_tokens)
         STRUCT_FOR_ID(facility)
         STRUCT_FOR_ID(factory)
+        STRUCT_FOR_ID(fallback)
         STRUCT_FOR_ID(false)
         STRUCT_FOR_ID(family)
         STRUCT_FOR_ID(fanout)
@@ -481,6 +483,7 @@ struct _Py_global_strings {
         STRUCT_FOR_ID(fromtimestamp)
         STRUCT_FOR_ID(fromutc)
         STRUCT_FOR_ID(fset)
+        STRUCT_FOR_ID(fullerror)
         STRUCT_FOR_ID(func)
         STRUCT_FOR_ID(future)
         STRUCT_FOR_ID(generation)
@@ -593,6 +596,7 @@ struct _Py_global_strings {
         STRUCT_FOR_ID(maxevents)
         STRUCT_FOR_ID(maxlen)
         STRUCT_FOR_ID(maxmem)
+        STRUCT_FOR_ID(maxsize)
         STRUCT_FOR_ID(maxsplit)
         STRUCT_FOR_ID(maxvalue)
         STRUCT_FOR_ID(memLevel)
@@ -691,7 +695,9 @@ struct _Py_global_strings {
         STRUCT_FOR_ID(protocol)
         STRUCT_FOR_ID(ps1)
         STRUCT_FOR_ID(ps2)
+        STRUCT_FOR_ID(qid)
         STRUCT_FOR_ID(query)
+        STRUCT_FOR_ID(queuetype)
         STRUCT_FOR_ID(quotetabs)
         STRUCT_FOR_ID(raw)
         STRUCT_FOR_ID(read)
@@ -817,6 +823,7 @@ struct _Py_global_strings {
         STRUCT_FOR_ID(tzinfo)
         STRUCT_FOR_ID(tzname)
         STRUCT_FOR_ID(uid)
+        STRUCT_FOR_ID(unboundop)
         STRUCT_FOR_ID(unlink)
         STRUCT_FOR_ID(unraisablehook)
         STRUCT_FOR_ID(updates)
index 3ce7200ffeb6a40a7db00626b83b97fa19dea83c..5c0ec7dd5471150d2fbfe8f45d2c0b3ecdcd7cd8 100644 (file)
@@ -931,6 +931,7 @@ extern "C" {
     INIT_ID(eager_start), \
     INIT_ID(effective_ids), \
     INIT_ID(element_factory), \
+    INIT_ID(emptyerror), \
     INIT_ID(encode), \
     INIT_ID(encoding), \
     INIT_ID(end), \
@@ -956,6 +957,7 @@ extern "C" {
     INIT_ID(extra_tokens), \
     INIT_ID(facility), \
     INIT_ID(factory), \
+    INIT_ID(fallback), \
     INIT_ID(false), \
     INIT_ID(family), \
     INIT_ID(fanout), \
@@ -988,6 +990,7 @@ extern "C" {
     INIT_ID(fromtimestamp), \
     INIT_ID(fromutc), \
     INIT_ID(fset), \
+    INIT_ID(fullerror), \
     INIT_ID(func), \
     INIT_ID(future), \
     INIT_ID(generation), \
@@ -1100,6 +1103,7 @@ extern "C" {
     INIT_ID(maxevents), \
     INIT_ID(maxlen), \
     INIT_ID(maxmem), \
+    INIT_ID(maxsize), \
     INIT_ID(maxsplit), \
     INIT_ID(maxvalue), \
     INIT_ID(memLevel), \
@@ -1198,7 +1202,9 @@ extern "C" {
     INIT_ID(protocol), \
     INIT_ID(ps1), \
     INIT_ID(ps2), \
+    INIT_ID(qid), \
     INIT_ID(query), \
+    INIT_ID(queuetype), \
     INIT_ID(quotetabs), \
     INIT_ID(raw), \
     INIT_ID(read), \
@@ -1324,6 +1330,7 @@ extern "C" {
     INIT_ID(tzinfo), \
     INIT_ID(tzname), \
     INIT_ID(uid), \
+    INIT_ID(unboundop), \
     INIT_ID(unlink), \
     INIT_ID(unraisablehook), \
     INIT_ID(updates), \
index e76e603230a5db9a8d69ca7902e5597b0a5979e6..1a7f1c13c6dd1659c63e8e84c4f9112f7c164a9a 100644 (file)
@@ -1484,6 +1484,10 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
     _PyUnicode_InternStatic(interp, &string);
     assert(_PyUnicode_CheckConsistency(string, 1));
     assert(PyUnicode_GET_LENGTH(string) != 1);
+    string = &_Py_ID(emptyerror);
+    _PyUnicode_InternStatic(interp, &string);
+    assert(_PyUnicode_CheckConsistency(string, 1));
+    assert(PyUnicode_GET_LENGTH(string) != 1);
     string = &_Py_ID(encode);
     _PyUnicode_InternStatic(interp, &string);
     assert(_PyUnicode_CheckConsistency(string, 1));
@@ -1584,6 +1588,10 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
     _PyUnicode_InternStatic(interp, &string);
     assert(_PyUnicode_CheckConsistency(string, 1));
     assert(PyUnicode_GET_LENGTH(string) != 1);
+    string = &_Py_ID(fallback);
+    _PyUnicode_InternStatic(interp, &string);
+    assert(_PyUnicode_CheckConsistency(string, 1));
+    assert(PyUnicode_GET_LENGTH(string) != 1);
     string = &_Py_ID(false);
     _PyUnicode_InternStatic(interp, &string);
     assert(_PyUnicode_CheckConsistency(string, 1));
@@ -1712,6 +1720,10 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
     _PyUnicode_InternStatic(interp, &string);
     assert(_PyUnicode_CheckConsistency(string, 1));
     assert(PyUnicode_GET_LENGTH(string) != 1);
+    string = &_Py_ID(fullerror);
+    _PyUnicode_InternStatic(interp, &string);
+    assert(_PyUnicode_CheckConsistency(string, 1));
+    assert(PyUnicode_GET_LENGTH(string) != 1);
     string = &_Py_ID(func);
     _PyUnicode_InternStatic(interp, &string);
     assert(_PyUnicode_CheckConsistency(string, 1));
@@ -2160,6 +2172,10 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
     _PyUnicode_InternStatic(interp, &string);
     assert(_PyUnicode_CheckConsistency(string, 1));
     assert(PyUnicode_GET_LENGTH(string) != 1);
+    string = &_Py_ID(maxsize);
+    _PyUnicode_InternStatic(interp, &string);
+    assert(_PyUnicode_CheckConsistency(string, 1));
+    assert(PyUnicode_GET_LENGTH(string) != 1);
     string = &_Py_ID(maxsplit);
     _PyUnicode_InternStatic(interp, &string);
     assert(_PyUnicode_CheckConsistency(string, 1));
@@ -2552,10 +2568,18 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
     _PyUnicode_InternStatic(interp, &string);
     assert(_PyUnicode_CheckConsistency(string, 1));
     assert(PyUnicode_GET_LENGTH(string) != 1);
+    string = &_Py_ID(qid);
+    _PyUnicode_InternStatic(interp, &string);
+    assert(_PyUnicode_CheckConsistency(string, 1));
+    assert(PyUnicode_GET_LENGTH(string) != 1);
     string = &_Py_ID(query);
     _PyUnicode_InternStatic(interp, &string);
     assert(_PyUnicode_CheckConsistency(string, 1));
     assert(PyUnicode_GET_LENGTH(string) != 1);
+    string = &_Py_ID(queuetype);
+    _PyUnicode_InternStatic(interp, &string);
+    assert(_PyUnicode_CheckConsistency(string, 1));
+    assert(PyUnicode_GET_LENGTH(string) != 1);
     string = &_Py_ID(quotetabs);
     _PyUnicode_InternStatic(interp, &string);
     assert(_PyUnicode_CheckConsistency(string, 1));
@@ -3056,6 +3080,10 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
     _PyUnicode_InternStatic(interp, &string);
     assert(_PyUnicode_CheckConsistency(string, 1));
     assert(PyUnicode_GET_LENGTH(string) != 1);
+    string = &_Py_ID(unboundop);
+    _PyUnicode_InternStatic(interp, &string);
+    assert(_PyUnicode_CheckConsistency(string, 1));
+    assert(PyUnicode_GET_LENGTH(string) != 1);
     string = &_Py_ID(unlink);
     _PyUnicode_InternStatic(interp, &string);
     assert(_PyUnicode_CheckConsistency(string, 1));
index 03ed081efbae0d31f473016ea22b5561d13d8e59..1db08628d29e0193aa421ab1633de74d72b604d8 100644 (file)
 #define MODINIT_FUNC_NAME RESOLVE_MODINIT_FUNC_NAME(MODULE_NAME)
 
 
+/*[clinic input]
+module _interpqueues
+[clinic start generated code]*/
+/*[clinic end generated code: output=da39a3ee5e6b4b0d input=cb1313f77fab132b]*/
+
 #define GLOBAL_MALLOC(TYPE) \
     PyMem_RawMalloc(sizeof(TYPE))
 #define GLOBAL_FREE(VAR) \
@@ -1466,31 +1471,48 @@ clear_interpreter(void *data)
 }
 
 
-typedef struct idarg_int64_converter_data qidarg_converter_data;
+/*[python input]
+
+class qidarg_converter(CConverter):
+    type = 'int64_t'
+    converter = 'qidarg_converter'
+
+[python start generated code]*/
+/*[python end generated code: output=da39a3ee5e6b4b0d input=c64fbf36771164d6]*/
 
 static int
 qidarg_converter(PyObject *arg, void *ptr)
 {
-    qidarg_converter_data *data = ptr;
-    if (data->label == NULL) {
-        data->label = "queue ID";
-    }
-    return idarg_int64_converter(arg, ptr);
+    int64_t *qid_ptr = ptr;
+    struct idarg_int64_converter_data data = {
+        .label = "queue ID",
+    };
+    int res = idarg_int64_converter(arg, &data);
+    *qid_ptr = data.id;
+    return res;
 }
 
+#include "clinic/_interpqueuesmodule.c.h"
+
+
+/*[clinic input]
+_interpqueues.create
+    maxsize: Py_ssize_t
+    unboundop as unboundarg: int = -1
+    fallback as fallbackarg: int = -1
+
+Create a new cross-interpreter queue and return its unique generated ID.
+
+It is a new reference as though bind() had been called on the queue.
+The caller is responsible for calling destroy() for the new queue
+before the runtime is finalized.
+[clinic start generated code]*/
 
 static PyObject *
-queuesmod_create(PyObject *self, PyObject *args, PyObject *kwds)
-{
-    static char *kwlist[] = {"maxsize", "unboundop", "fallback", NULL};
-    Py_ssize_t maxsize;
-    int unboundarg = -1;
-    int fallbackarg = -1;
-    if (!PyArg_ParseTupleAndKeywords(args, kwds, "n|ii:create", kwlist,
-                                     &maxsize, &unboundarg, &fallbackarg))
-    {
-        return NULL;
-    }
+_interpqueues_create_impl(PyObject *module, Py_ssize_t maxsize,
+                          int unboundarg, int fallbackarg)
+/*[clinic end generated code: output=9a889b93773251eb input=4f79b710a87360e1]*/
+{
     struct _queuedefaults defaults = {0};
     if (resolve_unboundop(unboundarg, UNBOUND_REPLACE,
                           &defaults.unboundop) < 0)
@@ -1505,7 +1527,7 @@ queuesmod_create(PyObject *self, PyObject *args, PyObject *kwds)
 
     int64_t qid = queue_create(&_globals.queues, maxsize, defaults);
     if (qid < 0) {
-        (void)handle_queue_error((int)qid, self, qid);
+        (void)handle_queue_error((int)qid, module, qid);
         return NULL;
     }
 
@@ -1513,7 +1535,7 @@ queuesmod_create(PyObject *self, PyObject *args, PyObject *kwds)
     if (qidobj == NULL) {
         PyObject *exc = PyErr_GetRaisedException();
         int err = queue_destroy(&_globals.queues, qid);
-        if (handle_queue_error(err, self, qid)) {
+        if (handle_queue_error(err, module, qid)) {
             // XXX issue a warning?
             PyErr_Clear();
         }
@@ -1524,41 +1546,37 @@ queuesmod_create(PyObject *self, PyObject *args, PyObject *kwds)
     return qidobj;
 }
 
-PyDoc_STRVAR(queuesmod_create_doc,
-"create(maxsize, unboundop, fallback) -> qid\n\
-\n\
-Create a new cross-interpreter queue and return its unique generated ID.\n\
-It is a new reference as though bind() had been called on the queue.\n\
-\n\
-The caller is responsible for calling destroy() for the new queue\n\
-before the runtime is finalized.");
+/*[clinic input]
+_interpqueues.destroy
+    qid: qidarg
+
+Clear and destroy the queue.
+
+Afterward attempts to use the queue will behave as though it never existed.
+[clinic start generated code]*/
 
 static PyObject *
-queuesmod_destroy(PyObject *self, PyObject *args, PyObject *kwds)
+_interpqueues_destroy_impl(PyObject *module, int64_t qid)
+/*[clinic end generated code: output=46b35623f080cbff input=8632bba87f81e3e9]*/
 {
-    static char *kwlist[] = {"qid", NULL};
-    qidarg_converter_data qidarg = {0};
-    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&:destroy", kwlist,
-                                     qidarg_converter, &qidarg)) {
-        return NULL;
-    }
-    int64_t qid = qidarg.id;
-
     int err = queue_destroy(&_globals.queues, qid);
-    if (handle_queue_error(err, self, qid)) {
+    if (handle_queue_error(err, module, qid)) {
         return NULL;
     }
     Py_RETURN_NONE;
 }
 
-PyDoc_STRVAR(queuesmod_destroy_doc,
-"destroy(qid)\n\
-\n\
-Clear and destroy the queue.  Afterward attempts to use the queue\n\
-will behave as though it never existed.");
+/*[clinic input]
+_interpqueues.list_all
+
+Return the list of ID triples for all queues.
+
+Each ID triple consists of (ID, default unbound op, default fallback).
+[clinic start generated code]*/
 
 static PyObject *
-queuesmod_list_all(PyObject *self, PyObject *Py_UNUSED(ignored))
+_interpqueues_list_all_impl(PyObject *module)
+/*[clinic end generated code: output=974280cb6442afdb input=19495f02cbb38b33]*/
 {
     int64_t count = 0;
     struct queue_id_and_info *qids = _queues_list_all(&_globals.queues, &count);
@@ -1589,31 +1607,25 @@ finally:
     return ids;
 }
 
-PyDoc_STRVAR(queuesmod_list_all_doc,
-"list_all() -> [(qid, unboundop, fallback)]\n\
-\n\
-Return the list of IDs for all queues.\n\
-Each corresponding default unbound op and fallback is also included.");
+/*[clinic input]
+_interpqueues.put
+    qid: qidarg
+    obj: object
+    unboundop as unboundarg: int = -1
+    fallback as fallbackarg: int = -1
+
+Add the object's data to the queue.
+[clinic start generated code]*/
 
 static PyObject *
-queuesmod_put(PyObject *self, PyObject *args, PyObject *kwds)
-{
-    static char *kwlist[] = {"qid", "obj", "unboundop", "fallback", NULL};
-    qidarg_converter_data qidarg = {0};
-    PyObject *obj;
-    int unboundarg = -1;
-    int fallbackarg = -1;
-    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&O|ii:put", kwlist,
-                                     qidarg_converter, &qidarg, &obj,
-                                     &unboundarg, &fallbackarg))
-    {
-        return NULL;
-    }
-    int64_t qid = qidarg.id;
+_interpqueues_put_impl(PyObject *module, int64_t qid, PyObject *obj,
+                       int unboundarg, int fallbackarg)
+/*[clinic end generated code: output=2e0b31c6eaec29c9 input=4906550ab5c73be3]*/
+{
     struct _queuedefaults defaults = {-1, -1};
     if (unboundarg < 0 || fallbackarg < 0) {
         int err = queue_get_defaults(&_globals.queues, qid, &defaults);
-        if (handle_queue_error(err, self, qid)) {
+        if (handle_queue_error(err, module, qid)) {
             return NULL;
         }
     }
@@ -1629,34 +1641,31 @@ queuesmod_put(PyObject *self, PyObject *args, PyObject *kwds)
     /* Queue up the object. */
     int err = queue_put(&_globals.queues, qid, obj, unboundop, fallback);
     // This is the only place that raises QueueFull.
-    if (handle_queue_error(err, self, qid)) {
+    if (handle_queue_error(err, module, qid)) {
         return NULL;
     }
 
     Py_RETURN_NONE;
 }
 
-PyDoc_STRVAR(queuesmod_put_doc,
-"put(qid, obj)\n\
-\n\
-Add the object's data to the queue.");
+/*[clinic input]
+_interpqueues.get
+    qid: qidarg
+
+Return the (object, unbound op) from the front of the queue.
+
+If there is nothing to receive then raise QueueEmpty.
+[clinic start generated code]*/
 
 static PyObject *
-queuesmod_get(PyObject *self, PyObject *args, PyObject *kwds)
+_interpqueues_get_impl(PyObject *module, int64_t qid)
+/*[clinic end generated code: output=b0988a0e29194f05 input=c5bccbc409ad0190]*/
 {
-    static char *kwlist[] = {"qid", NULL};
-    qidarg_converter_data qidarg = {0};
-    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&:get", kwlist,
-                                     qidarg_converter, &qidarg)) {
-        return NULL;
-    }
-    int64_t qid = qidarg.id;
-
     PyObject *obj = NULL;
     int unboundop = 0;
     int err = queue_get(&_globals.queues, qid, &obj, &unboundop);
     // This is the only place that raises QueueEmpty.
-    if (handle_queue_error(err, self, qid)) {
+    if (handle_queue_error(err, module, qid)) {
         return NULL;
     }
 
@@ -1668,29 +1677,23 @@ queuesmod_get(PyObject *self, PyObject *args, PyObject *kwds)
     return res;
 }
 
-PyDoc_STRVAR(queuesmod_get_doc,
-"get(qid) -> (obj, unboundop)\n\
-\n\
-Return a new object from the data at the front of the queue.\n\
-The unbound op is also returned.\n\
-\n\
-If there is nothing to receive then raise QueueEmpty.");
+/*[clinic input]
+_interpqueues.bind
+    qid: qidarg
+
+Take a reference to the identified queue.
+
+The queue is not destroyed until there are no references left.
+[clinic start generated code]*/
 
 static PyObject *
-queuesmod_bind(PyObject *self, PyObject *args, PyObject *kwds)
+_interpqueues_bind_impl(PyObject *module, int64_t qid)
+/*[clinic end generated code: output=02b515e203c3f926 input=b0efd1a6ce0e576e]*/
 {
-    static char *kwlist[] = {"qid", NULL};
-    qidarg_converter_data qidarg = {0};
-    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&:bind", kwlist,
-                                     qidarg_converter, &qidarg)) {
-        return NULL;
-    }
-    int64_t qid = qidarg.id;
-
     // XXX Check module state if bound already.
 
     int err = _queues_incref(&_globals.queues, qid);
-    if (handle_queue_error(err, self, qid)) {
+    if (handle_queue_error(err, module, qid)) {
         return NULL;
     }
 
@@ -1699,82 +1702,65 @@ queuesmod_bind(PyObject *self, PyObject *args, PyObject *kwds)
     Py_RETURN_NONE;
 }
 
-PyDoc_STRVAR(queuesmod_bind_doc,
-"bind(qid)\n\
-\n\
-Take a reference to the identified queue.\n\
-The queue is not destroyed until there are no references left.");
+/*[clinic input]
+_interpqueues.release
+    qid: qidarg
+
+Release a reference to the queue.
+
+The queue is destroyed once there are no references left.
+[clinic start generated code]*/
 
 static PyObject *
-queuesmod_release(PyObject *self, PyObject *args, PyObject *kwds)
+_interpqueues_release_impl(PyObject *module, int64_t qid)
+/*[clinic end generated code: output=a59545d7c61fc6ee input=664125cf0262ff6f]*/
 {
     // Note that only the current interpreter is affected.
-    static char *kwlist[] = {"qid", NULL};
-    qidarg_converter_data qidarg = {0};
-    if (!PyArg_ParseTupleAndKeywords(args, kwds,
-                                     "O&:release", kwlist,
-                                     qidarg_converter, &qidarg)) {
-        return NULL;
-    }
-    int64_t qid = qidarg.id;
 
     // XXX Check module state if bound already.
     // XXX Update module state.
 
     int err = _queues_decref(&_globals.queues, qid);
-    if (handle_queue_error(err, self, qid)) {
+    if (handle_queue_error(err, module, qid)) {
         return NULL;
     }
 
     Py_RETURN_NONE;
 }
 
-PyDoc_STRVAR(queuesmod_release_doc,
-"release(qid)\n\
-\n\
-Release a reference to the queue.\n\
-The queue is destroyed once there are no references left.");
+/*[clinic input]
+_interpqueues.get_maxsize
+    qid: qidarg
+
+Return the maximum number of items in the queue.
+[clinic start generated code]*/
 
 static PyObject *
-queuesmod_get_maxsize(PyObject *self, PyObject *args, PyObject *kwds)
+_interpqueues_get_maxsize_impl(PyObject *module, int64_t qid)
+/*[clinic end generated code: output=074202b9c6dc37bf input=ef55def3496cc379]*/
 {
-    static char *kwlist[] = {"qid", NULL};
-    qidarg_converter_data qidarg = {0};
-    if (!PyArg_ParseTupleAndKeywords(args, kwds,
-                                     "O&:get_maxsize", kwlist,
-                                     qidarg_converter, &qidarg)) {
-        return NULL;
-    }
-    int64_t qid = qidarg.id;
-
     Py_ssize_t maxsize = -1;
     int err = queue_get_maxsize(&_globals.queues, qid, &maxsize);
-    if (handle_queue_error(err, self, qid)) {
+    if (handle_queue_error(err, module, qid)) {
         return NULL;
     }
     return PyLong_FromLongLong(maxsize);
 }
 
-PyDoc_STRVAR(queuesmod_get_maxsize_doc,
-"get_maxsize(qid)\n\
-\n\
-Return the maximum number of items in the queue.");
+/*[clinic input]
+_interpqueues.get_queue_defaults
+    qid: qidarg
+
+Return the queue's default values, set when it was created.
+[clinic start generated code]*/
 
 static PyObject *
-queuesmod_get_queue_defaults(PyObject *self, PyObject *args, PyObject *kwds)
+_interpqueues_get_queue_defaults_impl(PyObject *module, int64_t qid)
+/*[clinic end generated code: output=b1b8b8103834191a input=3102315a7bff77fc]*/
 {
-    static char *kwlist[] = {"qid", NULL};
-    qidarg_converter_data qidarg = {0};
-    if (!PyArg_ParseTupleAndKeywords(args, kwds,
-                                     "O&:get_queue_defaults", kwlist,
-                                     qidarg_converter, &qidarg)) {
-        return NULL;
-    }
-    int64_t qid = qidarg.id;
-
     struct _queuedefaults defaults = {0};
     int err = queue_get_defaults(&_globals.queues, qid, &defaults);
-    if (handle_queue_error(err, self, qid)) {
+    if (handle_queue_error(err, module, qid)) {
         return NULL;
     }
 
@@ -1782,26 +1768,20 @@ queuesmod_get_queue_defaults(PyObject *self, PyObject *args, PyObject *kwds)
     return res;
 }
 
-PyDoc_STRVAR(queuesmod_get_queue_defaults_doc,
-"get_queue_defaults(qid)\n\
-\n\
-Return the queue's default values, set when it was created.");
+/*[clinic input]
+_interpqueues.is_full
+    qid: qidarg
+
+Return true if the queue has a maxsize and has reached it.
+[clinic start generated code]*/
 
 static PyObject *
-queuesmod_is_full(PyObject *self, PyObject *args, PyObject *kwds)
+_interpqueues_is_full_impl(PyObject *module, int64_t qid)
+/*[clinic end generated code: output=47a6e18477cddfee input=25d86a327ed3a2e7]*/
 {
-    static char *kwlist[] = {"qid", NULL};
-    qidarg_converter_data qidarg = {0};
-    if (!PyArg_ParseTupleAndKeywords(args, kwds,
-                                     "O&:is_full", kwlist,
-                                     qidarg_converter, &qidarg)) {
-        return NULL;
-    }
-    int64_t qid = qidarg.id;
-
     int is_full = 0;
     int err = queue_is_full(&_globals.queues, qid, &is_full);
-    if (handle_queue_error(err, self, qid)) {
+    if (handle_queue_error(err, module, qid)) {
         return NULL;
     }
     if (is_full) {
@@ -1810,54 +1790,42 @@ queuesmod_is_full(PyObject *self, PyObject *args, PyObject *kwds)
     Py_RETURN_FALSE;
 }
 
-PyDoc_STRVAR(queuesmod_is_full_doc,
-"is_full(qid)\n\
-\n\
-Return true if the queue has a maxsize and has reached it.");
+/*[clinic input]
+_interpqueues.get_count
+    qid: qidarg
+
+Return the number of items in the queue.
+[clinic start generated code]*/
 
 static PyObject *
-queuesmod_get_count(PyObject *self, PyObject *args, PyObject *kwds)
+_interpqueues_get_count_impl(PyObject *module, int64_t qid)
+/*[clinic end generated code: output=fb9e66e829cdd964 input=ce47690e7598884b]*/
 {
-    static char *kwlist[] = {"qid", NULL};
-    qidarg_converter_data qidarg = {0};
-    if (!PyArg_ParseTupleAndKeywords(args, kwds,
-                                     "O&:get_count", kwlist,
-                                     qidarg_converter, &qidarg)) {
-        return NULL;
-    }
-    int64_t qid = qidarg.id;
-
     Py_ssize_t count = -1;
     int err = queue_get_count(&_globals.queues, qid, &count);
-    if (handle_queue_error(err, self, qid)) {
+    if (handle_queue_error(err, module, qid)) {
         return NULL;
     }
     assert(count >= 0);
     return PyLong_FromSsize_t(count);
 }
 
-PyDoc_STRVAR(queuesmod_get_count_doc,
-"get_count(qid)\n\
-\n\
-Return the number of items in the queue.");
+/*[clinic input]
+_interpqueues._register_heap_types
+    queuetype: object(subclass_of='&PyType_Type', type='PyTypeObject *')
+    emptyerror: object
+    fullerror: object
+
+Return the number of items in the queue.
+[clinic start generated code]*/
 
 static PyObject *
-queuesmod__register_heap_types(PyObject *self, PyObject *args, PyObject *kwds)
-{
-    static char *kwlist[] = {"queuetype", "emptyerror", "fullerror", NULL};
-    PyObject *queuetype;
-    PyObject *emptyerror;
-    PyObject *fullerror;
-    if (!PyArg_ParseTupleAndKeywords(args, kwds,
-                                     "OOO:_register_heap_types", kwlist,
-                                     &queuetype, &emptyerror, &fullerror)) {
-        return NULL;
-    }
-    if (!PyType_Check(queuetype)) {
-        PyErr_SetString(PyExc_TypeError,
-                        "expected a type for 'queuetype'");
-        return NULL;
-    }
+_interpqueues__register_heap_types_impl(PyObject *module,
+                                        PyTypeObject *queuetype,
+                                        PyObject *emptyerror,
+                                        PyObject *fullerror)
+/*[clinic end generated code: output=f33f6e8b5af905cd input=57d24ae405eda521]*/
+{
     if (!PyExceptionClass_Check(emptyerror)) {
         PyErr_SetString(PyExc_TypeError,
                         "expected an exception type for 'emptyerror'");
@@ -1869,9 +1837,9 @@ queuesmod__register_heap_types(PyObject *self, PyObject *args, PyObject *kwds)
         return NULL;
     }
 
-    module_state *state = get_module_state(self);
+    module_state *state = get_module_state(module);
 
-    if (set_external_queue_type(state, (PyTypeObject *)queuetype) < 0) {
+    if (set_external_queue_type(state, queuetype) < 0) {
         return NULL;
     }
     if (set_external_exc_types(state, emptyerror, fullerror) < 0) {
@@ -1882,30 +1850,18 @@ queuesmod__register_heap_types(PyObject *self, PyObject *args, PyObject *kwds)
 }
 
 static PyMethodDef module_functions[] = {
-    {"create",                     _PyCFunction_CAST(queuesmod_create),
-     METH_VARARGS | METH_KEYWORDS, queuesmod_create_doc},
-    {"destroy",                    _PyCFunction_CAST(queuesmod_destroy),
-     METH_VARARGS | METH_KEYWORDS, queuesmod_destroy_doc},
-    {"list_all",                   queuesmod_list_all,
-     METH_NOARGS,                  queuesmod_list_all_doc},
-    {"put",                        _PyCFunction_CAST(queuesmod_put),
-     METH_VARARGS | METH_KEYWORDS, queuesmod_put_doc},
-    {"get",                        _PyCFunction_CAST(queuesmod_get),
-     METH_VARARGS | METH_KEYWORDS, queuesmod_get_doc},
-    {"bind",                       _PyCFunction_CAST(queuesmod_bind),
-     METH_VARARGS | METH_KEYWORDS, queuesmod_bind_doc},
-    {"release",                    _PyCFunction_CAST(queuesmod_release),
-     METH_VARARGS | METH_KEYWORDS, queuesmod_release_doc},
-    {"get_maxsize",                _PyCFunction_CAST(queuesmod_get_maxsize),
-     METH_VARARGS | METH_KEYWORDS, queuesmod_get_maxsize_doc},
-    {"get_queue_defaults",         _PyCFunction_CAST(queuesmod_get_queue_defaults),
-     METH_VARARGS | METH_KEYWORDS, queuesmod_get_queue_defaults_doc},
-    {"is_full",                    _PyCFunction_CAST(queuesmod_is_full),
-     METH_VARARGS | METH_KEYWORDS, queuesmod_is_full_doc},
-    {"get_count",                  _PyCFunction_CAST(queuesmod_get_count),
-     METH_VARARGS | METH_KEYWORDS, queuesmod_get_count_doc},
-    {"_register_heap_types",       _PyCFunction_CAST(queuesmod__register_heap_types),
-     METH_VARARGS | METH_KEYWORDS, NULL},
+    _INTERPQUEUES_CREATE_METHODDEF
+    _INTERPQUEUES_DESTROY_METHODDEF
+    _INTERPQUEUES_LIST_ALL_METHODDEF
+    _INTERPQUEUES_PUT_METHODDEF
+    _INTERPQUEUES_GET_METHODDEF
+    _INTERPQUEUES_BIND_METHODDEF
+    _INTERPQUEUES_RELEASE_METHODDEF
+    _INTERPQUEUES_GET_MAXSIZE_METHODDEF
+    _INTERPQUEUES_GET_QUEUE_DEFAULTS_METHODDEF
+    _INTERPQUEUES_IS_FULL_METHODDEF
+    _INTERPQUEUES_GET_COUNT_METHODDEF
+    _INTERPQUEUES__REGISTER_HEAP_TYPES_METHODDEF
 
     {NULL,                        NULL}           /* sentinel */
 };
diff --git a/Modules/clinic/_interpqueuesmodule.c.h b/Modules/clinic/_interpqueuesmodule.c.h
new file mode 100644 (file)
index 0000000..3f08a0c
--- /dev/null
@@ -0,0 +1,765 @@
+/*[clinic input]
+preserve
+[clinic start generated code]*/
+
+#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+#  include "pycore_gc.h"          // PyGC_Head
+#  include "pycore_runtime.h"     // _Py_ID()
+#endif
+#include "pycore_abstract.h"      // _PyNumber_Index()
+#include "pycore_modsupport.h"    // _PyArg_UnpackKeywords()
+
+PyDoc_STRVAR(_interpqueues_create__doc__,
+"create($module, /, maxsize, unboundop=-1, fallback=-1)\n"
+"--\n"
+"\n"
+"Create a new cross-interpreter queue and return its unique generated ID.\n"
+"\n"
+"It is a new reference as though bind() had been called on the queue.\n"
+"The caller is responsible for calling destroy() for the new queue\n"
+"before the runtime is finalized.");
+
+#define _INTERPQUEUES_CREATE_METHODDEF    \
+    {"create", _PyCFunction_CAST(_interpqueues_create), METH_FASTCALL|METH_KEYWORDS, _interpqueues_create__doc__},
+
+static PyObject *
+_interpqueues_create_impl(PyObject *module, Py_ssize_t maxsize,
+                          int unboundarg, int fallbackarg);
+
+static PyObject *
+_interpqueues_create(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+    PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+
+    #define NUM_KEYWORDS 3
+    static struct {
+        PyGC_Head _this_is_not_used;
+        PyObject_VAR_HEAD
+        Py_hash_t ob_hash;
+        PyObject *ob_item[NUM_KEYWORDS];
+    } _kwtuple = {
+        .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
+        .ob_hash = -1,
+        .ob_item = { &_Py_ID(maxsize), &_Py_ID(unboundop), &_Py_ID(fallback), },
+    };
+    #undef NUM_KEYWORDS
+    #define KWTUPLE (&_kwtuple.ob_base.ob_base)
+
+    #else  // !Py_BUILD_CORE
+    #  define KWTUPLE NULL
+    #endif  // !Py_BUILD_CORE
+
+    static const char * const _keywords[] = {"maxsize", "unboundop", "fallback", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "create",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[3];
+    Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1;
+    Py_ssize_t maxsize;
+    int unboundarg = -1;
+    int fallbackarg = -1;
+
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 1, /*maxpos*/ 3, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
+        goto exit;
+    }
+    {
+        Py_ssize_t ival = -1;
+        PyObject *iobj = _PyNumber_Index(args[0]);
+        if (iobj != NULL) {
+            ival = PyLong_AsSsize_t(iobj);
+            Py_DECREF(iobj);
+        }
+        if (ival == -1 && PyErr_Occurred()) {
+            goto exit;
+        }
+        maxsize = ival;
+    }
+    if (!noptargs) {
+        goto skip_optional_pos;
+    }
+    if (args[1]) {
+        unboundarg = PyLong_AsInt(args[1]);
+        if (unboundarg == -1 && PyErr_Occurred()) {
+            goto exit;
+        }
+        if (!--noptargs) {
+            goto skip_optional_pos;
+        }
+    }
+    fallbackarg = PyLong_AsInt(args[2]);
+    if (fallbackarg == -1 && PyErr_Occurred()) {
+        goto exit;
+    }
+skip_optional_pos:
+    return_value = _interpqueues_create_impl(module, maxsize, unboundarg, fallbackarg);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(_interpqueues_destroy__doc__,
+"destroy($module, /, qid)\n"
+"--\n"
+"\n"
+"Clear and destroy the queue.\n"
+"\n"
+"Afterward attempts to use the queue will behave as though it never existed.");
+
+#define _INTERPQUEUES_DESTROY_METHODDEF    \
+    {"destroy", _PyCFunction_CAST(_interpqueues_destroy), METH_FASTCALL|METH_KEYWORDS, _interpqueues_destroy__doc__},
+
+static PyObject *
+_interpqueues_destroy_impl(PyObject *module, int64_t qid);
+
+static PyObject *
+_interpqueues_destroy(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+    PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+
+    #define NUM_KEYWORDS 1
+    static struct {
+        PyGC_Head _this_is_not_used;
+        PyObject_VAR_HEAD
+        Py_hash_t ob_hash;
+        PyObject *ob_item[NUM_KEYWORDS];
+    } _kwtuple = {
+        .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
+        .ob_hash = -1,
+        .ob_item = { &_Py_ID(qid), },
+    };
+    #undef NUM_KEYWORDS
+    #define KWTUPLE (&_kwtuple.ob_base.ob_base)
+
+    #else  // !Py_BUILD_CORE
+    #  define KWTUPLE NULL
+    #endif  // !Py_BUILD_CORE
+
+    static const char * const _keywords[] = {"qid", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "destroy",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[1];
+    int64_t qid;
+
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 1, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
+        goto exit;
+    }
+    if (!qidarg_converter(args[0], &qid)) {
+        goto exit;
+    }
+    return_value = _interpqueues_destroy_impl(module, qid);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(_interpqueues_list_all__doc__,
+"list_all($module, /)\n"
+"--\n"
+"\n"
+"Return the list of ID triples for all queues.\n"
+"\n"
+"Each ID triple consists of (ID, default unbound op, default fallback).");
+
+#define _INTERPQUEUES_LIST_ALL_METHODDEF    \
+    {"list_all", (PyCFunction)_interpqueues_list_all, METH_NOARGS, _interpqueues_list_all__doc__},
+
+static PyObject *
+_interpqueues_list_all_impl(PyObject *module);
+
+static PyObject *
+_interpqueues_list_all(PyObject *module, PyObject *Py_UNUSED(ignored))
+{
+    return _interpqueues_list_all_impl(module);
+}
+
+PyDoc_STRVAR(_interpqueues_put__doc__,
+"put($module, /, qid, obj, unboundop=-1, fallback=-1)\n"
+"--\n"
+"\n"
+"Add the object\'s data to the queue.");
+
+#define _INTERPQUEUES_PUT_METHODDEF    \
+    {"put", _PyCFunction_CAST(_interpqueues_put), METH_FASTCALL|METH_KEYWORDS, _interpqueues_put__doc__},
+
+static PyObject *
+_interpqueues_put_impl(PyObject *module, int64_t qid, PyObject *obj,
+                       int unboundarg, int fallbackarg);
+
+static PyObject *
+_interpqueues_put(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+    PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+
+    #define NUM_KEYWORDS 4
+    static struct {
+        PyGC_Head _this_is_not_used;
+        PyObject_VAR_HEAD
+        Py_hash_t ob_hash;
+        PyObject *ob_item[NUM_KEYWORDS];
+    } _kwtuple = {
+        .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
+        .ob_hash = -1,
+        .ob_item = { &_Py_ID(qid), &_Py_ID(obj), &_Py_ID(unboundop), &_Py_ID(fallback), },
+    };
+    #undef NUM_KEYWORDS
+    #define KWTUPLE (&_kwtuple.ob_base.ob_base)
+
+    #else  // !Py_BUILD_CORE
+    #  define KWTUPLE NULL
+    #endif  // !Py_BUILD_CORE
+
+    static const char * const _keywords[] = {"qid", "obj", "unboundop", "fallback", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "put",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[4];
+    Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2;
+    int64_t qid;
+    PyObject *obj;
+    int unboundarg = -1;
+    int fallbackarg = -1;
+
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 2, /*maxpos*/ 4, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
+        goto exit;
+    }
+    if (!qidarg_converter(args[0], &qid)) {
+        goto exit;
+    }
+    obj = args[1];
+    if (!noptargs) {
+        goto skip_optional_pos;
+    }
+    if (args[2]) {
+        unboundarg = PyLong_AsInt(args[2]);
+        if (unboundarg == -1 && PyErr_Occurred()) {
+            goto exit;
+        }
+        if (!--noptargs) {
+            goto skip_optional_pos;
+        }
+    }
+    fallbackarg = PyLong_AsInt(args[3]);
+    if (fallbackarg == -1 && PyErr_Occurred()) {
+        goto exit;
+    }
+skip_optional_pos:
+    return_value = _interpqueues_put_impl(module, qid, obj, unboundarg, fallbackarg);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(_interpqueues_get__doc__,
+"get($module, /, qid)\n"
+"--\n"
+"\n"
+"Return the (object, unbound op) from the front of the queue.\n"
+"\n"
+"If there is nothing to receive then raise QueueEmpty.");
+
+#define _INTERPQUEUES_GET_METHODDEF    \
+    {"get", _PyCFunction_CAST(_interpqueues_get), METH_FASTCALL|METH_KEYWORDS, _interpqueues_get__doc__},
+
+static PyObject *
+_interpqueues_get_impl(PyObject *module, int64_t qid);
+
+static PyObject *
+_interpqueues_get(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+    PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+
+    #define NUM_KEYWORDS 1
+    static struct {
+        PyGC_Head _this_is_not_used;
+        PyObject_VAR_HEAD
+        Py_hash_t ob_hash;
+        PyObject *ob_item[NUM_KEYWORDS];
+    } _kwtuple = {
+        .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
+        .ob_hash = -1,
+        .ob_item = { &_Py_ID(qid), },
+    };
+    #undef NUM_KEYWORDS
+    #define KWTUPLE (&_kwtuple.ob_base.ob_base)
+
+    #else  // !Py_BUILD_CORE
+    #  define KWTUPLE NULL
+    #endif  // !Py_BUILD_CORE
+
+    static const char * const _keywords[] = {"qid", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "get",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[1];
+    int64_t qid;
+
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 1, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
+        goto exit;
+    }
+    if (!qidarg_converter(args[0], &qid)) {
+        goto exit;
+    }
+    return_value = _interpqueues_get_impl(module, qid);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(_interpqueues_bind__doc__,
+"bind($module, /, qid)\n"
+"--\n"
+"\n"
+"Take a reference to the identified queue.\n"
+"\n"
+"The queue is not destroyed until there are no references left.");
+
+#define _INTERPQUEUES_BIND_METHODDEF    \
+    {"bind", _PyCFunction_CAST(_interpqueues_bind), METH_FASTCALL|METH_KEYWORDS, _interpqueues_bind__doc__},
+
+static PyObject *
+_interpqueues_bind_impl(PyObject *module, int64_t qid);
+
+static PyObject *
+_interpqueues_bind(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+    PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+
+    #define NUM_KEYWORDS 1
+    static struct {
+        PyGC_Head _this_is_not_used;
+        PyObject_VAR_HEAD
+        Py_hash_t ob_hash;
+        PyObject *ob_item[NUM_KEYWORDS];
+    } _kwtuple = {
+        .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
+        .ob_hash = -1,
+        .ob_item = { &_Py_ID(qid), },
+    };
+    #undef NUM_KEYWORDS
+    #define KWTUPLE (&_kwtuple.ob_base.ob_base)
+
+    #else  // !Py_BUILD_CORE
+    #  define KWTUPLE NULL
+    #endif  // !Py_BUILD_CORE
+
+    static const char * const _keywords[] = {"qid", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "bind",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[1];
+    int64_t qid;
+
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 1, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
+        goto exit;
+    }
+    if (!qidarg_converter(args[0], &qid)) {
+        goto exit;
+    }
+    return_value = _interpqueues_bind_impl(module, qid);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(_interpqueues_release__doc__,
+"release($module, /, qid)\n"
+"--\n"
+"\n"
+"Release a reference to the queue.\n"
+"\n"
+"The queue is destroyed once there are no references left.");
+
+#define _INTERPQUEUES_RELEASE_METHODDEF    \
+    {"release", _PyCFunction_CAST(_interpqueues_release), METH_FASTCALL|METH_KEYWORDS, _interpqueues_release__doc__},
+
+static PyObject *
+_interpqueues_release_impl(PyObject *module, int64_t qid);
+
+static PyObject *
+_interpqueues_release(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+    PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+
+    #define NUM_KEYWORDS 1
+    static struct {
+        PyGC_Head _this_is_not_used;
+        PyObject_VAR_HEAD
+        Py_hash_t ob_hash;
+        PyObject *ob_item[NUM_KEYWORDS];
+    } _kwtuple = {
+        .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
+        .ob_hash = -1,
+        .ob_item = { &_Py_ID(qid), },
+    };
+    #undef NUM_KEYWORDS
+    #define KWTUPLE (&_kwtuple.ob_base.ob_base)
+
+    #else  // !Py_BUILD_CORE
+    #  define KWTUPLE NULL
+    #endif  // !Py_BUILD_CORE
+
+    static const char * const _keywords[] = {"qid", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "release",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[1];
+    int64_t qid;
+
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 1, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
+        goto exit;
+    }
+    if (!qidarg_converter(args[0], &qid)) {
+        goto exit;
+    }
+    return_value = _interpqueues_release_impl(module, qid);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(_interpqueues_get_maxsize__doc__,
+"get_maxsize($module, /, qid)\n"
+"--\n"
+"\n"
+"Return the maximum number of items in the queue.");
+
+#define _INTERPQUEUES_GET_MAXSIZE_METHODDEF    \
+    {"get_maxsize", _PyCFunction_CAST(_interpqueues_get_maxsize), METH_FASTCALL|METH_KEYWORDS, _interpqueues_get_maxsize__doc__},
+
+static PyObject *
+_interpqueues_get_maxsize_impl(PyObject *module, int64_t qid);
+
+static PyObject *
+_interpqueues_get_maxsize(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+    PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+
+    #define NUM_KEYWORDS 1
+    static struct {
+        PyGC_Head _this_is_not_used;
+        PyObject_VAR_HEAD
+        Py_hash_t ob_hash;
+        PyObject *ob_item[NUM_KEYWORDS];
+    } _kwtuple = {
+        .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
+        .ob_hash = -1,
+        .ob_item = { &_Py_ID(qid), },
+    };
+    #undef NUM_KEYWORDS
+    #define KWTUPLE (&_kwtuple.ob_base.ob_base)
+
+    #else  // !Py_BUILD_CORE
+    #  define KWTUPLE NULL
+    #endif  // !Py_BUILD_CORE
+
+    static const char * const _keywords[] = {"qid", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "get_maxsize",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[1];
+    int64_t qid;
+
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 1, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
+        goto exit;
+    }
+    if (!qidarg_converter(args[0], &qid)) {
+        goto exit;
+    }
+    return_value = _interpqueues_get_maxsize_impl(module, qid);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(_interpqueues_get_queue_defaults__doc__,
+"get_queue_defaults($module, /, qid)\n"
+"--\n"
+"\n"
+"Return the queue\'s default values, set when it was created.");
+
+#define _INTERPQUEUES_GET_QUEUE_DEFAULTS_METHODDEF    \
+    {"get_queue_defaults", _PyCFunction_CAST(_interpqueues_get_queue_defaults), METH_FASTCALL|METH_KEYWORDS, _interpqueues_get_queue_defaults__doc__},
+
+static PyObject *
+_interpqueues_get_queue_defaults_impl(PyObject *module, int64_t qid);
+
+static PyObject *
+_interpqueues_get_queue_defaults(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+    PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+
+    #define NUM_KEYWORDS 1
+    static struct {
+        PyGC_Head _this_is_not_used;
+        PyObject_VAR_HEAD
+        Py_hash_t ob_hash;
+        PyObject *ob_item[NUM_KEYWORDS];
+    } _kwtuple = {
+        .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
+        .ob_hash = -1,
+        .ob_item = { &_Py_ID(qid), },
+    };
+    #undef NUM_KEYWORDS
+    #define KWTUPLE (&_kwtuple.ob_base.ob_base)
+
+    #else  // !Py_BUILD_CORE
+    #  define KWTUPLE NULL
+    #endif  // !Py_BUILD_CORE
+
+    static const char * const _keywords[] = {"qid", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "get_queue_defaults",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[1];
+    int64_t qid;
+
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 1, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
+        goto exit;
+    }
+    if (!qidarg_converter(args[0], &qid)) {
+        goto exit;
+    }
+    return_value = _interpqueues_get_queue_defaults_impl(module, qid);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(_interpqueues_is_full__doc__,
+"is_full($module, /, qid)\n"
+"--\n"
+"\n"
+"Return true if the queue has a maxsize and has reached it.");
+
+#define _INTERPQUEUES_IS_FULL_METHODDEF    \
+    {"is_full", _PyCFunction_CAST(_interpqueues_is_full), METH_FASTCALL|METH_KEYWORDS, _interpqueues_is_full__doc__},
+
+static PyObject *
+_interpqueues_is_full_impl(PyObject *module, int64_t qid);
+
+static PyObject *
+_interpqueues_is_full(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+    PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+
+    #define NUM_KEYWORDS 1
+    static struct {
+        PyGC_Head _this_is_not_used;
+        PyObject_VAR_HEAD
+        Py_hash_t ob_hash;
+        PyObject *ob_item[NUM_KEYWORDS];
+    } _kwtuple = {
+        .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
+        .ob_hash = -1,
+        .ob_item = { &_Py_ID(qid), },
+    };
+    #undef NUM_KEYWORDS
+    #define KWTUPLE (&_kwtuple.ob_base.ob_base)
+
+    #else  // !Py_BUILD_CORE
+    #  define KWTUPLE NULL
+    #endif  // !Py_BUILD_CORE
+
+    static const char * const _keywords[] = {"qid", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "is_full",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[1];
+    int64_t qid;
+
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 1, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
+        goto exit;
+    }
+    if (!qidarg_converter(args[0], &qid)) {
+        goto exit;
+    }
+    return_value = _interpqueues_is_full_impl(module, qid);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(_interpqueues_get_count__doc__,
+"get_count($module, /, qid)\n"
+"--\n"
+"\n"
+"Return the number of items in the queue.");
+
+#define _INTERPQUEUES_GET_COUNT_METHODDEF    \
+    {"get_count", _PyCFunction_CAST(_interpqueues_get_count), METH_FASTCALL|METH_KEYWORDS, _interpqueues_get_count__doc__},
+
+static PyObject *
+_interpqueues_get_count_impl(PyObject *module, int64_t qid);
+
+static PyObject *
+_interpqueues_get_count(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+    PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+
+    #define NUM_KEYWORDS 1
+    static struct {
+        PyGC_Head _this_is_not_used;
+        PyObject_VAR_HEAD
+        Py_hash_t ob_hash;
+        PyObject *ob_item[NUM_KEYWORDS];
+    } _kwtuple = {
+        .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
+        .ob_hash = -1,
+        .ob_item = { &_Py_ID(qid), },
+    };
+    #undef NUM_KEYWORDS
+    #define KWTUPLE (&_kwtuple.ob_base.ob_base)
+
+    #else  // !Py_BUILD_CORE
+    #  define KWTUPLE NULL
+    #endif  // !Py_BUILD_CORE
+
+    static const char * const _keywords[] = {"qid", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "get_count",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[1];
+    int64_t qid;
+
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 1, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
+        goto exit;
+    }
+    if (!qidarg_converter(args[0], &qid)) {
+        goto exit;
+    }
+    return_value = _interpqueues_get_count_impl(module, qid);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(_interpqueues__register_heap_types__doc__,
+"_register_heap_types($module, /, queuetype, emptyerror, fullerror)\n"
+"--\n"
+"\n"
+"Return the number of items in the queue.");
+
+#define _INTERPQUEUES__REGISTER_HEAP_TYPES_METHODDEF    \
+    {"_register_heap_types", _PyCFunction_CAST(_interpqueues__register_heap_types), METH_FASTCALL|METH_KEYWORDS, _interpqueues__register_heap_types__doc__},
+
+static PyObject *
+_interpqueues__register_heap_types_impl(PyObject *module,
+                                        PyTypeObject *queuetype,
+                                        PyObject *emptyerror,
+                                        PyObject *fullerror);
+
+static PyObject *
+_interpqueues__register_heap_types(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+    PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+
+    #define NUM_KEYWORDS 3
+    static struct {
+        PyGC_Head _this_is_not_used;
+        PyObject_VAR_HEAD
+        Py_hash_t ob_hash;
+        PyObject *ob_item[NUM_KEYWORDS];
+    } _kwtuple = {
+        .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
+        .ob_hash = -1,
+        .ob_item = { &_Py_ID(queuetype), &_Py_ID(emptyerror), &_Py_ID(fullerror), },
+    };
+    #undef NUM_KEYWORDS
+    #define KWTUPLE (&_kwtuple.ob_base.ob_base)
+
+    #else  // !Py_BUILD_CORE
+    #  define KWTUPLE NULL
+    #endif  // !Py_BUILD_CORE
+
+    static const char * const _keywords[] = {"queuetype", "emptyerror", "fullerror", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "_register_heap_types",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[3];
+    PyTypeObject *queuetype;
+    PyObject *emptyerror;
+    PyObject *fullerror;
+
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 3, /*maxpos*/ 3, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
+        goto exit;
+    }
+    if (!PyObject_TypeCheck(args[0], &PyType_Type)) {
+        _PyArg_BadArgument("_register_heap_types", "argument 'queuetype'", (&PyType_Type)->tp_name, args[0]);
+        goto exit;
+    }
+    queuetype = (PyTypeObject *)args[0];
+    emptyerror = args[1];
+    fullerror = args[2];
+    return_value = _interpqueues__register_heap_types_impl(module, queuetype, emptyerror, fullerror);
+
+exit:
+    return return_value;
+}
+/*[clinic end generated code: output=64cea8e1063429b6 input=a9049054013a1b77]*/