Issue #20173: Convert sha1, sha256, sha512 and md5 to ArgumentClinic.
Patch by Vajrasky Kok.
diff --git a/Modules/sha256module.c b/Modules/sha256module.c
index b05bfc1..7b14886 100644
--- a/Modules/sha256module.c
+++ b/Modules/sha256module.c
@@ -20,6 +20,11 @@
 #include "structmember.h"
 #include "hashlib.h"
 
+/*[clinic input]
+module _sha256
+class SHA256Type "SHAobject *" "&PyType_Type"
+[clinic start generated code]*/
+/*[clinic end generated code: output=da39a3ee5e6b4b0d input=71a39174d4f0a744]*/
 
 /* Some useful types */
 
@@ -393,10 +398,33 @@
 
 /* External methods for a hash object */
 
-PyDoc_STRVAR(SHA256_copy__doc__, "Return a copy of the hash object.");
+/*[clinic input]
+SHA256Type.copy
+
+Return a copy of the hash object.
+[clinic start generated code]*/
+
+PyDoc_STRVAR(SHA256Type_copy__doc__,
+"copy($self, /)\n"
+"--\n"
+"\n"
+"Return a copy of the hash object.");
+
+#define SHA256TYPE_COPY_METHODDEF    \
+    {"copy", (PyCFunction)SHA256Type_copy, METH_NOARGS, SHA256Type_copy__doc__},
 
 static PyObject *
-SHA256_copy(SHAobject *self, PyObject *unused)
+SHA256Type_copy_impl(SHAobject *self);
+
+static PyObject *
+SHA256Type_copy(SHAobject *self, PyObject *Py_UNUSED(ignored))
+{
+    return SHA256Type_copy_impl(self);
+}
+
+static PyObject *
+SHA256Type_copy_impl(SHAobject *self)
+/*[clinic end generated code: output=f716c39d3f81c27c input=f58840a618d4f2a7]*/
 {
     SHAobject *newobj;
 
@@ -412,11 +440,33 @@
     return (PyObject *)newobj;
 }
 
-PyDoc_STRVAR(SHA256_digest__doc__,
+/*[clinic input]
+SHA256Type.digest
+
+Return the digest value as a string of binary data.
+[clinic start generated code]*/
+
+PyDoc_STRVAR(SHA256Type_digest__doc__,
+"digest($self, /)\n"
+"--\n"
+"\n"
 "Return the digest value as a string of binary data.");
 
+#define SHA256TYPE_DIGEST_METHODDEF    \
+    {"digest", (PyCFunction)SHA256Type_digest, METH_NOARGS, SHA256Type_digest__doc__},
+
 static PyObject *
-SHA256_digest(SHAobject *self, PyObject *unused)
+SHA256Type_digest_impl(SHAobject *self);
+
+static PyObject *
+SHA256Type_digest(SHAobject *self, PyObject *Py_UNUSED(ignored))
+{
+    return SHA256Type_digest_impl(self);
+}
+
+static PyObject *
+SHA256Type_digest_impl(SHAobject *self)
+/*[clinic end generated code: output=72d34723d7bb694c input=1fb752e58954157d]*/
 {
     unsigned char digest[SHA_DIGESTSIZE];
     SHAobject temp;
@@ -426,11 +476,33 @@
     return PyBytes_FromStringAndSize((const char *)digest, self->digestsize);
 }
 
-PyDoc_STRVAR(SHA256_hexdigest__doc__,
+/*[clinic input]
+SHA256Type.hexdigest
+
+Return the digest value as a string of hexadecimal digits.
+[clinic start generated code]*/
+
+PyDoc_STRVAR(SHA256Type_hexdigest__doc__,
+"hexdigest($self, /)\n"
+"--\n"
+"\n"
 "Return the digest value as a string of hexadecimal digits.");
 
+#define SHA256TYPE_HEXDIGEST_METHODDEF    \
+    {"hexdigest", (PyCFunction)SHA256Type_hexdigest, METH_NOARGS, SHA256Type_hexdigest__doc__},
+
 static PyObject *
-SHA256_hexdigest(SHAobject *self, PyObject *unused)
+SHA256Type_hexdigest_impl(SHAobject *self);
+
+static PyObject *
+SHA256Type_hexdigest(SHAobject *self, PyObject *Py_UNUSED(ignored))
+{
+    return SHA256Type_hexdigest_impl(self);
+}
+
+static PyObject *
+SHA256Type_hexdigest_impl(SHAobject *self)
+/*[clinic end generated code: output=3687aa6183c7d27f input=0cc4c714693010d1]*/
 {
     unsigned char digest[SHA_DIGESTSIZE];
     SHAobject temp;
@@ -462,18 +534,30 @@
     return retval;
 }
 
-PyDoc_STRVAR(SHA256_update__doc__,
-"Update this hash object's state with the provided string.");
+/*[clinic input]
+SHA256Type.update
+
+    obj: object
+    /
+
+Update this hash object's state with the provided string.
+[clinic start generated code]*/
+
+PyDoc_STRVAR(SHA256Type_update__doc__,
+"update($self, obj, /)\n"
+"--\n"
+"\n"
+"Update this hash object\'s state with the provided string.");
+
+#define SHA256TYPE_UPDATE_METHODDEF    \
+    {"update", (PyCFunction)SHA256Type_update, METH_O, SHA256Type_update__doc__},
 
 static PyObject *
-SHA256_update(SHAobject *self, PyObject *args)
+SHA256Type_update(SHAobject *self, PyObject *obj)
+/*[clinic end generated code: output=b47f53d7cbeabee4 input=b2d449d5b30f0f5a]*/
 {
-    PyObject *obj;
     Py_buffer buf;
 
-    if (!PyArg_ParseTuple(args, "O:update", &obj))
-        return NULL;
-
     GET_BUFFER_VIEW_OR_ERROUT(obj, &buf);
 
     sha_update(self, buf.buf, buf.len);
@@ -484,10 +568,10 @@
 }
 
 static PyMethodDef SHA_methods[] = {
-    {"copy",      (PyCFunction)SHA256_copy,      METH_NOARGS,  SHA256_copy__doc__},
-    {"digest",    (PyCFunction)SHA256_digest,    METH_NOARGS,  SHA256_digest__doc__},
-    {"hexdigest", (PyCFunction)SHA256_hexdigest, METH_NOARGS,  SHA256_hexdigest__doc__},
-    {"update",    (PyCFunction)SHA256_update,    METH_VARARGS, SHA256_update__doc__},
+    SHA256TYPE_COPY_METHODDEF
+    SHA256TYPE_DIGEST_METHODDEF
+    SHA256TYPE_HEXDIGEST_METHODDEF
+    SHA256TYPE_UPDATE_METHODDEF
     {NULL,        NULL}         /* sentinel */
 };
 
@@ -594,27 +678,55 @@
 
 /* The single module-level function: new() */
 
-PyDoc_STRVAR(SHA256_new__doc__,
+/*[clinic input]
+_sha256.sha256
+
+    string: object(c_default="NULL") = b''
+
+Return a new SHA-256 hash object; optionally initialized with a string.
+[clinic start generated code]*/
+
+PyDoc_STRVAR(_sha256_sha256__doc__,
+"sha256($module, /, string=b\'\')\n"
+"--\n"
+"\n"
 "Return a new SHA-256 hash object; optionally initialized with a string.");
 
+#define _SHA256_SHA256_METHODDEF    \
+    {"sha256", (PyCFunction)_sha256_sha256, METH_VARARGS|METH_KEYWORDS, _sha256_sha256__doc__},
+
 static PyObject *
-SHA256_new(PyObject *self, PyObject *args, PyObject *kwdict)
+_sha256_sha256_impl(PyModuleDef *module, PyObject *string);
+
+static PyObject *
+_sha256_sha256(PyModuleDef *module, PyObject *args, PyObject *kwargs)
 {
-    static char *kwlist[] = {"string", NULL};
+    PyObject *return_value = NULL;
+    static char *_keywords[] = {"string", NULL};
+    PyObject *string = NULL;
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+        "|O:sha256", _keywords,
+        &string))
+        goto exit;
+    return_value = _sha256_sha256_impl(module, string);
+
+exit:
+    return return_value;
+}
+
+static PyObject *
+_sha256_sha256_impl(PyModuleDef *module, PyObject *string)
+/*[clinic end generated code: output=4b1263d1e2fcdb98 input=09cce3fb855056b2]*/
+{
     SHAobject *new;
-    PyObject *data_obj = NULL;
     Py_buffer buf;
 
-    if (!PyArg_ParseTupleAndKeywords(args, kwdict, "|O:new", kwlist,
-                                     &data_obj)) {
-        return NULL;
-    }
-
-    if (data_obj)
-        GET_BUFFER_VIEW_OR_ERROUT(data_obj, &buf);
+    if (string)
+        GET_BUFFER_VIEW_OR_ERROUT(string, &buf);
 
     if ((new = newSHA256object()) == NULL) {
-        if (data_obj)
+        if (string)
             PyBuffer_Release(&buf);
         return NULL;
     }
@@ -623,11 +735,11 @@
 
     if (PyErr_Occurred()) {
         Py_DECREF(new);
-        if (data_obj)
+        if (string)
             PyBuffer_Release(&buf);
         return NULL;
     }
-    if (data_obj) {
+    if (string) {
         sha_update(new, buf.buf, buf.len);
         PyBuffer_Release(&buf);
     }
@@ -635,27 +747,55 @@
     return (PyObject *)new;
 }
 
-PyDoc_STRVAR(SHA224_new__doc__,
+/*[clinic input]
+_sha256.sha224
+
+    string: object(c_default="NULL") = b''
+
+Return a new SHA-224 hash object; optionally initialized with a string.
+[clinic start generated code]*/
+
+PyDoc_STRVAR(_sha256_sha224__doc__,
+"sha224($module, /, string=b\'\')\n"
+"--\n"
+"\n"
 "Return a new SHA-224 hash object; optionally initialized with a string.");
 
+#define _SHA256_SHA224_METHODDEF    \
+    {"sha224", (PyCFunction)_sha256_sha224, METH_VARARGS|METH_KEYWORDS, _sha256_sha224__doc__},
+
 static PyObject *
-SHA224_new(PyObject *self, PyObject *args, PyObject *kwdict)
+_sha256_sha224_impl(PyModuleDef *module, PyObject *string);
+
+static PyObject *
+_sha256_sha224(PyModuleDef *module, PyObject *args, PyObject *kwargs)
 {
-    static char *kwlist[] = {"string", NULL};
+    PyObject *return_value = NULL;
+    static char *_keywords[] = {"string", NULL};
+    PyObject *string = NULL;
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+        "|O:sha224", _keywords,
+        &string))
+        goto exit;
+    return_value = _sha256_sha224_impl(module, string);
+
+exit:
+    return return_value;
+}
+
+static PyObject *
+_sha256_sha224_impl(PyModuleDef *module, PyObject *string)
+/*[clinic end generated code: output=4dde0eb1cdaebc06 input=27a04ba24c353a73]*/
+{
     SHAobject *new;
-    PyObject *data_obj = NULL;
     Py_buffer buf;
 
-    if (!PyArg_ParseTupleAndKeywords(args, kwdict, "|O:new", kwlist,
-                                     &data_obj)) {
-        return NULL;
-    }
-
-    if (data_obj)
-        GET_BUFFER_VIEW_OR_ERROUT(data_obj, &buf);
+    if (string)
+        GET_BUFFER_VIEW_OR_ERROUT(string, &buf);
 
     if ((new = newSHA224object()) == NULL) {
-        if (data_obj)
+        if (string)
             PyBuffer_Release(&buf);
         return NULL;
     }
@@ -664,11 +804,11 @@
 
     if (PyErr_Occurred()) {
         Py_DECREF(new);
-        if (data_obj)
+        if (string)
             PyBuffer_Release(&buf);
         return NULL;
     }
-    if (data_obj) {
+    if (string) {
         sha_update(new, buf.buf, buf.len);
         PyBuffer_Release(&buf);
     }
@@ -680,8 +820,8 @@
 /* List of functions exported by this module */
 
 static struct PyMethodDef SHA_functions[] = {
-    {"sha256", (PyCFunction)SHA256_new, METH_VARARGS|METH_KEYWORDS, SHA256_new__doc__},
-    {"sha224", (PyCFunction)SHA224_new, METH_VARARGS|METH_KEYWORDS, SHA224_new__doc__},
+    _SHA256_SHA256_METHODDEF
+    _SHA256_SHA224_METHODDEF
     {NULL,      NULL}            /* Sentinel */
 };