From c45e6e1bb3b3045b413574d25ebb2a473f6f5a1e Mon Sep 17 00:00:00 2001 From: Donghee Na Date: Thu, 30 Oct 2025 19:32:08 +0900 Subject: [PATCH] gh-137821: Improve Argument Clinic definitions in the ``_json`` module (#140780) --- Lib/test/test_json/test_scanstring.py | 2 +- ...-10-30-15-33-07.gh-issue-137821.8_Iavt.rst | 1 - ...-10-30-15-33-07.gh-issue-137821.8_Iavt.rst | 2 + Modules/_json.c | 55 ++++--------------- Modules/clinic/_json.c.h | 46 +++++++++++++++- 5 files changed, 59 insertions(+), 47 deletions(-) delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2025-10-30-15-33-07.gh-issue-137821.8_Iavt.rst create mode 100644 Misc/NEWS.d/next/Library/2025-10-30-15-33-07.gh-issue-137821.8_Iavt.rst diff --git a/Lib/test/test_json/test_scanstring.py b/Lib/test/test_json/test_scanstring.py index cca556a3b95b..9a6cdfe12d26 100644 --- a/Lib/test/test_json/test_scanstring.py +++ b/Lib/test/test_json/test_scanstring.py @@ -144,7 +144,7 @@ class TestScanstring: def test_overflow(self): with self.assertRaises(OverflowError): - self.json.decoder.scanstring(b"xxx", sys.maxsize+1) + self.json.decoder.scanstring("xxx", sys.maxsize+1) class TestPyScanstring(TestScanstring, PyTest): pass 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 deleted file mode 100644 index 124ea3f99938..000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2025-10-30-15-33-07.gh-issue-137821.8_Iavt.rst +++ /dev/null @@ -1 +0,0 @@ -Convert ``_json`` module to use Argument Clinic diff --git a/Misc/NEWS.d/next/Library/2025-10-30-15-33-07.gh-issue-137821.8_Iavt.rst b/Misc/NEWS.d/next/Library/2025-10-30-15-33-07.gh-issue-137821.8_Iavt.rst new file mode 100644 index 000000000000..7ccbfc3cb950 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-10-30-15-33-07.gh-issue-137821.8_Iavt.rst @@ -0,0 +1,2 @@ +Convert ``_json`` module to use Argument Clinic. +Patched by Yoonho Hann. diff --git a/Modules/_json.c b/Modules/_json.c index 6a84661a243e..14714d4b3465 100644 --- a/Modules/_json.c +++ b/Modules/_json.c @@ -645,7 +645,7 @@ bail: /*[clinic input] _json.scanstring as py_scanstring - pystr: object + pystr: unicode end: Py_ssize_t strict: bool = True / @@ -664,74 +664,41 @@ after the end quote. static PyObject * py_scanstring_impl(PyObject *module, PyObject *pystr, Py_ssize_t end, int strict) -/*[clinic end generated code: output=961740cfae07cdb3 input=9d46d7df7ac749b0]*/ +/*[clinic end generated code: output=961740cfae07cdb3 input=cff59e47498f4d8e]*/ { - PyObject *rval; Py_ssize_t next_end = -1; - if (PyUnicode_Check(pystr)) { - rval = scanstring_unicode(pystr, end, strict, &next_end); - } - else { - PyErr_Format(PyExc_TypeError, - "first argument must be a string, not %.80s", - Py_TYPE(pystr)->tp_name); - return NULL; - } + PyObject *rval = scanstring_unicode(pystr, end, strict, &next_end); return _build_rval_index_tuple(rval, next_end); } /*[clinic input] _json.encode_basestring_ascii as py_encode_basestring_ascii - pystr: object + pystr: unicode / Return an ASCII-only JSON representation of a Python string [clinic start generated code]*/ static PyObject * -py_encode_basestring_ascii(PyObject *module, PyObject *pystr) -/*[clinic end generated code: output=a8afcd88eba0b572 input=f4085ccd5928ea55]*/ +py_encode_basestring_ascii_impl(PyObject *module, PyObject *pystr) +/*[clinic end generated code: output=7b3841287cf211df input=4f3609498aff2de5]*/ { - PyObject *rval; - /* Return an ASCII-only JSON representation of a Python string */ - /* METH_O */ - if (PyUnicode_Check(pystr)) { - rval = ascii_escape_unicode(pystr); - } - else { - PyErr_Format(PyExc_TypeError, - "first argument must be a string, not %.80s", - Py_TYPE(pystr)->tp_name); - return NULL; - } - return rval; + return ascii_escape_unicode(pystr); } /*[clinic input] _json.encode_basestring as py_encode_basestring - pystr: object + pystr: unicode / Return a JSON representation of a Python string [clinic start generated code]*/ static PyObject * -py_encode_basestring(PyObject *module, PyObject *pystr) -/*[clinic end generated code: output=c87752300776d3b1 input=c3c7ef6e72624f6e]*/ +py_encode_basestring_impl(PyObject *module, PyObject *pystr) +/*[clinic end generated code: output=900950f95df3f1c9 input=d42ef714b2c07386]*/ { - PyObject *rval; - /* Return a JSON representation of a Python string */ - /* METH_O */ - if (PyUnicode_Check(pystr)) { - rval = escape_unicode(pystr); - } - else { - PyErr_Format(PyExc_TypeError, - "first argument must be a string, not %.80s", - Py_TYPE(pystr)->tp_name); - return NULL; - } - return rval; + return escape_unicode(pystr); } static void diff --git a/Modules/clinic/_json.c.h b/Modules/clinic/_json.c.h index b80e72ad00a6..cd37a236c761 100644 --- a/Modules/clinic/_json.c.h +++ b/Modules/clinic/_json.c.h @@ -37,6 +37,10 @@ py_scanstring(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("scanstring", nargs, 2, 3)) { goto exit; } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("scanstring", "argument 1", "str", args[0]); + goto exit; + } pystr = args[0]; { Py_ssize_t ival = -1; @@ -73,6 +77,26 @@ PyDoc_STRVAR(py_encode_basestring_ascii__doc__, #define PY_ENCODE_BASESTRING_ASCII_METHODDEF \ {"encode_basestring_ascii", (PyCFunction)py_encode_basestring_ascii, METH_O, py_encode_basestring_ascii__doc__}, +static PyObject * +py_encode_basestring_ascii_impl(PyObject *module, PyObject *pystr); + +static PyObject * +py_encode_basestring_ascii(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + PyObject *pystr; + + if (!PyUnicode_Check(arg)) { + _PyArg_BadArgument("encode_basestring_ascii", "argument", "str", arg); + goto exit; + } + pystr = arg; + return_value = py_encode_basestring_ascii_impl(module, pystr); + +exit: + return return_value; +} + PyDoc_STRVAR(py_encode_basestring__doc__, "encode_basestring($module, pystr, /)\n" "--\n" @@ -81,4 +105,24 @@ PyDoc_STRVAR(py_encode_basestring__doc__, #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]*/ + +static PyObject * +py_encode_basestring_impl(PyObject *module, PyObject *pystr); + +static PyObject * +py_encode_basestring(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + PyObject *pystr; + + if (!PyUnicode_Check(arg)) { + _PyArg_BadArgument("encode_basestring", "argument", "str", arg); + goto exit; + } + pystr = arg; + return_value = py_encode_basestring_impl(module, pystr); + +exit: + return return_value; +} +/*[clinic end generated code: output=5bdd16375c95a4d9 input=a9049054013a1b77]*/ -- 2.47.3