]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-137821: Convert _json module to use Argument Clinic (gh-140778)
authorYoonho Hann <hnnynh125@gmail.com>
Thu, 30 Oct 2025 09:42:09 +0000 (18:42 +0900)
committerGitHub <noreply@github.com>
Thu, 30 Oct 2025 09:42:09 +0000 (09:42 +0000)
Misc/NEWS.d/next/Core_and_Builtins/2025-10-30-15-33-07.gh-issue-137821.8_Iavt.rst [new file with mode: 0644]
Modules/_json.c
Modules/clinic/_json.c.h [new file with mode: 0644]

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 (file)
index 0000000..124ea3f
--- /dev/null
@@ -0,0 +1 @@
+Convert ``_json`` module to use Argument Clinic
index 9a1fc3aba3611672c4b2f6f9427e6ca0eaa4db03..6a84661a243ea4da1fc3fac2260217af66f5d568 100644 (file)
 
 #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 @@ bail:
     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 (file)
index 0000000..b80e72a
--- /dev/null
@@ -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]*/