summaryrefslogtreecommitdiffstats
path: root/Modules
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2017-12-16 09:25:56 (GMT)
committerIvan Levkivskyi <levkivskyi@gmail.com>2017-12-16 09:25:56 (GMT)
commit45700fb757591a672e9d25b8252971c2a2caeaf2 (patch)
tree80af830fb9a999bca2665b53488e3ee00ad0f747 /Modules
parent9c19b020249c451891affd81751947321a1e6957 (diff)
downloadcpython-45700fb757591a672e9d25b8252971c2a2caeaf2.zip
cpython-45700fb757591a672e9d25b8252971c2a2caeaf2.tar.gz
cpython-45700fb757591a672e9d25b8252971c2a2caeaf2.tar.bz2
Add tests for using PEP560 with classes implemented in C. (#4883)
Based on tests from #4878
Diffstat (limited to 'Modules')
-rw-r--r--Modules/_testcapimodule.c85
1 files changed, 85 insertions, 0 deletions
diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c
index 4bb3e82..47b5064 100644
--- a/Modules/_testcapimodule.c
+++ b/Modules/_testcapimodule.c
@@ -5053,6 +5053,81 @@ recurse_infinitely_error_init(PyObject *self, PyObject *args, PyObject *kwds)
}
+/* Test PEP 560 */
+
+typedef struct {
+ PyObject_HEAD
+ PyObject *item;
+} PyGenericAliasObject;
+
+static void
+generic_alias_dealloc(PyGenericAliasObject *self)
+{
+ Py_CLEAR(self->item);
+}
+
+static PyObject *
+generic_alias_mro_entries(PyGenericAliasObject *self, PyObject *bases)
+{
+ return PyTuple_Pack(1, self->item);
+}
+
+static PyMethodDef generic_alias_methods[] = {
+ {"__mro_entries__", (PyCFunction) generic_alias_mro_entries, METH_O, NULL},
+ {NULL} /* sentinel */
+};
+
+PyTypeObject GenericAlias_Type = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "GenericAlias",
+ sizeof(PyGenericAliasObject),
+ 0,
+ .tp_dealloc = (destructor)generic_alias_dealloc,
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ .tp_methods = generic_alias_methods,
+};
+
+static PyObject *
+generic_alias_new(PyObject *item)
+{
+ PyGenericAliasObject *o = PyObject_New(PyGenericAliasObject, &GenericAlias_Type);
+ if (o == NULL) {
+ return NULL;
+ }
+ Py_INCREF(item);
+ o->item = item;
+ return (PyObject*) o;
+}
+
+typedef struct {
+ PyObject_HEAD
+} PyGenericObject;
+
+static PyObject *
+generic_class_getitem(PyObject *self, PyObject *args)
+{
+ PyObject *type, *item;
+ if (!PyArg_UnpackTuple(args, "__class_getitem__", 2, 2, &type, &item)) {
+ return NULL;
+ }
+ return generic_alias_new(item);
+}
+
+static PyMethodDef generic_methods[] = {
+ {"__class_getitem__", generic_class_getitem, METH_VARARGS|METH_STATIC, NULL},
+ {NULL} /* sentinel */
+};
+
+PyTypeObject Generic_Type = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "Generic",
+ sizeof(PyGenericObject),
+ 0,
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ .tp_methods = generic_methods,
+};
+
+
static struct PyModuleDef _testcapimodule = {
PyModuleDef_HEAD_INIT,
"_testcapi",
@@ -5094,6 +5169,16 @@ PyInit__testcapi(void)
Py_INCREF(&awaitType);
PyModule_AddObject(m, "awaitType", (PyObject *)&awaitType);
+ if (PyType_Ready(&GenericAlias_Type) < 0)
+ return NULL;
+ Py_INCREF(&GenericAlias_Type);
+ PyModule_AddObject(m, "GenericAlias", (PyObject *)&GenericAlias_Type);
+
+ if (PyType_Ready(&Generic_Type) < 0)
+ return NULL;
+ Py_INCREF(&Generic_Type);
+ PyModule_AddObject(m, "Generic", (PyObject *)&Generic_Type);
+
PyRecursingInfinitelyError_Type.tp_base = (PyTypeObject *)PyExc_Exception;
if (PyType_Ready(&PyRecursingInfinitelyError_Type) < 0) {
return NULL;