gh-135748: Use Argument Clinic for more socket functions (GH-155257)

serhiy-storchaka <[email protected]> Thu, 13 Aug 2026 09:25:28 -0400 (EDT)
Newsgroups gmane.comp.python.cvs
Message-ID <[email protected]>
https://github.com/python/cpython/commit/9f8780022058e629dada82221c384b67c5687b2e
commit: 9f8780022058e629dada82221c384b67c5687b2e
branch: main
author: Serhiy Storchaka <[email protected]>
committer: serhiy-storchaka <[email protected]>
date: 2026-08-13T16:24:59+03:00
summary:

gh-135748: Use Argument Clinic for more socket functions (GH-155257)

Convert all convertible functions and methods of the socket module.
They now have signatures for introspection, and functions which take
several arguments use METH_FASTCALL instead of METH_VARARGS.

ioctl(), sendto() and setsockopt() are left as they are.  Their
behaviour depends on the number of the arguments or on the value of a
preceding argument, which Argument Clinic cannot express.

files:
M Include/internal/pycore_global_objects_fini_generated.h
M Include/internal/pycore_global_strings.h
M Include/internal/pycore_runtime_init_generated.h
M Include/internal/pycore_unicodeobject_generated.h
M Lib/test/test_inspect/test_inspect.py
M Modules/clinic/socketmodule.c.h
M Modules/socketmodule.c

diff --git a/Include/internal/pycore_global_objects_fini_generated.h b/Include/internal/pycore_global_objects_fini_generated.h
index 6df1c01f151f68e..c982f76431c52d1 100644
--- a/Include/internal/pycore_global_objects_fini_generated.h
+++ b/Include/internal/pycore_global_objects_fini_generated.h
@@ -1596,6 +1596,7 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(argv));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(as_integer_ratio));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(asend));
+    _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(assoclen));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(ast));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(athrow));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(attr));
@@ -1811,6 +1812,7 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(headers));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(hi));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(hook));
+    _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(host));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(hour));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(hours));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(id));
@@ -1859,6 +1861,7 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(iter));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(iterable));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(iterations));
+    _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(iv));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(join));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(jump));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(keepends));
@@ -1937,6 +1940,7 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(namespace_separator));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(namespaces));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(native));
+    _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(nbytes));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(ndigits));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(nested));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(new_file_name));
@@ -1961,6 +1965,7 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(onceregistry));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(only_active_thread));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(only_keys));
+    _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(op));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(oparg));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(opcode));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(opcodes));
@@ -1995,6 +2000,7 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(pidfd));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(pointer_bits));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(policy));
+    _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(port));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(pos));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(pos1));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(pos2));
diff --git a/Include/internal/pycore_global_strings.h b/Include/internal/pycore_global_strings.h
index 873344fbdcb67b0..c430d0fb99bc41d 100644
--- a/Include/internal/pycore_global_strings.h
+++ b/Include/internal/pycore_global_strings.h
@@ -319,6 +319,7 @@ struct _Py_global_strings {
         STRUCT_FOR_ID(argv)
         STRUCT_FOR_ID(as_integer_ratio)
         STRUCT_FOR_ID(asend)
+        STRUCT_FOR_ID(assoclen)
         STRUCT_FOR_ID(ast)
         STRUCT_FOR_ID(athrow)
         STRUCT_FOR_ID(attr)
@@ -534,6 +535,7 @@ struct _Py_global_strings {
         STRUCT_FOR_ID(headers)
         STRUCT_FOR_ID(hi)
         STRUCT_FOR_ID(hook)
+        STRUCT_FOR_ID(host)
         STRUCT_FOR_ID(hour)
         STRUCT_FOR_ID(hours)
         STRUCT_FOR_ID(id)
@@ -582,6 +584,7 @@ struct _Py_global_strings {
         STRUCT_FOR_ID(iter)
         STRUCT_FOR_ID(iterable)
         STRUCT_FOR_ID(iterations)
+        STRUCT_FOR_ID(iv)
         STRUCT_FOR_ID(join)
         STRUCT_FOR_ID(jump)
         STRUCT_FOR_ID(keepends)
@@ -660,6 +663,7 @@ struct _Py_global_strings {
         STRUCT_FOR_ID(namespace_separator)
         STRUCT_FOR_ID(namespaces)
         STRUCT_FOR_ID(native)
+        STRUCT_FOR_ID(nbytes)
         STRUCT_FOR_ID(ndigits)
         STRUCT_FOR_ID(nested)
         STRUCT_FOR_ID(new_file_name)
@@ -684,6 +688,7 @@ struct _Py_global_strings {
         STRUCT_FOR_ID(onceregistry)
         STRUCT_FOR_ID(only_active_thread)
         STRUCT_FOR_ID(only_keys)
+        STRUCT_FOR_ID(op)
         STRUCT_FOR_ID(oparg)
         STRUCT_FOR_ID(opcode)
         STRUCT_FOR_ID(opcodes)
@@ -718,6 +723,7 @@ struct _Py_global_strings {
         STRUCT_FOR_ID(pidfd)
         STRUCT_FOR_ID(pointer_bits)
         STRUCT_FOR_ID(policy)
+        STRUCT_FOR_ID(port)
         STRUCT_FOR_ID(pos)
         STRUCT_FOR_ID(pos1)
         STRUCT_FOR_ID(pos2)
diff --git a/Include/internal/pycore_runtime_init_generated.h b/Include/internal/pycore_runtime_init_generated.h
index 378f27ca17b5079..5a194478f562314 100644
--- a/Include/internal/pycore_runtime_init_generated.h
+++ b/Include/internal/pycore_runtime_init_generated.h
@@ -1594,6 +1594,7 @@ extern "C" {
     INIT_ID(argv), \
     INIT_ID(as_integer_ratio), \
     INIT_ID(asend), \
+    INIT_ID(assoclen), \
     INIT_ID(ast), \
     INIT_ID(athrow), \
     INIT_ID(attr), \
@@ -1809,6 +1810,7 @@ extern "C" {
     INIT_ID(headers), \
     INIT_ID(hi), \
     INIT_ID(hook), \
+    INIT_ID(host), \
     INIT_ID(hour), \
     INIT_ID(hours), \
     INIT_ID(id), \
@@ -1857,6 +1859,7 @@ extern "C" {
     INIT_ID(iter), \
     INIT_ID(iterable), \
     INIT_ID(iterations), \
+    INIT_ID(iv), \
     INIT_ID(join), \
     INIT_ID(jump), \
     INIT_ID(keepends), \
@@ -1935,6 +1938,7 @@ extern "C" {
     INIT_ID(namespace_separator), \
     INIT_ID(namespaces), \
     INIT_ID(native), \
+    INIT_ID(nbytes), \
     INIT_ID(ndigits), \
     INIT_ID(nested), \
     INIT_ID(new_file_name), \
@@ -1959,6 +1963,7 @@ extern "C" {
     INIT_ID(onceregistry), \
     INIT_ID(only_active_thread), \
     INIT_ID(only_keys), \
+    INIT_ID(op), \
     INIT_ID(oparg), \
     INIT_ID(opcode), \
     INIT_ID(opcodes), \
@@ -1993,6 +1998,7 @@ extern "C" {
     INIT_ID(pidfd), \
     INIT_ID(pointer_bits), \
     INIT_ID(policy), \
+    INIT_ID(port), \
     INIT_ID(pos), \
     INIT_ID(pos1), \
     INIT_ID(pos2), \
diff --git a/Include/internal/pycore_unicodeobject_generated.h b/Include/internal/pycore_unicodeobject_generated.h
index daf6840aa47f328..25529c5ca713a95 100644
--- a/Include/internal/pycore_unicodeobject_generated.h
+++ b/Include/internal/pycore_unicodeobject_generated.h
@@ -1056,6 +1056,10 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
     _PyUnicode_InternStatic(interp, &string);
     assert(_PyUnicode_CheckConsistency(string, 1));
     assert(PyUnicode_GET_LENGTH(string) != 1);
+    string = &_Py_ID(assoclen);
+    _PyUnicode_InternStatic(interp, &string);
+    assert(_PyUnicode_CheckConsistency(string, 1));
+    assert(PyUnicode_GET_LENGTH(string) != 1);
     string = &_Py_ID(ast);
     _PyUnicode_InternStatic(interp, &string);
     assert(_PyUnicode_CheckConsistency(string, 1));
@@ -1916,6 +1920,10 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
     _PyUnicode_InternStatic(interp, &string);
     assert(_PyUnicode_CheckConsistency(string, 1));
     assert(PyUnicode_GET_LENGTH(string) != 1);
+    string = &_Py_ID(host);
+    _PyUnicode_InternStatic(interp, &string);
+    assert(_PyUnicode_CheckConsistency(string, 1));
+    assert(PyUnicode_GET_LENGTH(string) != 1);
     string = &_Py_ID(hour);
     _PyUnicode_InternStatic(interp, &string);
     assert(_PyUnicode_CheckConsistency(string, 1));
@@ -2108,6 +2116,10 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
     _PyUnicode_InternStatic(interp, &string);
     assert(_PyUnicode_CheckConsistency(string, 1));
     assert(PyUnicode_GET_LENGTH(string) != 1);
+    string = &_Py_ID(iv);
+    _PyUnicode_InternStatic(interp, &string);
+    assert(_PyUnicode_CheckConsistency(string, 1));
+    assert(PyUnicode_GET_LENGTH(string) != 1);
     string = &_Py_ID(join);
     _PyUnicode_InternStatic(interp, &string);
     assert(_PyUnicode_CheckConsistency(string, 1));
@@ -2420,6 +2432,10 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
     _PyUnicode_InternStatic(interp, &string);
     assert(_PyUnicode_CheckConsistency(string, 1));
     assert(PyUnicode_GET_LENGTH(string) != 1);
+    string = &_Py_ID(nbytes);
+    _PyUnicode_InternStatic(interp, &string);
+    assert(_PyUnicode_CheckConsistency(string, 1));
+    assert(PyUnicode_GET_LENGTH(string) != 1);
     string = &_Py_ID(ndigits);
     _PyUnicode_InternStatic(interp, &string);
     assert(_PyUnicode_CheckConsistency(string, 1));
@@ -2516,6 +2532,10 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
     _PyUnicode_InternStatic(interp, &string);
     assert(_PyUnicode_CheckConsistency(string, 1));
     assert(PyUnicode_GET_LENGTH(string) != 1);
+    string = &_Py_ID(op);
+    _PyUnicode_InternStatic(interp, &string);
+    assert(_PyUnicode_CheckConsistency(string, 1));
+    assert(PyUnicode_GET_LENGTH(string) != 1);
     string = &_Py_ID(oparg);
     _PyUnicode_InternStatic(interp, &string);
     assert(_PyUnicode_CheckConsistency(string, 1));
@@ -2652,6 +2672,10 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
     _PyUnicode_InternStatic(interp, &string);
     assert(_PyUnicode_CheckConsistency(string, 1));
     assert(PyUnicode_GET_LENGTH(string) != 1);
+    string = &_Py_ID(port);
+    _PyUnicode_InternStatic(interp, &string);
+    assert(_PyUnicode_CheckConsistency(string, 1));
+    assert(PyUnicode_GET_LENGTH(string) != 1);
     string = &_Py_ID(pos);
     _PyUnicode_InternStatic(interp, &string);
     assert(_PyUnicode_CheckConsistency(string, 1));
diff --git a/Lib/test/test_inspect/test_inspect.py b/Lib/test/test_inspect/test_inspect.py
index 844811692df2d6d..76c346cd89eac04 100644
--- a/Lib/test/test_inspect/test_inspect.py
+++ b/Lib/test/test_inspect/test_inspect.py
@@ -6328,6 +6328,25 @@ def test_signal_module_has_signatures(self):
         import signal
         self._test_module_has_signatures(signal)
 
+    def test_socket_module_has_signatures(self):
+        import socket
+        # The socket type has no signature, it is created by socket().
+        no_signature = {'SocketType'}
+        # The C default is NULL and None is not accepted
+        unsupported_signature = {'getservbyname', 'getservbyport'}
+        # Not all functions and methods are available on all platforms.
+        unsupported_signature &= vars(socket).keys()
+        # These cannot be converted to Argument Clinic: their behaviour
+        # depends on the number of the arguments.
+        methods_no_signature = {'ioctl', 'sendto', 'setsockopt'}
+        # These have parameters with unrepresentable default values.
+        methods_unsupported_signature = {'listen', 'sendmsg', 'sendmsg_afalg'}
+        defined = vars(socket.SocketType).keys()
+        self._test_module_has_signatures(socket,
+                no_signature, unsupported_signature,
+                {'SocketType': methods_no_signature & defined},
+                {'SocketType': methods_unsupported_signature & defined})
+
     def test_stat_module_has_signatures(self):
         import stat
         self._test_module_has_signatures(stat)
diff --git a/Modules/clinic/socketmodule.c.h b/Modules/clinic/socketmodule.c.h
index b565e7516d50f33..00e5fb4cde3aefd 100644
--- a/Modules/clinic/socketmodule.c.h
+++ b/Modules/clinic/socketmodule.c.h
@@ -6,29 +6,917 @@ preserve
 #  include "pycore_gc.h"          // PyGC_Head
 #  include "pycore_runtime.h"     // _Py_ID()
 #endif
+#include "pycore_abstract.h"      // _PyNumber_Index()
 #include "pycore_long.h"          // _PyLong_UInt16_Converter()
 #include "pycore_modsupport.h"    // _PyArg_CheckPositional()
 
+#if (defined(HAVE_ACCEPT) || defined(HAVE_ACCEPT4))
+
+PyDoc_STRVAR(_socket_socket__accept__doc__,
+"_accept($self, /)\n"
+"--\n"
+"\n"
+"Wait for an incoming connection.\n"
+"\n"
+"Return a new socket file descriptor representing the connection, and\n"
+"the address of the client.  For IP sockets, the address info is a\n"
+"pair (hostaddr, port).");
+
+#define _SOCKET_SOCKET__ACCEPT_METHODDEF    \
+    {"_accept", (PyCFunction)_socket_socket__accept, METH_NOARGS, _socket_socket__accept__doc__},
+
+static PyObject *
+_socket_socket__accept_impl(PySocketSockObject *s);
+
+static PyObject *
+_socket_socket__accept(PyObject *s, PyObject *Py_UNUSED(ignored))
+{
+    return _socket_socket__accept_impl((PySocketSockObject *)s);
+}
+
+#endif /* (defined(HAVE_ACCEPT) || defined(HAVE_ACCEPT4)) */
+
+PyDoc_STRVAR(_socket_socket_setblocking__doc__,
+"setblocking($self, flag, /)\n"
+"--\n"
+"\n"
+"Set the socket to blocking (flag is true) or non-blocking (false).\n"
+"\n"
+"setblocking(True) is equivalent to settimeout(None);\n"
+"setblocking(False) is equivalent to settimeout(0.0).");
+
+#define _SOCKET_SOCKET_SETBLOCKING_METHODDEF    \
+    {"setblocking", (PyCFunction)_socket_socket_setblocking, METH_O, _socket_socket_setblocking__doc__},
+
+static PyObject *
+_socket_socket_setblocking_impl(PySocketSockObject *s, int flag);
+
+static PyObject *
+_socket_socket_setblocking(PyObject *s, PyObject *arg)
+{
+    PyObject *return_value = NULL;
+    int flag;
+
+    flag = PyObject_IsTrue(arg);
+    if (flag < 0) {
+        goto exit;
+    }
+    return_value = _socket_socket_setblocking_impl((PySocketSockObject *)s, flag);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(_socket_socket_getblocking__doc__,
+"getblocking($self, /)\n"
+"--\n"
+"\n"
+"Return True if socket is in blocking mode, False if in non-blocking.");
+
+#define _SOCKET_SOCKET_GETBLOCKING_METHODDEF    \
+    {"getblocking", (PyCFunction)_socket_socket_getblocking, METH_NOARGS, _socket_socket_getblocking__doc__},
+
+static PyObject *
+_socket_socket_getblocking_impl(PySocketSockObject *s);
+
+static PyObject *
+_socket_socket_getblocking(PyObject *s, PyObject *Py_UNUSED(ignored))
+{
+    return _socket_socket_getblocking_impl((PySocketSockObject *)s);
+}
+
+PyDoc_STRVAR(_socket_socket_settimeout__doc__,
+"settimeout($self, timeout, /)\n"
+"--\n"
+"\n"
+"Set a timeout on socket operations.\n"
+"\n"
+"\'timeout\' can be a float, giving in seconds, or None.  Setting a\n"
+"timeout of None disables the timeout feature and is equivalent to\n"
+"setblocking(1).  Setting a timeout of zero is the same as\n"
+"setblocking(0).");
+
+#define _SOCKET_SOCKET_SETTIMEOUT_METHODDEF    \
+    {"settimeout", (PyCFunction)_socket_socket_settimeout, METH_O, _socket_socket_settimeout__doc__},
+
+static PyObject *
+_socket_socket_settimeout_impl(PySocketSockObject *s, PyObject *arg);
+
+static PyObject *
+_socket_socket_settimeout(PyObject *s, PyObject *arg)
+{
+    PyObject *return_value = NULL;
+
+    return_value = _socket_socket_settimeout_impl((PySocketSockObject *)s, arg);
+
+    return return_value;
+}
+
+PyDoc_STRVAR(_socket_socket_gettimeout__doc__,
+"gettimeout($self, /)\n"
+"--\n"
+"\n"
+"Return the timeout in seconds (float) of socket operations.\n"
+"\n"
+"A timeout of None indicates that timeouts on socket operations are\n"
+"disabled.");
+
+#define _SOCKET_SOCKET_GETTIMEOUT_METHODDEF    \
+    {"gettimeout", (PyCFunction)_socket_socket_gettimeout, METH_NOARGS, _socket_socket_gettimeout__doc__},
+
+static PyObject *
+_socket_socket_gettimeout_impl(PySocketSockObject *self);
+
+static PyObject *
+_socket_socket_gettimeout(PyObject *self, PyObject *Py_UNUSED(ignored))
+{
+    return _socket_socket_gettimeout_impl((PySocketSockObject *)self);
+}
+
+PyDoc_STRVAR(_socket_socket_getsockopt__doc__,
+"getsockopt($self, level, option, buffersize=0, /)\n"
+"--\n"
+"\n"
+"Get a socket option.\n"
+"\n"
+"See the Unix manual for level and option.  If a nonzero buffersize\n"
+"argument is given, the return value is a bytes object of that\n"
+"length; otherwise it is an integer.");
+
+#define _SOCKET_SOCKET_GETSOCKOPT_METHODDEF    \
+    {"getsockopt", _PyCFunction_CAST(_socket_socket_getsockopt), METH_FASTCALL, _socket_socket_getsockopt__doc__},
+
+static PyObject *
+_socket_socket_getsockopt_impl(PySocketSockObject *s, int level, int optname,
+                               int buflen);
+
+static PyObject *
+_socket_socket_getsockopt(PyObject *s, PyObject *const *args, Py_ssize_t nargs)
+{
+    PyObject *return_value = NULL;
+    int level;
+    int optname;
+    int buflen = 0;
+
+    if (!_PyArg_CheckPositional("getsockopt", nargs, 2, 3)) {
+        goto exit;
+    }
+    level = PyLong_AsInt(args[0]);
+    if (level == -1 && PyErr_Occurred()) {
+        goto exit;
+    }
+    optname = PyLong_AsInt(args[1]);
+    if (optname == -1 && PyErr_Occurred()) {
+        goto exit;
+    }
+    if (nargs < 3) {
+        goto skip_optional;
+    }
+    buflen = PyLong_AsInt(args[2]);
+    if (buflen == -1 && PyErr_Occurred()) {
+        goto exit;
+    }
+skip_optional:
+    return_value = _socket_socket_getsockopt_impl((PySocketSockObject *)s, level, optname, buflen);
+
+exit:
+    return return_value;
+}
+
+#if defined(HAVE_BIND)
+
+PyDoc_STRVAR(_socket_socket_bind__doc__,
+"bind($self, address, /)\n"
+"--\n"
+"\n"
+"Bind the socket to a local address.\n"
+"\n"
+"For IP sockets, the address is a pair (host, port); the host must\n"
+"refer to the local host.  For raw packet sockets the address is a\n"
+"tuple (ifname, proto [,pkttype [,hatype [,addr]]]).");
+
+#define _SOCKET_SOCKET_BIND_METHODDEF    \
+    {"bind", (PyCFunction)_socket_socket_bind, METH_O, _socket_socket_bind__doc__},
+
+static PyObject *
+_socket_socket_bind_impl(PySocketSockObject *s, PyObject *addro);
+
+static PyObject *
+_socket_socket_bind(PyObject *s, PyObject *addro)
+{
+    PyObject *return_value = NULL;
+
+    return_value = _socket_socket_bind_impl((PySocketSockObject *)s, addro);
+
+    return return_value;
+}
+
+#endif /* defined(HAVE_BIND) */
+
 PyDoc_STRVAR(_socket_socket_close__doc__,
 "close($self, /)\n"
 "--\n"
 "\n"
-"close()\n"
+"close()\n"
+"\n"
+"Close the socket.  It cannot be used after this call.");
+
+#define _SOCKET_SOCKET_CLOSE_METHODDEF    \
+    {"close", (PyCFunction)_socket_socket_close, METH_NOARGS, _socket_socket_close__doc__},
+
+static PyObject *
+_socket_socket_close_impl(PySocketSockObject *s);
+
+static PyObject *
+_socket_socket_close(PyObject *s, PyObject *Py_UNUSED(ignored))
+{
+    return _socket_socket_close_impl((PySocketSockObject *)s);
+}
+
+PyDoc_STRVAR(_socket_socket_detach__doc__,
+"detach($self, /)\n"
+"--\n"
+"\n"
+"Close the socket object without closing the file descriptor.\n"
+"\n"
+"The object cannot be used after this call, but the file descriptor\n"
+"can be reused for other purposes.  The file descriptor is returned.");
+
+#define _SOCKET_SOCKET_DETACH_METHODDEF    \
+    {"detach", (PyCFunction)_socket_socket_detach, METH_NOARGS, _socket_socket_detach__doc__},
+
+static PyObject *
+_socket_socket_detach_impl(PySocketSockObject *s);
+
+static PyObject *
+_socket_socket_detach(PyObject *s, PyObject *Py_UNUSED(ignored))
+{
+    return _socket_socket_detach_impl((PySocketSockObject *)s);
+}
+
+#if defined(HAVE_CONNECT)
+
+PyDoc_STRVAR(_socket_socket_connect__doc__,
+"connect($self, address, /)\n"
+"--\n"
+"\n"
+"Connect the socket to a remote address.\n"
+"\n"
+"For IP sockets, the address is a pair (host, port).");
+
+#define _SOCKET_SOCKET_CONNECT_METHODDEF    \
+    {"connect", (PyCFunction)_socket_socket_connect, METH_O, _socket_socket_connect__doc__},
+
+static PyObject *
+_socket_socket_connect_impl(PySocketSockObject *s, PyObject *addro);
+
+static PyObject *
+_socket_socket_connect(PyObject *s, PyObject *addro)
+{
+    PyObject *return_value = NULL;
+
+    return_value = _socket_socket_connect_impl((PySocketSockObject *)s, addro);
+
+    return return_value;
+}
+
+#endif /* defined(HAVE_CONNECT) */
+
+#if defined(HAVE_CONNECT)
+
+PyDoc_STRVAR(_socket_socket_connect_ex__doc__,
+"connect_ex($self, address, /)\n"
+"--\n"
+"\n"
+"Connect the socket to a remote address.\n"
+"\n"
+"This is like connect(address), but returns an error code (the errno\n"
+"value) instead of raising an exception when an error occurs.");
+
+#define _SOCKET_SOCKET_CONNECT_EX_METHODDEF    \
+    {"connect_ex", (PyCFunction)_socket_socket_connect_ex, METH_O, _socket_socket_connect_ex__doc__},
+
+static PyObject *
+_socket_socket_connect_ex_impl(PySocketSockObject *s, PyObject *addro);
+
+static PyObject *
+_socket_socket_connect_ex(PyObject *s, PyObject *addro)
+{
+    PyObject *return_value = NULL;
+
+    return_value = _socket_socket_connect_ex_impl((PySocketSockObject *)s, addro);
+
+    return return_value;
+}
+
+#endif /* defined(HAVE_CONNECT) */
+
+PyDoc_STRVAR(_socket_socket_fileno__doc__,
+"fileno($self, /)\n"
+"--\n"
+"\n"
+"Return the integer file descriptor of the socket.");
+
+#define _SOCKET_SOCKET_FILENO_METHODDEF    \
+    {"fileno", (PyCFunction)_socket_socket_fileno, METH_NOARGS, _socket_socket_fileno__doc__},
+
+static PyObject *
+_socket_socket_fileno_impl(PySocketSockObject *s);
+
+static PyObject *
+_socket_socket_fileno(PyObject *s, PyObject *Py_UNUSED(ignored))
+{
+    return _socket_socket_fileno_impl((PySocketSockObject *)s);
+}
+
+#if defined(HAVE_GETSOCKNAME)
+
+PyDoc_STRVAR(_socket_socket_getsockname__doc__,
+"getsockname($self, /)\n"
+"--\n"
+"\n"
+"Return the address of the local endpoint.\n"
+"\n"
+"The format depends on the address family.  For IPv4 sockets, the\n"
+"address info is a pair (hostaddr, port). For IPv6 sockets, the\n"
+"address info is a 4-tuple (hostaddr, port, flowinfo, scope_id).");
+
+#define _SOCKET_SOCKET_GETSOCKNAME_METHODDEF    \
+    {"getsockname", (PyCFunction)_socket_socket_getsockname, METH_NOARGS, _socket_socket_getsockname__doc__},
+
+static PyObject *
+_socket_socket_getsockname_impl(PySocketSockObject *s);
+
+static PyObject *
+_socket_socket_getsockname(PyObject *s, PyObject *Py_UNUSED(ignored))
+{
+    return _socket_socket_getsockname_impl((PySocketSockObject *)s);
+}
+
+#endif /* defined(HAVE_GETSOCKNAME) */
+
+#if defined(HAVE_GETPEERNAME)
+
+PyDoc_STRVAR(_socket_socket_getpeername__doc__,
+"getpeername($self, /)\n"
+"--\n"
+"\n"
+"Return the address of the remote endpoint.\n"
+"\n"
+"For IP sockets, the address info is a pair (hostaddr, port).");
+
+#define _SOCKET_SOCKET_GETPEERNAME_METHODDEF    \
+    {"getpeername", (PyCFunction)_socket_socket_getpeername, METH_NOARGS, _socket_socket_getpeername__doc__},
+
+static PyObject *
+_socket_socket_getpeername_impl(PySocketSockObject *s);
+
+static PyObject *
+_socket_socket_getpeername(PyObject *s, PyObject *Py_UNUSED(ignored))
+{
+    return _socket_socket_getpeername_impl((PySocketSockObject *)s);
+}
+
+#endif /* defined(HAVE_GETPEERNAME) */
+
+#if defined(HAVE_LISTEN)
+
+PyDoc_STRVAR(_socket_socket_listen__doc__,
+"listen($self, backlog=min(SOMAXCONN, 128), /)\n"
+"--\n"
+"\n"
+"Enable a server to accept connections.\n"
+"\n"
+"If backlog is specified, it must be at least 0 (if it is lower, it\n"
+"is set to 0); it specifies the number of unaccepted connections that\n"
+"the system will allow before refusing new connections. If not\n"
+"specified, a default reasonable value is chosen.");
+
+#define _SOCKET_SOCKET_LISTEN_METHODDEF    \
+    {"listen", _PyCFunction_CAST(_socket_socket_listen), METH_FASTCALL, _socket_socket_listen__doc__},
+
+static PyObject *
+_socket_socket_listen_impl(PySocketSockObject *s, int backlog);
+
+static PyObject *
+_socket_socket_listen(PyObject *s, PyObject *const *args, Py_ssize_t nargs)
+{
+    PyObject *return_value = NULL;
+    int backlog = Py_MIN(SOMAXCONN, 128);
+
+    if (!_PyArg_CheckPositional("listen", nargs, 0, 1)) {
+        goto exit;
+    }
+    if (nargs < 1) {
+        goto skip_optional;
+    }
+    backlog = PyLong_AsInt(args[0]);
+    if (backlog == -1 && PyErr_Occurred()) {
+        goto exit;
+    }
+skip_optional:
+    return_value = _socket_socket_listen_impl((PySocketSockObject *)s, backlog);
+
+exit:
+    return return_value;
+}
+
+#endif /* defined(HAVE_LISTEN) */
+
+PyDoc_STRVAR(_socket_socket_recv__doc__,
+"recv($self, buffersize, flags=0, /)\n"
+"--\n"
+"\n"
+"Receive up to buffersize bytes from the socket.\n"
+"\n"
+"For the optional flags argument, see the Unix manual. When no data\n"
+"is available, block until at least one byte is available or until\n"
+"the remote end is closed. When the remote end is closed and all data\n"
+"is read, return the empty string.");
+
+#define _SOCKET_SOCKET_RECV_METHODDEF    \
+    {"recv", _PyCFunction_CAST(_socket_socket_recv), METH_FASTCALL, _socket_socket_recv__doc__},
+
+static PyObject *
+_socket_socket_recv_impl(PySocketSockObject *s, Py_ssize_t recvlen,
+                         int flags);
+
+static PyObject *
+_socket_socket_recv(PyObject *s, PyObject *const *args, Py_ssize_t nargs)
+{
+    PyObject *return_value = NULL;
+    Py_ssize_t recvlen;
+    int flags = 0;
+
+    if (!_PyArg_CheckPositional("recv", nargs, 1, 2)) {
+        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;
+        }
+        recvlen = ival;
+    }
+    if (nargs < 2) {
+        goto skip_optional;
+    }
+    flags = PyLong_AsInt(args[1]);
+    if (flags == -1 && PyErr_Occurred()) {
+        goto exit;
+    }
+skip_optional:
+    return_value = _socket_socket_recv_impl((PySocketSockObject *)s, recvlen, flags);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(_socket_socket_recv_into__doc__,
+"recv_into($self, /, buffer, nbytes=0, flags=0)\n"
+"--\n"
+"\n"
+"Receive up to nbytes bytes from the socket, storing into a buffer.\n"
+"\n"
+"A version of recv() that stores its data into a buffer rather than\n"
+"creating a new bytes object.  If nbytes is not specified (or 0),\n"
+"receive up to the size available in the given buffer.\n"
+"\n"
+"See recv() for documentation about the flags.");
+
+#define _SOCKET_SOCKET_RECV_INTO_METHODDEF    \
+    {"recv_into", _PyCFunction_CAST(_socket_socket_recv_into), METH_FASTCALL|METH_KEYWORDS, _socket_socket_recv_into__doc__},
+
+static PyObject *
+_socket_socket_recv_into_impl(PySocketSockObject *s, Py_buffer *pbuf,
+                              Py_ssize_t recvlen, int flags);
+
+static PyObject *
+_socket_socket_recv_into(PyObject *s, 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(buffer), &_Py_ID(nbytes), &_Py_ID(flags), },
+    };
+    #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[] = {"buffer", "nbytes", "flags", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "recv_into",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[3];
+    Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1;
+    Py_buffer pbuf = {NULL, NULL};
+    Py_ssize_t recvlen = 0;
+    int flags = 0;
+
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 1, /*maxpos*/ 3, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
+        goto exit;
+    }
+    if (PyObject_GetBuffer(args[0], &pbuf, PyBUF_WRITABLE) < 0) {
+        _PyArg_BadArgument("recv_into", "argument 'buffer'", "read-write bytes-like object", args[0]);
+        goto exit;
+    }
+    if (!noptargs) {
+        goto skip_optional_pos;
+    }
+    if (args[1]) {
+        {
+            Py_ssize_t ival = -1;
+            PyObject *iobj = _PyNumber_Index(args[1]);
+            if (iobj != NULL) {
+                ival = PyLong_AsSsize_t(iobj);
+                Py_DECREF(iobj);
+            }
+            if (ival == -1 && PyErr_Occurred()) {
+                goto exit;
+            }
+            recvlen = ival;
+        }
+        if (!--noptargs) {
+            goto skip_optional_pos;
+        }
+    }
+    flags = PyLong_AsInt(args[2]);
+    if (flags == -1 && PyErr_Occurred()) {
+        goto exit;
+    }
+skip_optional_pos:
+    return_value = _socket_socket_recv_into_impl((PySocketSockObject *)s, &pbuf, recvlen, flags);
+
+exit:
+    /* Cleanup for pbuf */
+    if (pbuf.obj) {
+       PyBuffer_Release(&pbuf);
+    }
+
+    return return_value;
+}
+
+#if defined(HAVE_RECVFROM)
+
+PyDoc_STRVAR(_socket_socket_recvfrom__doc__,
+"recvfrom($self, buffersize, flags=0, /)\n"
+"--\n"
+"\n"
+"Receive up to buffersize bytes and the sender\'s address info.\n"
+"\n"
+"Like recv(buffersize, flags), but return a (data, address info)\n"
+"pair.");
+
+#define _SOCKET_SOCKET_RECVFROM_METHODDEF    \
+    {"recvfrom", _PyCFunction_CAST(_socket_socket_recvfrom), METH_FASTCALL, _socket_socket_recvfrom__doc__},
+
+static PyObject *
+_socket_socket_recvfrom_impl(PySocketSockObject *s, Py_ssize_t recvlen,
+                             int flags);
+
+static PyObject *
+_socket_socket_recvfrom(PyObject *s, PyObject *const *args, Py_ssize_t nargs)
+{
+    PyObject *return_value = NULL;
+    Py_ssize_t recvlen;
+    int flags = 0;
+
+    if (!_PyArg_CheckPositional("recvfrom", nargs, 1, 2)) {
+        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;
+        }
+        recvlen = ival;
+    }
+    if (nargs < 2) {
+        goto skip_optional;
+    }
+    flags = PyLong_AsInt(args[1]);
+    if (flags == -1 && PyErr_Occurred()) {
+        goto exit;
+    }
+skip_optional:
+    return_value = _socket_socket_recvfrom_impl((PySocketSockObject *)s, recvlen, flags);
+
+exit:
+    return return_value;
+}
+
+#endif /* defined(HAVE_RECVFROM) */
+
+#if defined(HAVE_RECVFROM)
+
+PyDoc_STRVAR(_socket_socket_recvfrom_into__doc__,
+"recvfrom_into($self, /, buffer, nbytes=0, flags=0)\n"
+"--\n"
+"\n"
+"Receive up to nbytes bytes and the sender\'s address info.\n"
+"\n"
+"Like recv_into(buffer, nbytes, flags), but return a (nbytes, address\n"
+"info) pair.");
+
+#define _SOCKET_SOCKET_RECVFROM_INTO_METHODDEF    \
+    {"recvfrom_into", _PyCFunction_CAST(_socket_socket_recvfrom_into), METH_FASTCALL|METH_KEYWORDS, _socket_socket_recvfrom_into__doc__},
+
+static PyObject *
+_socket_socket_recvfrom_into_impl(PySocketSockObject *s, Py_buffer *pbuf,
+                                  Py_ssize_t recvlen, int flags);
+
+static PyObject *
+_socket_socket_recvfrom_into(PyObject *s, 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(buffer), &_Py_ID(nbytes), &_Py_ID(flags), },
+    };
+    #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[] = {"buffer", "nbytes", "flags", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "recvfrom_into",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[3];
+    Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1;
+    Py_buffer pbuf = {NULL, NULL};
+    Py_ssize_t recvlen = 0;
+    int flags = 0;
+
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 1, /*maxpos*/ 3, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
+        goto exit;
+    }
+    if (PyObject_GetBuffer(args[0], &pbuf, PyBUF_WRITABLE) < 0) {
+        _PyArg_BadArgument("recvfrom_into", "argument 'buffer'", "read-write bytes-like object", args[0]);
+        goto exit;
+    }
+    if (!noptargs) {
+        goto skip_optional_pos;
+    }
+    if (args[1]) {
+        {
+            Py_ssize_t ival = -1;
+            PyObject *iobj = _PyNumber_Index(args[1]);
+            if (iobj != NULL) {
+                ival = PyLong_AsSsize_t(iobj);
+                Py_DECREF(iobj);
+            }
+            if (ival == -1 && PyErr_Occurred()) {
+                goto exit;
+            }
+            recvlen = ival;
+        }
+        if (!--noptargs) {
+            goto skip_optional_pos;
+        }
+    }
+    flags = PyLong_AsInt(args[2]);
+    if (flags == -1 && PyErr_Occurred()) {
+        goto exit;
+    }
+skip_optional_pos:
+    return_value = _socket_socket_recvfrom_into_impl((PySocketSockObject *)s, &pbuf, recvlen, flags);
+
+exit:
+    /* Cleanup for pbuf */
+    if (pbuf.obj) {
+       PyBuffer_Release(&pbuf);
+    }
+
+    return return_value;
+}
+
+#endif /* defined(HAVE_RECVFROM) */
+
+#if defined(CMSG_LEN)
+
+PyDoc_STRVAR(_socket_socket_recvmsg__doc__,
+"recvmsg($self, bufsize, ancbufsize=0, flags=0, /)\n"
+"--\n"
+"\n"
+"Receive normal data and ancillary data from the socket.\n"
 "\n"
-"Close the socket.  It cannot be used after this call.");
+"Receive up to bufsize bytes of normal data.  The ancbufsize argument\n"
+"sets the size in bytes of the internal buffer used to receive the\n"
+"ancillary data; it defaults to 0, meaning that no ancillary data\n"
+"will be received.  Appropriate buffer sizes for ancillary data can\n"
+"be calculated using CMSG_SPACE() or CMSG_LEN(), and items which do\n"
+"not fit into the buffer might be truncated or discarded.  The flags\n"
+"argument defaults to 0 and has the same meaning as for recv().\n"
+"\n"
+"The return value is a 4-tuple: (data, ancdata, msg_flags, address).\n"
+"The data item is a bytes object holding the non-ancillary data\n"
+"received.  The ancdata item is a list of zero or more tuples\n"
+"(cmsg_level, cmsg_type, cmsg_data) representing the ancillary data\n"
+"(control messages) received: cmsg_level and cmsg_type are integers\n"
+"specifying the protocol level and protocol-specific type\n"
+"respectively, and cmsg_data is a bytes object holding the associated\n"
+"data.  The msg_flags item is the bitwise OR of various flags\n"
+"indicating conditions on the received message; see your system\n"
+"documentation for details.  If the receiving socket is unconnected,\n"
+"address is the address of the sending socket, if available;\n"
+"otherwise, its value is unspecified.\n"
+"\n"
+"If recvmsg() raises an exception after the system call returns, it\n"
+"will first attempt to close any file descriptors received via the\n"
+"SCM_RIGHTS mechanism.");
 
-#define _SOCKET_SOCKET_CLOSE_METHODDEF    \
-    {"close", (PyCFunction)_socket_socket_close, METH_NOARGS, _socket_socket_close__doc__},
+#define _SOCKET_SOCKET_RECVMSG_METHODDEF    \
+    {"recvmsg", _PyCFunction_CAST(_socket_socket_recvmsg), METH_FASTCALL, _socket_socket_recvmsg__doc__},
 
 static PyObject *
-_socket_socket_close_impl(PySocketSockObject *s);
+_socket_socket_recvmsg_impl(PySocketSockObject *s, Py_ssize_t bufsize,
+                            Py_ssize_t ancbufsize, int flags);
 
 static PyObject *
-_socket_socket_close(PyObject *s, PyObject *Py_UNUSED(ignored))
+_socket_socket_recvmsg(PyObject *s, PyObject *const *args, Py_ssize_t nargs)
 {
-    return _socket_socket_close_impl((PySocketSockObject *)s);
+    PyObject *return_value = NULL;
+    Py_ssize_t bufsize;
+    Py_ssize_t ancbufsize = 0;
+    int flags = 0;
+
+    if (!_PyArg_CheckPositional("recvmsg", nargs, 1, 3)) {
+        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;
+        }
+        bufsize = ival;
+    }
+    if (nargs < 2) {
+        goto skip_optional;
+    }
+    {
+        Py_ssize_t ival = -1;
+        PyObject *iobj = _PyNumber_Index(args[1]);
+        if (iobj != NULL) {
+            ival = PyLong_AsSsize_t(iobj);
+            Py_DECREF(iobj);
+        }
+        if (ival == -1 && PyErr_Occurred()) {
+            goto exit;
+        }
+        ancbufsize = ival;
+    }
+    if (nargs < 3) {
+        goto skip_optional;
+    }
+    flags = PyLong_AsInt(args[2]);
+    if (flags == -1 && PyErr_Occurred()) {
+        goto exit;
+    }
+skip_optional:
+    return_value = _socket_socket_recvmsg_impl((PySocketSockObject *)s, bufsize, ancbufsize, flags);
+
+exit:
+    return return_value;
+}
+
+#endif /* defined(CMSG_LEN) */
+
+#if defined(CMSG_LEN)
+
+PyDoc_STRVAR(_socket_socket_recvmsg_into__doc__,
+"recvmsg_into($self, buffers, ancbufsize=0, flags=0, /)\n"
+"--\n"
+"\n"
+"Receive normal and ancillary data, scattering the normal data.\n"
+"\n"
+"The buffers argument must be an iterable of objects that export\n"
+"writable buffers (e.g.  bytearray objects); these will be filled\n"
+"with successive chunks of the non-ancillary data until it has all\n"
+"been written or there are no more buffers.  The ancbufsize argument\n"
+"sets the size in bytes of the internal buffer used to receive the\n"
+"ancillary data; it defaults to 0, meaning that no ancillary data\n"
+"will be received.  Appropriate buffer sizes for ancillary data can\n"
+"be calculated using CMSG_SPACE() or CMSG_LEN(), and items which do\n"
+"not fit into the buffer might be truncated or discarded.  The flags\n"
+"argument defaults to 0 and has the same meaning as for recv().\n"
+"\n"
+"The return value is a 4-tuple: (nbytes, ancdata, msg_flags,\n"
+"address). The nbytes item is the total number of bytes of\n"
+"non-ancillary data written into the buffers.  The ancdata item is a\n"
+"list of zero or more tuples (cmsg_level, cmsg_type, cmsg_data)\n"
+"representing the ancillary data (control messages) received:\n"
+"cmsg_level and cmsg_type are integers specifying the protocol level\n"
+"and protocol-specific type respectively, and cmsg_data is a bytes\n"
+"object holding the associated data.  The msg_flags item is the\n"
+"bitwise OR of various flags indicating conditions on the received\n"
+"message; see your system documentation for details.  If the\n"
+"receiving socket is unconnected, address is the address of the\n"
+"sending socket, if available; otherwise, its value is unspecified.\n"
+"\n"
+"If recvmsg_into() raises an exception after the system call returns,\n"
+"it will first attempt to close any file descriptors received via the\n"
+"SCM_RIGHTS mechanism.");
+
+#define _SOCKET_SOCKET_RECVMSG_INTO_METHODDEF    \
+    {"recvmsg_into", _PyCFunction_CAST(_socket_socket_recvmsg_into), METH_FASTCALL, _socket_socket_recvmsg_into__doc__},
+
+static PyObject *
+_socket_socket_recvmsg_into_impl(PySocketSockObject *s,
+                                 PyObject *buffers_arg,
+                                 Py_ssize_t ancbufsize, int flags);
+
+static PyObject *
+_socket_socket_recvmsg_into(PyObject *s, PyObject *const *args, Py_ssize_t nargs)
+{
+    PyObject *return_value = NULL;
+    PyObject *buffers_arg;
+    Py_ssize_t ancbufsize = 0;
+    int flags = 0;
+
+    if (!_PyArg_CheckPositional("recvmsg_into", nargs, 1, 3)) {
+        goto exit;
+    }
+    buffers_arg = args[0];
+    if (nargs < 2) {
+        goto skip_optional;
+    }
+    {
+        Py_ssize_t ival = -1;
+        PyObject *iobj = _PyNumber_Index(args[1]);
+        if (iobj != NULL) {
+            ival = PyLong_AsSsize_t(iobj);
+            Py_DECREF(iobj);
+        }
+        if (ival == -1 && PyErr_Occurred()) {
+            goto exit;
+        }
+        ancbufsize = ival;
+    }
+    if (nargs < 3) {
+        goto skip_optional;
+    }
+    flags = PyLong_AsInt(args[2]);
+    if (flags == -1 && PyErr_Occurred()) {
+        goto exit;
+    }
+skip_optional:
+    return_value = _socket_socket_recvmsg_into_impl((PySocketSockObject *)s, buffers_arg, ancbufsize, flags);
+
+exit:
+    return return_value;
 }
 
+#endif /* defined(CMSG_LEN) */
+
 PyDoc_STRVAR(_socket_socket_send__doc__,
 "send($self, data, flags=0, /)\n"
 "--\n"
@@ -115,85 +1003,286 @@ _socket_socket_sendall(PyObject *s, PyObject *const *args, Py_ssize_t nargs)
     if (flags == -1 && PyErr_Occurred()) {
         goto exit;
     }
-skip_optional:
-    return_value = _socket_socket_sendall_impl((PySocketSockObject *)s, &pbuf, flags);
+skip_optional:
+    return_value = _socket_socket_sendall_impl((PySocketSockObject *)s, &pbuf, flags);
+
+exit:
+    /* Cleanup for pbuf */
+    if (pbuf.obj) {
+       PyBuffer_Release(&pbuf);
+    }
+
+    return return_value;
+}
+
+#if defined(CMSG_LEN)
+
+PyDoc_STRVAR(_socket_socket_sendmsg__doc__,
+"sendmsg($self, buffers, ancdata=<unrepresentable>, flags=0,\n"
+"        address=<unrepresentable>, /)\n"
+"--\n"
+"\n"
+"Send normal and ancillary data to the socket.\n"
+"\n"
+"It gathering the non-ancillary data from a series of buffers\n"
+"and concatenating it into a single message.\n"
+"The buffers argument specifies the non-ancillary\n"
+"data as an iterable of bytes-like objects (e.g. bytes objects).\n"
+"The ancdata argument specifies the ancillary data (control messages)\n"
+"as an iterable of zero or more tuples (cmsg_level, cmsg_type,\n"
+"cmsg_data), where cmsg_level and cmsg_type are integers specifying\n"
+"the protocol level and protocol-specific type respectively, and\n"
+"cmsg_data is a bytes-like object holding the associated data.  The\n"
+"flags argument defaults to 0 and has the same meaning as for send().\n"
+"If address is supplied and not None, it sets a destination address\n"
+"for the message.  The return value is the number of bytes of\n"
+"non-ancillary data sent.");
+
+#define _SOCKET_SOCKET_SENDMSG_METHODDEF    \
+    {"sendmsg", _PyCFunction_CAST(_socket_socket_sendmsg), METH_FASTCALL, _socket_socket_sendmsg__doc__},
+
+static PyObject *
+_socket_socket_sendmsg_impl(PySocketSockObject *s, PyObject *data_arg,
+                            PyObject *cmsg_arg, int flags,
+                            PyObject *addr_arg);
+
+static PyObject *
+_socket_socket_sendmsg(PyObject *s, PyObject *const *args, Py_ssize_t nargs)
+{
+    PyObject *return_value = NULL;
+    PyObject *data_arg;
+    PyObject *cmsg_arg = NULL;
+    int flags = 0;
+    PyObject *addr_arg = NULL;
+
+    if (!_PyArg_CheckPositional("sendmsg", nargs, 1, 4)) {
+        goto exit;
+    }
+    data_arg = args[0];
+    if (nargs < 2) {
+        goto skip_optional;
+    }
+    cmsg_arg = args[1];
+    if (nargs < 3) {
+        goto skip_optional;
+    }
+    flags = PyLong_AsInt(args[2]);
+    if (flags == -1 && PyErr_Occurred()) {
+        goto exit;
+    }
+    if (nargs < 4) {
+        goto skip_optional;
+    }
+    addr_arg = args[3];
+skip_optional:
+    return_value = _socket_socket_sendmsg_impl((PySocketSockObject *)s, data_arg, cmsg_arg, flags, addr_arg);
+
+exit:
+    return return_value;
+}
+
+#endif /* defined(CMSG_LEN) */
+
+#if defined(HAVE_SOCKADDR_ALG)
+
+PyDoc_STRVAR(_socket_socket_sendmsg_afalg__doc__,
+"sendmsg_afalg($self, /, msg=<unrepresentable>, *, op=<unrepresentable>,\n"
+"              iv=<unrepresentable>, assoclen=<unrepresentable>, flags=0)\n"
+"--\n"
+"\n"
+"Set operation mode, IV and associated data length.\n"
+"\n"
+"For an AF_ALG operation socket.");
+
+#define _SOCKET_SOCKET_SENDMSG_AFALG_METHODDEF    \
+    {"sendmsg_afalg", _PyCFunction_CAST(_socket_socket_sendmsg_afalg), METH_FASTCALL|METH_KEYWORDS, _socket_socket_sendmsg_afalg__doc__},
+
+static PyObject *
+_socket_socket_sendmsg_afalg_impl(PySocketSockObject *self,
+                                  PyObject *data_arg, PyObject *opobj,
+                                  Py_buffer *iv, PyObject *assoclenobj,
+                                  int flags);
+
+static PyObject *
+_socket_socket_sendmsg_afalg(PyObject *self, 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 5
+    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(msg), &_Py_ID(op), &_Py_ID(iv), &_Py_ID(assoclen), &_Py_ID(flags), },
+    };
+    #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[] = {"msg", "op", "iv", "assoclen", "flags", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "sendmsg_afalg",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[5];
+    Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0;
+    PyObject *data_arg = NULL;
+    PyObject *opobj = NULL;
+    Py_buffer iv = {NULL, NULL};
+    PyObject *assoclenobj = NULL;
+    int flags = 0;
+
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 0, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
+        goto exit;
+    }
+    if (!noptargs) {
+        goto skip_optional_pos;
+    }
+    if (args[0]) {
+        data_arg = args[0];
+        if (!--noptargs) {
+            goto skip_optional_pos;
+        }
+    }
+skip_optional_pos:
+    if (!noptargs) {
+        goto skip_optional_kwonly;
+    }
+    if (args[1]) {
+        if (!PyLong_Check(args[1])) {
+            _PyArg_BadArgument("sendmsg_afalg", "argument 'op'", "int", args[1]);
+            goto exit;
+        }
+        opobj = args[1];
+        if (!--noptargs) {
+            goto skip_optional_kwonly;
+        }
+    }
+    if (args[2]) {
+        if (PyObject_GetBuffer(args[2], &iv, PyBUF_SIMPLE) != 0) {
+            goto exit;
+        }
+        if (!--noptargs) {
+            goto skip_optional_kwonly;
+        }
+    }
+    if (args[3]) {
+        if (!PyLong_Check(args[3])) {
+            _PyArg_BadArgument("sendmsg_afalg", "argument 'assoclen'", "int", args[3]);
+            goto exit;
+        }
+        assoclenobj = args[3];
+        if (!--noptargs) {
+            goto skip_optional_kwonly;
+        }
+    }
+    flags = PyLong_AsInt(args[4]);
+    if (flags == -1 && PyErr_Occurred()) {
+        goto exit;
+    }
+skip_optional_kwonly:
+    return_value = _socket_socket_sendmsg_afalg_impl((PySocketSockObject *)self, data_arg, opobj, &iv, assoclenobj, flags);
 
 exit:
-    /* Cleanup for pbuf */
-    if (pbuf.obj) {
-       PyBuffer_Release(&pbuf);
+    /* Cleanup for iv */
+    if (iv.obj) {
+       PyBuffer_Release(&iv);
     }
 
     return return_value;
 }
 
-#if defined(CMSG_LEN)
+#endif /* defined(HAVE_SOCKADDR_ALG) */
 
-PyDoc_STRVAR(_socket_socket_sendmsg__doc__,
-"sendmsg($self, buffers, ancdata=<unrepresentable>, flags=0,\n"
-"        address=<unrepresentable>, /)\n"
+#if defined(HAVE_SHUTDOWN)
+
+PyDoc_STRVAR(_socket_socket_shutdown__doc__,
+"shutdown($self, flag, /)\n"
 "--\n"
 "\n"
-"Send normal and ancillary data to the socket.\n"
+"Shut down one or both halves of the connection.\n"
 "\n"
-"It gathering the non-ancillary data from a series of buffers\n"
-"and concatenating it into a single message.\n"
-"The buffers argument specifies the non-ancillary\n"
-"data as an iterable of bytes-like objects (e.g. bytes objects).\n"
-"The ancdata argument specifies the ancillary data (control messages)\n"
-"as an iterable of zero or more tuples (cmsg_level, cmsg_type,\n"
-"cmsg_data), where cmsg_level and cmsg_type are integers specifying\n"
-"the protocol level and protocol-specific type respectively, and\n"
-"cmsg_data is a bytes-like object holding the associated data.  The\n"
-"flags argument defaults to 0 and has the same meaning as for send().\n"
-"If address is supplied and not None, it sets a destination address\n"
-"for the message.  The return value is the number of bytes of\n"
-"non-ancillary data sent.");
+"Shut down the reading side of the socket (flag == SHUT_RD), the\n"
+"writing side of the socket (flag == SHUT_WR), or both ends (flag ==\n"
+"SHUT_RDWR).");
 
-#define _SOCKET_SOCKET_SENDMSG_METHODDEF    \
-    {"sendmsg", _PyCFunction_CAST(_socket_socket_sendmsg), METH_FASTCALL, _socket_socket_sendmsg__doc__},
+#define _SOCKET_SOCKET_SHUTDOWN_METHODDEF    \
+    {"shutdown", (PyCFunction)_socket_socket_shutdown, METH_O, _socket_socket_shutdown__doc__},
 
 static PyObject *
-_socket_socket_sendmsg_impl(PySocketSockObject *s, PyObject *data_arg,
-                            PyObject *cmsg_arg, int flags,
-                            PyObject *addr_arg);
+_socket_socket_shutdown_impl(PySocketSockObject *s, PyObject *arg);
 
 static PyObject *
-_socket_socket_sendmsg(PyObject *s, PyObject *const *args, Py_ssize_t nargs)
+_socket_socket_shutdown(PyObject *s, PyObject *arg)
 {
     PyObject *return_value = NULL;
-    PyObject *data_arg;
-    PyObject *cmsg_arg = NULL;
-    int flags = 0;
-    PyObject *addr_arg = NULL;
 
-    if (!_PyArg_CheckPositional("sendmsg", nargs, 1, 4)) {
-        goto exit;
-    }
-    data_arg = args[0];
-    if (nargs < 2) {
-        goto skip_optional;
-    }
-    cmsg_arg = args[1];
-    if (nargs < 3) {
-        goto skip_optional;
-    }
-    flags = PyLong_AsInt(args[2]);
-    if (flags == -1 && PyErr_Occurred()) {
-        goto exit;
-    }
-    if (nargs < 4) {
-        goto skip_optional;
+    return_value = _socket_socket_shutdown_impl((PySocketSockObject *)s, arg);
+
+    return return_value;
+}
+
+#endif /* defined(HAVE_SHUTDOWN) */
+
+#if defined(MS_WINDOWS)
+
+PyDoc_STRVAR(_socket_socket_share__doc__,
+"share($self, process_id, /)\n"
+"--\n"
+"\n"
+"Share the socket with another process.\n"
+"\n"
+"The target process id must be provided and the resulting bytes\n"
+"object passed to the target process.  There the shared socket can be\n"
+"instantiated by calling socket.fromshare().");
+
+#define _SOCKET_SOCKET_SHARE_METHODDEF    \
+    {"share", (PyCFunction)_socket_socket_share, METH_O, _socket_socket_share__doc__},
+
+static PyObject *
+_socket_socket_share_impl(PySocketSockObject *s, unsigned int processId);
+
+static PyObject *
+_socket_socket_share(PyObject *s, PyObject *arg)
+{
+    PyObject *return_value = NULL;
+    unsigned int processId;
+
+    {
+        Py_ssize_t _bytes = PyLong_AsNativeBytes(arg, &processId, sizeof(unsigned int),
+                Py_ASNATIVEBYTES_NATIVE_ENDIAN |
+                Py_ASNATIVEBYTES_ALLOW_INDEX |
+                Py_ASNATIVEBYTES_UNSIGNED_BUFFER);
+        if (_bytes < 0) {
+            goto exit;
+        }
+        if ((size_t)_bytes > sizeof(unsigned int)) {
+            if (PyErr_WarnEx(PyExc_DeprecationWarning,
+                "integer value out of range", 1) < 0)
+            {
+                goto exit;
+            }
+        }
     }
-    addr_arg = args[3];
-skip_optional:
-    return_value = _socket_socket_sendmsg_impl((PySocketSockObject *)s, data_arg, cmsg_arg, flags, addr_arg);
+    return_value = _socket_socket_share_impl((PySocketSockObject *)s, processId);
 
 exit:
     return return_value;
 }
 
-#endif /* defined(CMSG_LEN) */
+#endif /* defined(MS_WINDOWS) */
 
 static int
 sock_initobj_impl(PySocketSockObject *self, int family, int type, int proto,
@@ -282,6 +1371,341 @@ sock_initobj(PyObject *self, PyObject *args, PyObject *kwargs)
     return return_value;
 }
 
+#if defined(HAVE_GETHOSTNAME)
+
+PyDoc_STRVAR(_socket_gethostname__doc__,
+"gethostname($module, /)\n"
+"--\n"
+"\n"
+"Return the current host name.");
+
+#define _SOCKET_GETHOSTNAME_METHODDEF    \
+    {"gethostname", (PyCFunction)_socket_gethostname, METH_NOARGS, _socket_gethostname__doc__},
+
+static PyObject *
+_socket_gethostname_impl(PyObject *module);
+
+static PyObject *
+_socket_gethostname(PyObject *module, PyObject *Py_UNUSED(ignored))
+{
+    return _socket_gethostname_impl(module);
+}
+
+#endif /* defined(HAVE_GETHOSTNAME) */
+
+#if defined(HAVE_SETHOSTNAME)
+
+PyDoc_STRVAR(_socket_sethostname__doc__,
+"sethostname($module, name, /)\n"
+"--\n"
+"\n"
+"Set the hostname to name.");
+
+#define _SOCKET_SETHOSTNAME_METHODDEF    \
+    {"sethostname", (PyCFunction)_socket_sethostname, METH_O, _socket_sethostname__doc__},
+
+#endif /* defined(HAVE_SETHOSTNAME) */
+
+#if defined(HAVE_GETADDRINFO)
+
+PyDoc_STRVAR(_socket_gethostbyname__doc__,
+"gethostbyname($module, host, /)\n"
+"--\n"
+"\n"
+"Return the IP address for a host.\n"
+"\n"
+"The address is a string of the form \'255.255.255.255\'.");
+
+#define _SOCKET_GETHOSTBYNAME_METHODDEF    \
+    {"gethostbyname", (PyCFunction)_socket_gethostbyname, METH_O, _socket_gethostbyname__doc__},
+
+#endif /* defined(HAVE_GETADDRINFO) */
+
+#if (defined(HAVE_GETHOSTBYNAME_R) || defined (HAVE_GETHOSTBYNAME))
+
+PyDoc_STRVAR(_socket_gethostbyname_ex__doc__,
+"gethostbyname_ex($module, host, /)\n"
+"--\n"
+"\n"
+"Map a host name to its IP number.\n"
+"\n"
+"Return the true host name, a list of aliases, and a list of IP\n"
+"addresses, which are strings of the form \'255.255.255.255\'.");
+
+#define _SOCKET_GETHOSTBYNAME_EX_METHODDEF    \
+    {"gethostbyname_ex", (PyCFunction)_socket_gethostbyname_ex, METH_O, _socket_gethostbyname_ex__doc__},
+
+#endif /* (defined(HAVE_GETHOSTBYNAME_R) || defined (HAVE_GETHOSTBYNAME)) */
+
+#if (defined(HAVE_GETHOSTBYNAME_R) || defined (HAVE_GETHOSTBYADDR))
+
+PyDoc_STRVAR(_socket_gethostbyaddr__doc__,
+"gethostbyaddr($module, host, /)\n"
+"--\n"
+"\n"
+"Map an IP number or host name to the true host name and addresses.\n"
+"\n"
+"Return the true host name, a list of aliases, and a list of IP\n"
+"addresses.  The host argument is a string giving a host name or IP\n"
+"number.");
+
+#define _SOCKET_GETHOSTBYADDR_METHODDEF    \
+    {"gethostbyaddr", (PyCFunction)_socket_gethostbyaddr, METH_O, _socket_gethostbyaddr__doc__},
+
+#endif /* (defined(HAVE_GETHOSTBYNAME_R) || defined (HAVE_GETHOSTBYADDR)) */
+
+#if defined(HAVE_GETSERVBYNAME)
+
+PyDoc_STRVAR(_socket_getservbyname__doc__,
+"getservbyname($module, servicename, protocolname=<unrepresentable>, /)\n"
+"--\n"
+"\n"
+"Return a port number from a service name and protocol name.\n"
+"\n"
+"The optional protocol name, if given, should be \'tcp\' or \'udp\',\n"
+"otherwise any protocol will match.");
+
+#define _SOCKET_GETSERVBYNAME_METHODDEF    \
+    {"getservbyname", _PyCFunction_CAST(_socket_getservbyname), METH_FASTCALL, _socket_getservbyname__doc__},
+
+static PyObject *
+_socket_getservbyname_impl(PyObject *module, const char *name,
+                           const char *proto);
+
+static PyObject *
+_socket_getservbyname(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
+{
+    PyObject *return_value = NULL;
+    const char *name;
+    const char *proto = NULL;
+
+    if (!_PyArg_CheckPositional("getservbyname", nargs, 1, 2)) {
+        goto exit;
+    }
+    if (!PyUnicode_Check(args[0])) {
+        _PyArg_BadArgument("getservbyname", "argument 1", "str", args[0]);
+        goto exit;
+    }
+    Py_ssize_t name_length;
+    name = PyUnicode_AsUTF8AndSize(args[0], &name_length);
+    if (name == NULL) {
+        goto exit;
+    }
+    if (strlen(name) != (size_t)name_length) {
+        PyErr_SetString(PyExc_ValueError, "embedded null character");
+        goto exit;
+    }
+    if (nargs < 2) {
+        goto skip_optional;
+    }
+    if (!PyUnicode_Check(args[1])) {
+        _PyArg_BadArgument("getservbyname", "argument 2", "str", args[1]);
+        goto exit;
+    }
+    Py_ssize_t proto_length;
+    proto = PyUnicode_AsUTF8AndSize(args[1], &proto_length);
+    if (proto == NULL) {
+        goto exit;
+    }
+    if (strlen(proto) != (size_t)proto_length) {
+        PyErr_SetString(PyExc_ValueError, "embedded null character");
+        goto exit;
+    }
+skip_optional:
+    return_value = _socket_getservbyname_impl(module, name, proto);
+
+exit:
+    return return_value;
+}
+
+#endif /* defined(HAVE_GETSERVBYNAME) */
+
+#if defined(HAVE_GETSERVBYPORT)
+
+PyDoc_STRVAR(_socket_getservbyport__doc__,
+"getservbyport($module, port, protocolname=<unrepresentable>, /)\n"
+"--\n"
+"\n"
+"Return the service name from a port number and protocol name.\n"
+"\n"
+"The optional protocol name, if given, should be \'tcp\' or \'udp\',\n"
+"otherwise any protocol will match.");
+
+#define _SOCKET_GETSERVBYPORT_METHODDEF    \
+    {"getservbyport", _PyCFunction_CAST(_socket_getservbyport), METH_FASTCALL, _socket_getservbyport__doc__},
+
+static PyObject *
+_socket_getservbyport_impl(PyObject *module, int port, const char *proto);
+
+static PyObject *
+_socket_getservbyport(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
+{
+    PyObject *return_value = NULL;
+    int port;
+    const char *proto = NULL;
+
+    if (!_PyArg_CheckPositional("getservbyport", nargs, 1, 2)) {
+        goto exit;
+    }
+    port = PyLong_AsInt(args[0]);
+    if (port == -1 && PyErr_Occurred()) {
+        goto exit;
+    }
+    if (nargs < 2) {
+        goto skip_optional;
+    }
+    if (!PyUnicode_Check(args[1])) {
+        _PyArg_BadArgument("getservbyport", "argument 2", "str", args[1]);
+        goto exit;
+    }
+    Py_ssize_t proto_length;
+    proto = PyUnicode_AsUTF8AndSize(args[1], &proto_length);
+    if (proto == NULL) {
+        goto exit;
+    }
+    if (strlen(proto) != (size_t)proto_length) {
+        PyErr_SetString(PyExc_ValueError, "embedded null character");
+        goto exit;
+    }
+skip_optional:
+    return_value = _socket_getservbyport_impl(module, port, proto);
+
+exit:
+    return return_value;
+}
+
+#endif /* defined(HAVE_GETSERVBYPORT) */
+
+#if defined(HAVE_GETPROTOBYNAME)
+
+PyDoc_STRVAR(_socket_getprotobyname__doc__,
+"getprotobyname($module, name, /)\n"
+"--\n"
+"\n"
+"Return the protocol number for the named protocol.");
+
+#define _SOCKET_GETPROTOBYNAME_METHODDEF    \
+    {"getprotobyname", (PyCFunction)_socket_getprotobyname, METH_O, _socket_getprotobyname__doc__},
+
+static PyObject *
+_socket_getprotobyname_impl(PyObject *module, const char *name);
+
+static PyObject *
+_socket_getprotobyname(PyObject *module, PyObject *arg)
+{
+    PyObject *return_value = NULL;
+    const char *name;
+
+    if (!PyUnicode_Check(arg)) {
+        _PyArg_BadArgument("getprotobyname", "argument", "str", arg);
+        goto exit;
+    }
+    Py_ssize_t name_length;
+    name = PyUnicode_AsUTF8AndSize(arg, &name_length);
+    if (name == NULL) {
+        goto exit;
+    }
+    if (strlen(name) != (size_t)name_length) {
+        PyErr_SetString(PyExc_ValueError, "embedded null character");
+        goto exit;
+    }
+    return_value = _socket_getprotobyname_impl(module, name);
+
+exit:
+    return return_value;
+}
+
+#endif /* defined(HAVE_GETPROTOBYNAME) */
+
+PyDoc_STRVAR(_socket_close__doc__,
+"close($module, fd, /)\n"
+"--\n"
+"\n"
+"Close a socket fd.\n"
+"\n"
+"This is like os.close(), but for sockets; on some platforms os.close()\n"
+"won\'t work for socket file descriptors.");
+
+#define _SOCKET_CLOSE_METHODDEF    \
+    {"close", (PyCFunction)_socket_close, METH_O, _socket_close__doc__},
+
+#if !defined(NO_DUP)
+
+PyDoc_STRVAR(_socket_dup__doc__,
+"dup($module, fd, /)\n"
+"--\n"
+"\n"
+"Duplicate a socket descriptor.\n"
+"\n"
+"The new descriptor is non-inheritable.  This is like os.dup(), but for\n"
+"sockets; on some platforms os.dup() won\'t work for socket file\n"
+"descriptors.");
+
+#define _SOCKET_DUP_METHODDEF    \
+    {"dup", (PyCFunction)_socket_dup, METH_O, _socket_dup__doc__},
+
+#endif /* !defined(NO_DUP) */
+
+#if defined(HAVE_SOCKETPAIR)
+
+PyDoc_STRVAR(_socket_socketpair__doc__,
+"socketpair($module, family=AF_UNIX, type=SOCK_STREAM, proto=0, /)\n"
+"--\n"
+"\n"
+"Create a pair of connected socket objects.\n"
+"\n"
+"The sockets are returned by the platform socketpair() function.  The\n"
+"arguments are the same as for socket(), except that the default\n"
+"family is AF_UNIX if defined on the platform; otherwise, the default\n"
+"is AF_INET.");
+
+#define _SOCKET_SOCKETPAIR_METHODDEF    \
+    {"socketpair", _PyCFunction_CAST(_socket_socketpair), METH_FASTCALL, _socket_socketpair__doc__},
+
+static PyObject *
+_socket_socketpair_impl(PyObject *module, int family, int type, int proto);
+
+static PyObject *
+_socket_socketpair(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
+{
+    PyObject *return_value = NULL;
+    int family = SOCKETPAIR_DEFAULT_FAMILY;
+    int type = SOCK_STREAM;
+    int proto = 0;
+
+    if (!_PyArg_CheckPositional("socketpair", nargs, 0, 3)) {
+        goto exit;
+    }
+    if (nargs < 1) {
+        goto skip_optional;
+    }
+    family = PyLong_AsInt(args[0]);
+    if (family == -1 && PyErr_Occurred()) {
+        goto exit;
+    }
+    if (nargs < 2) {
+        goto skip_optional;
+    }
+    type = PyLong_AsInt(args[1]);
+    if (type == -1 && PyErr_Occurred()) {
+        goto exit;
+    }
+    if (nargs < 3) {
+        goto skip_optional;
+    }
+    proto = PyLong_AsInt(args[2]);
+    if (proto == -1 && PyErr_Occurred()) {
+        goto exit;
+    }
+skip_optional:
+    return_value = _socket_socketpair_impl(module, family, type, proto);
+
+exit:
+    return return_value;
+}
+
+#endif /* defined(HAVE_SOCKETPAIR) */
+
 PyDoc_STRVAR(_socket_ntohs__doc__,
 "ntohs($module, integer, /)\n"
 "--\n"
@@ -463,6 +1887,301 @@ _socket_inet_ntoa(PyObject *module, PyObject *arg)
 
 #endif /* defined(HAVE_INET_NTOA) */
 
+#if defined(HAVE_INET_PTON)
+
+PyDoc_STRVAR(_socket_inet_pton__doc__,
+"inet_pton($module, af, ip, /)\n"
+"--\n"
+"\n"
+"Convert an IP address from string format to a packed string.\n"
+"\n"
+"The string is suitable for use with low-level network functions.");
+
+#define _SOCKET_INET_PTON_METHODDEF    \
+    {"inet_pton", _PyCFunction_CAST(_socket_inet_pton), METH_FASTCALL, _socket_inet_pton__doc__},
+
+static PyObject *
+_socket_inet_pton_impl(PyObject *module, int af, const char *ip);
+
+static PyObject *
+_socket_inet_pton(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
+{
+    PyObject *return_value = NULL;
+    int af;
+    const char *ip;
+
+    if (!_PyArg_CheckPositional("inet_pton", nargs, 2, 2)) {
+        goto exit;
+    }
+    af = PyLong_AsInt(args[0]);
+    if (af == -1 && PyErr_Occurred()) {
+        goto exit;
+    }
+    if (!PyUnicode_Check(args[1])) {
+        _PyArg_BadArgument("inet_pton", "argument 2", "str", args[1]);
+        goto exit;
+    }
+    Py_ssize_t ip_length;
+    ip = PyUnicode_AsUTF8AndSize(args[1], &ip_length);
+    if (ip == NULL) {
+        goto exit;
+    }
+    if (strlen(ip) != (size_t)ip_length) {
+        PyErr_SetString(PyExc_ValueError, "embedded null character");
+        goto exit;
+    }
+    return_value = _socket_inet_pton_impl(module, af, ip);
+
+exit:
+    return return_value;
+}
+
+#endif /* defined(HAVE_INET_PTON) */
+
+#if defined(HAVE_INET_PTON)
+
+PyDoc_STRVAR(_socket_inet_ntop__doc__,
+"inet_ntop($module, af, packed_ip, /)\n"
+"--\n"
+"\n"
+"Convert a packed IP address of the given family to string format.");
+
+#define _SOCKET_INET_NTOP_METHODDEF    \
+    {"inet_ntop", _PyCFunction_CAST(_socket_inet_ntop), METH_FASTCALL, _socket_inet_ntop__doc__},
+
+static PyObject *
+_socket_inet_ntop_impl(PyObject *module, int af, Py_buffer *packed_ip);
+
+static PyObject *
+_socket_inet_ntop(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
+{
+    PyObject *return_value = NULL;
+    int af;
+    Py_buffer packed_ip = {NULL, NULL};
+
+    if (!_PyArg_CheckPositional("inet_ntop", nargs, 2, 2)) {
+        goto exit;
+    }
+    af = PyLong_AsInt(args[0]);
+    if (af == -1 && PyErr_Occurred()) {
+        goto exit;
+    }
+    if (PyObject_GetBuffer(args[1], &packed_ip, PyBUF_SIMPLE) != 0) {
+        goto exit;
+    }
+    return_value = _socket_inet_ntop_impl(module, af, &packed_ip);
+
+exit:
+    /* Cleanup for packed_ip */
+    if (packed_ip.obj) {
+       PyBuffer_Release(&packed_ip);
+    }
+
+    return return_value;
+}
+
+#endif /* defined(HAVE_INET_PTON) */
+
+#if defined(HAVE_GETADDRINFO)
+
+PyDoc_STRVAR(_socket_getaddrinfo__doc__,
+"getaddrinfo($module, /, host, port, family=AF_UNSPEC, type=0, proto=0,\n"
+"            flags=0)\n"
+"--\n"
+"\n"
+"Resolve host and port into a list of 5-tuples.\n"
+"\n"
+"Each tuple is (family, type, proto, canonname, sockaddr).");
+
+#define _SOCKET_GETADDRINFO_METHODDEF    \
+    {"getaddrinfo", _PyCFunction_CAST(_socket_getaddrinfo), METH_FASTCALL|METH_KEYWORDS, _socket_getaddrinfo__doc__},
+
+static PyObject *
+_socket_getaddrinfo_impl(PyObject *module, PyObject *hobj, PyObject *pobj,
+                         int family, int socktype, int protocol, int flags);
+
+static PyObject *
+_socket_getaddrinfo(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 6
+    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(host), &_Py_ID(port), &_Py_ID(family), &_Py_ID(type), &_Py_ID(proto), &_Py_ID(flags), },
+    };
+    #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[] = {"host", "port", "family", "type", "proto", "flags", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "getaddrinfo",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[6];
+    Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2;
+    PyObject *hobj;
+    PyObject *pobj;
+    int family = AF_UNSPEC;
+    int socktype = 0;
+    int protocol = 0;
+    int flags = 0;
+
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 2, /*maxpos*/ 6, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
+        goto exit;
+    }
+    hobj = args[0];
+    pobj = args[1];
+    if (!noptargs) {
+        goto skip_optional_pos;
+    }
+    if (args[2]) {
+        family = PyLong_AsInt(args[2]);
+        if (family == -1 && PyErr_Occurred()) {
+            goto exit;
+        }
+        if (!--noptargs) {
+            goto skip_optional_pos;
+        }
+    }
+    if (args[3]) {
+        socktype = PyLong_AsInt(args[3]);
+        if (socktype == -1 && PyErr_Occurred()) {
+            goto exit;
+        }
+        if (!--noptargs) {
+            goto skip_optional_pos;
+        }
+    }
+    if (args[4]) {
+        protocol = PyLong_AsInt(args[4]);
+        if (protocol == -1 && PyErr_Occurred()) {
+            goto exit;
+        }
+        if (!--noptargs) {
+            goto skip_optional_pos;
+        }
+    }
+    flags = PyLong_AsInt(args[5]);
+    if (flags == -1 && PyErr_Occurred()) {
+        goto exit;
+    }
+skip_optional_pos:
+    return_value = _socket_getaddrinfo_impl(module, hobj, pobj, family, socktype, protocol, flags);
+
+exit:
+    return return_value;
+}
+
+#endif /* defined(HAVE_GETADDRINFO) */
+
+#if defined(HAVE_GETNAMEINFO)
+
+PyDoc_STRVAR(_socket_getnameinfo__doc__,
+"getnameinfo($module, sockaddr, flags, /)\n"
+"--\n"
+"\n"
+"Get host and port for a sockaddr.");
+
+#define _SOCKET_GETNAMEINFO_METHODDEF    \
+    {"getnameinfo", _PyCFunction_CAST(_socket_getnameinfo), METH_FASTCALL, _socket_getnameinfo__doc__},
+
+static PyObject *
+_socket_getnameinfo_impl(PyObject *module, PyObject *sa, int flags);
+
+static PyObject *
+_socket_getnameinfo(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
+{
+    PyObject *return_value = NULL;
+    PyObject *sa;
+    int flags;
+
+    if (!_PyArg_CheckPositional("getnameinfo", nargs, 2, 2)) {
+        goto exit;
+    }
+    sa = args[0];
+    flags = PyLong_AsInt(args[1]);
+    if (flags == -1 && PyErr_Occurred()) {
+        goto exit;
+    }
+    return_value = _socket_getnameinfo_impl(module, sa, flags);
+
+exit:
+    return return_value;
+}
+
+#endif /* defined(HAVE_GETNAMEINFO) */
+
+PyDoc_STRVAR(_socket_getdefaulttimeout__doc__,
+"getdefaulttimeout($module, /)\n"
+"--\n"
+"\n"
+"Return the default timeout in seconds for new socket objects.\n"
+"\n"
+"A value of None indicates that new socket objects have no timeout.\n"
+"When the socket module is first imported, the default is None.");
+
+#define _SOCKET_GETDEFAULTTIMEOUT_METHODDEF    \
+    {"getdefaulttimeout", (PyCFunction)_socket_getdefaulttimeout, METH_NOARGS, _socket_getdefaulttimeout__doc__},
+
+static PyObject *
+_socket_getdefaulttimeout_impl(PyObject *module);
+
+static PyObject *
+_socket_getdefaulttimeout(PyObject *module, PyObject *Py_UNUSED(ignored))
+{
+    return _socket_getdefaulttimeout_impl(module);
+}
+
+PyDoc_STRVAR(_socket_setdefaulttimeout__doc__,
+"setdefaulttimeout($module, timeout, /)\n"
+"--\n"
+"\n"
+"Set the default timeout in seconds for new socket objects.\n"
+"\n"
+"A value of None indicates that new socket objects have no timeout.\n"
+"When the socket module is first imported, the default is None.");
+
+#define _SOCKET_SETDEFAULTTIMEOUT_METHODDEF    \
+    {"setdefaulttimeout", (PyCFunction)_socket_setdefaulttimeout, METH_O, _socket_setdefaulttimeout__doc__},
+
+#if (defined(HAVE_IF_NAMEINDEX) || defined(MS_WINDOWS))
+
+PyDoc_STRVAR(_socket_if_nameindex__doc__,
+"if_nameindex($module, /)\n"
+"--\n"
+"\n"
+"Return a list of network interface information (index, name) tuples.");
+
+#define _SOCKET_IF_NAMEINDEX_METHODDEF    \
+    {"if_nameindex", (PyCFunction)_socket_if_nameindex, METH_NOARGS, _socket_if_nameindex__doc__},
+
+static PyObject *
+_socket_if_nameindex_impl(PyObject *module);
+
+static PyObject *
+_socket_if_nameindex(PyObject *module, PyObject *Py_UNUSED(ignored))
+{
+    return _socket_if_nameindex_impl(module);
+}
+
+#endif /* (defined(HAVE_IF_NAMEINDEX) || defined(MS_WINDOWS)) */
+
 #if (defined(HAVE_IF_NAMEINDEX) || defined(MS_WINDOWS))
 
 PyDoc_STRVAR(_socket_if_nametoindex__doc__,
@@ -528,14 +2247,223 @@ _socket_if_indextoname(PyObject *module, PyObject *arg)
 
 #endif /* (defined(HAVE_IF_NAMEINDEX) || defined(MS_WINDOWS)) */
 
+#if defined(CMSG_LEN)
+
+PyDoc_STRVAR(_socket_CMSG_LEN__doc__,
+"CMSG_LEN($module, length, /)\n"
+"--\n"
+"\n"
+"Return the total length of an ancillary data item with associated data.\n"
+"\n"
+"The associated data has the given length.  This value can often be\n"
+"used as the buffer size for recvmsg() to receive a single item of\n"
+"ancillary data, but RFC 3542 requires portable applications to use\n"
+"CMSG_SPACE() and thus include space for padding, even when the item\n"
+"will be the last in the buffer.  Raises OverflowError if length is\n"
+"outside the permissible range of values.");
+
+#define _SOCKET_CMSG_LEN_METHODDEF    \
+    {"CMSG_LEN", (PyCFunction)_socket_CMSG_LEN, METH_O, _socket_CMSG_LEN__doc__},
+
+static PyObject *
+_socket_CMSG_LEN_impl(PyObject *module, Py_ssize_t length);
+
+static PyObject *
+_socket_CMSG_LEN(PyObject *module, PyObject *arg)
+{
+    PyObject *return_value = NULL;
+    Py_ssize_t length;
+
+    {
+        Py_ssize_t ival = -1;
+        PyObject *iobj = _PyNumber_Index(arg);
+        if (iobj != NULL) {
+            ival = PyLong_AsSsize_t(iobj);
+            Py_DECREF(iobj);
+        }
+        if (ival == -1 && PyErr_Occurred()) {
+            goto exit;
+        }
+        length = ival;
+    }
+    return_value = _socket_CMSG_LEN_impl(module, length);
+
+exit:
+    return return_value;
+}
+
+#endif /* defined(CMSG_LEN) */
+
+#if defined(CMSG_LEN) && defined(CMSG_SPACE)
+
+PyDoc_STRVAR(_socket_CMSG_SPACE__doc__,
+"CMSG_SPACE($module, length, /)\n"
+"--\n"
+"\n"
+"Return the buffer size needed to receive an ancillary data item.\n"
+"\n"
+"The item has associated data of the given length, and the size\n"
+"includes any trailing padding.  The buffer space needed to receive\n"
+"multiple items is the sum of the CMSG_SPACE() values for their\n"
+"associated data lengths.  Raises OverflowError if length is outside\n"
+"the permissible range of values.");
+
+#define _SOCKET_CMSG_SPACE_METHODDEF    \
+    {"CMSG_SPACE", (PyCFunction)_socket_CMSG_SPACE, METH_O, _socket_CMSG_SPACE__doc__},
+
+static PyObject *
+_socket_CMSG_SPACE_impl(PyObject *module, Py_ssize_t length);
+
+static PyObject *
+_socket_CMSG_SPACE(PyObject *module, PyObject *arg)
+{
+    PyObject *return_value = NULL;
+    Py_ssize_t length;
+
+    {
+        Py_ssize_t ival = -1;
+        PyObject *iobj = _PyNumber_Index(arg);
+        if (iobj != NULL) {
+            ival = PyLong_AsSsize_t(iobj);
+            Py_DECREF(iobj);
+        }
+        if (ival == -1 && PyErr_Occurred()) {
+            goto exit;
+        }
+        length = ival;
+    }
+    return_value = _socket_CMSG_SPACE_impl(module, length);
+
+exit:
+    return return_value;
+}
+
+#endif /* defined(CMSG_LEN) && defined(CMSG_SPACE) */
+
+#ifndef _SOCKET_SOCKET__ACCEPT_METHODDEF
+    #define _SOCKET_SOCKET__ACCEPT_METHODDEF
+#endif /* !defined(_SOCKET_SOCKET__ACCEPT_METHODDEF) */
+
+#ifndef _SOCKET_SOCKET_BIND_METHODDEF
+    #define _SOCKET_SOCKET_BIND_METHODDEF
+#endif /* !defined(_SOCKET_SOCKET_BIND_METHODDEF) */
+
+#ifndef _SOCKET_SOCKET_CONNECT_METHODDEF
+    #define _SOCKET_SOCKET_CONNECT_METHODDEF
+#endif /* !defined(_SOCKET_SOCKET_CONNECT_METHODDEF) */
+
+#ifndef _SOCKET_SOCKET_CONNECT_EX_METHODDEF
+    #define _SOCKET_SOCKET_CONNECT_EX_METHODDEF
+#endif /* !defined(_SOCKET_SOCKET_CONNECT_EX_METHODDEF) */
+
+#ifndef _SOCKET_SOCKET_GETSOCKNAME_METHODDEF
+    #define _SOCKET_SOCKET_GETSOCKNAME_METHODDEF
+#endif /* !defined(_SOCKET_SOCKET_GETSOCKNAME_METHODDEF) */
+
+#ifndef _SOCKET_SOCKET_GETPEERNAME_METHODDEF
+    #define _SOCKET_SOCKET_GETPEERNAME_METHODDEF
+#endif /* !defined(_SOCKET_SOCKET_GETPEERNAME_METHODDEF) */
+
+#ifndef _SOCKET_SOCKET_LISTEN_METHODDEF
+    #define _SOCKET_SOCKET_LISTEN_METHODDEF
+#endif /* !defined(_SOCKET_SOCKET_LISTEN_METHODDEF) */
+
+#ifndef _SOCKET_SOCKET_RECVFROM_METHODDEF
+    #define _SOCKET_SOCKET_RECVFROM_METHODDEF
+#endif /* !defined(_SOCKET_SOCKET_RECVFROM_METHODDEF) */
+
+#ifndef _SOCKET_SOCKET_RECVFROM_INTO_METHODDEF
+    #define _SOCKET_SOCKET_RECVFROM_INTO_METHODDEF
+#endif /* !defined(_SOCKET_SOCKET_RECVFROM_INTO_METHODDEF) */
+
+#ifndef _SOCKET_SOCKET_RECVMSG_METHODDEF
+    #define _SOCKET_SOCKET_RECVMSG_METHODDEF
+#endif /* !defined(_SOCKET_SOCKET_RECVMSG_METHODDEF) */
+
+#ifndef _SOCKET_SOCKET_RECVMSG_INTO_METHODDEF
+    #define _SOCKET_SOCKET_RECVMSG_INTO_METHODDEF
+#endif /* !defined(_SOCKET_SOCKET_RECVMSG_INTO_METHODDEF) */
+
 #ifndef _SOCKET_SOCKET_SENDMSG_METHODDEF
     #define _SOCKET_SOCKET_SENDMSG_METHODDEF
 #endif /* !defined(_SOCKET_SOCKET_SENDMSG_METHODDEF) */
 
+#ifndef _SOCKET_SOCKET_SENDMSG_AFALG_METHODDEF
+    #define _SOCKET_SOCKET_SENDMSG_AFALG_METHODDEF
+#endif /* !defined(_SOCKET_SOCKET_SENDMSG_AFALG_METHODDEF) */
+
+#ifndef _SOCKET_SOCKET_SHUTDOWN_METHODDEF
+    #define _SOCKET_SOCKET_SHUTDOWN_METHODDEF
+#endif /* !defined(_SOCKET_SOCKET_SHUTDOWN_METHODDEF) */
+
+#ifndef _SOCKET_SOCKET_SHARE_METHODDEF
+    #define _SOCKET_SOCKET_SHARE_METHODDEF
+#endif /* !defined(_SOCKET_SOCKET_SHARE_METHODDEF) */
+
+#ifndef _SOCKET_GETHOSTNAME_METHODDEF
+    #define _SOCKET_GETHOSTNAME_METHODDEF
+#endif /* !defined(_SOCKET_GETHOSTNAME_METHODDEF) */
+
+#ifndef _SOCKET_SETHOSTNAME_METHODDEF
+    #define _SOCKET_SETHOSTNAME_METHODDEF
+#endif /* !defined(_SOCKET_SETHOSTNAME_METHODDEF) */
+
+#ifndef _SOCKET_GETHOSTBYNAME_METHODDEF
+    #define _SOCKET_GETHOSTBYNAME_METHODDEF
+#endif /* !defined(_SOCKET_GETHOSTBYNAME_METHODDEF) */
+
+#ifndef _SOCKET_GETHOSTBYNAME_EX_METHODDEF
+    #define _SOCKET_GETHOSTBYNAME_EX_METHODDEF
+#endif /* !defined(_SOCKET_GETHOSTBYNAME_EX_METHODDEF) */
+
+#ifndef _SOCKET_GETHOSTBYADDR_METHODDEF
+    #define _SOCKET_GETHOSTBYADDR_METHODDEF
+#endif /* !defined(_SOCKET_GETHOSTBYADDR_METHODDEF) */
+
+#ifndef _SOCKET_GETSERVBYNAME_METHODDEF
+    #define _SOCKET_GETSERVBYNAME_METHODDEF
+#endif /* !defined(_SOCKET_GETSERVBYNAME_METHODDEF) */
+
+#ifndef _SOCKET_GETSERVBYPORT_METHODDEF
+    #define _SOCKET_GETSERVBYPORT_METHODDEF
+#endif /* !defined(_SOCKET_GETSERVBYPORT_METHODDEF) */
+
+#ifndef _SOCKET_GETPROTOBYNAME_METHODDEF
+    #define _SOCKET_GETPROTOBYNAME_METHODDEF
+#endif /* !defined(_SOCKET_GETPROTOBYNAME_METHODDEF) */
+
+#ifndef _SOCKET_DUP_METHODDEF
+    #define _SOCKET_DUP_METHODDEF
+#endif /* !defined(_SOCKET_DUP_METHODDEF) */
+
+#ifndef _SOCKET_SOCKETPAIR_METHODDEF
+    #define _SOCKET_SOCKETPAIR_METHODDEF
+#endif /* !defined(_SOCKET_SOCKETPAIR_METHODDEF) */
+
 #ifndef _SOCKET_INET_NTOA_METHODDEF
     #define _SOCKET_INET_NTOA_METHODDEF
 #endif /* !defined(_SOCKET_INET_NTOA_METHODDEF) */
 
+#ifndef _SOCKET_INET_PTON_METHODDEF
+    #define _SOCKET_INET_PTON_METHODDEF
+#endif /* !defined(_SOCKET_INET_PTON_METHODDEF) */
+
+#ifndef _SOCKET_INET_NTOP_METHODDEF
+    #define _SOCKET_INET_NTOP_METHODDEF
+#endif /* !defined(_SOCKET_INET_NTOP_METHODDEF) */
+
+#ifndef _SOCKET_GETADDRINFO_METHODDEF
+    #define _SOCKET_GETADDRINFO_METHODDEF
+#endif /* !defined(_SOCKET_GETADDRINFO_METHODDEF) */
+
+#ifndef _SOCKET_GETNAMEINFO_METHODDEF
+    #define _SOCKET_GETNAMEINFO_METHODDEF
+#endif /* !defined(_SOCKET_GETNAMEINFO_METHODDEF) */
+
+#ifndef _SOCKET_IF_NAMEINDEX_METHODDEF
+    #define _SOCKET_IF_NAMEINDEX_METHODDEF
+#endif /* !defined(_SOCKET_IF_NAMEINDEX_METHODDEF) */
+
 #ifndef _SOCKET_IF_NAMETOINDEX_METHODDEF
     #define _SOCKET_IF_NAMETOINDEX_METHODDEF
 #endif /* !defined(_SOCKET_IF_NAMETOINDEX_METHODDEF) */
@@ -543,4 +2471,12 @@ _socket_if_indextoname(PyObject *module, PyObject *arg)
 #ifndef _SOCKET_IF_INDEXTONAME_METHODDEF
     #define _SOCKET_IF_INDEXTONAME_METHODDEF
 #endif /* !defined(_SOCKET_IF_INDEXTONAME_METHODDEF) */
-/*[clinic end generated code: output=0b1fa78ac6589353 input=a9049054013a1b77]*/
+
+#ifndef _SOCKET_CMSG_LEN_METHODDEF
+    #define _SOCKET_CMSG_LEN_METHODDEF
+#endif /* !defined(_SOCKET_CMSG_LEN_METHODDEF) */
+
+#ifndef _SOCKET_CMSG_SPACE_METHODDEF
+    #define _SOCKET_CMSG_SPACE_METHODDEF
+#endif /* !defined(_SOCKET_CMSG_SPACE_METHODDEF) */
+/*[clinic end generated code: output=133662a8c304b1b7 input=a9049054013a1b77]*/
diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c
index f9c77c631b5d2af..a01569017937620 100644
--- a/Modules/socketmodule.c
+++ b/Modules/socketmodule.c
@@ -692,6 +692,14 @@ class _socket.socket "PySocketSockObject *" "clinic_state()->sock_type"
 #  undef HAVE_SETHOSTNAME
 #endif
 
+/* The default family of socketpair() is AF_UNIX if defined on the
+   platform; otherwise, the default is AF_INET. */
+#if defined(AF_UNIX)
+#  define SOCKETPAIR_DEFAULT_FAMILY AF_UNIX
+#else
+#  define SOCKETPAIR_DEFAULT_FAMILY AF_INET
+#endif
+
 #define clinic_state() (find_module_state_by_def(type))
 #include "clinic/socketmodule.c.h"
 #undef clinic_state
@@ -3085,11 +3093,21 @@ sock_accept_impl(PySocketSockObject *s, void *data)
 
 /* s._accept() -> (fd, address) */
 
+/*[clinic input]
+_socket.socket._accept
+    self as s: self(type="PySocketSockObject *")
+
+Wait for an incoming connection.
+
+Return a new socket file descriptor representing the connection, and
+the address of the client.  For IP sockets, the address info is a
+pair (hostaddr, port).
+[clinic start generated code]*/
+
 static PyObject *
-sock_accept(PyObject *self, PyObject *Py_UNUSED(ignored))
+_socket_socket__accept_impl(PySocketSockObject *s)
+/*[clinic end generated code: output=d24eca9a1d4c988e input=07959cdbb2f2a387]*/
 {
-    PySocketSockObject *s = _PySocketSockObject_CAST(self);
-
     sock_addr_t addrbuf;
     SOCKET_T newfd;
     socklen_t addrlen;
@@ -3155,12 +3173,6 @@ sock_accept(PyObject *self, PyObject *Py_UNUSED(ignored))
     return NULL;
 }
 
-PyDoc_STRVAR(accept_doc,
-"_accept() -> (integer, address info)\n\
-\n\
-Wait for an incoming connection.  Return a new socket file descriptor\n\
-representing the connection, and the address of the client.\n\
-For IP sockets, the address info is a pair (hostaddr, port).");
 #endif // defined(HAVE_ACCEPT) || defined(HAVE_ACCEPT4)
 
 
@@ -3169,38 +3181,45 @@ For IP sockets, the address info is a pair (hostaddr, port).");
    True -- blocking mode; same as settimeout(None)
 */
 
-static PyObject *
-sock_setblocking(PyObject *self, PyObject *arg)
-{
-    long block;
+/*[clinic input]
+_socket.socket.setblocking
+    self as s: self(type="PySocketSockObject *")
+    flag: bool
+    /
 
-    block = PyObject_IsTrue(arg);
-    if (block < 0)
-        return NULL;
+Set the socket to blocking (flag is true) or non-blocking (false).
 
-   PySocketSockObject *s = _PySocketSockObject_CAST(self);
-    s->sock_timeout = _PyTime_FromSeconds(block ? -1 : 0);
-    if (internal_setblocking(s, block) == -1) {
+setblocking(True) is equivalent to settimeout(None);
+setblocking(False) is equivalent to settimeout(0.0).
+[clinic start generated code]*/
+
+static PyObject *
+_socket_socket_setblocking_impl(PySocketSockObject *s, int flag)
+/*[clinic end generated code: output=0d27b1c391538401 input=bfc2c8564d8b67f6]*/
+{
+    s->sock_timeout = _PyTime_FromSeconds(flag ? -1 : 0);
+    if (internal_setblocking(s, flag) == -1) {
         return NULL;
     }
     Py_RETURN_NONE;
 }
 
-PyDoc_STRVAR(setblocking_doc,
-"setblocking(flag)\n\
-\n\
-Set the socket to blocking (flag is true) or non-blocking (false).\n\
-setblocking(True) is equivalent to settimeout(None);\n\
-setblocking(False) is equivalent to settimeout(0.0).");
 
 /* s.getblocking() method.
    Returns True if socket is in blocking mode,
    False if it is in non-blocking mode.
 */
+/*[clinic input]
+_socket.socket.getblocking
+    self as s: self(type="PySocketSockObject *")
+
+Return True if socket is in blocking mode, False if in non-blocking.
+[clinic start generated code]*/
+
 static PyObject *
-sock_getblocking(PyObject *self, PyObject *Py_UNUSED(ignored))
+_socket_socket_getblocking_impl(PySocketSockObject *s)
+/*[clinic end generated code: output=e760d93dae8b6ef7 input=13dfb70bc40c3cf8]*/
 {
-   PySocketSockObject *s = _PySocketSockObject_CAST(self);
     if (s->sock_timeout) {
         Py_RETURN_TRUE;
     }
@@ -3209,11 +3228,6 @@ sock_getblocking(PyObject *self, PyObject *Py_UNUSED(ignored))
     }
 }
 
-PyDoc_STRVAR(getblocking_doc,
-"getblocking()\n\
-\n\
-Returns True if socket is in blocking mode, or False if it\n\
-is in non-blocking mode.");
 
 static int
 socket_parse_timeout(PyTime_t *timeout, PyObject *timeout_obj)
@@ -3262,15 +3276,29 @@ socket_parse_timeout(PyTime_t *timeout, PyObject *timeout_obj)
    > 0  -- timeout mode; operations time out after timeout seconds
    < 0  -- illegal; raises an exception
 */
+/*[clinic input]
+_socket.socket.settimeout
+    self as s: self(type="PySocketSockObject *")
+    timeout as arg: object
+    /
+
+Set a timeout on socket operations.
+
+'timeout' can be a float, giving in seconds, or None.  Setting a
+timeout of None disables the timeout feature and is equivalent to
+setblocking(1).  Setting a timeout of zero is the same as
+setblocking(0).
+[clinic start generated code]*/
+
 static PyObject *
-sock_settimeout(PyObject *self, PyObject *arg)
+_socket_socket_settimeout_impl(PySocketSockObject *s, PyObject *arg)
+/*[clinic end generated code: output=5e57e2e1cba1c234 input=08bc8324b9fdb3f9]*/
 {
     PyTime_t timeout;
 
     if (socket_parse_timeout(&timeout, arg) < 0)
         return NULL;
 
-    PySocketSockObject *s = _PySocketSockObject_CAST(self);
     s->sock_timeout = timeout;
 
     int block = timeout < 0;
@@ -3301,13 +3329,6 @@ sock_settimeout(PyObject *self, PyObject *arg)
     Py_RETURN_NONE;
 }
 
-PyDoc_STRVAR(settimeout_doc,
-"settimeout(timeout)\n\
-\n\
-Set a timeout on socket operations.  'timeout' can be a float,\n\
-giving in seconds, or None.  Setting a timeout of None disables\n\
-the timeout feature and is equivalent to setblocking(1).\n\
-Setting a timeout of zero is the same as setblocking(0).");
 
 /* s.gettimeout() method.
    Returns the timeout associated with a socket. */
@@ -3324,10 +3345,20 @@ sock_gettimeout_impl(PyObject *self, void *Py_UNUSED(ignored))
     }
 }
 
-static inline PyObject *
-sock_gettimeout_method(PyObject *self, PyObject *Py_UNUSED(ignored))
+/*[clinic input]
+_socket.socket.gettimeout
+
+Return the timeout in seconds (float) of socket operations.
+
+A timeout of None indicates that timeouts on socket operations are
+disabled.
+[clinic start generated code]*/
+
+static PyObject *
+_socket_socket_gettimeout_impl(PySocketSockObject *self)
+/*[clinic end generated code: output=cd49b7758a504532 input=47e7c5bf80e26eaa]*/
 {
-    return sock_gettimeout_impl(self, NULL);
+    return sock_gettimeout_impl((PyObject *)self, NULL);
 }
 
 static inline PyObject *
@@ -3336,12 +3367,6 @@ sock_gettimeout_getter(PyObject *self, void *Py_UNUSED(closure))
     return sock_gettimeout_impl(self, NULL);
 }
 
-PyDoc_STRVAR(gettimeout_doc,
-"gettimeout() -> timeout\n\
-\n\
-Returns the timeout in seconds (float) associated with socket\n\
-operations. A timeout of None indicates that timeouts on socket\n\
-operations are disabled.");
 
 #ifdef HAVE_SETSOCKOPT
 /* s.setsockopt() method.
@@ -3483,22 +3508,30 @@ None, optlen.");
    With a third integer argument, retrieves a string buffer of that size;
    use optional built-in module 'struct' to decode the string. */
 
+/*[clinic input]
+_socket.socket.getsockopt
+    self as s: self(type="PySocketSockObject *")
+    level: int
+    option as optname: int
+    buffersize as buflen: int = 0
+    /
+
+Get a socket option.
+
+See the Unix manual for level and option.  If a nonzero buffersize
+argument is given, the return value is a bytes object of that
+length; otherwise it is an integer.
+[clinic start generated code]*/
+
 static PyObject *
-sock_getsockopt(PyObject *self, PyObject *args)
+_socket_socket_getsockopt_impl(PySocketSockObject *s, int level, int optname,
+                               int buflen)
+/*[clinic end generated code: output=0b397d1e2237a512 input=1a586fad20b3c3fa]*/
 {
-    PySocketSockObject *s = _PySocketSockObject_CAST(self);
-
-    int level;
-    int optname;
     int res;
-    socklen_t buflen = 0;
     int flag = 0;
     socklen_t flagsize;
 
-    if (!PyArg_ParseTuple(args, "ii|i:getsockopt",
-                          &level, &optname, &buflen))
-        return NULL;
-
     if (buflen == 0) {
 #ifdef AF_VSOCK
         if (s->sock_family == AF_VSOCK) {
@@ -3539,31 +3572,38 @@ sock_getsockopt(PyObject *self, PyObject *args)
     if (writer == NULL) {
         return NULL;
     }
+    socklen_t optlen = buflen;
     res = getsockopt(get_sock_fd(s), level, optname,
-                     PyBytesWriter_GetData(writer), &buflen);
+                     PyBytesWriter_GetData(writer), &optlen);
     if (res < 0) {
         PyBytesWriter_Discard(writer);
         return s->errorhandler();
     }
-    return PyBytesWriter_FinishWithSize(writer, buflen);
+    return PyBytesWriter_FinishWithSize(writer, optlen);
 }
 
-PyDoc_STRVAR(getsockopt_doc,
-"getsockopt(level, option[, buffersize]) -> value\n\
-\n\
-Get a socket option.  See the Unix manual for level and option.\n\
-If a nonzero buffersize argument is given, the return value is a\n\
-string of that length; otherwise it is an integer.");
 
 
 #ifdef HAVE_BIND
 /* s.bind(sockaddr) method */
 
+/*[clinic input]
+_socket.socket.bind
+    self as s: self(type="PySocketSockObject *")
+    address as addro: object
+    /
+
+Bind the socket to a local address.
+
+For IP sockets, the address is a pair (host, port); the host must
+refer to the local host.  For raw packet sockets the address is a
+tuple (ifname, proto [,pkttype [,hatype [,addr]]]).
+[clinic start generated code]*/
+
 static PyObject *
-sock_bind(PyObject *self, PyObject *addro)
+_socket_socket_bind_impl(PySocketSockObject *s, PyObject *addro)
+/*[clinic end generated code: output=b8d74d0184a9f187 input=ee3f536adbaaa1cb]*/
 {
-    PySocketSockObject *s = _PySocketSockObject_CAST(self);
-
     sock_addr_t addrbuf;
     int addrlen;
     int res;
@@ -3584,12 +3624,6 @@ sock_bind(PyObject *self, PyObject *addro)
     Py_RETURN_NONE;
 }
 
-PyDoc_STRVAR(bind_doc,
-"bind(address)\n\
-\n\
-Bind the socket to a local address.  For IP sockets, the address is a\n\
-pair (host, port); the host must refer to the local host. For raw packet\n\
-sockets the address is a tuple (ifname, proto [,pkttype [,hatype [,addr]]])");
 #endif
 
 
@@ -3633,21 +3667,25 @@ _socket_socket_close_impl(PySocketSockObject *s)
     Py_RETURN_NONE;
 }
 
+/*[clinic input]
+_socket.socket.detach
+    self as s: self(type="PySocketSockObject *")
+
+Close the socket object without closing the file descriptor.
+
+The object cannot be used after this call, but the file descriptor
+can be reused for other purposes.  The file descriptor is returned.
+[clinic start generated code]*/
+
 static PyObject *
-sock_detach(PyObject *self, PyObject *Py_UNUSED(ignored))
+_socket_socket_detach_impl(PySocketSockObject *s)
+/*[clinic end generated code: output=769cc72d7fdddebd input=ee1305f0594b88cc]*/
 {
-    PySocketSockObject *s = _PySocketSockObject_CAST(self);
     SOCKET_T fd = get_sock_fd(s);
     set_sock_fd(s, INVALID_SOCKET);
     return PyLong_FromSocket_t(fd);
 }
 
-PyDoc_STRVAR(detach_doc,
-"detach()\n\
-\n\
-Close the socket object without closing the underlying file descriptor.\n\
-The object cannot be used after this call, but the file descriptor\n\
-can be reused for other purposes.  The file descriptor is returned.");
 
 #ifdef HAVE_CONNECT
 static int
@@ -3751,11 +3789,21 @@ internal_connect(PySocketSockObject *s, struct sockaddr *addr, int addrlen,
 
 /* s.connect(sockaddr) method */
 
+/*[clinic input]
+_socket.socket.connect
+    self as s: self(type="PySocketSockObject *")
+    address as addro: object
+    /
+
+Connect the socket to a remote address.
+
+For IP sockets, the address is a pair (host, port).
+[clinic start generated code]*/
+
 static PyObject *
-sock_connect(PyObject *self, PyObject *addro)
+_socket_socket_connect_impl(PySocketSockObject *s, PyObject *addro)
+/*[clinic end generated code: output=d4f73817eb43ed12 input=1b7c601416490538]*/
 {
-    PySocketSockObject *s = _PySocketSockObject_CAST(self);
-
     sock_addr_t addrbuf;
     int addrlen;
     int res;
@@ -3777,20 +3825,26 @@ sock_connect(PyObject *self, PyObject *addro)
     Py_RETURN_NONE;
 }
 
-PyDoc_STRVAR(connect_doc,
-"connect(address)\n\
-\n\
-Connect the socket to a remote address.  For IP sockets, the address\n\
-is a pair (host, port).");
 
 
 /* s.connect_ex(sockaddr) method */
 
+/*[clinic input]
+_socket.socket.connect_ex
+    self as s: self(type="PySocketSockObject *")
+    address as addro: object
+    /
+
+Connect the socket to a remote address.
+
+This is like connect(address), but returns an error code (the errno
+value) instead of raising an exception when an error occurs.
+[clinic start generated code]*/
+
 static PyObject *
-sock_connect_ex(PyObject *self, PyObject *addro)
+_socket_socket_connect_ex_impl(PySocketSockObject *s, PyObject *addro)
+/*[clinic end generated code: output=bc8b7cdf80e419af input=716f3a78a296d7ca]*/
 {
-    PySocketSockObject *s = _PySocketSockObject_CAST(self);
-
     sock_addr_t addrbuf;
     int addrlen;
     int res;
@@ -3811,37 +3865,45 @@ sock_connect_ex(PyObject *self, PyObject *addro)
     return PyLong_FromLong((long) res);
 }
 
-PyDoc_STRVAR(connect_ex_doc,
-"connect_ex(address) -> errno\n\
-\n\
-This is like connect(address), but returns an error code (the errno value)\n\
-instead of raising an exception when an error occurs.");
 #endif // HAVE_CONNECT
 
 
 /* s.fileno() method */
 
+/*[clinic input]
+_socket.socket.fileno
+    self as s: self(type="PySocketSockObject *")
+
+Return the integer file descriptor of the socket.
+[clinic start generated code]*/
+
 static PyObject *
-sock_fileno(PyObject *self, PyObject *Py_UNUSED(ignored))
+_socket_socket_fileno_impl(PySocketSockObject *s)
+/*[clinic end generated code: output=6d422560f508d2c6 input=7f817a2413c3c37c]*/
 {
-    PySocketSockObject *s = _PySocketSockObject_CAST(self);
     return PyLong_FromSocket_t(get_sock_fd(s));
 }
 
-PyDoc_STRVAR(fileno_doc,
-"fileno() -> integer\n\
-\n\
-Return the integer file descriptor of the socket.");
 
 
 #ifdef HAVE_GETSOCKNAME
 /* s.getsockname() method */
 
+/*[clinic input]
+_socket.socket.getsockname
+    self as s: self(type="PySocketSockObject *")
+
+Return the address of the local endpoint.
+
+The format depends on the address family.  For IPv4 sockets, the
+address info is a pair (hostaddr, port). For IPv6 sockets, the
+address info is a 4-tuple (hostaddr, port, flowinfo, scope_id).
+[clinic start generated code]*/
+
 static PyObject *
-sock_getsockname(PyObject *self, PyObject *Py_UNUSED(ignored))
+_socket_socket_getsockname_impl(PySocketSockObject *s)
+/*[clinic end generated code: output=b4c94874b6bf20ed input=b6628802847b2eef]*/
 {
-    PySocketSockObject *s = _PySocketSockObject_CAST(self);
-
     sock_addr_t addrbuf;
     int res;
     socklen_t addrlen;
@@ -3858,24 +3920,25 @@ sock_getsockname(PyObject *self, PyObject *Py_UNUSED(ignored))
                         s->sock_proto);
 }
 
-PyDoc_STRVAR(getsockname_doc,
-"getsockname() -> address info\n\
-\n\
-Return the address of the local endpoint. The format depends on the\n\
-address family. For IPv4 sockets, the address info is a pair\n\
-(hostaddr, port). For IPv6 sockets, the address info is a 4-tuple\n\
-(hostaddr, port, flowinfo, scope_id).");
 #endif
 
 
 #ifdef HAVE_GETPEERNAME         /* Cray APP doesn't have this :-( */
 /* s.getpeername() method */
 
+/*[clinic input]
+_socket.socket.getpeername
+    self as s: self(type="PySocketSockObject *")
+
+Return the address of the remote endpoint.
+
+For IP sockets, the address info is a pair (hostaddr, port).
+[clinic start generated code]*/
+
 static PyObject *
-sock_getpeername(PyObject *self, PyObject *Py_UNUSED(ignored))
+_socket_socket_getpeername_impl(PySocketSockObject *s)
+/*[clinic end generated code: output=3e20211d74c8f60b input=aa6b96e92c7996be]*/
 {
-    PySocketSockObject *s = _PySocketSockObject_CAST(self);
-
     sock_addr_t addrbuf;
     int res;
     socklen_t addrlen;
@@ -3892,11 +3955,6 @@ sock_getpeername(PyObject *self, PyObject *Py_UNUSED(ignored))
                         s->sock_proto);
 }
 
-PyDoc_STRVAR(getpeername_doc,
-"getpeername() -> address info\n\
-\n\
-Return the address of the remote endpoint.  For IP sockets, the address\n\
-info is a pair (hostaddr, port).");
 
 #endif /* HAVE_GETPEERNAME */
 
@@ -3904,18 +3962,26 @@ info is a pair (hostaddr, port).");
 #ifdef HAVE_LISTEN
 /* s.listen(n) method */
 
+/*[clinic input]
+_socket.socket.listen
+    self as s: self(type="PySocketSockObject *")
+    backlog: int(c_default="Py_MIN(SOMAXCONN, 128)") = min(SOMAXCONN, 128)
+    /
+
+Enable a server to accept connections.
+
+If backlog is specified, it must be at least 0 (if it is lower, it
+is set to 0); it specifies the number of unaccepted connections that
+the system will allow before refusing new connections. If not
+specified, a default reasonable value is chosen.
+[clinic start generated code]*/
+
 static PyObject *
-sock_listen(PyObject *self, PyObject *args)
+_socket_socket_listen_impl(PySocketSockObject *s, int backlog)
+/*[clinic end generated code: output=245718576af7f07b input=8eb794d108797ad9]*/
 {
-    PySocketSockObject *s = _PySocketSockObject_CAST(self);
-    /* We try to choose a default backlog high enough to avoid connection drops
-     * for common workloads, yet not too high to limit resource usage. */
-    int backlog = Py_MIN(SOMAXCONN, 128);
     int res;
 
-    if (!PyArg_ParseTuple(args, "|i:listen", &backlog))
-        return NULL;
-
     Py_BEGIN_ALLOW_THREADS
     /* To avoid problems on systems that don't allow a negative backlog
      * (which doesn't make sense anyway) we force a minimum value of 0. */
@@ -3928,13 +3994,6 @@ sock_listen(PyObject *self, PyObject *args)
     Py_RETURN_NONE;
 }
 
-PyDoc_STRVAR(listen_doc,
-"listen([backlog])\n\
-\n\
-Enable a server to accept connections.  If backlog is specified, it must be\n\
-at least 0 (if it is lower, it is set to 0); it specifies the number of\n\
-unaccepted connections that the system will allow before refusing new\n\
-connections. If not specified, a default reasonable value is chosen.");
 #endif
 
 struct sock_recv {
@@ -3995,16 +4054,27 @@ sock_recv_guts(PySocketSockObject *s, char* cbuf, Py_ssize_t len, int flags)
 
 /* s.recv(nbytes [,flags]) method */
 
-static PyObject *
-sock_recv(PyObject *self, PyObject *args)
-{
-    PySocketSockObject *s = _PySocketSockObject_CAST(self);
+/*[clinic input]
+_socket.socket.recv
+    self as s: self(type="PySocketSockObject *")
+    buffersize as recvlen: Py_ssize_t
+    flags: int = 0
+    /
 
-    Py_ssize_t recvlen, outlen;
-    int flags = 0;
+Receive up to buffersize bytes from the socket.
 
-    if (!PyArg_ParseTuple(args, "n|i:recv", &recvlen, &flags))
-        return NULL;
+For the optional flags argument, see the Unix manual. When no data
+is available, block until at least one byte is available or until
+the remote end is closed. When the remote end is closed and all data
+is read, return the empty string.
+[clinic start generated code]*/
+
+static PyObject *
+_socket_socket_recv_impl(PySocketSockObject *s, Py_ssize_t recvlen,
+                         int flags)
+/*[clinic end generated code: output=412b46af1a68ee75 input=6c8382200e8f85fc]*/
+{
+    Py_ssize_t outlen;
 
     if (recvlen < 0) {
         PyErr_SetString(PyExc_ValueError,
@@ -4030,37 +4100,34 @@ sock_recv(PyObject *self, PyObject *args)
     return PyBytesWriter_FinishWithSize(writer, outlen);
 }
 
-PyDoc_STRVAR(recv_doc,
-"recv(buffersize[, flags]) -> data\n\
-\n\
-Receive up to buffersize bytes from the socket.  For the optional flags\n\
-argument, see the Unix manual.  When no data is available, block until\n\
-at least one byte is available or until the remote end is closed.  When\n\
-the remote end is closed and all data is read, return the empty string.");
-
 
 /* s.recv_into(buffer, [nbytes [,flags]]) method */
 
-static PyObject*
-sock_recv_into(PyObject *self, PyObject *args, PyObject *kwds)
-{
-    static char *kwlist[] = {"buffer", "nbytes", "flags", 0};
-    PySocketSockObject *s = _PySocketSockObject_CAST(self);
+/*[clinic input]
+_socket.socket.recv_into
+    self as s: self(type="PySocketSockObject *")
+    buffer as pbuf: Py_buffer(accept={rwbuffer})
+    nbytes as recvlen: Py_ssize_t = 0
+    flags: int = 0
 
-    int flags = 0;
-    Py_buffer pbuf;
-    char *buf;
-    Py_ssize_t buflen, readlen, recvlen = 0;
+Receive up to nbytes bytes from the socket, storing into a buffer.
 
-    /* Get the buffer's memory */
-    if (!PyArg_ParseTupleAndKeywords(args, kwds, "w*|ni:recv_into", kwlist,
-                                     &pbuf, &recvlen, &flags))
-        return NULL;
-    buf = pbuf.buf;
-    buflen = pbuf.len;
+A version of recv() that stores its data into a buffer rather than
+creating a new bytes object.  If nbytes is not specified (or 0),
+receive up to the size available in the given buffer.
+
+See recv() for documentation about the flags.
+[clinic start generated code]*/
+
+static PyObject *
+_socket_socket_recv_into_impl(PySocketSockObject *s, Py_buffer *pbuf,
+                              Py_ssize_t recvlen, int flags)
+/*[clinic end generated code: output=58a1cbe9fadb88d7 input=410e6aff36c416a0]*/
+{
+    char *buf = pbuf->buf;
+    Py_ssize_t buflen = pbuf->len, readlen;
 
     if (recvlen < 0) {
-        PyBuffer_Release(&pbuf);
         PyErr_SetString(PyExc_ValueError,
                         "negative buffersize in recv_into");
         return NULL;
@@ -4072,7 +4139,6 @@ sock_recv_into(PyObject *self, PyObject *args, PyObject *kwds)
 
     /* Check if the buffer is large enough */
     if (buflen < recvlen) {
-        PyBuffer_Release(&pbuf);
         PyErr_SetString(PyExc_ValueError,
                         "buffer too small for requested bytes");
         return NULL;
@@ -4082,24 +4148,14 @@ sock_recv_into(PyObject *self, PyObject *args, PyObject *kwds)
     readlen = sock_recv_guts(s, buf, recvlen, flags);
     if (readlen < 0) {
         /* Return an error. */
-        PyBuffer_Release(&pbuf);
         return NULL;
     }
 
-    PyBuffer_Release(&pbuf);
     /* Return the number of bytes read.  Note that we do not do anything
        special here in the case that readlen < recvlen. */
     return PyLong_FromSsize_t(readlen);
 }
 
-PyDoc_STRVAR(recv_into_doc,
-"recv_into(buffer, [nbytes[, flags]]) -> nbytes_read\n\
-\n\
-A version of recv() that stores its data into a buffer rather than creating\n\
-a new string.  Receive up to buffersize bytes from the socket.  If buffersize\n\
-is not specified (or 0), receive up to the size available in the given buffer.\n\
-\n\
-See recv() for documentation about the flags.");
 
 struct sock_recvfrom {
     char* cbuf;
@@ -4178,17 +4234,26 @@ sock_recvfrom_guts(PySocketSockObject *s, char* cbuf, Py_ssize_t len, int flags,
 
 /* s.recvfrom(nbytes [,flags]) method */
 
+/*[clinic input]
+_socket.socket.recvfrom
+    self as s: self(type="PySocketSockObject *")
+    buffersize as recvlen: Py_ssize_t
+    flags: int = 0
+    /
+
+Receive up to buffersize bytes and the sender's address info.
+
+Like recv(buffersize, flags), but return a (data, address info)
+pair.
+[clinic start generated code]*/
+
 static PyObject *
-sock_recvfrom(PyObject *self, PyObject *args)
+_socket_socket_recvfrom_impl(PySocketSockObject *s, Py_ssize_t recvlen,
+                             int flags)
+/*[clinic end generated code: output=52b2ece9ea4251b1 input=d8c8c5dc56c02e86]*/
 {
-    PySocketSockObject *s = _PySocketSockObject_CAST(self);
-
     PyObject *addr = NULL;
-    int flags = 0;
-    Py_ssize_t recvlen, outlen;
-
-    if (!PyArg_ParseTuple(args, "n|i:recvfrom", &recvlen, &flags))
-        return NULL;
+    Py_ssize_t outlen;
 
     if (recvlen < 0) {
         PyErr_SetString(PyExc_ValueError,
@@ -4220,36 +4285,33 @@ sock_recvfrom(PyObject *self, PyObject *args)
     return NULL;
 }
 
-PyDoc_STRVAR(recvfrom_doc,
-"recvfrom(buffersize[, flags]) -> (data, address info)\n\
-\n\
-Like recv(buffersize, flags) but also return the sender's address info.");
 
 
 /* s.recvfrom_into(buffer[, nbytes [,flags]]) method */
 
-static PyObject *
-sock_recvfrom_into(PyObject *self, PyObject *args, PyObject* kwds)
-{
-    static char *kwlist[] = {"buffer", "nbytes", "flags", 0};
-    PySocketSockObject *s = _PySocketSockObject_CAST(self);
+/*[clinic input]
+_socket.socket.recvfrom_into
+    self as s: self(type="PySocketSockObject *")
+    buffer as pbuf: Py_buffer(accept={rwbuffer})
+    nbytes as recvlen: Py_ssize_t = 0
+    flags: int = 0
 
-    int flags = 0;
-    Py_buffer pbuf;
-    char *buf;
-    Py_ssize_t readlen, buflen, recvlen = 0;
+Receive up to nbytes bytes and the sender's address info.
 
-    PyObject *addr = NULL;
+Like recv_into(buffer, nbytes, flags), but return a (nbytes, address
+info) pair.
+[clinic start generated code]*/
 
-    if (!PyArg_ParseTupleAndKeywords(args, kwds, "w*|ni:recvfrom_into",
-                                     kwlist, &pbuf,
-                                     &recvlen, &flags))
-        return NULL;
-    buf = pbuf.buf;
-    buflen = pbuf.len;
+static PyObject *
+_socket_socket_recvfrom_into_impl(PySocketSockObject *s, Py_buffer *pbuf,
+                                  Py_ssize_t recvlen, int flags)
+/*[clinic end generated code: output=e60b491a1c9d5bec input=2a15bf437b8b98ba]*/
+{
+    char *buf = pbuf->buf;
+    Py_ssize_t readlen, buflen = pbuf->len;
+    PyObject *addr = NULL;
 
     if (recvlen < 0) {
-        PyBuffer_Release(&pbuf);
         PyErr_SetString(PyExc_ValueError,
                         "negative buffersize in recvfrom_into");
         return NULL;
@@ -4258,7 +4320,6 @@ sock_recvfrom_into(PyObject *self, PyObject *args, PyObject* kwds)
         /* If nbytes was not specified, use the buffer's length */
         recvlen = buflen;
     } else if (recvlen > buflen) {
-        PyBuffer_Release(&pbuf);
         PyErr_SetString(PyExc_ValueError,
                         "nbytes is greater than the length of the buffer");
         return NULL;
@@ -4266,22 +4327,16 @@ sock_recvfrom_into(PyObject *self, PyObject *args, PyObject* kwds)
 
     readlen = sock_recvfrom_guts(s, buf, recvlen, flags, &addr);
     if (readlen < 0) {
-        PyBuffer_Release(&pbuf);
         /* Return an error */
         Py_XDECREF(addr);
         return NULL;
     }
 
-    PyBuffer_Release(&pbuf);
     /* Return the number of bytes read and the address.  Note that we do
        not do anything special here in the case that readlen < recvlen. */
     return Py_BuildValue("nN", readlen, addr);
 }
 
-PyDoc_STRVAR(recvfrom_into_doc,
-"recvfrom_into(buffer[, nbytes[, flags]]) -> (nbytes, address info)\n\
-\n\
-Like recv_into(buffer[, nbytes[, flags]]) but also return the sender's address info.");
 #endif
 
 /* The sendmsg() and recvmsg[_into]() methods require a working
@@ -4456,14 +4511,47 @@ makeval_recvmsg(ssize_t received, void *data)
 
 /* s.recvmsg(bufsize[, ancbufsize[, flags]]) method */
 
+/*[clinic input]
+_socket.socket.recvmsg
+    self as s: self(type="PySocketSockObject *")
+    bufsize: Py_ssize_t
+    ancbufsize: Py_ssize_t = 0
+    flags: int = 0
+    /
+
+Receive normal data and ancillary data from the socket.
+
+Receive up to bufsize bytes of normal data.  The ancbufsize argument
+sets the size in bytes of the internal buffer used to receive the
+ancillary data; it defaults to 0, meaning that no ancillary data
+will be received.  Appropriate buffer sizes for ancillary data can
+be calculated using CMSG_SPACE() or CMSG_LEN(), and items which do
+not fit into the buffer might be truncated or discarded.  The flags
+argument defaults to 0 and has the same meaning as for recv().
+
+The return value is a 4-tuple: (data, ancdata, msg_flags, address).
+The data item is a bytes object holding the non-ancillary data
+received.  The ancdata item is a list of zero or more tuples
+(cmsg_level, cmsg_type, cmsg_data) representing the ancillary data
+(control messages) received: cmsg_level and cmsg_type are integers
+specifying the protocol level and protocol-specific type
+respectively, and cmsg_data is a bytes object holding the associated
+data.  The msg_flags item is the bitwise OR of various flags
+indicating conditions on the received message; see your system
+documentation for details.  If the receiving socket is unconnected,
+address is the address of the sending socket, if available;
+otherwise, its value is unspecified.
+
+If recvmsg() raises an exception after the system call returns, it
+will first attempt to close any file descriptors received via the
+SCM_RIGHTS mechanism.
+[clinic start generated code]*/
+
 static PyObject *
-sock_recvmsg(PyObject *self, PyObject *args)
+_socket_socket_recvmsg_impl(PySocketSockObject *s, Py_ssize_t bufsize,
+                            Py_ssize_t ancbufsize, int flags)
+/*[clinic end generated code: output=1a26c130cf1a898f input=ae53e29436e6c0a3]*/
 {
-    Py_ssize_t bufsize, ancbufsize = 0;
-    int flags = 0;
-    if (!PyArg_ParseTuple(args, "n|ni:recvmsg", &bufsize, &ancbufsize, &flags))
-        return NULL;
-
     if (bufsize < 0) {
         PyErr_SetString(PyExc_ValueError, "negative buffer size in recvmsg()");
         return NULL;
@@ -4481,41 +4569,12 @@ sock_recvmsg(PyObject *self, PyObject *args)
        writer (&writer); makeval_recvmsg() finish it and set our pointer to
        NULL. */
     PyObject *retval;
-    PySocketSockObject *s = _PySocketSockObject_CAST(self);
     retval = sock_recvmsg_guts(s, &iov, 1, flags, ancbufsize,
                                &makeval_recvmsg, &writer);
     PyBytesWriter_Discard(writer);
     return retval;
 }
 
-PyDoc_STRVAR(recvmsg_doc,
-"recvmsg(bufsize[, ancbufsize[, flags]]) -> (data, ancdata, msg_flags, address)\n\
-\n\
-Receive normal data (up to bufsize bytes) and ancillary data from the\n\
-socket.  The ancbufsize argument sets the size in bytes of the\n\
-internal buffer used to receive the ancillary data; it defaults to 0,\n\
-meaning that no ancillary data will be received.  Appropriate buffer\n\
-sizes for ancillary data can be calculated using CMSG_SPACE() or\n\
-CMSG_LEN(), and items which do not fit into the buffer might be\n\
-truncated or discarded.  The flags argument defaults to 0 and has the\n\
-same meaning as for recv().\n\
-\n\
-The return value is a 4-tuple: (data, ancdata, msg_flags, address).\n\
-The data item is a bytes object holding the non-ancillary data\n\
-received.  The ancdata item is a list of zero or more tuples\n\
-(cmsg_level, cmsg_type, cmsg_data) representing the ancillary data\n\
-(control messages) received: cmsg_level and cmsg_type are integers\n\
-specifying the protocol level and protocol-specific type respectively,\n\
-and cmsg_data is a bytes object holding the associated data.  The\n\
-msg_flags item is the bitwise OR of various flags indicating\n\
-conditions on the received message; see your system documentation for\n\
-details.  If the receiving socket is unconnected, address is the\n\
-address of the sending socket, if available; otherwise, its value is\n\
-unspecified.\n\
-\n\
-If recvmsg() raises an exception after the system call returns, it\n\
-will first attempt to close any file descriptors received via the\n\
-SCM_RIGHTS mechanism.");
 
 
 static PyObject *
@@ -4526,21 +4585,55 @@ makeval_recvmsg_into(ssize_t received, void *data)
 
 /* s.recvmsg_into(buffers[, ancbufsize[, flags]]) method */
 
+/*[clinic input]
+_socket.socket.recvmsg_into
+    self as s: self(type="PySocketSockObject *")
+    buffers as buffers_arg: object
+    ancbufsize: Py_ssize_t = 0
+    flags: int = 0
+    /
+
+Receive normal and ancillary data, scattering the normal data.
+
+The buffers argument must be an iterable of objects that export
+writable buffers (e.g.  bytearray objects); these will be filled
+with successive chunks of the non-ancillary data until it has all
+been written or there are no more buffers.  The ancbufsize argument
+sets the size in bytes of the internal buffer used to receive the
+ancillary data; it defaults to 0, meaning that no ancillary data
+will be received.  Appropriate buffer sizes for ancillary data can
+be calculated using CMSG_SPACE() or CMSG_LEN(), and items which do
+not fit into the buffer might be truncated or discarded.  The flags
+argument defaults to 0 and has the same meaning as for recv().
+
+The return value is a 4-tuple: (nbytes, ancdata, msg_flags,
+address). The nbytes item is the total number of bytes of
+non-ancillary data written into the buffers.  The ancdata item is a
+list of zero or more tuples (cmsg_level, cmsg_type, cmsg_data)
+representing the ancillary data (control messages) received:
+cmsg_level and cmsg_type are integers specifying the protocol level
+and protocol-specific type respectively, and cmsg_data is a bytes
+object holding the associated data.  The msg_flags item is the
+bitwise OR of various flags indicating conditions on the received
+message; see your system documentation for details.  If the
+receiving socket is unconnected, address is the address of the
+sending socket, if available; otherwise, its value is unspecified.
+
+If recvmsg_into() raises an exception after the system call returns,
+it will first attempt to close any file descriptors received via the
+SCM_RIGHTS mechanism.
+[clinic start generated code]*/
+
 static PyObject *
-sock_recvmsg_into(PyObject *self, PyObject *args)
+_socket_socket_recvmsg_into_impl(PySocketSockObject *s,
+                                 PyObject *buffers_arg,
+                                 Py_ssize_t ancbufsize, int flags)
+/*[clinic end generated code: output=282fd7dd1bdb15f8 input=427536a5043122d2]*/
 {
-    PySocketSockObject *s = _PySocketSockObject_CAST(self);
-
-    Py_ssize_t ancbufsize = 0;
-    int flags = 0;
     struct iovec *iovs = NULL;
     Py_ssize_t i, nitems, nbufs = 0;
     Py_buffer *bufs = NULL;
-    PyObject *buffers_arg, *buffers_tuple, *retval = NULL;
-
-    if (!PyArg_ParseTuple(args, "O|ni:recvmsg_into",
-                          &buffers_arg, &ancbufsize, &flags))
-        return NULL;
+    PyObject *buffers_tuple, *retval = NULL;
 
     buffers_tuple = PySequence_Tuple(buffers_arg);
     if (buffers_tuple == NULL) {
@@ -4582,38 +4675,6 @@ sock_recvmsg_into(PyObject *self, PyObject *args)
     return retval;
 }
 
-PyDoc_STRVAR(recvmsg_into_doc,
-"recvmsg_into(buffers[, ancbufsize[, flags]]) -> (nbytes, ancdata, msg_flags, address)\n\
-\n\
-Receive normal data and ancillary data from the socket, scattering the\n\
-non-ancillary data into a series of buffers.  The buffers argument\n\
-must be an iterable of objects that export writable buffers\n\
-(e.g. bytearray objects); these will be filled with successive chunks\n\
-of the non-ancillary data until it has all been written or there are\n\
-no more buffers.  The ancbufsize argument sets the size in bytes of\n\
-the internal buffer used to receive the ancillary data; it defaults to\n\
-0, meaning that no ancillary data will be received.  Appropriate\n\
-buffer sizes for ancillary data can be calculated using CMSG_SPACE()\n\
-or CMSG_LEN(), and items which do not fit into the buffer might be\n\
-truncated or discarded.  The flags argument defaults to 0 and has the\n\
-same meaning as for recv().\n\
-\n\
-The return value is a 4-tuple: (nbytes, ancdata, msg_flags, address).\n\
-The nbytes item is the total number of bytes of non-ancillary data\n\
-written into the buffers.  The ancdata item is a list of zero or more\n\
-tuples (cmsg_level, cmsg_type, cmsg_data) representing the ancillary\n\
-data (control messages) received: cmsg_level and cmsg_type are\n\
-integers specifying the protocol level and protocol-specific type\n\
-respectively, and cmsg_data is a bytes object holding the associated\n\
-data.  The msg_flags item is the bitwise OR of various flags\n\
-indicating conditions on the received message; see your system\n\
-documentation for details.  If the receiving socket is unconnected,\n\
-address is the address of the sending socket, if available; otherwise,\n\
-its value is unspecified.\n\
-\n\
-If recvmsg_into() raises an exception after the system call returns,\n\
-it will first attempt to close any file descriptors received via the\n\
-SCM_RIGHTS mechanism.");
 #endif    /* CMSG_LEN */
 
 
@@ -5140,27 +5201,37 @@ _socket_socket_sendmsg_impl(PySocketSockObject *s, PyObject *data_arg,
 #endif    /* CMSG_LEN */
 
 #ifdef HAVE_SOCKADDR_ALG
-static PyObject*
-sock_sendmsg_afalg(PyObject *s, PyObject *args, PyObject *kwds)
-{
-    PySocketSockObject *self = _PySocketSockObject_CAST(s);
+/*[clinic input]
+_socket.socket.sendmsg_afalg
+    self: self(type="PySocketSockObject *")
+    msg as data_arg: object = NULL
+    *
+    op as opobj: object(subclass_of='&PyLong_Type') = NULL
+    iv: Py_buffer = NULL
+    assoclen as assoclenobj: object(subclass_of='&PyLong_Type') = NULL
+    flags: int = 0
+
+Set operation mode, IV and associated data length.
+
+For an AF_ALG operation socket.
+[clinic start generated code]*/
 
+static PyObject *
+_socket_socket_sendmsg_afalg_impl(PySocketSockObject *self,
+                                  PyObject *data_arg, PyObject *opobj,
+                                  Py_buffer *iv, PyObject *assoclenobj,
+                                  int flags)
+/*[clinic end generated code: output=3fd9856d4d9f7c97 input=3ed371da034a1bb3]*/
+{
     PyObject *retval = NULL;
 
     Py_ssize_t i, ndatabufs = 0;
     Py_buffer *databufs = NULL;
-    PyObject *data_arg = NULL;
-
-    Py_buffer iv = {NULL, NULL};
 
-    PyObject *opobj = NULL;
     int op = -1;
-
-    PyObject *assoclenobj = NULL;
     int assoclen = -1;
 
     unsigned int *uiptr;
-    int flags = 0;
 
     struct msghdr msg;
     struct cmsghdr *header = NULL;
@@ -5168,7 +5239,6 @@ sock_sendmsg_afalg(PyObject *s, PyObject *args, PyObject *kwds)
     struct sock_sendmsg ctx;
     Py_ssize_t controllen;
     void *controlbuf = NULL;
-    static char *keywords[] = {"msg", "op", "iv", "assoclen", "flags", 0};
 
     if (self->sock_family != AF_ALG) {
         PyErr_SetString(PyExc_OSError,
@@ -5176,14 +5246,6 @@ sock_sendmsg_afalg(PyObject *s, PyObject *args, PyObject *kwds)
         return NULL;
     }
 
-    if (!PyArg_ParseTupleAndKeywords(args, kwds,
-                                     "|O$O!y*O!i:sendmsg_afalg", keywords,
-                                     &data_arg,
-                                     &PyLong_Type, &opobj, &iv,
-                                     &PyLong_Type, &assoclenobj, &flags)) {
-        return NULL;
-    }
-
     memset(&msg, 0, sizeof(msg));
 
     /* op is a required, keyword-only argument >= 0 */
@@ -5210,8 +5272,8 @@ sock_sendmsg_afalg(PyObject *s, PyObject *args, PyObject *kwds)
     }
 
     controllen = CMSG_SPACE(4);
-    if (iv.buf != NULL) {
-        controllen += CMSG_SPACE(sizeof(*alg_iv) + iv.len);
+    if (iv->buf != NULL) {
+        controllen += CMSG_SPACE(sizeof(*alg_iv) + iv->len);
     }
     if (assoclen >= 0) {
         controllen += CMSG_SPACE(4);
@@ -5249,7 +5311,7 @@ sock_sendmsg_afalg(PyObject *s, PyObject *args, PyObject *kwds)
     *uiptr = (unsigned int)op;
 
     /* set initialization vector */
-    if (iv.buf != NULL) {
+    if (iv->buf != NULL) {
         header = CMSG_NXTHDR(&msg, header);
         if (header == NULL) {
             PyErr_SetString(PyExc_RuntimeError,
@@ -5258,10 +5320,10 @@ sock_sendmsg_afalg(PyObject *s, PyObject *args, PyObject *kwds)
         }
         header->cmsg_level = SOL_ALG;
         header->cmsg_type = ALG_SET_IV;
-        header->cmsg_len = CMSG_SPACE(sizeof(*alg_iv) + iv.len);
+        header->cmsg_len = CMSG_SPACE(sizeof(*alg_iv) + iv->len);
         alg_iv = (void*)CMSG_DATA(header);
-        alg_iv->ivlen = iv.len;
-        memcpy(alg_iv->iv, iv.buf, iv.len);
+        alg_iv->ivlen = iv->len;
+        memcpy(alg_iv->iv, iv->buf, iv->len);
     }
 
     /* set length of associated data for AEAD */
@@ -5289,9 +5351,6 @@ sock_sendmsg_afalg(PyObject *s, PyObject *args, PyObject *kwds)
 
   finally:
     PyMem_Free(controlbuf);
-    if (iv.buf != NULL) {
-        PyBuffer_Release(&iv);
-    }
     PyMem_Free(msg.msg_iov);
     for (i = 0; i < ndatabufs; i++) {
         PyBuffer_Release(&databufs[i]);
@@ -5300,21 +5359,28 @@ sock_sendmsg_afalg(PyObject *s, PyObject *args, PyObject *kwds)
     return retval;
 }
 
-PyDoc_STRVAR(sendmsg_afalg_doc,
-"sendmsg_afalg([msg], *, op[, iv[, assoclen[, flags=MSG_MORE]]])\n\
-\n\
-Set operation mode, IV and length of associated data for an AF_ALG\n\
-operation socket.");
 #endif
 
 #ifdef HAVE_SHUTDOWN
 /* s.shutdown(how) method */
 
+/*[clinic input]
+_socket.socket.shutdown
+    self as s: self(type="PySocketSockObject *")
+    flag as arg: object
+    /
+
+Shut down one or both halves of the connection.
+
+Shut down the reading side of the socket (flag == SHUT_RD), the
+writing side of the socket (flag == SHUT_WR), or both ends (flag ==
+SHUT_RDWR).
+[clinic start generated code]*/
+
 static PyObject *
-sock_shutdown(PyObject *self, PyObject *arg)
+_socket_socket_shutdown_impl(PySocketSockObject *s, PyObject *arg)
+/*[clinic end generated code: output=84264513a6049ca7 input=a90afb227247ce03]*/
 {
-    PySocketSockObject *s = _PySocketSockObject_CAST(self);
-
     int how;
     int res;
 
@@ -5329,11 +5395,6 @@ sock_shutdown(PyObject *self, PyObject *arg)
     Py_RETURN_NONE;
 }
 
-PyDoc_STRVAR(shutdown_doc,
-"shutdown(flag)\n\
-\n\
-Shut down the reading side of the socket (flag == SHUT_RD), the writing side\n\
-of the socket (flag == SHUT_WR), or both ends (flag == SHUT_RDWR).");
 #endif
 
 #if defined(MS_WINDOWS) && defined(SIO_RCVALL)
@@ -5395,18 +5456,26 @@ SIO_LOOPBACK_FAST_PATH: 'option' is a boolean value, and is disabled by default"
 #endif
 
 #if defined(MS_WINDOWS)
-static PyObject*
-sock_share(PyObject *self, PyObject *arg)
-{
-    PySocketSockObject *s = _PySocketSockObject_CAST(self);
+/*[clinic input]
+_socket.socket.share
+    self as s: self(type="PySocketSockObject *")
+    process_id as processId: unsigned_int(bitwise=True)
+    /
+
+Share the socket with another process.
+
+The target process id must be provided and the resulting bytes
+object passed to the target process.  There the shared socket can be
+instantiated by calling socket.fromshare().
+[clinic start generated code]*/
 
+static PyObject *
+_socket_socket_share_impl(PySocketSockObject *s, unsigned int processId)
+/*[clinic end generated code: output=446bfcc5fe3273c6 input=0a9d7536371bfe2d]*/
+{
     WSAPROTOCOL_INFOW info;
-    DWORD processId;
     int result;
 
-    if (!PyArg_ParseTuple(arg, "I", &processId))
-        return NULL;
-
     Py_BEGIN_ALLOW_THREADS
     result = WSADuplicateSocketW(get_sock_fd(s), processId, &info);
     Py_END_ALLOW_THREADS
@@ -5414,13 +5483,6 @@ sock_share(PyObject *self, PyObject *arg)
         return set_error();
     return PyBytes_FromStringAndSize((const char*)&info, sizeof(info));
 }
-PyDoc_STRVAR(sock_share_doc,
-"share(process_id) -> bytes\n\
-\n\
-Share the socket with another process.  The target process id\n\
-must be provided and the resulting bytes object passed to the target\n\
-process.  There the shared socket can be instantiated by calling\n\
-socket.fromshare().");
 
 
 #endif
@@ -5428,82 +5490,42 @@ socket.fromshare().");
 /* List of methods for socket objects */
 
 static PyMethodDef sock_methods[] = {
-#if defined(HAVE_ACCEPT) || defined(HAVE_ACCEPT4)
-    {"_accept", sock_accept, METH_NOARGS, accept_doc},
-#endif
-#ifdef HAVE_BIND
-    {"bind", sock_bind, METH_O, bind_doc},
-#endif
+    _SOCKET_SOCKET__ACCEPT_METHODDEF
+    _SOCKET_SOCKET_BIND_METHODDEF
     _SOCKET_SOCKET_CLOSE_METHODDEF
-#ifdef HAVE_CONNECT
-    {"connect", sock_connect, METH_O, connect_doc},
-    {"connect_ex", sock_connect_ex, METH_O, connect_ex_doc},
-#endif
-    {"detach", sock_detach, METH_NOARGS, detach_doc},
-    {"fileno", sock_fileno, METH_NOARGS, fileno_doc},
-#ifdef HAVE_GETPEERNAME
-    {"getpeername", sock_getpeername, METH_NOARGS, getpeername_doc},
-#endif
-#ifdef HAVE_GETSOCKNAME
-    {"getsockname", sock_getsockname, METH_NOARGS, getsockname_doc},
-#endif
-    {"getsockopt", sock_getsockopt, METH_VARARGS, getsockopt_doc},
+    _SOCKET_SOCKET_CONNECT_METHODDEF
+    _SOCKET_SOCKET_CONNECT_EX_METHODDEF
+    _SOCKET_SOCKET_DETACH_METHODDEF
+    _SOCKET_SOCKET_FILENO_METHODDEF
+    _SOCKET_SOCKET_GETPEERNAME_METHODDEF
+    _SOCKET_SOCKET_GETSOCKNAME_METHODDEF
+    _SOCKET_SOCKET_GETSOCKOPT_METHODDEF
 #if defined(MS_WINDOWS) && defined(SIO_RCVALL)
     {"ioctl", sock_ioctl, METH_VARARGS, sock_ioctl_doc},
 #endif
-#if defined(MS_WINDOWS)
-    {"share", sock_share, METH_VARARGS, sock_share_doc},
-#endif
-#ifdef HAVE_LISTEN
-    {"listen", sock_listen, METH_VARARGS, listen_doc},
-#endif
-    {"recv", sock_recv, METH_VARARGS, recv_doc},
-    {
-        "recv_into",
-        _PyCFunction_CAST(sock_recv_into),
-        METH_VARARGS | METH_KEYWORDS,
-        recv_into_doc
-    },
-#ifdef HAVE_RECVFROM
-    {"recvfrom", sock_recvfrom, METH_VARARGS, recvfrom_doc},
-    {
-        "recvfrom_into",
-        _PyCFunction_CAST(sock_recvfrom_into),
-        METH_VARARGS | METH_KEYWORDS,
-        recvfrom_into_doc
-    },
-#endif
+    _SOCKET_SOCKET_SHARE_METHODDEF
+    _SOCKET_SOCKET_LISTEN_METHODDEF
+    _SOCKET_SOCKET_RECV_METHODDEF
+    _SOCKET_SOCKET_RECV_INTO_METHODDEF
+    _SOCKET_SOCKET_RECVFROM_METHODDEF
+    _SOCKET_SOCKET_RECVFROM_INTO_METHODDEF
     _SOCKET_SOCKET_SEND_METHODDEF
     _SOCKET_SOCKET_SENDALL_METHODDEF
 #ifdef HAVE_SENDTO
     {"sendto", sock_sendto, METH_VARARGS, sendto_doc},
 #endif
-    {"setblocking", sock_setblocking, METH_O, setblocking_doc},
-    {"getblocking", sock_getblocking, METH_NOARGS, getblocking_doc},
-    {"settimeout", sock_settimeout, METH_O, settimeout_doc},
-    {
-        "gettimeout", sock_gettimeout_method, METH_NOARGS,
-        gettimeout_doc
-    },
+    _SOCKET_SOCKET_SETBLOCKING_METHODDEF
+    _SOCKET_SOCKET_GETBLOCKING_METHODDEF
+    _SOCKET_SOCKET_SETTIMEOUT_METHODDEF
+    _SOCKET_SOCKET_GETTIMEOUT_METHODDEF
 #ifdef HAVE_SETSOCKOPT
     {"setsockopt", sock_setsockopt, METH_VARARGS, setsockopt_doc},
 #endif
-#ifdef HAVE_SHUTDOWN
-    {"shutdown", sock_shutdown, METH_O, shutdown_doc},
-#endif
-#ifdef CMSG_LEN
-    {"recvmsg", sock_recvmsg, METH_VARARGS, recvmsg_doc},
-    {"recvmsg_into", sock_recvmsg_into, METH_VARARGS, recvmsg_into_doc},
+    _SOCKET_SOCKET_SHUTDOWN_METHODDEF
+    _SOCKET_SOCKET_RECVMSG_METHODDEF
+    _SOCKET_SOCKET_RECVMSG_INTO_METHODDEF
     _SOCKET_SOCKET_SENDMSG_METHODDEF
-#endif
-#ifdef HAVE_SOCKADDR_ALG
-    {
-        "sendmsg_afalg",
-        _PyCFunction_CAST(sock_sendmsg_afalg),
-        METH_VARARGS | METH_KEYWORDS,
-        sendmsg_afalg_doc
-    },
-#endif
+    _SOCKET_SOCKET_SENDMSG_AFALG_METHODDEF
     {NULL, NULL, 0, NULL} /* sentinel */
 };
 
@@ -5882,8 +5904,15 @@ static PyType_Spec sock_spec = {
 /* Python interface to gethostname(). */
 
 /*ARGSUSED*/
+/*[clinic input]
+_socket.gethostname
+
+Return the current host name.
+[clinic start generated code]*/
+
 static PyObject *
-socket_gethostname(PyObject *self, PyObject *unused)
+_socket_gethostname_impl(PyObject *module)
+/*[clinic end generated code: output=1d9b789d69464c01 input=994028f092f41baf]*/
 {
     if (PySys_Audit("socket.gethostname", NULL) < 0) {
         return NULL;
@@ -5939,21 +5968,23 @@ socket_gethostname(PyObject *self, PyObject *unused)
 #endif
 }
 
-PyDoc_STRVAR(gethostname_doc,
-"gethostname() -> string\n\
-\n\
-Return the current host name.");
 #endif
 
 #ifdef HAVE_SETHOSTNAME
-PyDoc_STRVAR(sethostname_doc,
-"sethostname(name)\n\n\
-Sets the hostname to name.");
+
+/*[clinic input]
+_socket.sethostname
+
+    name as hnobj: object
+    /
+
+Set the hostname to name.
+[clinic start generated code]*/
 
 static PyObject *
-socket_sethostname(PyObject *self, PyObject *args)
+_socket_sethostname(PyObject *module, PyObject *hnobj)
+/*[clinic end generated code: output=0b789350cbbc4553 input=89c1a7022cb1082a]*/
 {
-    PyObject *hnobj;
     Py_buffer buf;
     int res, flag = 0;
 
@@ -5963,15 +5994,16 @@ socket_sethostname(PyObject *self, PyObject *args)
 extern int sethostname(const char *, size_t);
 #endif
 
-    if (!PyArg_ParseTuple(args, "S:sethostname", &hnobj)) {
-        PyErr_Clear();
-        if (!PyArg_ParseTuple(args, "O&:sethostname",
-                PyUnicode_FSConverter, &hnobj))
+    if (!PyBytes_Check(hnobj)) {
+        if (!PyUnicode_FSConverter(hnobj, &hnobj)) {
             return NULL;
+        }
         flag = 1;
     }
 
     if (PySys_Audit("socket.sethostname", "(O)", hnobj) < 0) {
+        if (flag)
+            Py_DECREF(hnobj);
         return NULL;
     }
 
@@ -5992,19 +6024,32 @@ extern int sethostname(const char *, size_t);
 /* Python interface to gethostbyname(name). */
 
 /*ARGSUSED*/
+/*[clinic input]
+_socket.gethostbyname
+
+    host as hobj: object
+    /
+
+Return the IP address for a host.
+
+The address is a string of the form '255.255.255.255'.
+[clinic start generated code]*/
+
 static PyObject *
-socket_gethostbyname(PyObject *self, PyObject *args)
+_socket_gethostbyname(PyObject *module, PyObject *hobj)
+/*[clinic end generated code: output=19f571343780c48b input=3c0d3b92e44a1795]*/
 {
-    char *name;
     struct sockaddr_in addrbuf;
+    char *name;
     PyObject *ret = NULL;
 
-    if (!PyArg_ParseTuple(args, "et:gethostbyname", "idna", &name))
+    if (!PyArg_Parse(hobj, "et:gethostbyname", "idna", &name)) {
         return NULL;
-    if (PySys_Audit("socket.gethostbyname", "O", args) < 0) {
+    }
+    if (PySys_Audit("socket.gethostbyname", "(O)", hobj) < 0) {
         goto finally;
     }
-    socket_state *state = get_module_state(self);
+    socket_state *state = get_module_state(module);
     int rc = setipaddr(state, name, (struct sockaddr *)&addrbuf,
                        sizeof(addrbuf), AF_INET);
     if (rc < 0) {
@@ -6015,11 +6060,6 @@ socket_gethostbyname(PyObject *self, PyObject *args)
     PyMem_Free(name);
     return ret;
 }
-
-PyDoc_STRVAR(gethostbyname_doc,
-"gethostbyname(host) -> address\n\
-\n\
-Return the IP address (a string of the form '255.255.255.255') for a host.");
 #endif
 
 
@@ -6184,8 +6224,21 @@ gethost_common(socket_state *state, struct hostent *h, struct sockaddr *addr,
 /* Python interface to gethostbyname_ex(name). */
 
 /*ARGSUSED*/
+/*[clinic input]
+_socket.gethostbyname_ex
+
+    host as hobj: object
+    /
+
+Map a host name to its IP number.
+
+Return the true host name, a list of aliases, and a list of IP
+addresses, which are strings of the form '255.255.255.255'.
+[clinic start generated code]*/
+
 static PyObject *
-socket_gethostbyname_ex(PyObject *self, PyObject *args)
+_socket_gethostbyname_ex(PyObject *module, PyObject *hobj)
+/*[clinic end generated code: output=a1ea4607d257756e input=1ee9eb485339c58b]*/
 {
     char *name;
     int h_error;
@@ -6206,12 +6259,13 @@ socket_gethostbyname_ex(PyObject *self, PyObject *args)
 #endif
 #endif /* HAVE_GETHOSTBYNAME_R */
 
-    if (!PyArg_ParseTuple(args, "et:gethostbyname_ex", "idna", &name))
+    if (!PyArg_Parse(hobj, "et:gethostbyname_ex", "idna", &name)) {
         return NULL;
-    if (PySys_Audit("socket.gethostbyname", "O", args) < 0) {
+    }
+    if (PySys_Audit("socket.gethostbyname", "(O)", hobj) < 0) {
         goto finally;
     }
-    socket_state *state = get_module_state(self);
+    socket_state *state = get_module_state(module);
     if (setipaddr(state, name, SAS2SA(&addr), sizeof(addr), AF_INET) < 0) {
         goto finally;
     }
@@ -6253,23 +6307,32 @@ socket_gethostbyname_ex(PyObject *self, PyObject *args)
     return ret;
 }
 
-PyDoc_STRVAR(ghbn_ex_doc,
-"gethostbyname_ex(host) -> (name, aliaslist, addresslist)\n\
-\n\
-Return the true host name, a list of aliases, and a list of IP addresses,\n\
-for a host.  The host argument is a string giving a host name or IP number.");
 #endif
 
 #if defined(HAVE_GETHOSTBYNAME_R) || defined (HAVE_GETHOSTBYADDR)
 /* Python interface to gethostbyaddr(IP). */
 
 /*ARGSUSED*/
+/*[clinic input]
+_socket.gethostbyaddr
+
+    host as hobj: object
+    /
+
+Map an IP number or host name to the true host name and addresses.
+
+Return the true host name, a list of aliases, and a list of IP
+addresses.  The host argument is a string giving a host name or IP
+number.
+[clinic start generated code]*/
+
 static PyObject *
-socket_gethostbyaddr(PyObject *self, PyObject *args)
+_socket_gethostbyaddr(PyObject *module, PyObject *hobj)
+/*[clinic end generated code: output=4ba6c4d7a3085ab5 input=c602ba97bf0d395b]*/
 {
+    char *ip_num;
     sock_addr_t addr;
     struct sockaddr *sa = SAS2SA(&addr);
-    char *ip_num;
     struct hostent *h;
     PyObject *ret = NULL;
 #ifdef HAVE_GETHOSTBYNAME_R
@@ -6293,13 +6356,14 @@ socket_gethostbyaddr(PyObject *self, PyObject *args)
     int af;
     int h_error;
 
-    if (!PyArg_ParseTuple(args, "et:gethostbyaddr", "idna", &ip_num))
+    if (!PyArg_Parse(hobj, "et:gethostbyaddr", "idna", &ip_num)) {
         return NULL;
-    if (PySys_Audit("socket.gethostbyaddr", "O", args) < 0) {
+    }
+    if (PySys_Audit("socket.gethostbyaddr", "(O)", hobj) < 0) {
         goto finally;
     }
     af = AF_UNSPEC;
-    socket_state *state = get_module_state(self);
+    socket_state *state = get_module_state(module);
     if (setipaddr(state, ip_num, sa, sizeof(addr), af) < 0) {
         goto finally;
     }
@@ -6352,12 +6416,6 @@ socket_gethostbyaddr(PyObject *self, PyObject *args)
     PyMem_Free(ip_num);
     return ret;
 }
-
-PyDoc_STRVAR(gethostbyaddr_doc,
-"gethostbyaddr(host) -> (name, aliaslist, addresslist)\n\
-\n\
-Return the true host name, a list of aliases, and a list of IP addresses,\n\
-for a host.  The host argument is a string giving a host name or IP number.");
 #endif
 
 #ifdef HAVE_GETSERVBYNAME
@@ -6366,13 +6424,25 @@ for a host.  The host argument is a string giving a host name or IP number.");
    known or not useful (like the list of aliases). */
 
 /*ARGSUSED*/
+/*[clinic input]
+_socket.getservbyname
+
+    servicename as name: str
+    protocolname as proto: str = NULL
+    /
+
+Return a port number from a service name and protocol name.
+
+The optional protocol name, if given, should be 'tcp' or 'udp',
+otherwise any protocol will match.
+[clinic start generated code]*/
+
 static PyObject *
-socket_getservbyname(PyObject *self, PyObject *args)
+_socket_getservbyname_impl(PyObject *module, const char *name,
+                           const char *proto)
+/*[clinic end generated code: output=b0c47287f8ec2b00 input=a8e3ad7ced8c8798]*/
 {
-    const char *name, *proto=NULL;
     struct servent *sp;
-    if (!PyArg_ParseTuple(args, "s|s:getservbyname", &name, &proto))
-        return NULL;
 
     if (PySys_Audit("socket.getservbyname", "ss", name, proto) < 0) {
         return NULL;
@@ -6388,12 +6458,6 @@ socket_getservbyname(PyObject *self, PyObject *args)
     return PyLong_FromLong((long) ntohs(sp->s_port));
 }
 
-PyDoc_STRVAR(getservbyname_doc,
-"getservbyname(servicename[, protocolname]) -> integer\n\
-\n\
-Return a port number from a service name and protocol name.\n\
-The optional protocol name, if given, should be 'tcp' or 'udp',\n\
-otherwise any protocol will match.");
 #endif
 
 #ifdef HAVE_GETSERVBYPORT
@@ -6402,14 +6466,25 @@ otherwise any protocol will match.");
    known or not useful (like the list of aliases). */
 
 /*ARGSUSED*/
+/*[clinic input]
+_socket.getservbyport
+
+    port: int
+    protocolname as proto: str = NULL
+    /
+
+Return the service name from a port number and protocol name.
+
+The optional protocol name, if given, should be 'tcp' or 'udp',
+otherwise any protocol will match.
+[clinic start generated code]*/
+
 static PyObject *
-socket_getservbyport(PyObject *self, PyObject *args)
+_socket_getservbyport_impl(PyObject *module, int port, const char *proto)
+/*[clinic end generated code: output=42351ab1857aa9e4 input=9a2a3091ea6ff146]*/
 {
-    int port;
-    const char *proto=NULL;
     struct servent *sp;
-    if (!PyArg_ParseTuple(args, "i|s:getservbyport", &port, &proto))
-        return NULL;
+
     if (port < 0 || port > 0xffff) {
         PyErr_SetString(
             PyExc_OverflowError,
@@ -6431,12 +6506,6 @@ socket_getservbyport(PyObject *self, PyObject *args)
     return PyUnicode_FromString(sp->s_name);
 }
 
-PyDoc_STRVAR(getservbyport_doc,
-"getservbyport(port[, protocolname]) -> string\n\
-\n\
-Return the service name from a port number and protocol name.\n\
-The optional protocol name, if given, should be 'tcp' or 'udp',\n\
-otherwise any protocol will match.");
 #endif
 
 #ifdef HAVE_GETPROTOBYNAME
@@ -6445,13 +6514,20 @@ otherwise any protocol will match.");
    already known or not useful (like the list of aliases). */
 
 /*ARGSUSED*/
+/*[clinic input]
+_socket.getprotobyname
+
+    name: str
+    /
+
+Return the protocol number for the named protocol.
+[clinic start generated code]*/
+
 static PyObject *
-socket_getprotobyname(PyObject *self, PyObject *args)
+_socket_getprotobyname_impl(PyObject *module, const char *name)
+/*[clinic end generated code: output=30fb71f0c6ffbaea input=d197d3726c828e38]*/
 {
-    const char *name;
     struct protoent *sp;
-    if (!PyArg_ParseTuple(args, "s:getprotobyname", &name))
-        return NULL;
     Py_BEGIN_ALLOW_THREADS
     sp = getprotobyname(name);
     Py_END_ALLOW_THREADS
@@ -6462,14 +6538,23 @@ socket_getprotobyname(PyObject *self, PyObject *args)
     return PyLong_FromLong((long) sp->p_proto);
 }
 
-PyDoc_STRVAR(getprotobyname_doc,
-"getprotobyname(name) -> integer\n\
-\n\
-Return the protocol number for the named protocol.  (Rarely used.)");
 #endif
 
+/*[clinic input]
+_socket.close
+
+    fd as fdobj: object
+    /
+
+Close a socket fd.
+
+This is like os.close(), but for sockets; on some platforms os.close()
+won't work for socket file descriptors.
+[clinic start generated code]*/
+
 static PyObject *
-socket_close(PyObject *self, PyObject *fdobj)
+_socket_close(PyObject *module, PyObject *fdobj)
+/*[clinic end generated code: output=1d62092e6fc365dc input=b9fc18380117ee4b]*/
 {
     SOCKET_T fd;
     int res;
@@ -6488,17 +6573,26 @@ socket_close(PyObject *self, PyObject *fdobj)
     Py_RETURN_NONE;
 }
 
-PyDoc_STRVAR(close_doc,
-"close(integer) -> None\n\
-\n\
-Close an integer socket file descriptor.  This is like os.close(), but for\n\
-sockets; on some platforms os.close() won't work for socket file descriptors.");
 
 #ifndef NO_DUP
 /* dup() function for socket fds */
 
+/*[clinic input]
+_socket.dup
+
+    fd as fdobj: object
+    /
+
+Duplicate a socket descriptor.
+
+The new descriptor is non-inheritable.  This is like os.dup(), but for
+sockets; on some platforms os.dup() won't work for socket file
+descriptors.
+[clinic start generated code]*/
+
 static PyObject *
-socket_dup(PyObject *self, PyObject *fdobj)
+_socket_dup(PyObject *module, PyObject *fdobj)
+/*[clinic end generated code: output=7e9c4485cf5a76c0 input=d1d74c320feb3d04]*/
 {
     SOCKET_T fd, newfd;
     PyObject *newfdobj;
@@ -6542,11 +6636,6 @@ socket_dup(PyObject *self, PyObject *fdobj)
     return newfdobj;
 }
 
-PyDoc_STRVAR(dup_doc,
-"dup(integer) -> integer\n\
-\n\
-Duplicate an integer socket file descriptor.  This is like os.dup(), but for\n\
-sockets; on some platforms os.dup() won't work for socket file descriptors.");
 #endif
 
 
@@ -6556,13 +6645,29 @@ sockets; on some platforms os.dup() won't work for socket file descriptors.");
    defined on the platform; otherwise, the default is AF_INET. */
 
 /*ARGSUSED*/
+/*[clinic input]
+_socket.socketpair
+
+    family: int(c_default="SOCKETPAIR_DEFAULT_FAMILY") = AF_UNIX
+    type: int(c_default="SOCK_STREAM") = SOCK_STREAM
+    proto: int = 0
+    /
+
+Create a pair of connected socket objects.
+
+The sockets are returned by the platform socketpair() function.  The
+arguments are the same as for socket(), except that the default
+family is AF_UNIX if defined on the platform; otherwise, the default
+is AF_INET.
+[clinic start generated code]*/
+
 static PyObject *
-socket_socketpair(PyObject *self, PyObject *args)
+_socket_socketpair_impl(PyObject *module, int family, int type, int proto)
+/*[clinic end generated code: output=c012ae1f558bb0ca input=59695511a31a2d52]*/
 {
     PySocketSockObject *s0 = NULL, *s1 = NULL;
     SOCKET_T sv[2];
-    int family, type = SOCK_STREAM, proto = 0;
-    socket_state *state = get_module_state(self);
+    socket_state *state = get_module_state(module);
 #ifdef SOCK_CLOEXEC
     int *atomic_flag_works = &sock_cloexec_works;
 #else
@@ -6570,15 +6675,6 @@ socket_socketpair(PyObject *self, PyObject *args)
 #endif
     int ret;
 
-#if defined(AF_UNIX)
-    family = AF_UNIX;
-#else
-    family = AF_INET;
-#endif
-    if (!PyArg_ParseTuple(args, "|iii:socketpair",
-                          &family, &type, &proto))
-        return NULL;
-
     /* Create a pair of socket fds */
     Py_BEGIN_ALLOW_THREADS
 #ifdef SOCK_CLOEXEC
@@ -6628,13 +6724,6 @@ socket_socketpair(PyObject *self, PyObject *args)
     return NULL;
 }
 
-PyDoc_STRVAR(socketpair_doc,
-"socketpair([family[, type [, proto]]]) -> (socket object, socket object)\n\
-\n\
-Create a pair of socket objects from the sockets returned by the platform\n\
-socketpair() function.\n\
-The arguments are the same as for socket() except the default family is\n\
-AF_UNIX if defined on the platform; otherwise, the default is AF_INET.");
 
 #endif /* HAVE_SOCKETPAIR */
 
@@ -6811,27 +6900,29 @@ _socket_inet_ntoa_impl(PyObject *module, Py_buffer *packed_ip)
 
 #ifdef HAVE_INET_PTON
 
-PyDoc_STRVAR(inet_pton_doc,
-"inet_pton(af, ip) -> packed IP address string\n\
-\n\
-Convert an IP address from string format to a packed string suitable\n\
-for use with low-level network functions.");
+
+/*[clinic input]
+_socket.inet_pton
+
+    af: int
+    ip: str
+    /
+
+Convert an IP address from string format to a packed string.
+
+The string is suitable for use with low-level network functions.
+[clinic start generated code]*/
 
 static PyObject *
-socket_inet_pton(PyObject *self, PyObject *args)
+_socket_inet_pton_impl(PyObject *module, int af, const char *ip)
+/*[clinic end generated code: output=a1488ddddc478dc2 input=044acc246469c125]*/
 {
-    int af;
-    const char* ip;
     int retval;
 #ifdef ENABLE_IPV6
     char packed[Py_MAX(sizeof(struct in_addr), sizeof(struct in6_addr))];
 #else
     char packed[sizeof(struct in_addr)];
 #endif
-    if (!PyArg_ParseTuple(args, "is:inet_pton", &af, &ip)) {
-        return NULL;
-    }
-
 #if !defined(ENABLE_IPV6) && defined(AF_INET6)
     if(af == AF_INET6) {
         PyErr_SetString(PyExc_OSError,
@@ -6862,16 +6953,21 @@ socket_inet_pton(PyObject *self, PyObject *args)
     }
 }
 
-PyDoc_STRVAR(inet_ntop_doc,
-"inet_ntop(af, packed_ip) -> string formatted IP address\n\
-\n\
-Convert a packed IP address of the given family to string format.");
+
+/*[clinic input]
+_socket.inet_ntop
+
+    af: int
+    packed_ip: Py_buffer
+    /
+
+Convert a packed IP address of the given family to string format.
+[clinic start generated code]*/
 
 static PyObject *
-socket_inet_ntop(PyObject *self, PyObject *args)
+_socket_inet_ntop_impl(PyObject *module, int af, Py_buffer *packed_ip)
+/*[clinic end generated code: output=eabff3e56456ede0 input=7027f0a0abdf71d1]*/
 {
-    int af;
-    Py_buffer packed_ip;
     const char* retval;
 #ifdef ENABLE_IPV6
     char ip[Py_MAX(INET_ADDRSTRLEN, INET6_ADDRSTRLEN)];
@@ -6879,43 +6975,33 @@ socket_inet_ntop(PyObject *self, PyObject *args)
     char ip[INET_ADDRSTRLEN];
 #endif
 
-    if (!PyArg_ParseTuple(args, "iy*:inet_ntop", &af, &packed_ip)) {
-        return NULL;
-    }
-
     if (af == AF_INET) {
-        if (packed_ip.len != sizeof(struct in_addr)) {
+        if (packed_ip->len != sizeof(struct in_addr)) {
             PyErr_SetString(PyExc_ValueError,
                 "invalid length of packed IP address string");
-            PyBuffer_Release(&packed_ip);
             return NULL;
         }
 #ifdef ENABLE_IPV6
     } else if (af == AF_INET6) {
-        if (packed_ip.len != sizeof(struct in6_addr)) {
+        if (packed_ip->len != sizeof(struct in6_addr)) {
             PyErr_SetString(PyExc_ValueError,
                 "invalid length of packed IP address string");
-            PyBuffer_Release(&packed_ip);
             return NULL;
         }
 #endif
     } else {
         PyErr_Format(PyExc_ValueError,
             "unknown address family %d", af);
-        PyBuffer_Release(&packed_ip);
         return NULL;
     }
 
     /* inet_ntop guarantee NUL-termination of resulting string. */
-    retval = inet_ntop(af, packed_ip.buf, ip, sizeof(ip));
+    retval = inet_ntop(af, packed_ip->buf, ip, sizeof(ip));
     if (!retval) {
         PyErr_SetFromErrno(PyExc_OSError);
-        PyBuffer_Release(&packed_ip);
         return NULL;
-    } else {
-        PyBuffer_Release(&packed_ip);
-        return PyUnicode_FromString(retval);
     }
+    return PyUnicode_FromString(retval);
 }
 
 #endif /* HAVE_INET_PTON */
@@ -6924,29 +7010,34 @@ socket_inet_ntop(PyObject *self, PyObject *args)
 /* Python interface to getaddrinfo(host, port). */
 
 /*ARGSUSED*/
+/*[clinic input]
+_socket.getaddrinfo
+
+    host as hobj: object
+    port as pobj: object
+    family: int(c_default="AF_UNSPEC") = AF_UNSPEC
+    type as socktype: int = 0
+    proto as protocol: int = 0
+    flags: int = 0
+
+Resolve host and port into a list of 5-tuples.
+
+Each tuple is (family, type, proto, canonname, sockaddr).
+[clinic start generated code]*/
+
 static PyObject *
-socket_getaddrinfo(PyObject *self, PyObject *args, PyObject* kwargs)
+_socket_getaddrinfo_impl(PyObject *module, PyObject *hobj, PyObject *pobj,
+                         int family, int socktype, int protocol, int flags)
+/*[clinic end generated code: output=a54f59f33f3da184 input=1fd64ac89aee1d18]*/
 {
-    static char* kwnames[] = {"host", "port", "family", "type", "proto",
-                              "flags", 0};
     struct addrinfo hints, *res;
     struct addrinfo *res0 = NULL;
-    PyObject *hobj = NULL;
-    PyObject *pobj = (PyObject *)NULL;
     PyObject *pstr = NULL;
     const char *hptr, *pptr;
-    int family, socktype, protocol, flags;
     int error;
     PyObject *all = (PyObject *)NULL;
     PyObject *idna = NULL;
 
-    socktype = protocol = flags = 0;
-    family = AF_UNSPEC;
-    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|iiii:getaddrinfo",
-                          kwnames, &hobj, &pobj, &family, &socktype,
-                          &protocol, &flags)) {
-        return NULL;
-    }
     if (hobj == Py_None) {
         hptr = NULL;
     } else if (PyUnicode_Check(hobj)) {
@@ -7011,7 +7102,7 @@ socket_getaddrinfo(PyObject *self, PyObject *args, PyObject* kwargs)
     Py_END_ALLOW_THREADS
     if (error) {
         res0 = NULL;  // gh-100795
-        socket_state *state = get_module_state(self);
+        socket_state *state = get_module_state(module);
         set_gaierror(state, error);
         goto err;
     }
@@ -7053,22 +7144,26 @@ socket_getaddrinfo(PyObject *self, PyObject *args, PyObject* kwargs)
     return (PyObject *)NULL;
 }
 
-PyDoc_STRVAR(getaddrinfo_doc,
-"getaddrinfo(host, port [, family, type, proto, flags])\n\
-    -> list of (family, type, proto, canonname, sockaddr)\n\
-\n\
-Resolve host and port into addrinfo struct.");
 #endif // HAVE_GETADDRINFO
 
 #ifdef HAVE_GETNAMEINFO
 /* Python interface to getnameinfo(sa, flags). */
 
 /*ARGSUSED*/
+/*[clinic input]
+_socket.getnameinfo
+
+    sockaddr as sa: object
+    flags: int
+    /
+
+Get host and port for a sockaddr.
+[clinic start generated code]*/
+
 static PyObject *
-socket_getnameinfo(PyObject *self, PyObject *args)
+_socket_getnameinfo_impl(PyObject *module, PyObject *sa, int flags)
+/*[clinic end generated code: output=2e1d7ef2bd94f698 input=dd0444ac9adae4d3]*/
 {
-    PyObject *sa = (PyObject *)NULL;
-    int flags;
     const char *hostp;
     int port;
     unsigned int flowinfo, scope_id;
@@ -7078,9 +7173,7 @@ socket_getnameinfo(PyObject *self, PyObject *args)
     PyObject *ret = (PyObject *)NULL;
     PyObject *name;
 
-    flags = flowinfo = scope_id = 0;
-    if (!PyArg_ParseTuple(args, "Oi:getnameinfo", &sa, &flags))
-        return NULL;
+    flowinfo = scope_id = 0;
     if (!PyTuple_Check(sa)) {
         PyErr_SetString(PyExc_TypeError,
                         "getnameinfo() argument 1 must be a tuple");
@@ -7111,7 +7204,7 @@ socket_getnameinfo(PyObject *self, PyObject *args)
     Py_END_ALLOW_THREADS
     if (error) {
         res = NULL;  // gh-100795
-        socket_state *state = get_module_state(self);
+        socket_state *state = get_module_state(module);
         set_gaierror(state, error);
         goto fail;
     }
@@ -7146,7 +7239,7 @@ socket_getnameinfo(PyObject *self, PyObject *args)
                     hbuf, sizeof(hbuf), pbuf, sizeof(pbuf), flags);
     Py_END_ALLOW_THREADS
     if (error) {
-        socket_state *state = get_module_state(self);
+        socket_state *state = get_module_state(module);
         set_gaierror(state, error);
         goto fail;
     }
@@ -7162,18 +7255,24 @@ socket_getnameinfo(PyObject *self, PyObject *args)
     return ret;
 }
 
-PyDoc_STRVAR(getnameinfo_doc,
-"getnameinfo(sockaddr, flags) --> (host, port)\n\
-\n\
-Get host and port for a sockaddr.");
 #endif // HAVE_GETNAMEINFO
 
 /* Python API to getting and setting the default timeout value. */
 
+/*[clinic input]
+_socket.getdefaulttimeout
+
+Return the default timeout in seconds for new socket objects.
+
+A value of None indicates that new socket objects have no timeout.
+When the socket module is first imported, the default is None.
+[clinic start generated code]*/
+
 static PyObject *
-socket_getdefaulttimeout(PyObject *self, PyObject *Py_UNUSED(ignored))
+_socket_getdefaulttimeout_impl(PyObject *module)
+/*[clinic end generated code: output=7b3e1be56948c44c input=c9fb729acf998a58]*/
 {
-    socket_state *state = get_module_state(self);
+    socket_state *state = get_module_state(module);
     PyTime_t timeout = _Py_atomic_load_int64_relaxed(&state->defaulttimeout);
     if (timeout < 0) {
         Py_RETURN_NONE;
@@ -7184,39 +7283,47 @@ socket_getdefaulttimeout(PyObject *self, PyObject *Py_UNUSED(ignored))
     }
 }
 
-PyDoc_STRVAR(getdefaulttimeout_doc,
-"getdefaulttimeout() -> timeout\n\
-\n\
-Returns the default timeout in seconds (float) for new socket objects.\n\
-A value of None indicates that new socket objects have no timeout.\n\
-When the socket module is first imported, the default is None.");
+
+/*[clinic input]
+_socket.setdefaulttimeout
+
+    timeout as arg: object
+    /
+
+Set the default timeout in seconds for new socket objects.
+
+A value of None indicates that new socket objects have no timeout.
+When the socket module is first imported, the default is None.
+[clinic start generated code]*/
 
 static PyObject *
-socket_setdefaulttimeout(PyObject *self, PyObject *arg)
+_socket_setdefaulttimeout(PyObject *module, PyObject *arg)
+/*[clinic end generated code: output=b5d59296163d66bf input=929785d885173684]*/
 {
     PyTime_t timeout;
 
     if (socket_parse_timeout(&timeout, arg) < 0)
         return NULL;
 
-    socket_state *state = get_module_state(self);
+    socket_state *state = get_module_state(module);
     _Py_atomic_store_int64_relaxed(&state->defaulttimeout, timeout);
 
     Py_RETURN_NONE;
 }
 
-PyDoc_STRVAR(setdefaulttimeout_doc,
-"setdefaulttimeout(timeout)\n\
-\n\
-Set the default timeout in seconds (real number) for new socket objects.\n\
-A value of None indicates that new socket objects have no timeout.\n\
-When the socket module is first imported, the default is None.");
 
 #if defined(HAVE_IF_NAMEINDEX) || defined(MS_WINDOWS)
 /* Python API for getting interface indices and names */
 
+/*[clinic input]
+_socket.if_nameindex
+
+Return a list of network interface information (index, name) tuples.
+[clinic start generated code]*/
+
 static PyObject *
-socket_if_nameindex(PyObject *self, PyObject *arg)
+_socket_if_nameindex_impl(PyObject *module)
+/*[clinic end generated code: output=93c863a6262059c4 input=d6438bb556de2100]*/
 {
     PyObject *list = PyList_New(0);
     if (list == NULL) {
@@ -7296,10 +7403,6 @@ socket_if_nameindex(PyObject *self, PyObject *arg)
 #endif
 }
 
-PyDoc_STRVAR(if_nameindex_doc,
-"if_nameindex()\n\
-\n\
-Returns a list of network interface information (index, name) tuples.");
 
 /*[clinic input]
 _socket.if_nametoindex
@@ -7359,14 +7462,28 @@ _socket_if_indextoname_impl(PyObject *module, NET_IFINDEX index)
 #ifdef CMSG_LEN
 /* Python interface to CMSG_LEN(length). */
 
+/*[clinic input]
+_socket.CMSG_LEN
+
+    length: Py_ssize_t
+    /
+
+Return the total length of an ancillary data item with associated data.
+
+The associated data has the given length.  This value can often be
+used as the buffer size for recvmsg() to receive a single item of
+ancillary data, but RFC 3542 requires portable applications to use
+CMSG_SPACE() and thus include space for padding, even when the item
+will be the last in the buffer.  Raises OverflowError if length is
+outside the permissible range of values.
+[clinic start generated code]*/
+
 static PyObject *
-socket_CMSG_LEN(PyObject *self, PyObject *args)
+_socket_CMSG_LEN_impl(PyObject *module, Py_ssize_t length)
+/*[clinic end generated code: output=e1dd6bb3a3f4a7ff input=b0787fd8c8d9c7be]*/
 {
-    Py_ssize_t length;
     size_t result;
 
-    if (!PyArg_ParseTuple(args, "n:CMSG_LEN", &length))
-        return NULL;
     if (length < 0 || !get_CMSG_LEN(length, &result)) {
         PyErr_Format(PyExc_OverflowError, "CMSG_LEN() argument out of range");
         return NULL;
@@ -7374,29 +7491,32 @@ socket_CMSG_LEN(PyObject *self, PyObject *args)
     return PyLong_FromSize_t(result);
 }
 
-PyDoc_STRVAR(CMSG_LEN_doc,
-"CMSG_LEN(length) -> control message length\n\
-\n\
-Return the total length, without trailing padding, of an ancillary\n\
-data item with associated data of the given length.  This value can\n\
-often be used as the buffer size for recvmsg() to receive a single\n\
-item of ancillary data, but RFC 3542 requires portable applications to\n\
-use CMSG_SPACE() and thus include space for padding, even when the\n\
-item will be the last in the buffer.  Raises OverflowError if length\n\
-is outside the permissible range of values.");
 
 
 #ifdef CMSG_SPACE
 /* Python interface to CMSG_SPACE(length). */
 
+/*[clinic input]
+_socket.CMSG_SPACE
+
+    length: Py_ssize_t
+    /
+
+Return the buffer size needed to receive an ancillary data item.
+
+The item has associated data of the given length, and the size
+includes any trailing padding.  The buffer space needed to receive
+multiple items is the sum of the CMSG_SPACE() values for their
+associated data lengths.  Raises OverflowError if length is outside
+the permissible range of values.
+[clinic start generated code]*/
+
 static PyObject *
-socket_CMSG_SPACE(PyObject *self, PyObject *args)
+_socket_CMSG_SPACE_impl(PyObject *module, Py_ssize_t length)
+/*[clinic end generated code: output=857b925dc29c68c3 input=dedf123dcda72642]*/
 {
-    Py_ssize_t length;
     size_t result;
 
-    if (!PyArg_ParseTuple(args, "n:CMSG_SPACE", &length))
-        return NULL;
     if (length < 0 || !get_CMSG_SPACE(length, &result)) {
         PyErr_SetString(PyExc_OverflowError,
                         "CMSG_SPACE() argument out of range");
@@ -7405,15 +7525,6 @@ socket_CMSG_SPACE(PyObject *self, PyObject *args)
     return PyLong_FromSize_t(result);
 }
 
-PyDoc_STRVAR(CMSG_SPACE_doc,
-"CMSG_SPACE(length) -> buffer size\n\
-\n\
-Return the buffer size needed for recvmsg() to receive an ancillary\n\
-data item with associated data of the given length, along with any\n\
-trailing padding.  The buffer space needed to receive multiple items\n\
-is the sum of the CMSG_SPACE() values for their associated data\n\
-lengths.  Raises OverflowError if length is outside the permissible\n\
-range of values.");
 #endif    /* CMSG_SPACE */
 #endif    /* CMSG_LEN */
 
@@ -7421,88 +7532,34 @@ range of values.");
 /* List of functions exported by this module. */
 
 static PyMethodDef socket_methods[] = {
-#ifdef HAVE_GETADDRINFO
-    {"gethostbyname",           socket_gethostbyname,
-     METH_VARARGS, gethostbyname_doc},
-#endif
-#if defined(HAVE_GETHOSTBYNAME_R) || defined (HAVE_GETHOSTBYNAME)
-    {"gethostbyname_ex",        socket_gethostbyname_ex,
-     METH_VARARGS, ghbn_ex_doc},
-#endif
-#if defined(HAVE_GETHOSTBYNAME_R) || defined (HAVE_GETHOSTBYADDR)
-    {"gethostbyaddr",           socket_gethostbyaddr,
-     METH_VARARGS, gethostbyaddr_doc},
-#endif
-#ifdef HAVE_GETHOSTNAME
-    {"gethostname",             socket_gethostname,
-     METH_NOARGS,  gethostname_doc},
-#endif
-#ifdef HAVE_SETHOSTNAME
-    {"sethostname",             socket_sethostname,
-     METH_VARARGS,  sethostname_doc},
-#endif
-#ifdef HAVE_GETSERVBYNAME
-    {"getservbyname",           socket_getservbyname,
-     METH_VARARGS, getservbyname_doc},
-#endif
-#ifdef HAVE_GETSERVBYPORT
-    {"getservbyport",           socket_getservbyport,
-     METH_VARARGS, getservbyport_doc},
-#endif
-#ifdef HAVE_GETPROTOBYNAME
-    {"getprotobyname",          socket_getprotobyname,
-     METH_VARARGS, getprotobyname_doc},
-#endif
-    {"close",                   socket_close,
-     METH_O, close_doc},
-#ifndef NO_DUP
-    {"dup",                     socket_dup,
-     METH_O, dup_doc},
-#endif
-#ifdef HAVE_SOCKETPAIR
-    {"socketpair",              socket_socketpair,
-     METH_VARARGS, socketpair_doc},
-#endif
+    _SOCKET_GETHOSTBYNAME_METHODDEF
+    _SOCKET_GETHOSTBYNAME_EX_METHODDEF
+    _SOCKET_GETHOSTBYADDR_METHODDEF
+    _SOCKET_GETHOSTNAME_METHODDEF
+    _SOCKET_SETHOSTNAME_METHODDEF
+    _SOCKET_GETSERVBYNAME_METHODDEF
+    _SOCKET_GETSERVBYPORT_METHODDEF
+    _SOCKET_GETPROTOBYNAME_METHODDEF
+    _SOCKET_CLOSE_METHODDEF
+    _SOCKET_DUP_METHODDEF
+    _SOCKET_SOCKETPAIR_METHODDEF
     _SOCKET_NTOHS_METHODDEF
     _SOCKET_NTOHL_METHODDEF
     _SOCKET_HTONS_METHODDEF
     _SOCKET_HTONL_METHODDEF
     _SOCKET_INET_ATON_METHODDEF
-#ifdef HAVE_INET_NTOA
     _SOCKET_INET_NTOA_METHODDEF
-#endif
-#ifdef HAVE_INET_PTON
-    {"inet_pton",               socket_inet_pton,
-     METH_VARARGS, inet_pton_doc},
-    {"inet_ntop",               socket_inet_ntop,
-     METH_VARARGS, inet_ntop_doc},
-#endif
-#ifdef HAVE_GETADDRINFO
-    {"getaddrinfo",             _PyCFunction_CAST(socket_getaddrinfo),
-     METH_VARARGS | METH_KEYWORDS, getaddrinfo_doc},
-#endif
-#ifdef HAVE_GETNAMEINFO
-    {"getnameinfo",             socket_getnameinfo,
-     METH_VARARGS, getnameinfo_doc},
-#endif
-    {"getdefaulttimeout",       socket_getdefaulttimeout,
-     METH_NOARGS, getdefaulttimeout_doc},
-    {"setdefaulttimeout",       socket_setdefaulttimeout,
-     METH_O, setdefaulttimeout_doc},
-#if defined(HAVE_IF_NAMEINDEX) || defined(MS_WINDOWS)
-    {"if_nameindex", socket_if_nameindex,
-     METH_NOARGS, if_nameindex_doc},
+    _SOCKET_INET_PTON_METHODDEF
+    _SOCKET_INET_NTOP_METHODDEF
+    _SOCKET_GETADDRINFO_METHODDEF
+    _SOCKET_GETNAMEINFO_METHODDEF
+    _SOCKET_GETDEFAULTTIMEOUT_METHODDEF
+    _SOCKET_SETDEFAULTTIMEOUT_METHODDEF
+    _SOCKET_IF_NAMEINDEX_METHODDEF
     _SOCKET_IF_NAMETOINDEX_METHODDEF
     _SOCKET_IF_INDEXTONAME_METHODDEF
-#endif
-#ifdef CMSG_LEN
-    {"CMSG_LEN",                socket_CMSG_LEN,
-     METH_VARARGS, CMSG_LEN_doc},
-#ifdef CMSG_SPACE
-    {"CMSG_SPACE",              socket_CMSG_SPACE,
-     METH_VARARGS, CMSG_SPACE_doc},
-#endif
-#endif
+    _SOCKET_CMSG_LEN_METHODDEF
+    _SOCKET_CMSG_SPACE_METHODDEF
     {NULL,                      NULL}            /* Sentinel */
 };
 

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]