]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-117613: Enhance test_clinic @defining_class tests (#117896)
authorVictor Stinner <vstinner@python.org>
Tue, 16 Apr 2024 07:32:51 +0000 (09:32 +0200)
committerGitHub <noreply@github.com>
Tue, 16 Apr 2024 07:32:51 +0000 (09:32 +0200)
Include/internal/pycore_global_objects_fini_generated.h
Include/internal/pycore_global_strings.h
Include/internal/pycore_runtime_init_generated.h
Include/internal/pycore_unicodeobject_generated.h
Lib/test/test_clinic.py
Modules/_testclinic.c
Modules/clinic/_testclinic.c.h

index 3605a6179abf135a58c2ea56de949561f3ca4f9a..24f32fca2e53310c2ae507654b42b3e5471b467a 100644 (file)
@@ -793,6 +793,7 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(alias));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(allow_code));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(append));
+    _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(arg));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(argdefs));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(args));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(arguments));
index c9b6a79a6d2a76eec249dc86b98b4b9caebda507..024f817408cee538dab73d80a75d503fcf331853 100644 (file)
@@ -282,6 +282,7 @@ struct _Py_global_strings {
         STRUCT_FOR_ID(alias)
         STRUCT_FOR_ID(allow_code)
         STRUCT_FOR_ID(append)
+        STRUCT_FOR_ID(arg)
         STRUCT_FOR_ID(argdefs)
         STRUCT_FOR_ID(args)
         STRUCT_FOR_ID(arguments)
index 49939ed17ebecfd3128e1cd7f3a838ad54766e51..795f95cb3a78850cb20793f5bf28255b1138fc4a 100644 (file)
@@ -791,6 +791,7 @@ extern "C" {
     INIT_ID(alias), \
     INIT_ID(allow_code), \
     INIT_ID(append), \
+    INIT_ID(arg), \
     INIT_ID(argdefs), \
     INIT_ID(args), \
     INIT_ID(arguments), \
index 1165ec513739d016d6129d774b99fe9b51cb61a9..272462e99b0d941e7f7076f4d5f9159b6173c036 100644 (file)
@@ -687,6 +687,9 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
     string = &_Py_ID(append);
     assert(_PyUnicode_CheckConsistency(string, 1));
     _PyUnicode_InternInPlace(interp, &string);
+    string = &_Py_ID(arg);
+    assert(_PyUnicode_CheckConsistency(string, 1));
+    _PyUnicode_InternInPlace(interp, &string);
     string = &_Py_ID(argdefs);
     assert(_PyUnicode_CheckConsistency(string, 1));
     _PyUnicode_InternInPlace(interp, &string);
index e8c638ea6107822c81a31fe329bf864fa839a8a8..ef57aaca9597bffa71963fa96296a84e4b2aac27 100644 (file)
@@ -3393,26 +3393,50 @@ class ClinicFunctionalTest(unittest.TestCase):
                 func = getattr(ac_tester, name)
                 self.assertEqual(func(), name)
 
-    def test_meth_method_no_params(self):
+    def test_get_defining_class(self):
         obj = ac_tester.TestClass()
-        meth = obj.meth_method_no_params
+        meth = obj.get_defining_class
+        self.assertIs(obj.get_defining_class(), ac_tester.TestClass)
+
+        # 'defining_class' argument is a positional only argument
+        with self.assertRaises(TypeError):
+            obj.get_defining_class_arg(cls=ac_tester.TestClass)
+
         check = partial(self.assertRaisesRegex, TypeError, "no arguments")
         check(meth, 1)
         check(meth, a=1)
 
-    def test_meth_method_no_params_capi(self):
+    def test_get_defining_class_capi(self):
         from _testcapi import pyobject_vectorcall
         obj = ac_tester.TestClass()
-        meth = obj.meth_method_no_params
+        meth = obj.get_defining_class
         pyobject_vectorcall(meth, None, None)
         pyobject_vectorcall(meth, (), None)
         pyobject_vectorcall(meth, (), ())
         pyobject_vectorcall(meth, None, ())
+        self.assertIs(pyobject_vectorcall(meth, (), ()), ac_tester.TestClass)
 
         check = partial(self.assertRaisesRegex, TypeError, "no arguments")
         check(pyobject_vectorcall, meth, (1,), None)
         check(pyobject_vectorcall, meth, (1,), ("a",))
 
+    def test_get_defining_class_arg(self):
+        obj = ac_tester.TestClass()
+        self.assertEqual(obj.get_defining_class_arg("arg"),
+                         (ac_tester.TestClass, "arg"))
+        self.assertEqual(obj.get_defining_class_arg(arg=123),
+                         (ac_tester.TestClass, 123))
+
+        # 'defining_class' argument is a positional only argument
+        with self.assertRaises(TypeError):
+            obj.get_defining_class_arg(cls=ac_tester.TestClass, arg="arg")
+
+        # wrong number of arguments
+        with self.assertRaises(TypeError):
+            obj.get_defining_class_arg()
+        with self.assertRaises(TypeError):
+            obj.get_defining_class_arg("arg1", "arg2")
+
     def test_depr_star_new(self):
         cls = ac_tester.DeprStarNew
         cls()
index fb0936bbccd318385505aa7195d56b114468c4f5..454173b434fb6bba01b54d0523f3f3afbd6d0d8e 100644 (file)
@@ -1219,21 +1219,36 @@ class _testclinic.TestClass "PyObject *" "PyObject"
 /*[clinic end generated code: output=da39a3ee5e6b4b0d input=668a591c65bec947]*/
 
 /*[clinic input]
-_testclinic.TestClass.meth_method_no_params
+_testclinic.TestClass.get_defining_class
     cls: defining_class
-    /
 [clinic start generated code]*/
 
 static PyObject *
-_testclinic_TestClass_meth_method_no_params_impl(PyObject *self,
-                                                 PyTypeObject *cls)
-/*[clinic end generated code: output=c140f100080c2fc8 input=6bd34503d11c63c1]*/
+_testclinic_TestClass_get_defining_class_impl(PyObject *self,
+                                              PyTypeObject *cls)
+/*[clinic end generated code: output=94f9b0b5f7add930 input=537c59417471dee3]*/
 {
-    Py_RETURN_NONE;
+    return Py_NewRef(cls);
+}
+
+/*[clinic input]
+_testclinic.TestClass.get_defining_class_arg
+    cls: defining_class
+    arg: object
+[clinic start generated code]*/
+
+static PyObject *
+_testclinic_TestClass_get_defining_class_arg_impl(PyObject *self,
+                                                  PyTypeObject *cls,
+                                                  PyObject *arg)
+/*[clinic end generated code: output=fe7e49d96cbb7718 input=d1b83d3b853af6d9]*/
+{
+    return Py_BuildValue("(OO)", cls, arg);
 }
 
 static struct PyMethodDef test_class_methods[] = {
-    _TESTCLINIC_TESTCLASS_METH_METHOD_NO_PARAMS_METHODDEF
+    _TESTCLINIC_TESTCLASS_GET_DEFINING_CLASS_METHODDEF
+    _TESTCLINIC_TESTCLASS_GET_DEFINING_CLASS_ARG_METHODDEF
     {NULL, NULL}
 };
 
index bb516be37ec3f09eab73aff5538a5383f6de99df..d1e09c94f051970f3f0d8a6b9057dd99978e64dc 100644 (file)
@@ -3142,25 +3142,81 @@ exit:
     return return_value;
 }
 
-PyDoc_STRVAR(_testclinic_TestClass_meth_method_no_params__doc__,
-"meth_method_no_params($self, /)\n"
+PyDoc_STRVAR(_testclinic_TestClass_get_defining_class__doc__,
+"get_defining_class($self, /)\n"
 "--\n"
 "\n");
 
-#define _TESTCLINIC_TESTCLASS_METH_METHOD_NO_PARAMS_METHODDEF    \
-    {"meth_method_no_params", _PyCFunction_CAST(_testclinic_TestClass_meth_method_no_params), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _testclinic_TestClass_meth_method_no_params__doc__},
+#define _TESTCLINIC_TESTCLASS_GET_DEFINING_CLASS_METHODDEF    \
+    {"get_defining_class", _PyCFunction_CAST(_testclinic_TestClass_get_defining_class), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _testclinic_TestClass_get_defining_class__doc__},
 
 static PyObject *
-_testclinic_TestClass_meth_method_no_params_impl(PyObject *self,
-                                                 PyTypeObject *cls);
+_testclinic_TestClass_get_defining_class_impl(PyObject *self,
+                                              PyTypeObject *cls);
 
 static PyObject *
-_testclinic_TestClass_meth_method_no_params(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+_testclinic_TestClass_get_defining_class(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
     if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) {
-        PyErr_SetString(PyExc_TypeError, "meth_method_no_params() takes no arguments");
+        PyErr_SetString(PyExc_TypeError, "get_defining_class() takes no arguments");
         return NULL;
     }
-    return _testclinic_TestClass_meth_method_no_params_impl(self, cls);
+    return _testclinic_TestClass_get_defining_class_impl(self, cls);
 }
-/*[clinic end generated code: output=6520c1ca5392a3f0 input=a9049054013a1b77]*/
+
+PyDoc_STRVAR(_testclinic_TestClass_get_defining_class_arg__doc__,
+"get_defining_class_arg($self, /, arg)\n"
+"--\n"
+"\n");
+
+#define _TESTCLINIC_TESTCLASS_GET_DEFINING_CLASS_ARG_METHODDEF    \
+    {"get_defining_class_arg", _PyCFunction_CAST(_testclinic_TestClass_get_defining_class_arg), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _testclinic_TestClass_get_defining_class_arg__doc__},
+
+static PyObject *
+_testclinic_TestClass_get_defining_class_arg_impl(PyObject *self,
+                                                  PyTypeObject *cls,
+                                                  PyObject *arg);
+
+static PyObject *
+_testclinic_TestClass_get_defining_class_arg(PyObject *self, PyTypeObject *cls, 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 2
+    static struct {
+        PyGC_Head _this_is_not_used;
+        PyObject_VAR_HEAD
+        PyObject *ob_item[NUM_KEYWORDS];
+    } _kwtuple = {
+        .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
+        .ob_item = { &_Py_ID(arg), },
+    };
+    #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[] = {"arg", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "get_defining_class_arg",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[1];
+    PyObject *arg;
+
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf);
+    if (!args) {
+        goto exit;
+    }
+    arg = args[0];
+    return_value = _testclinic_TestClass_get_defining_class_arg_impl(self, cls, arg);
+
+exit:
+    return return_value;
+}
+/*[clinic end generated code: output=71b2a15aa86c2bcf input=a9049054013a1b77]*/