diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-08-05-15-45-07.gh-issue-107659.QgtQ5M.rst b/Misc/NEWS.d/next/Core and Builtins/2023-08-05-15-45-07.gh-issue-107659.QgtQ5M.rst new file mode 100644 index 00000000000..31cc6982400 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2023-08-05-15-45-07.gh-issue-107659.QgtQ5M.rst @@ -0,0 +1 @@ +Add docstrings for :func:`ctypes.pointer` and :func:`ctypes.POINTER`. diff --git a/Modules/_ctypes/callproc.c b/Modules/_ctypes/callproc.c index 69cf8a98af6..f9535db4f57 100644 --- a/Modules/_ctypes/callproc.c +++ b/Modules/_ctypes/callproc.c @@ -54,6 +54,11 @@ */ +/*[clinic input] +module _ctypes +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=476a19c49b31a75c]*/ + #ifndef Py_BUILD_CORE_BUILTIN # define Py_BUILD_CORE_MODULE 1 #endif @@ -98,6 +103,7 @@ #include "pycore_runtime.h" // _PyRuntime #include "pycore_global_objects.h" // _Py_ID() +#include "clinic/callproc.c.h" #define CTYPES_CAPSULE_NAME_PYMEM "_ctypes pymem" @@ -1893,8 +1899,22 @@ error: return NULL; } +/*[clinic input] +_ctypes.POINTER as create_pointer_type + + type as cls: object + A ctypes type. + / + +Create and return a new ctypes pointer type. + +Pointer types are cached and reused internally, +so calling this function repeatedly is cheap. +[clinic start generated code]*/ + static PyObject * -POINTER(PyObject *self, PyObject *cls) +create_pointer_type(PyObject *module, PyObject *cls) +/*[clinic end generated code: output=98c3547ab6f4f40b input=3b81cff5ff9b9d5b]*/ { PyObject *result; PyTypeObject *typ; @@ -1944,8 +1964,22 @@ POINTER(PyObject *self, PyObject *cls) return result; } +/*[clinic input] +_ctypes.pointer as create_pointer_inst + + obj as arg: object + / + +Create a new pointer instance, pointing to 'obj'. + +The returned object is of the type POINTER(type(obj)). Note that if you +just want to pass a pointer to an object to a foreign function call, you +should use byref(obj) which is much faster. +[clinic start generated code]*/ + static PyObject * -pointer(PyObject *self, PyObject *arg) +create_pointer_inst(PyObject *module, PyObject *arg) +/*[clinic end generated code: output=3b543bc9f0de2180 input=713685fdb4d9bc27]*/ { PyObject *result; PyObject *typ; @@ -1957,7 +1991,7 @@ pointer(PyObject *self, PyObject *arg) else if (PyErr_Occurred()) { return NULL; } - typ = POINTER(NULL, (PyObject *)Py_TYPE(arg)); + typ = create_pointer_type(NULL, (PyObject *)Py_TYPE(arg)); if (typ == NULL) return NULL; result = PyObject_CallOneArg(typ, arg); @@ -1997,8 +2031,8 @@ buffer_info(PyObject *self, PyObject *arg) PyMethodDef _ctypes_module_methods[] = { {"get_errno", get_errno, METH_NOARGS}, {"set_errno", set_errno, METH_VARARGS}, - {"POINTER", POINTER, METH_O }, - {"pointer", pointer, METH_O }, + CREATE_POINTER_TYPE_METHODDEF + CREATE_POINTER_INST_METHODDEF {"_unpickle", unpickle, METH_VARARGS }, {"buffer_info", buffer_info, METH_O, "Return buffer interface information"}, {"resize", resize, METH_VARARGS, "Resize the memory buffer of a ctypes instance"}, diff --git a/Modules/_ctypes/clinic/callproc.c.h b/Modules/_ctypes/clinic/callproc.c.h new file mode 100644 index 00000000000..6f036bb66b2 --- /dev/null +++ b/Modules/_ctypes/clinic/callproc.c.h @@ -0,0 +1,38 @@ +/*[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 + + +PyDoc_STRVAR(create_pointer_type__doc__, +"POINTER($module, type, /)\n" +"--\n" +"\n" +"Create and return a new ctypes pointer type.\n" +"\n" +" type\n" +" A ctypes type.\n" +"\n" +"Pointer types are cached and reused internally,\n" +"so calling this function repeatedly is cheap."); + +#define CREATE_POINTER_TYPE_METHODDEF \ + {"POINTER", (PyCFunction)create_pointer_type, METH_O, create_pointer_type__doc__}, + +PyDoc_STRVAR(create_pointer_inst__doc__, +"pointer($module, obj, /)\n" +"--\n" +"\n" +"Create a new pointer instance, pointing to \'obj\'.\n" +"\n" +"The returned object is of the type POINTER(type(obj)). Note that if you\n" +"just want to pass a pointer to an object to a foreign function call, you\n" +"should use byref(obj) which is much faster."); + +#define CREATE_POINTER_INST_METHODDEF \ + {"pointer", (PyCFunction)create_pointer_inst, METH_O, create_pointer_inst__doc__}, +/*[clinic end generated code: output=ae26452a759ba56d input=a9049054013a1b77]*/