https://github.com/python/cpython/commit/25bd72d6833765a5d37c10acc7ae7c7cb69c8ab4
commit: 25bd72d6833765a5d37c10acc7ae7c7cb69c8ab4
branch: main
author: Yoonho Hann <[email protected]>
committer: corona10 <[email protected]>
date: 2025-10-30T09:42:09Z
summary:

gh-137821: Convert _json module to use Argument Clinic (gh-140778)

files:
A 
Misc/NEWS.d/next/Core_and_Builtins/2025-10-30-15-33-07.gh-issue-137821.8_Iavt.rst
A Modules/clinic/_json.c.h
M Modules/_json.c

diff --git 
a/Misc/NEWS.d/next/Core_and_Builtins/2025-10-30-15-33-07.gh-issue-137821.8_Iavt.rst
 
b/Misc/NEWS.d/next/Core_and_Builtins/2025-10-30-15-33-07.gh-issue-137821.8_Iavt.rst
new file mode 100644
index 00000000000000..124ea3f9993814
--- /dev/null
+++ 
b/Misc/NEWS.d/next/Core_and_Builtins/2025-10-30-15-33-07.gh-issue-137821.8_Iavt.rst
@@ -0,0 +1 @@
+Convert ``_json`` module to use Argument Clinic
diff --git a/Modules/_json.c b/Modules/_json.c
index 9a1fc3aba36116..6a84661a243ea4 100644
--- a/Modules/_json.c
+++ b/Modules/_json.c
@@ -18,6 +18,12 @@
 
 #include <stdbool.h>              // bool
 
+#include "clinic/_json.c.h"
+
+/*[clinic input]
+module _json
+[clinic start generated code]*/
+/*[clinic end generated code: output=da39a3ee5e6b4b0d input=549fa53592c925b2]*/
 
 typedef struct _PyScannerObject {
     PyObject_HEAD
@@ -637,30 +643,31 @@ scanstring_unicode(PyObject *pystr, Py_ssize_t end, int 
strict, Py_ssize_t *next
     return NULL;
 }
 
-PyDoc_STRVAR(pydoc_scanstring,
-    "scanstring(string, end, strict=True) -> (string, end)\n"
-    "\n"
-    "Scan the string s for a JSON string. End is the index of the\n"
-    "character in s after the quote that started the JSON string.\n"
-    "Unescapes all valid JSON string escape sequences and raises ValueError\n"
-    "on attempt to decode an invalid string. If strict is False then literal\n"
-    "control characters are allowed in the string.\n"
-    "\n"
-    "Returns a tuple of the decoded string and the index of the character in 
s\n"
-    "after the end quote."
-);
+/*[clinic input]
+_json.scanstring as py_scanstring
+    pystr: object
+    end: Py_ssize_t
+    strict: bool = True
+    /
+
+Scan the string s for a JSON string.
+
+End is the index of the character in s after the quote that started the
+JSON string. Unescapes all valid JSON string escape sequences and raises
+ValueError on attempt to decode an invalid string. If strict is False
+then literal control characters are allowed in the string.
+
+Returns a tuple of the decoded string and the index of the character in s
+after the end quote.
+[clinic start generated code]*/
 
 static PyObject *
-py_scanstring(PyObject* Py_UNUSED(self), PyObject *args)
+py_scanstring_impl(PyObject *module, PyObject *pystr, Py_ssize_t end,
+                   int strict)
+/*[clinic end generated code: output=961740cfae07cdb3 input=9d46d7df7ac749b0]*/
 {
-    PyObject *pystr;
     PyObject *rval;
-    Py_ssize_t end;
     Py_ssize_t next_end = -1;
-    int strict = 1;
-    if (!PyArg_ParseTuple(args, "On|p:scanstring", &pystr, &end, &strict)) {
-        return NULL;
-    }
     if (PyUnicode_Check(pystr)) {
         rval = scanstring_unicode(pystr, end, strict, &next_end);
     }
@@ -673,14 +680,17 @@ py_scanstring(PyObject* Py_UNUSED(self), PyObject *args)
     return _build_rval_index_tuple(rval, next_end);
 }
 
-PyDoc_STRVAR(pydoc_encode_basestring_ascii,
-    "encode_basestring_ascii(string) -> string\n"
-    "\n"
-    "Return an ASCII-only JSON representation of a Python string"
-);
+/*[clinic input]
+_json.encode_basestring_ascii as py_encode_basestring_ascii
+    pystr: object
+    /
+
+Return an ASCII-only JSON representation of a Python string
+[clinic start generated code]*/
 
 static PyObject *
-py_encode_basestring_ascii(PyObject* Py_UNUSED(self), PyObject *pystr)
+py_encode_basestring_ascii(PyObject *module, PyObject *pystr)
+/*[clinic end generated code: output=a8afcd88eba0b572 input=f4085ccd5928ea55]*/
 {
     PyObject *rval;
     /* Return an ASCII-only JSON representation of a Python string */
@@ -697,15 +707,17 @@ py_encode_basestring_ascii(PyObject* Py_UNUSED(self), 
PyObject *pystr)
     return rval;
 }
 
+/*[clinic input]
+_json.encode_basestring as py_encode_basestring
+    pystr: object
+    /
 
-PyDoc_STRVAR(pydoc_encode_basestring,
-    "encode_basestring(string) -> string\n"
-    "\n"
-    "Return a JSON representation of a Python string"
-);
+Return a JSON representation of a Python string
+[clinic start generated code]*/
 
 static PyObject *
-py_encode_basestring(PyObject* Py_UNUSED(self), PyObject *pystr)
+py_encode_basestring(PyObject *module, PyObject *pystr)
+/*[clinic end generated code: output=c87752300776d3b1 input=c3c7ef6e72624f6e]*/
 {
     PyObject *rval;
     /* Return a JSON representation of a Python string */
@@ -2080,18 +2092,9 @@ static PyType_Spec PyEncoderType_spec = {
 };
 
 static PyMethodDef speedups_methods[] = {
-    {"encode_basestring_ascii",
-        py_encode_basestring_ascii,
-        METH_O,
-        pydoc_encode_basestring_ascii},
-    {"encode_basestring",
-        py_encode_basestring,
-        METH_O,
-        pydoc_encode_basestring},
-    {"scanstring",
-        py_scanstring,
-        METH_VARARGS,
-        pydoc_scanstring},
+    PY_ENCODE_BASESTRING_ASCII_METHODDEF
+    PY_ENCODE_BASESTRING_METHODDEF
+    PY_SCANSTRING_METHODDEF
     {NULL, NULL, 0, NULL}
 };
 
diff --git a/Modules/clinic/_json.c.h b/Modules/clinic/_json.c.h
new file mode 100644
index 00000000000000..b80e72ad00a62a
--- /dev/null
+++ b/Modules/clinic/_json.c.h
@@ -0,0 +1,84 @@
+/*[clinic input]
+preserve
+[clinic start generated code]*/
+
+#include "pycore_abstract.h"      // _PyNumber_Index()
+#include "pycore_modsupport.h"    // _PyArg_CheckPositional()
+
+PyDoc_STRVAR(py_scanstring__doc__,
+"scanstring($module, pystr, end, strict=True, /)\n"
+"--\n"
+"\n"
+"Scan the string s for a JSON string.\n"
+"\n"
+"End is the index of the character in s after the quote that started the\n"
+"JSON string. Unescapes all valid JSON string escape sequences and raises\n"
+"ValueError on attempt to decode an invalid string. If strict is False\n"
+"then literal control characters are allowed in the string.\n"
+"\n"
+"Returns a tuple of the decoded string and the index of the character in s\n"
+"after the end quote.");
+
+#define PY_SCANSTRING_METHODDEF    \
+    {"scanstring", _PyCFunction_CAST(py_scanstring), METH_FASTCALL, 
py_scanstring__doc__},
+
+static PyObject *
+py_scanstring_impl(PyObject *module, PyObject *pystr, Py_ssize_t end,
+                   int strict);
+
+static PyObject *
+py_scanstring(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
+{
+    PyObject *return_value = NULL;
+    PyObject *pystr;
+    Py_ssize_t end;
+    int strict = 1;
+
+    if (!_PyArg_CheckPositional("scanstring", nargs, 2, 3)) {
+        goto exit;
+    }
+    pystr = args[0];
+    {
+        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;
+        }
+        end = ival;
+    }
+    if (nargs < 3) {
+        goto skip_optional;
+    }
+    strict = PyObject_IsTrue(args[2]);
+    if (strict < 0) {
+        goto exit;
+    }
+skip_optional:
+    return_value = py_scanstring_impl(module, pystr, end, strict);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(py_encode_basestring_ascii__doc__,
+"encode_basestring_ascii($module, pystr, /)\n"
+"--\n"
+"\n"
+"Return an ASCII-only JSON representation of a Python string");
+
+#define PY_ENCODE_BASESTRING_ASCII_METHODDEF    \
+    {"encode_basestring_ascii", (PyCFunction)py_encode_basestring_ascii, 
METH_O, py_encode_basestring_ascii__doc__},
+
+PyDoc_STRVAR(py_encode_basestring__doc__,
+"encode_basestring($module, pystr, /)\n"
+"--\n"
+"\n"
+"Return a JSON representation of a Python string");
+
+#define PY_ENCODE_BASESTRING_METHODDEF    \
+    {"encode_basestring", (PyCFunction)py_encode_basestring, METH_O, 
py_encode_basestring__doc__},
+/*[clinic end generated code: output=d3aa505efc0acb3f input=a9049054013a1b77]*/

_______________________________________________
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]

Reply via email to