From c26eadc68b112a622308c9956aed20b7a05d5c08 Mon Sep 17 00:00:00 2001 From: AN Long Date: Wed, 5 Apr 2023 00:05:54 +0800 Subject: [PATCH 01/33] gh-103092: isolate winreg --- PC/winreg.c | 127 +++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 92 insertions(+), 35 deletions(-) diff --git a/PC/winreg.c b/PC/winreg.c index 073598a12a68aa..8322f185a2dca9 100644 --- a/PC/winreg.c +++ b/PC/winreg.c @@ -37,6 +37,10 @@ static char errNotAHandle[] = "Object is not a handle"; /* Forward declares */ +typedef struct { + PyTypeObject* PyHKEY_Type; +} winreg_state; + /* Doc strings */ PyDoc_STRVAR(module_doc, "This module provides access to the Windows registry API.\n" @@ -150,6 +154,13 @@ PyHKEY_deallocFunc(PyObject *ob) PyObject_Free(ob); } +static int +PyHKEY_traverseFunc(PyHKEYObject* self, visitproc visit, void* arg) +{ + Py_VISIT(Py_TYPE(self)); + return 0; +} + static int PyHKEY_boolFunc(PyObject *ob) { @@ -354,10 +365,10 @@ static PyMemberDef PyHKEY_memberlist[] = { PyTypeObject PyHKEY_Type = { PyVarObject_HEAD_INIT(0, 0) /* fill in type at module init */ - "PyHKEY", - sizeof(PyHKEYObject), + "PyHKEY", //- + sizeof(PyHKEYObject), //- 0, - PyHKEY_deallocFunc, /* tp_dealloc */ + PyHKEY_deallocFunc, /* tp_dealloc */ //- 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ @@ -366,22 +377,59 @@ PyTypeObject PyHKEY_Type = &PyHKEY_NumberMethods, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ - PyHKEY_hashFunc, /* tp_hash */ + PyHKEY_hashFunc, /* tp_hash */ //- 0, /* tp_call */ - PyHKEY_strFunc, /* tp_str */ + PyHKEY_strFunc, /* tp_str */ //- 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ - 0, /* tp_flags */ - PyHKEY_doc, /* tp_doc */ - 0, /*tp_traverse*/ + 0, /* tp_flags */ //- + PyHKEY_doc, /* tp_doc */ //- + 0, /*tp_traverse*/ //- 0, /*tp_clear*/ 0, /*tp_richcompare*/ 0, /*tp_weaklistoffset*/ 0, /*tp_iter*/ 0, /*tp_iternext*/ - PyHKEY_methods, /*tp_methods*/ - PyHKEY_memberlist, /*tp_members*/ + PyHKEY_methods, /*tp_methods*/ //- + PyHKEY_memberlist, /*tp_members*/ //- +}; + +static PyType_Slot pyhkey_type_slots[] = { + {Py_tp_dealloc, PyHKEY_deallocFunc}, + {Py_tp_members, PyHKEY_memberlist}, + {Py_tp_methods, PyHKEY_methods}, + {Py_tp_doc, PyHKEY_doc}, + {Py_tp_traverse, PyHKEY_traverseFunc}, + {Py_tp_hash, PyHKEY_hashFunc}, + {Py_tp_str, PyHKEY_strFunc}, + {Py_nb_add, PyHKEY_binaryFailureFunc}, + {Py_nb_subtract, PyHKEY_binaryFailureFunc}, + {Py_nb_multiply, PyHKEY_binaryFailureFunc}, + {Py_nb_remainder, PyHKEY_binaryFailureFunc}, + {Py_nb_divmod, PyHKEY_binaryFailureFunc}, + {Py_nb_power, PyHKEY_ternaryFailureFunc}, + {Py_nb_negative, PyHKEY_unaryFailureFunc}, + {Py_nb_positive, PyHKEY_unaryFailureFunc}, + {Py_nb_absolute, PyHKEY_unaryFailureFunc}, + {Py_nb_bool, PyHKEY_boolFunc}, + {Py_nb_invert, PyHKEY_unaryFailureFunc}, + {Py_nb_lshift, PyHKEY_binaryFailureFunc}, + {Py_nb_rshift, PyHKEY_binaryFailureFunc}, + {Py_nb_and, PyHKEY_binaryFailureFunc}, + {Py_nb_xor, PyHKEY_binaryFailureFunc}, + {Py_nb_or, PyHKEY_binaryFailureFunc}, + {Py_nb_int, PyHKEY_intFunc}, + {Py_nb_float, PyHKEY_unaryFailureFunc}, + {0, NULL}, +}; + +static PyType_Spec pyhkey_type_spec = { + .name = "winreg.PYHkey", + .basicsize = sizeof(PyHKEYObject), + .flags = Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_IMMUTABLETYPE + | Py_TPFLAGS_DISALLOW_INSTANTIATION, + .slots = pyhkey_type_slots, }; /************************************************************************ @@ -2081,35 +2129,21 @@ inskey(PyObject * d, char * name, HKEY key) #define ADD_KEY(val) inskey(d, #val, val) - -static struct PyModuleDef winregmodule = { - PyModuleDef_HEAD_INIT, - "winreg", - module_doc, - -1, - winreg_methods, - NULL, - NULL, - NULL, - NULL -}; - -PyMODINIT_FUNC PyInit_winreg(void) +static int +exec_module(PyObject* m) { - PyObject *m, *d; - m = PyModule_Create(&winregmodule); - if (m == NULL) - return NULL; + winreg_state *st = (winreg_state *)PyModule_GetState(m); + + PyObject *d; d = PyModule_GetDict(m); - PyHKEY_Type.tp_doc = PyHKEY_doc; - if (PyType_Ready(&PyHKEY_Type) < 0) - return NULL; + st->PyHKEY_Type = (PyTypeObject *) + PyType_FromModuleAndSpec(m, &pyhkey_type_spec, NULL); if (PyDict_SetItemString(d, "HKEYType", - (PyObject *)&PyHKEY_Type) != 0) - return NULL; + (PyObject *)st->PyHKEY_Type) != 0) + return -1; if (PyDict_SetItemString(d, "error", PyExc_OSError) != 0) - return NULL; + return -1; /* Add the relevant constants */ ADD_KEY(HKEY_CLASSES_ROOT); @@ -2170,7 +2204,30 @@ PyMODINIT_FUNC PyInit_winreg(void) ADD_INT(REG_RESOURCE_LIST); ADD_INT(REG_FULL_RESOURCE_DESCRIPTOR); ADD_INT(REG_RESOURCE_REQUIREMENTS_LIST); - return m; + + return 0; +} + +static PyModuleDef_Slot winreg_slots[] = { + {Py_mod_exec, exec_module}, + {0, NULL} +}; + +static struct PyModuleDef winregmodule = { + PyModuleDef_HEAD_INIT, + "winreg", + module_doc, + sizeof(winreg_state), + winreg_methods, + winreg_slots, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC PyInit_winreg(void) +{ + return PyModuleDef_Init(&winregmodule); } #endif /* MS_WINDOWS_DESKTOP || MS_WINDOWS_SYSTEM || MS_WINDOWS_GAMES */ From cb7758001999ee6aaedb62f77cfa73a9d19c15c0 Mon Sep 17 00:00:00 2001 From: AN Long Date: Thu, 6 Apr 2023 15:25:16 +0800 Subject: [PATCH 02/33] Update PC/winreg.c Co-authored-by: Oleg Iarygin --- PC/winreg.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/PC/winreg.c b/PC/winreg.c index 8322f185a2dca9..b067a995c8d029 100644 --- a/PC/winreg.c +++ b/PC/winreg.c @@ -2214,15 +2214,12 @@ static PyModuleDef_Slot winreg_slots[] = { }; static struct PyModuleDef winregmodule = { - PyModuleDef_HEAD_INIT, - "winreg", - module_doc, - sizeof(winreg_state), - winreg_methods, - winreg_slots, - NULL, - NULL, - NULL + .m_base = PyModuleDef_HEAD_INIT, + .m_name = "winreg", + .m_doc = module_doc, + .m_size = sizeof(winreg_state), + .m_methods = winreg_methods, + .m_slots = winreg_slots, }; PyMODINIT_FUNC PyInit_winreg(void) From 1f0ecc072e7db0c7f75335d3eb889ad20ba6b9d0 Mon Sep 17 00:00:00 2001 From: AN Long Date: Sat, 8 Apr 2023 00:33:48 +0800 Subject: [PATCH 03/33] finish the isolate --- Objects/object.c | 6 --- PC/clinic/winreg.c.h | 79 +++++++++++++++------------- PC/winreg.c | 120 ++++++++++++++++++++----------------------- 3 files changed, 98 insertions(+), 107 deletions(-) diff --git a/Objects/object.c b/Objects/object.c index 9dd5eb998217f6..a76af63fdbb690 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -1971,9 +1971,6 @@ PyObject _Py_NotImplementedStruct = { 1, &_PyNotImplemented_Type }; -#ifdef MS_WINDOWS -extern PyTypeObject PyHKEY_Type; -#endif extern PyTypeObject _Py_GenericAliasIterType; extern PyTypeObject _PyMemoryIter_Type; extern PyTypeObject _PyLineIterator; @@ -2023,9 +2020,6 @@ static PyTypeObject* static_types[] = { &PyFunction_Type, &PyGen_Type, &PyGetSetDescr_Type, -#ifdef MS_WINDOWS - &PyHKEY_Type, -#endif &PyInstanceMethod_Type, &PyListIter_Type, &PyListRevIter_Type, diff --git a/PC/clinic/winreg.c.h b/PC/clinic/winreg.c.h index 7a9474301da8a1..9c395e3804bb36 100644 --- a/PC/clinic/winreg.c.h +++ b/PC/clinic/winreg.c.h @@ -19,15 +19,19 @@ PyDoc_STRVAR(winreg_HKEYType_Close__doc__, "If the handle is already closed, no error is raised."); #define WINREG_HKEYTYPE_CLOSE_METHODDEF \ - {"Close", (PyCFunction)winreg_HKEYType_Close, METH_NOARGS, winreg_HKEYType_Close__doc__}, + {"Close", _PyCFunction_CAST(winreg_HKEYType_Close), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, winreg_HKEYType_Close__doc__}, static PyObject * -winreg_HKEYType_Close_impl(PyHKEYObject *self); +winreg_HKEYType_Close_impl(PyHKEYObject *self, PyTypeObject *cls); static PyObject * -winreg_HKEYType_Close(PyHKEYObject *self, PyObject *Py_UNUSED(ignored)) +winreg_HKEYType_Close(PyHKEYObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - return winreg_HKEYType_Close_impl(self); + if (nargs) { + PyErr_SetString(PyExc_TypeError, "Close() takes no arguments"); + return NULL; + } + return winreg_HKEYType_Close_impl(self, cls); } #endif /* (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) || defined(MS_WINDOWS_GAMES)) */ @@ -97,19 +101,20 @@ PyDoc_STRVAR(winreg_HKEYType___exit____doc__, "\n"); #define WINREG_HKEYTYPE___EXIT___METHODDEF \ - {"__exit__", _PyCFunction_CAST(winreg_HKEYType___exit__), METH_FASTCALL|METH_KEYWORDS, winreg_HKEYType___exit____doc__}, + {"__exit__", _PyCFunction_CAST(winreg_HKEYType___exit__), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, winreg_HKEYType___exit____doc__}, static PyObject * -winreg_HKEYType___exit___impl(PyHKEYObject *self, PyObject *exc_type, - PyObject *exc_value, PyObject *traceback); +winreg_HKEYType___exit___impl(PyHKEYObject *self, PyTypeObject *cls, + PyObject *exc_type, PyObject *exc_value, + PyObject *traceback); static PyObject * -winreg_HKEYType___exit__(PyHKEYObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +winreg_HKEYType___exit__(PyHKEYObject *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 3 + #define NUM_KEYWORDS 4 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -144,7 +149,7 @@ winreg_HKEYType___exit__(PyHKEYObject *self, PyObject *const *args, Py_ssize_t n exc_type = args[0]; exc_value = args[1]; traceback = args[2]; - return_value = winreg_HKEYType___exit___impl(self, exc_type, exc_value, traceback); + return_value = winreg_HKEYType___exit___impl(self, cls, exc_type, exc_value, traceback); exit: return return_value; @@ -219,14 +224,14 @@ winreg_ConnectRegistry(PyObject *module, PyObject *const *args, Py_ssize_t nargs _PyArg_BadArgument("ConnectRegistry", "argument 1", "str or None", args[0]); goto exit; } - if (!clinic_HKEY_converter(args[1], &key)) { + if (!clinic_HKEY_converter(module, args[1], &key)) { goto exit; } _return_value = winreg_ConnectRegistry_impl(module, computer_name, key); if (_return_value == NULL) { goto exit; } - return_value = PyHKEY_FromHKEY(_return_value); + return_value = PyHKEY_FromHKEY(module, _return_value); exit: /* Cleanup for computer_name */ @@ -275,7 +280,7 @@ winreg_CreateKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("CreateKey", nargs, 2, 2)) { goto exit; } - if (!clinic_HKEY_converter(args[0], &key)) { + if (!clinic_HKEY_converter(module, args[0], &key)) { goto exit; } if (args[1] == Py_None) { @@ -295,7 +300,7 @@ winreg_CreateKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (_return_value == NULL) { goto exit; } - return_value = PyHKEY_FromHKEY(_return_value); + return_value = PyHKEY_FromHKEY(module, _return_value); exit: /* Cleanup for sub_key */ @@ -382,7 +387,7 @@ winreg_CreateKeyEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs, Py if (!args) { goto exit; } - if (!clinic_HKEY_converter(args[0], &key)) { + if (!clinic_HKEY_converter(module, args[0], &key)) { goto exit; } if (args[1] == Py_None) { @@ -419,7 +424,7 @@ winreg_CreateKeyEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs, Py if (_return_value == NULL) { goto exit; } - return_value = PyHKEY_FromHKEY(_return_value); + return_value = PyHKEY_FromHKEY(module, _return_value); exit: /* Cleanup for sub_key */ @@ -466,7 +471,7 @@ winreg_DeleteKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("DeleteKey", nargs, 2, 2)) { goto exit; } - if (!clinic_HKEY_converter(args[0], &key)) { + if (!clinic_HKEY_converter(module, args[0], &key)) { goto exit; } if (!PyUnicode_Check(args[1])) { @@ -566,7 +571,7 @@ winreg_DeleteKeyEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs, Py if (!args) { goto exit; } - if (!clinic_HKEY_converter(args[0], &key)) { + if (!clinic_HKEY_converter(module, args[0], &key)) { goto exit; } if (!PyUnicode_Check(args[1])) { @@ -634,7 +639,7 @@ winreg_DeleteValue(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("DeleteValue", nargs, 2, 2)) { goto exit; } - if (!clinic_HKEY_converter(args[0], &key)) { + if (!clinic_HKEY_converter(module, args[0], &key)) { goto exit; } if (args[1] == Py_None) { @@ -694,7 +699,7 @@ winreg_EnumKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("EnumKey", nargs, 2, 2)) { goto exit; } - if (!clinic_HKEY_converter(args[0], &key)) { + if (!clinic_HKEY_converter(module, args[0], &key)) { goto exit; } index = _PyLong_AsInt(args[1]); @@ -751,7 +756,7 @@ winreg_EnumValue(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("EnumValue", nargs, 2, 2)) { goto exit; } - if (!clinic_HKEY_converter(args[0], &key)) { + if (!clinic_HKEY_converter(module, args[0], &key)) { goto exit; } index = _PyLong_AsInt(args[1]); @@ -839,7 +844,7 @@ winreg_FlushKey(PyObject *module, PyObject *arg) PyObject *return_value = NULL; HKEY key; - if (!clinic_HKEY_converter(arg, &key)) { + if (!clinic_HKEY_converter(module, arg, &key)) { goto exit; } return_value = winreg_FlushKey_impl(module, key); @@ -898,7 +903,7 @@ winreg_LoadKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("LoadKey", nargs, 3, 3)) { goto exit; } - if (!clinic_HKEY_converter(args[0], &key)) { + if (!clinic_HKEY_converter(module, args[0], &key)) { goto exit; } if (!PyUnicode_Check(args[1])) { @@ -999,7 +1004,7 @@ winreg_OpenKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje if (!args) { goto exit; } - if (!clinic_HKEY_converter(args[0], &key)) { + if (!clinic_HKEY_converter(module, args[0], &key)) { goto exit; } if (args[1] == Py_None) { @@ -1036,7 +1041,7 @@ winreg_OpenKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje if (_return_value == NULL) { goto exit; } - return_value = PyHKEY_FromHKEY(_return_value); + return_value = PyHKEY_FromHKEY(module, _return_value); exit: /* Cleanup for sub_key */ @@ -1116,7 +1121,7 @@ winreg_OpenKeyEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyOb if (!args) { goto exit; } - if (!clinic_HKEY_converter(args[0], &key)) { + if (!clinic_HKEY_converter(module, args[0], &key)) { goto exit; } if (args[1] == Py_None) { @@ -1153,7 +1158,7 @@ winreg_OpenKeyEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyOb if (_return_value == NULL) { goto exit; } - return_value = PyHKEY_FromHKEY(_return_value); + return_value = PyHKEY_FromHKEY(module, _return_value); exit: /* Cleanup for sub_key */ @@ -1193,7 +1198,7 @@ winreg_QueryInfoKey(PyObject *module, PyObject *arg) PyObject *return_value = NULL; HKEY key; - if (!clinic_HKEY_converter(arg, &key)) { + if (!clinic_HKEY_converter(module, arg, &key)) { goto exit; } return_value = winreg_QueryInfoKey_impl(module, key); @@ -1242,7 +1247,7 @@ winreg_QueryValue(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("QueryValue", nargs, 2, 2)) { goto exit; } - if (!clinic_HKEY_converter(args[0], &key)) { + if (!clinic_HKEY_converter(module, args[0], &key)) { goto exit; } if (args[1] == Py_None) { @@ -1303,7 +1308,7 @@ winreg_QueryValueEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("QueryValueEx", nargs, 2, 2)) { goto exit; } - if (!clinic_HKEY_converter(args[0], &key)) { + if (!clinic_HKEY_converter(module, args[0], &key)) { goto exit; } if (args[1] == Py_None) { @@ -1369,7 +1374,7 @@ winreg_SaveKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("SaveKey", nargs, 2, 2)) { goto exit; } - if (!clinic_HKEY_converter(args[0], &key)) { + if (!clinic_HKEY_converter(module, args[0], &key)) { goto exit; } if (!PyUnicode_Check(args[1])) { @@ -1438,7 +1443,7 @@ winreg_SetValue(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("SetValue", nargs, 4, 4)) { goto exit; } - if (!clinic_HKEY_converter(args[0], &key)) { + if (!clinic_HKEY_converter(module, args[0], &key)) { goto exit; } if (args[1] == Py_None) { @@ -1542,7 +1547,7 @@ winreg_SetValueEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("SetValueEx", nargs, 5, 5)) { goto exit; } - if (!clinic_HKEY_converter(args[0], &key)) { + if (!clinic_HKEY_converter(module, args[0], &key)) { goto exit; } if (args[1] == Py_None) { @@ -1603,7 +1608,7 @@ winreg_DisableReflectionKey(PyObject *module, PyObject *arg) PyObject *return_value = NULL; HKEY key; - if (!clinic_HKEY_converter(arg, &key)) { + if (!clinic_HKEY_converter(module, arg, &key)) { goto exit; } return_value = winreg_DisableReflectionKey_impl(module, key); @@ -1641,7 +1646,7 @@ winreg_EnableReflectionKey(PyObject *module, PyObject *arg) PyObject *return_value = NULL; HKEY key; - if (!clinic_HKEY_converter(arg, &key)) { + if (!clinic_HKEY_converter(module, arg, &key)) { goto exit; } return_value = winreg_EnableReflectionKey_impl(module, key); @@ -1677,7 +1682,7 @@ winreg_QueryReflectionKey(PyObject *module, PyObject *arg) PyObject *return_value = NULL; HKEY key; - if (!clinic_HKEY_converter(arg, &key)) { + if (!clinic_HKEY_converter(module, arg, &key)) { goto exit; } return_value = winreg_QueryReflectionKey_impl(module, key); @@ -1795,4 +1800,4 @@ winreg_QueryReflectionKey(PyObject *module, PyObject *arg) #ifndef WINREG_QUERYREFLECTIONKEY_METHODDEF #define WINREG_QUERYREFLECTIONKEY_METHODDEF #endif /* !defined(WINREG_QUERYREFLECTIONKEY_METHODDEF) */ -/*[clinic end generated code: output=715db416dc1321ee input=a9049054013a1b77]*/ +/*[clinic end generated code: output=e280486839dc13a8 input=a9049054013a1b77]*/ diff --git a/PC/winreg.c b/PC/winreg.c index b067a995c8d029..20e885251b0469 100644 --- a/PC/winreg.c +++ b/PC/winreg.c @@ -20,10 +20,12 @@ #if defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) || defined(MS_WINDOWS_GAMES) -static BOOL PyHKEY_AsHKEY(PyObject *ob, HKEY *pRes, BOOL bNoneOK); -static BOOL clinic_HKEY_converter(PyObject *ob, void *p); -static PyObject *PyHKEY_FromHKEY(HKEY h); -static BOOL PyHKEY_Close(PyObject *obHandle); +static BOOL PyHKEY_AsHKEY(PyObject *m, PyObject *ob, HKEY *pRes, BOOL bNoneOK); +static BOOL clinic_HKEY_converter(PyObject *m, PyObject *ob, void *p); +static PyObject *PyHKEY_FromHKEY(PyObject *m, HKEY h); +static BOOL PyHKEY_Close(PyObject *m, PyObject *obHandle); + +static struct PyModuleDef winregmodule; static char errNotAHandle[] = "Object is not a handle"; @@ -118,7 +120,8 @@ typedef struct { HKEY hkey; } PyHKEYObject; -#define PyHKEY_Check(op) Py_IS_TYPE(op, &PyHKEY_Type) +#define PyHKEY_Check(m, op)\ + Py_IS_TYPE(op, ((winreg_state *)PyModule_GetState(m))->PyHKEY_Type) static char *failMsg = "bad operand type"; @@ -240,6 +243,14 @@ class HKEY_converter(CConverter): type = 'HKEY' converter = 'clinic_HKEY_converter' + def parse_arg(self, argname, displayname): + return """ + if (!{converter}(module, {argname}, &{paramname})) {{{{ + goto exit; + }}}} + """.format(argname=argname, paramname=self.parser_name, + converter=self.converter) + class HKEY_return_converter(CReturnConverter): type = 'HKEY' @@ -247,7 +258,7 @@ class HKEY_return_converter(CReturnConverter): self.declare(data) self.err_occurred_if_null_pointer("_return_value", data) data.return_conversion.append( - 'return_value = PyHKEY_FromHKEY(_return_value);\n') + 'return_value = PyHKEY_FromHKEY(module, _return_value);\n') # HACK: this only works for PyHKEYObjects, nothing else. # Should this be generalized and enshrined in clinic.py, @@ -260,7 +271,7 @@ class self_return_converter(CReturnConverter): data.return_conversion.append( 'return_value = (PyObject *)_return_value;\n') [python start generated code]*/ -/*[python end generated code: output=da39a3ee5e6b4b0d input=2ebb7a4922d408d6]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=1bf6a0ebbb134810]*/ #include "clinic/winreg.c.h" @@ -272,16 +283,22 @@ class self_return_converter(CReturnConverter): /*[clinic input] winreg.HKEYType.Close + cls: defining_class + Closes the underlying Windows handle. If the handle is already closed, no error is raised. [clinic start generated code]*/ static PyObject * -winreg_HKEYType_Close_impl(PyHKEYObject *self) -/*[clinic end generated code: output=fced3a624fb0c344 input=6786ac75f6b89de6]*/ +winreg_HKEYType_Close_impl(PyHKEYObject *self, PyTypeObject *cls) +/*[clinic end generated code: output=4a1fc85168cf5102 input=b30c5bb22161fbf0]*/ { - if (!PyHKEY_Close((PyObject *)self)) + PyObject *m = PyType_GetModule(cls); + if (m == NULL) { + return NULL; + } + if (!PyHKEY_Close(m, (PyObject *)self)) return NULL; Py_RETURN_NONE; } @@ -328,17 +345,23 @@ winreg_HKEYType___enter___impl(PyHKEYObject *self) /*[clinic input] winreg.HKEYType.__exit__ + cls: defining_class exc_type: object exc_value: object traceback: object [clinic start generated code]*/ static PyObject * -winreg_HKEYType___exit___impl(PyHKEYObject *self, PyObject *exc_type, - PyObject *exc_value, PyObject *traceback) -/*[clinic end generated code: output=923ebe7389e6a263 input=fb32489ee92403c7]*/ +winreg_HKEYType___exit___impl(PyHKEYObject *self, PyTypeObject *cls, + PyObject *exc_type, PyObject *exc_value, + PyObject *traceback) +/*[clinic end generated code: output=47d05b29b8f34b89 input=95a8d2759df9dd54]*/ { - if (!PyHKEY_Close((PyObject *)self)) + PyObject *m = PyType_GetModule(cls); + if (m == NULL) { + return NULL; + } + if (!PyHKEY_Close(m, (PyObject *)self)) return NULL; Py_RETURN_NONE; } @@ -361,45 +384,11 @@ static PyMemberDef PyHKEY_memberlist[] = { {NULL} /* Sentinel */ }; -/* The type itself */ -PyTypeObject PyHKEY_Type = -{ - PyVarObject_HEAD_INIT(0, 0) /* fill in type at module init */ - "PyHKEY", //- - sizeof(PyHKEYObject), //- - 0, - PyHKEY_deallocFunc, /* tp_dealloc */ //- - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - &PyHKEY_NumberMethods, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - PyHKEY_hashFunc, /* tp_hash */ //- - 0, /* tp_call */ - PyHKEY_strFunc, /* tp_str */ //- - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - 0, /* tp_flags */ //- - PyHKEY_doc, /* tp_doc */ //- - 0, /*tp_traverse*/ //- - 0, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - PyHKEY_methods, /*tp_methods*/ //- - PyHKEY_memberlist, /*tp_members*/ //- -}; - static PyType_Slot pyhkey_type_slots[] = { {Py_tp_dealloc, PyHKEY_deallocFunc}, {Py_tp_members, PyHKEY_memberlist}, {Py_tp_methods, PyHKEY_methods}, - {Py_tp_doc, PyHKEY_doc}, + {Py_tp_doc, (char *)PyHKEY_doc}, {Py_tp_traverse, PyHKEY_traverseFunc}, {Py_tp_hash, PyHKEY_hashFunc}, {Py_tp_str, PyHKEY_strFunc}, @@ -436,24 +425,25 @@ static PyType_Spec pyhkey_type_spec = { The public PyHKEY API (well, not public yet :-) ************************************************************************/ PyObject * -PyHKEY_New(HKEY hInit) +PyHKEY_New(PyObject *m, HKEY hInit) { - PyHKEYObject *key = PyObject_New(PyHKEYObject, &PyHKEY_Type); + winreg_state *st = PyModule_GetState(m); + PyHKEYObject *key = PyObject_New(PyHKEYObject, st->PyHKEY_Type); if (key) key->hkey = hInit; return (PyObject *)key; } BOOL -PyHKEY_Close(PyObject *ob_handle) +PyHKEY_Close(PyObject *m, PyObject *ob_handle) { LONG rc; HKEY key; - if (!PyHKEY_AsHKEY(ob_handle, &key, TRUE)) { + if (!PyHKEY_AsHKEY(m, ob_handle, &key, TRUE)) { return FALSE; } - if (PyHKEY_Check(ob_handle)) { + if (PyHKEY_Check(m, ob_handle)) { ((PyHKEYObject*)ob_handle)->hkey = 0; } rc = key ? RegCloseKey(key) : ERROR_SUCCESS; @@ -463,7 +453,7 @@ PyHKEY_Close(PyObject *ob_handle) } BOOL -PyHKEY_AsHKEY(PyObject *ob, HKEY *pHANDLE, BOOL bNoneOK) +PyHKEY_AsHKEY(PyObject *m, PyObject *ob, HKEY *pHANDLE, BOOL bNoneOK) { if (ob == Py_None) { if (!bNoneOK) { @@ -474,7 +464,7 @@ PyHKEY_AsHKEY(PyObject *ob, HKEY *pHANDLE, BOOL bNoneOK) } *pHANDLE = (HKEY)0; } - else if (PyHKEY_Check(ob)) { + else if (PyHKEY_Check(m ,ob)) { PyHKEYObject *pH = (PyHKEYObject *)ob; *pHANDLE = pH->hkey; } @@ -495,22 +485,24 @@ PyHKEY_AsHKEY(PyObject *ob, HKEY *pHANDLE, BOOL bNoneOK) } BOOL -clinic_HKEY_converter(PyObject *ob, void *p) +clinic_HKEY_converter(PyObject *m, PyObject *ob, void *p) { - if (!PyHKEY_AsHKEY(ob, (HKEY *)p, FALSE)) + if (!PyHKEY_AsHKEY(m, ob, (HKEY *)p, FALSE)) return FALSE; return TRUE; } PyObject * -PyHKEY_FromHKEY(HKEY h) +PyHKEY_FromHKEY(PyObject *m, HKEY h) { + winreg_state *st = PyModule_GetState(m); + /* Inline PyObject_New */ PyHKEYObject *op = (PyHKEYObject *) PyObject_Malloc(sizeof(PyHKEYObject)); if (op == NULL) { return PyErr_NoMemory(); } - _PyObject_Init((PyObject*)op, &PyHKEY_Type); + _PyObject_Init((PyObject*)op, st->PyHKEY_Type); op->hkey = h; return (PyObject *)op; } @@ -520,11 +512,11 @@ PyHKEY_FromHKEY(HKEY h) The module methods ************************************************************************/ BOOL -PyWinObject_CloseHKEY(PyObject *obHandle) +PyWinObject_CloseHKEY(PyObject *m, PyObject *obHandle) { BOOL ok; - if (PyHKEY_Check(obHandle)) { - ok = PyHKEY_Close(obHandle); + if (PyHKEY_Check(m, obHandle)) { + ok = PyHKEY_Close(m, obHandle); } #if SIZEOF_LONG >= SIZEOF_HKEY else if (PyLong_Check(obHandle)) { @@ -874,7 +866,7 @@ static PyObject * winreg_CloseKey(PyObject *module, PyObject *hkey) /*[clinic end generated code: output=a4fa537019a80d15 input=5b1aac65ba5127ad]*/ { - if (!PyHKEY_Close(hkey)) + if (!PyHKEY_Close(module, hkey)) return NULL; Py_RETURN_NONE; } From d48fc88b6c019fcee87d1e596f73b0f0f4906633 Mon Sep 17 00:00:00 2001 From: AN Long Date: Sat, 8 Apr 2023 00:47:40 +0800 Subject: [PATCH 04/33] add tests for winreg --- Lib/test/test_winreg.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Lib/test/test_winreg.py b/Lib/test/test_winreg.py index 769ab67b0f5611..83a26283b1353c 100644 --- a/Lib/test/test_winreg.py +++ b/Lib/test/test_winreg.py @@ -1,8 +1,10 @@ # Test the windows specific win32reg module. # Only win32reg functions not hit here: FlushKey, LoadKey and SaveKey +import gc import os, sys, errno import unittest +from test.support import cpython_only from test.support import import_helper import threading from platform import machine, win32_edition @@ -49,6 +51,16 @@ ("Japanese 日本", "日本語", REG_SZ), ] + +@cpython_only +class HeapTypeTests(unittest.TestCase): + def test_have_gc(self): + self.assertTrue(gc.is_tracked(HKEYType)) + + def test_immutable(self): + with self.assertRaisesRegex(TypeError, "immutable"): + HKEYType.foo = "bar" + class BaseWinregTests(unittest.TestCase): def setUp(self): From 22010372ff4ae079498d670c70f019d90c07f0da Mon Sep 17 00:00:00 2001 From: AN Long Date: Sat, 8 Apr 2023 00:49:00 +0800 Subject: [PATCH 05/33] add news --- .../next/Library/2023-04-08-00-48-40.gh-issue-103092.5EFts0.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Library/2023-04-08-00-48-40.gh-issue-103092.5EFts0.rst diff --git a/Misc/NEWS.d/next/Library/2023-04-08-00-48-40.gh-issue-103092.5EFts0.rst b/Misc/NEWS.d/next/Library/2023-04-08-00-48-40.gh-issue-103092.5EFts0.rst new file mode 100644 index 00000000000000..63eb795d67e18d --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-04-08-00-48-40.gh-issue-103092.5EFts0.rst @@ -0,0 +1 @@ +Adapt :mod:`!winreg` to :pep:`687`. From 71547efc300f1732ebdec0ddd9e666e6baa32caa Mon Sep 17 00:00:00 2001 From: AN Long Date: Sun, 9 Apr 2023 13:59:31 +0800 Subject: [PATCH 06/33] Update Lib/test/test_winreg.py Co-authored-by: Erlend E. Aasland --- Lib/test/test_winreg.py | 1 + 1 file changed, 1 insertion(+) diff --git a/Lib/test/test_winreg.py b/Lib/test/test_winreg.py index 83a26283b1353c..a85c583358a603 100644 --- a/Lib/test/test_winreg.py +++ b/Lib/test/test_winreg.py @@ -61,6 +61,7 @@ def test_immutable(self): with self.assertRaisesRegex(TypeError, "immutable"): HKEYType.foo = "bar" + class BaseWinregTests(unittest.TestCase): def setUp(self): From 1b5b87379b7b6b8196999d5cf5cec7f95400f8ba Mon Sep 17 00:00:00 2001 From: AN Long Date: Sun, 9 Apr 2023 13:59:39 +0800 Subject: [PATCH 07/33] Update Misc/NEWS.d/next/Library/2023-04-08-00-48-40.gh-issue-103092.5EFts0.rst Co-authored-by: Erlend E. Aasland --- .../next/Library/2023-04-08-00-48-40.gh-issue-103092.5EFts0.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Library/2023-04-08-00-48-40.gh-issue-103092.5EFts0.rst b/Misc/NEWS.d/next/Library/2023-04-08-00-48-40.gh-issue-103092.5EFts0.rst index 63eb795d67e18d..0f2108fee763d0 100644 --- a/Misc/NEWS.d/next/Library/2023-04-08-00-48-40.gh-issue-103092.5EFts0.rst +++ b/Misc/NEWS.d/next/Library/2023-04-08-00-48-40.gh-issue-103092.5EFts0.rst @@ -1 +1 @@ -Adapt :mod:`!winreg` to :pep:`687`. +Adapt the :mod:`winreg` extension module to :pep:`687`. From a4eb9c519e73b26fa68727fb8e21eb7cdac33869 Mon Sep 17 00:00:00 2001 From: AN Long Date: Sun, 9 Apr 2023 14:00:14 +0800 Subject: [PATCH 08/33] Update PC/winreg.c Co-authored-by: Erlend E. Aasland --- PC/winreg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PC/winreg.c b/PC/winreg.c index 20e885251b0469..c43ebd639e136d 100644 --- a/PC/winreg.c +++ b/PC/winreg.c @@ -158,7 +158,7 @@ PyHKEY_deallocFunc(PyObject *ob) } static int -PyHKEY_traverseFunc(PyHKEYObject* self, visitproc visit, void* arg) +PyHKEY_traverseFunc(PyHKEYObject *self, visitproc visit, void *arg) { Py_VISIT(Py_TYPE(self)); return 0; From 179416a2b7af884463f62ba2ba92592aa61258a6 Mon Sep 17 00:00:00 2001 From: AN Long Date: Sun, 9 Apr 2023 14:00:25 +0800 Subject: [PATCH 09/33] Update PC/winreg.c Co-authored-by: Erlend E. Aasland --- PC/winreg.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/PC/winreg.c b/PC/winreg.c index c43ebd639e136d..5756445c4409d2 100644 --- a/PC/winreg.c +++ b/PC/winreg.c @@ -416,8 +416,8 @@ static PyType_Slot pyhkey_type_slots[] = { static PyType_Spec pyhkey_type_spec = { .name = "winreg.PYHkey", .basicsize = sizeof(PyHKEYObject), - .flags = Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_IMMUTABLETYPE - | Py_TPFLAGS_DISALLOW_INSTANTIATION, + .flags = (Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_IMMUTABLETYPE | + Py_TPFLAGS_DISALLOW_INSTANTIATION), .slots = pyhkey_type_slots, }; From 73f3ffe8e69934ed6aa43e4be57d7e91cf6b8905 Mon Sep 17 00:00:00 2001 From: AN Long Date: Sun, 9 Apr 2023 14:00:50 +0800 Subject: [PATCH 10/33] Update PC/winreg.c Co-authored-by: Erlend E. Aasland --- PC/winreg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PC/winreg.c b/PC/winreg.c index 5756445c4409d2..b511ef9bebdbf6 100644 --- a/PC/winreg.c +++ b/PC/winreg.c @@ -121,7 +121,7 @@ typedef struct { } PyHKEYObject; #define PyHKEY_Check(m, op)\ - Py_IS_TYPE(op, ((winreg_state *)PyModule_GetState(m))->PyHKEY_Type) + Py_IS_TYPE(op, ((winreg_state *)_PyModule_GetState(m))->PyHKEY_Type) static char *failMsg = "bad operand type"; From dff3839a88b1aaf50d51acc99fd5ad8beaafd5b6 Mon Sep 17 00:00:00 2001 From: AN Long Date: Sun, 9 Apr 2023 14:01:06 +0800 Subject: [PATCH 11/33] Update PC/winreg.c Co-authored-by: Erlend E. Aasland --- PC/winreg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PC/winreg.c b/PC/winreg.c index b511ef9bebdbf6..fe586608c15c1e 100644 --- a/PC/winreg.c +++ b/PC/winreg.c @@ -2122,7 +2122,7 @@ inskey(PyObject * d, char * name, HKEY key) #define ADD_KEY(val) inskey(d, #val, val) static int -exec_module(PyObject* m) +exec_module(PyObject *m) { winreg_state *st = (winreg_state *)PyModule_GetState(m); From 86237190de73163204cb275be145cb9a321f7029 Mon Sep 17 00:00:00 2001 From: AN Long Date: Sun, 9 Apr 2023 14:18:21 +0800 Subject: [PATCH 12/33] Update PC/winreg.c Co-authored-by: Erlend E. Aasland --- PC/winreg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PC/winreg.c b/PC/winreg.c index fe586608c15c1e..e55049169c9c3d 100644 --- a/PC/winreg.c +++ b/PC/winreg.c @@ -428,7 +428,7 @@ PyObject * PyHKEY_New(PyObject *m, HKEY hInit) { winreg_state *st = PyModule_GetState(m); - PyHKEYObject *key = PyObject_New(PyHKEYObject, st->PyHKEY_Type); + PyHKEYObject *key = PyObject_GC_New(PyHKEYObject, st->PyHKEY_Type); if (key) key->hkey = hInit; return (PyObject *)key; From 3f1cd90f9731f1c7089ceb1331a01a5de5ca82f7 Mon Sep 17 00:00:00 2001 From: AN Long Date: Sun, 9 Apr 2023 14:20:22 +0800 Subject: [PATCH 13/33] fix gc track on PyHKEY --- PC/winreg.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/PC/winreg.c b/PC/winreg.c index e55049169c9c3d..c0eaf0b15d854f 100644 --- a/PC/winreg.c +++ b/PC/winreg.c @@ -154,7 +154,11 @@ PyHKEY_deallocFunc(PyObject *ob) PyHKEYObject *obkey = (PyHKEYObject *)ob; if (obkey->hkey) RegCloseKey((HKEY)obkey->hkey); - PyObject_Free(ob); + + PyTypeObject *tp = Py_TYPE(ob); + PyObject_GC_UnTrack(ob); + PyObject_GC_Del(ob); + Py_DECREF(tp); } static int @@ -431,6 +435,7 @@ PyHKEY_New(PyObject *m, HKEY hInit) PyHKEYObject *key = PyObject_GC_New(PyHKEYObject, st->PyHKEY_Type); if (key) key->hkey = hInit; + PyObject_GC_Track(key); return (PyObject *)key; } @@ -497,13 +502,9 @@ PyHKEY_FromHKEY(PyObject *m, HKEY h) { winreg_state *st = PyModule_GetState(m); - /* Inline PyObject_New */ - PyHKEYObject *op = (PyHKEYObject *) PyObject_Malloc(sizeof(PyHKEYObject)); - if (op == NULL) { - return PyErr_NoMemory(); - } - _PyObject_Init((PyObject*)op, st->PyHKEY_Type); + PyHKEYObject *op = (PyHKEYObject *) PyObject_GC_New(PyHKEYObject, st->PyHKEY_Type); op->hkey = h; + PyObject_GC_Track(op); return (PyObject *)op; } From f3da3182b310fe8cb265e4cd0dd30415f4b3f3ee Mon Sep 17 00:00:00 2001 From: AN Long Date: Sun, 9 Apr 2023 15:40:34 +0800 Subject: [PATCH 14/33] using Py_Type to get class instead of using defining_class and using PyModule_GetState instead of _PyModule_GetState --- PC/clinic/winreg.c.h | 27 +++++++++++---------------- PC/winreg.c | 25 +++++++++++-------------- 2 files changed, 22 insertions(+), 30 deletions(-) diff --git a/PC/clinic/winreg.c.h b/PC/clinic/winreg.c.h index 9c395e3804bb36..e24f7d3d003fee 100644 --- a/PC/clinic/winreg.c.h +++ b/PC/clinic/winreg.c.h @@ -19,19 +19,15 @@ PyDoc_STRVAR(winreg_HKEYType_Close__doc__, "If the handle is already closed, no error is raised."); #define WINREG_HKEYTYPE_CLOSE_METHODDEF \ - {"Close", _PyCFunction_CAST(winreg_HKEYType_Close), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, winreg_HKEYType_Close__doc__}, + {"Close", (PyCFunction)winreg_HKEYType_Close, METH_NOARGS, winreg_HKEYType_Close__doc__}, static PyObject * -winreg_HKEYType_Close_impl(PyHKEYObject *self, PyTypeObject *cls); +winreg_HKEYType_Close_impl(PyHKEYObject *self); static PyObject * -winreg_HKEYType_Close(PyHKEYObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +winreg_HKEYType_Close(PyHKEYObject *self, PyObject *Py_UNUSED(ignored)) { - if (nargs) { - PyErr_SetString(PyExc_TypeError, "Close() takes no arguments"); - return NULL; - } - return winreg_HKEYType_Close_impl(self, cls); + return winreg_HKEYType_Close_impl(self); } #endif /* (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) || defined(MS_WINDOWS_GAMES)) */ @@ -101,20 +97,19 @@ PyDoc_STRVAR(winreg_HKEYType___exit____doc__, "\n"); #define WINREG_HKEYTYPE___EXIT___METHODDEF \ - {"__exit__", _PyCFunction_CAST(winreg_HKEYType___exit__), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, winreg_HKEYType___exit____doc__}, + {"__exit__", _PyCFunction_CAST(winreg_HKEYType___exit__), METH_FASTCALL|METH_KEYWORDS, winreg_HKEYType___exit____doc__}, static PyObject * -winreg_HKEYType___exit___impl(PyHKEYObject *self, PyTypeObject *cls, - PyObject *exc_type, PyObject *exc_value, - PyObject *traceback); +winreg_HKEYType___exit___impl(PyHKEYObject *self, PyObject *exc_type, + PyObject *exc_value, PyObject *traceback); static PyObject * -winreg_HKEYType___exit__(PyHKEYObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +winreg_HKEYType___exit__(PyHKEYObject *self, 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 4 + #define NUM_KEYWORDS 3 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -149,7 +144,7 @@ winreg_HKEYType___exit__(PyHKEYObject *self, PyTypeObject *cls, PyObject *const exc_type = args[0]; exc_value = args[1]; traceback = args[2]; - return_value = winreg_HKEYType___exit___impl(self, cls, exc_type, exc_value, traceback); + return_value = winreg_HKEYType___exit___impl(self, exc_type, exc_value, traceback); exit: return return_value; @@ -1800,4 +1795,4 @@ winreg_QueryReflectionKey(PyObject *module, PyObject *arg) #ifndef WINREG_QUERYREFLECTIONKEY_METHODDEF #define WINREG_QUERYREFLECTIONKEY_METHODDEF #endif /* !defined(WINREG_QUERYREFLECTIONKEY_METHODDEF) */ -/*[clinic end generated code: output=e280486839dc13a8 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=ad8592b2d01094e7 input=a9049054013a1b77]*/ diff --git a/PC/winreg.c b/PC/winreg.c index c0eaf0b15d854f..82f51eadeb7b7d 100644 --- a/PC/winreg.c +++ b/PC/winreg.c @@ -15,6 +15,7 @@ #define PY_SSIZE_T_CLEAN #include "Python.h" #include "pycore_object.h" // _PyObject_Init() +#include "pycore_moduleobject.h" #include "structmember.h" // PyMemberDef #include @@ -287,18 +288,16 @@ class self_return_converter(CReturnConverter): /*[clinic input] winreg.HKEYType.Close - cls: defining_class - Closes the underlying Windows handle. If the handle is already closed, no error is raised. [clinic start generated code]*/ static PyObject * -winreg_HKEYType_Close_impl(PyHKEYObject *self, PyTypeObject *cls) -/*[clinic end generated code: output=4a1fc85168cf5102 input=b30c5bb22161fbf0]*/ +winreg_HKEYType_Close_impl(PyHKEYObject *self) +/*[clinic end generated code: output=fced3a624fb0c344 input=6786ac75f6b89de6]*/ { - PyObject *m = PyType_GetModule(cls); + PyObject *m = PyType_GetModule(Py_TYPE(self)); if (m == NULL) { return NULL; } @@ -349,19 +348,17 @@ winreg_HKEYType___enter___impl(PyHKEYObject *self) /*[clinic input] winreg.HKEYType.__exit__ - cls: defining_class exc_type: object exc_value: object traceback: object [clinic start generated code]*/ static PyObject * -winreg_HKEYType___exit___impl(PyHKEYObject *self, PyTypeObject *cls, - PyObject *exc_type, PyObject *exc_value, - PyObject *traceback) -/*[clinic end generated code: output=47d05b29b8f34b89 input=95a8d2759df9dd54]*/ +winreg_HKEYType___exit___impl(PyHKEYObject *self, PyObject *exc_type, + PyObject *exc_value, PyObject *traceback) +/*[clinic end generated code: output=923ebe7389e6a263 input=fb32489ee92403c7]*/ { - PyObject *m = PyType_GetModule(cls); + PyObject *m = PyType_GetModule(Py_TYPE(self)); if (m == NULL) { return NULL; } @@ -431,7 +428,7 @@ static PyType_Spec pyhkey_type_spec = { PyObject * PyHKEY_New(PyObject *m, HKEY hInit) { - winreg_state *st = PyModule_GetState(m); + winreg_state *st = _PyModule_GetState(m); PyHKEYObject *key = PyObject_GC_New(PyHKEYObject, st->PyHKEY_Type); if (key) key->hkey = hInit; @@ -500,7 +497,7 @@ clinic_HKEY_converter(PyObject *m, PyObject *ob, void *p) PyObject * PyHKEY_FromHKEY(PyObject *m, HKEY h) { - winreg_state *st = PyModule_GetState(m); + winreg_state *st = _PyModule_GetState(m); PyHKEYObject *op = (PyHKEYObject *) PyObject_GC_New(PyHKEYObject, st->PyHKEY_Type); op->hkey = h; @@ -2125,7 +2122,7 @@ inskey(PyObject * d, char * name, HKEY key) static int exec_module(PyObject *m) { - winreg_state *st = (winreg_state *)PyModule_GetState(m); + winreg_state *st = (winreg_state *)_PyModule_GetState(m); PyObject *d; d = PyModule_GetDict(m); From a2017d1ac04ba2777c90722a2c3c5cf80c39723a Mon Sep 17 00:00:00 2001 From: AN Long Date: Sun, 9 Apr 2023 19:34:39 +0800 Subject: [PATCH 15/33] fix the memory leak --- PC/winreg.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/PC/winreg.c b/PC/winreg.c index 82f51eadeb7b7d..b669a000608d14 100644 --- a/PC/winreg.c +++ b/PC/winreg.c @@ -2203,6 +2203,20 @@ static PyModuleDef_Slot winreg_slots[] = { {0, NULL} }; +static winreg_traverse(PyObject* module, visitproc visit, void* arg) +{ + winreg_state *state = PyModule_GetState(module); + Py_VISIT(state->PyHKEY_Type); + return 0; +} + +static winreg_clear(PyObject *module) +{ + winreg_state *state = PyModule_GetState(module); + Py_CLEAR(state->PyHKEY_Type); + return 0; +} + static struct PyModuleDef winregmodule = { .m_base = PyModuleDef_HEAD_INIT, .m_name = "winreg", @@ -2210,6 +2224,8 @@ static struct PyModuleDef winregmodule = { .m_size = sizeof(winreg_state), .m_methods = winreg_methods, .m_slots = winreg_slots, + .m_traverse = winreg_traverse, + .m_clear = winreg_clear, }; PyMODINIT_FUNC PyInit_winreg(void) From 80af80ca48f77f28ca5edfe81e6a6c283d6fbd91 Mon Sep 17 00:00:00 2001 From: AN Long Date: Mon, 10 Apr 2023 17:34:41 +0800 Subject: [PATCH 16/33] Update PC/winreg.c Co-authored-by: Erlend E. Aasland --- PC/winreg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PC/winreg.c b/PC/winreg.c index b669a000608d14..4bf9c06a20739c 100644 --- a/PC/winreg.c +++ b/PC/winreg.c @@ -41,7 +41,7 @@ static char errNotAHandle[] = "Object is not a handle"; /* Forward declares */ typedef struct { - PyTypeObject* PyHKEY_Type; + PyTypeObject *PyHKEY_Type; } winreg_state; /* Doc strings */ From 9da5f0e14d657e1d8aeb470af199130d8b3864ab Mon Sep 17 00:00:00 2001 From: AN Long Date: Mon, 10 Apr 2023 17:35:53 +0800 Subject: [PATCH 17/33] Update PC/winreg.c Co-authored-by: Erlend E. Aasland --- PC/winreg.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/PC/winreg.c b/PC/winreg.c index 4bf9c06a20739c..f3ca0625203e3d 100644 --- a/PC/winreg.c +++ b/PC/winreg.c @@ -298,9 +298,7 @@ winreg_HKEYType_Close_impl(PyHKEYObject *self) /*[clinic end generated code: output=fced3a624fb0c344 input=6786ac75f6b89de6]*/ { PyObject *m = PyType_GetModule(Py_TYPE(self)); - if (m == NULL) { - return NULL; - } + assert(m != NULL); if (!PyHKEY_Close(m, (PyObject *)self)) return NULL; Py_RETURN_NONE; From a06b9b5664cbab0cf8252054969ac04a61bf4a5b Mon Sep 17 00:00:00 2001 From: AN Long Date: Mon, 10 Apr 2023 17:36:06 +0800 Subject: [PATCH 18/33] Update PC/winreg.c Co-authored-by: Erlend E. Aasland --- PC/winreg.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/PC/winreg.c b/PC/winreg.c index f3ca0625203e3d..4e3ad06bfc0582 100644 --- a/PC/winreg.c +++ b/PC/winreg.c @@ -357,9 +357,7 @@ winreg_HKEYType___exit___impl(PyHKEYObject *self, PyObject *exc_type, /*[clinic end generated code: output=923ebe7389e6a263 input=fb32489ee92403c7]*/ { PyObject *m = PyType_GetModule(Py_TYPE(self)); - if (m == NULL) { - return NULL; - } + assert(m != NULL); if (!PyHKEY_Close(m, (PyObject *)self)) return NULL; Py_RETURN_NONE; From 0d7249a24177ec5192f867bb12598f21afd31d0f Mon Sep 17 00:00:00 2001 From: AN Long Date: Mon, 10 Apr 2023 17:36:43 +0800 Subject: [PATCH 19/33] Update PC/winreg.c Co-authored-by: Erlend E. Aasland --- PC/winreg.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/PC/winreg.c b/PC/winreg.c index 4e3ad06bfc0582..4f1dd662b0187b 100644 --- a/PC/winreg.c +++ b/PC/winreg.c @@ -495,7 +495,8 @@ PyHKEY_FromHKEY(PyObject *m, HKEY h) { winreg_state *st = _PyModule_GetState(m); - PyHKEYObject *op = (PyHKEYObject *) PyObject_GC_New(PyHKEYObject, st->PyHKEY_Type); + PyHKEYObject *op = (PyHKEYObject *)PyObject_GC_New(PyHKEYObject, + st->PyHKEY_Type); op->hkey = h; PyObject_GC_Track(op); return (PyObject *)op; From 488cae83c8f2b30cefdf35fc57777d1082b7a3e8 Mon Sep 17 00:00:00 2001 From: AN Long Date: Mon, 10 Apr 2023 17:37:05 +0800 Subject: [PATCH 20/33] Update PC/winreg.c Co-authored-by: Erlend E. Aasland --- PC/winreg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PC/winreg.c b/PC/winreg.c index 4f1dd662b0187b..67fe4c5fd5be8b 100644 --- a/PC/winreg.c +++ b/PC/winreg.c @@ -2202,7 +2202,7 @@ static PyModuleDef_Slot winreg_slots[] = { static winreg_traverse(PyObject* module, visitproc visit, void* arg) { - winreg_state *state = PyModule_GetState(module); + winreg_state *state = _PyModule_GetState(module); Py_VISIT(state->PyHKEY_Type); return 0; } From bbd1d6dfdde473846962e443ed97d6c3ffad338f Mon Sep 17 00:00:00 2001 From: AN Long Date: Mon, 10 Apr 2023 17:37:26 +0800 Subject: [PATCH 21/33] Update PC/winreg.c Co-authored-by: Erlend E. Aasland --- PC/winreg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PC/winreg.c b/PC/winreg.c index 67fe4c5fd5be8b..4f5ed4031ae77d 100644 --- a/PC/winreg.c +++ b/PC/winreg.c @@ -2209,7 +2209,7 @@ static winreg_traverse(PyObject* module, visitproc visit, void* arg) static winreg_clear(PyObject *module) { - winreg_state *state = PyModule_GetState(module); + winreg_state *state = _PyModule_GetState(module); Py_CLEAR(state->PyHKEY_Type); return 0; } From 45fedf69168bcf9a557bb81256df57f0bc2bde2b Mon Sep 17 00:00:00 2001 From: AN Long Date: Mon, 10 Apr 2023 17:37:46 +0800 Subject: [PATCH 22/33] Update PC/winreg.c Co-authored-by: Erlend E. Aasland --- PC/winreg.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/PC/winreg.c b/PC/winreg.c index 4f5ed4031ae77d..2174b81fbb35d0 100644 --- a/PC/winreg.c +++ b/PC/winreg.c @@ -2200,7 +2200,8 @@ static PyModuleDef_Slot winreg_slots[] = { {0, NULL} }; -static winreg_traverse(PyObject* module, visitproc visit, void* arg) +static int +winreg_traverse(PyObject *module, visitproc visit, void *arg) { winreg_state *state = _PyModule_GetState(module); Py_VISIT(state->PyHKEY_Type); From 964e1dd8d32c88f2febd65b31e62108094fa4c19 Mon Sep 17 00:00:00 2001 From: AN Long Date: Mon, 10 Apr 2023 17:38:05 +0800 Subject: [PATCH 23/33] Update PC/winreg.c Co-authored-by: Erlend E. Aasland --- PC/winreg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PC/winreg.c b/PC/winreg.c index 2174b81fbb35d0..8bb577b3ed9e4c 100644 --- a/PC/winreg.c +++ b/PC/winreg.c @@ -121,7 +121,7 @@ typedef struct { HKEY hkey; } PyHKEYObject; -#define PyHKEY_Check(m, op)\ +#define PyHKEY_Check(m, op) \ Py_IS_TYPE(op, ((winreg_state *)_PyModule_GetState(m))->PyHKEY_Type) static char *failMsg = "bad operand type"; From 16de5c6611bd36dbb7eb7b352c7374259462ec80 Mon Sep 17 00:00:00 2001 From: AN Long Date: Mon, 10 Apr 2023 17:39:45 +0800 Subject: [PATCH 24/33] Update PC/winreg.c Co-authored-by: Erlend E. Aasland --- PC/winreg.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/PC/winreg.c b/PC/winreg.c index 8bb577b3ed9e4c..5dd1d17421d057 100644 --- a/PC/winreg.c +++ b/PC/winreg.c @@ -2208,7 +2208,8 @@ winreg_traverse(PyObject *module, visitproc visit, void *arg) return 0; } -static winreg_clear(PyObject *module) +static int +winreg_clear(PyObject *module) { winreg_state *state = _PyModule_GetState(module); Py_CLEAR(state->PyHKEY_Type); From 0572407b748eafb88d9210309b6c5be5c2d5421f Mon Sep 17 00:00:00 2001 From: AN Long Date: Mon, 10 Apr 2023 17:41:06 +0800 Subject: [PATCH 25/33] Update PC/winreg.c Co-authored-by: Kirill <80244920+Eclips4@users.noreply.github.com> --- PC/winreg.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/PC/winreg.c b/PC/winreg.c index 5dd1d17421d057..7ea84100a4a1fb 100644 --- a/PC/winreg.c +++ b/PC/winreg.c @@ -2125,6 +2125,8 @@ exec_module(PyObject *m) d = PyModule_GetDict(m); st->PyHKEY_Type = (PyTypeObject *) PyType_FromModuleAndSpec(m, &pyhkey_type_spec, NULL); + if (st->PyHKEY_Type == NULL) + return -1; if (PyDict_SetItemString(d, "HKEYType", (PyObject *)st->PyHKEY_Type) != 0) return -1; From ae54a8e6ceee0bbc01223dcc8d0778b0ee356d6b Mon Sep 17 00:00:00 2001 From: AN Long Date: Mon, 10 Apr 2023 21:58:12 +0800 Subject: [PATCH 26/33] nit fixes --- Lib/test/test_winreg.py | 5 ++--- PC/winreg.c | 27 ++++++++++++++++++--------- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/Lib/test/test_winreg.py b/Lib/test/test_winreg.py index a85c583358a603..6b80a88d4907a7 100644 --- a/Lib/test/test_winreg.py +++ b/Lib/test/test_winreg.py @@ -3,11 +3,10 @@ import gc import os, sys, errno -import unittest -from test.support import cpython_only -from test.support import import_helper import threading +import unittest from platform import machine, win32_edition +from test.support import cpython_only import_helper # Do this first so test will be skipped if module doesn't exist import_helper.import_module('winreg', required_on=['win']) diff --git a/PC/winreg.c b/PC/winreg.c index 7ea84100a4a1fb..8435df24061cb7 100644 --- a/PC/winreg.c +++ b/PC/winreg.c @@ -299,8 +299,9 @@ winreg_HKEYType_Close_impl(PyHKEYObject *self) { PyObject *m = PyType_GetModule(Py_TYPE(self)); assert(m != NULL); - if (!PyHKEY_Close(m, (PyObject *)self)) + if (!PyHKEY_Close(m, (PyObject *)self)) { return NULL; + } Py_RETURN_NONE; } @@ -358,8 +359,9 @@ winreg_HKEYType___exit___impl(PyHKEYObject *self, PyObject *exc_type, { PyObject *m = PyType_GetModule(Py_TYPE(self)); assert(m != NULL); - if (!PyHKEY_Close(m, (PyObject *)self)) + if (!PyHKEY_Close(m, (PyObject *)self)) { return NULL; + } Py_RETURN_NONE; } @@ -426,8 +428,10 @@ PyHKEY_New(PyObject *m, HKEY hInit) { winreg_state *st = _PyModule_GetState(m); PyHKEYObject *key = PyObject_GC_New(PyHKEYObject, st->PyHKEY_Type); - if (key) - key->hkey = hInit; + if (key == NULL) { + return NULL; + } + key->hkey = hInit; PyObject_GC_Track(key); return (PyObject *)key; } @@ -485,8 +489,9 @@ PyHKEY_AsHKEY(PyObject *m, PyObject *ob, HKEY *pHANDLE, BOOL bNoneOK) BOOL clinic_HKEY_converter(PyObject *m, PyObject *ob, void *p) { - if (!PyHKEY_AsHKEY(m, ob, (HKEY *)p, FALSE)) + if (!PyHKEY_AsHKEY(m, ob, (HKEY *)p, FALSE)) { return FALSE; + } return TRUE; } @@ -861,8 +866,9 @@ static PyObject * winreg_CloseKey(PyObject *module, PyObject *hkey) /*[clinic end generated code: output=a4fa537019a80d15 input=5b1aac65ba5127ad]*/ { - if (!PyHKEY_Close(module, hkey)) + if (!PyHKEY_Close(module, hkey)) { return NULL; + } Py_RETURN_NONE; } @@ -2125,14 +2131,17 @@ exec_module(PyObject *m) d = PyModule_GetDict(m); st->PyHKEY_Type = (PyTypeObject *) PyType_FromModuleAndSpec(m, &pyhkey_type_spec, NULL); - if (st->PyHKEY_Type == NULL) + if (st->PyHKEY_Type == NULL) { return -1; + } if (PyDict_SetItemString(d, "HKEYType", - (PyObject *)st->PyHKEY_Type) != 0) + (PyObject *)st->PyHKEY_Type) != 0) { return -1; + } if (PyDict_SetItemString(d, "error", - PyExc_OSError) != 0) + PyExc_OSError) != 0) { return -1; + } /* Add the relevant constants */ ADD_KEY(HKEY_CLASSES_ROOT); From 42bcb444e7b91eae68483f51e516e491014d2682 Mon Sep 17 00:00:00 2001 From: AN Long Date: Mon, 10 Apr 2023 22:29:51 +0800 Subject: [PATCH 27/33] fix syntax error --- Lib/test/test_winreg.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_winreg.py b/Lib/test/test_winreg.py index 6b80a88d4907a7..924a962781a75b 100644 --- a/Lib/test/test_winreg.py +++ b/Lib/test/test_winreg.py @@ -6,7 +6,7 @@ import threading import unittest from platform import machine, win32_edition -from test.support import cpython_only import_helper +from test.support import cpython_only, import_helper # Do this first so test will be skipped if module doesn't exist import_helper.import_module('winreg', required_on=['win']) From 1998c06f85644dbb421b27e7a69949b157435985 Mon Sep 17 00:00:00 2001 From: AN Long Date: Tue, 11 Apr 2023 00:24:46 +0800 Subject: [PATCH 28/33] passing state instead of module in c level module functions --- PC/clinic/winreg.c.h | 54 +++++++++++++++++------------------ PC/winreg.c | 67 +++++++++++++++++++++----------------------- 2 files changed, 59 insertions(+), 62 deletions(-) diff --git a/PC/clinic/winreg.c.h b/PC/clinic/winreg.c.h index e24f7d3d003fee..4109c85276f0a4 100644 --- a/PC/clinic/winreg.c.h +++ b/PC/clinic/winreg.c.h @@ -219,14 +219,14 @@ winreg_ConnectRegistry(PyObject *module, PyObject *const *args, Py_ssize_t nargs _PyArg_BadArgument("ConnectRegistry", "argument 1", "str or None", args[0]); goto exit; } - if (!clinic_HKEY_converter(module, args[1], &key)) { + if (!clinic_HKEY_converter(_PyModule_GetState(module), args[1], &key)) { goto exit; } _return_value = winreg_ConnectRegistry_impl(module, computer_name, key); if (_return_value == NULL) { goto exit; } - return_value = PyHKEY_FromHKEY(module, _return_value); + return_value = PyHKEY_FromHKEY(_PyModule_GetState(module), _return_value); exit: /* Cleanup for computer_name */ @@ -275,7 +275,7 @@ winreg_CreateKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("CreateKey", nargs, 2, 2)) { goto exit; } - if (!clinic_HKEY_converter(module, args[0], &key)) { + if (!clinic_HKEY_converter(_PyModule_GetState(module), args[0], &key)) { goto exit; } if (args[1] == Py_None) { @@ -295,7 +295,7 @@ winreg_CreateKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (_return_value == NULL) { goto exit; } - return_value = PyHKEY_FromHKEY(module, _return_value); + return_value = PyHKEY_FromHKEY(_PyModule_GetState(module), _return_value); exit: /* Cleanup for sub_key */ @@ -382,7 +382,7 @@ winreg_CreateKeyEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs, Py if (!args) { goto exit; } - if (!clinic_HKEY_converter(module, args[0], &key)) { + if (!clinic_HKEY_converter(_PyModule_GetState(module), args[0], &key)) { goto exit; } if (args[1] == Py_None) { @@ -419,7 +419,7 @@ winreg_CreateKeyEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs, Py if (_return_value == NULL) { goto exit; } - return_value = PyHKEY_FromHKEY(module, _return_value); + return_value = PyHKEY_FromHKEY(_PyModule_GetState(module), _return_value); exit: /* Cleanup for sub_key */ @@ -466,7 +466,7 @@ winreg_DeleteKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("DeleteKey", nargs, 2, 2)) { goto exit; } - if (!clinic_HKEY_converter(module, args[0], &key)) { + if (!clinic_HKEY_converter(_PyModule_GetState(module), args[0], &key)) { goto exit; } if (!PyUnicode_Check(args[1])) { @@ -566,7 +566,7 @@ winreg_DeleteKeyEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs, Py if (!args) { goto exit; } - if (!clinic_HKEY_converter(module, args[0], &key)) { + if (!clinic_HKEY_converter(_PyModule_GetState(module), args[0], &key)) { goto exit; } if (!PyUnicode_Check(args[1])) { @@ -634,7 +634,7 @@ winreg_DeleteValue(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("DeleteValue", nargs, 2, 2)) { goto exit; } - if (!clinic_HKEY_converter(module, args[0], &key)) { + if (!clinic_HKEY_converter(_PyModule_GetState(module), args[0], &key)) { goto exit; } if (args[1] == Py_None) { @@ -694,7 +694,7 @@ winreg_EnumKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("EnumKey", nargs, 2, 2)) { goto exit; } - if (!clinic_HKEY_converter(module, args[0], &key)) { + if (!clinic_HKEY_converter(_PyModule_GetState(module), args[0], &key)) { goto exit; } index = _PyLong_AsInt(args[1]); @@ -751,7 +751,7 @@ winreg_EnumValue(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("EnumValue", nargs, 2, 2)) { goto exit; } - if (!clinic_HKEY_converter(module, args[0], &key)) { + if (!clinic_HKEY_converter(_PyModule_GetState(module), args[0], &key)) { goto exit; } index = _PyLong_AsInt(args[1]); @@ -839,7 +839,7 @@ winreg_FlushKey(PyObject *module, PyObject *arg) PyObject *return_value = NULL; HKEY key; - if (!clinic_HKEY_converter(module, arg, &key)) { + if (!clinic_HKEY_converter(_PyModule_GetState(module), arg, &key)) { goto exit; } return_value = winreg_FlushKey_impl(module, key); @@ -898,7 +898,7 @@ winreg_LoadKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("LoadKey", nargs, 3, 3)) { goto exit; } - if (!clinic_HKEY_converter(module, args[0], &key)) { + if (!clinic_HKEY_converter(_PyModule_GetState(module), args[0], &key)) { goto exit; } if (!PyUnicode_Check(args[1])) { @@ -999,7 +999,7 @@ winreg_OpenKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje if (!args) { goto exit; } - if (!clinic_HKEY_converter(module, args[0], &key)) { + if (!clinic_HKEY_converter(_PyModule_GetState(module), args[0], &key)) { goto exit; } if (args[1] == Py_None) { @@ -1036,7 +1036,7 @@ winreg_OpenKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje if (_return_value == NULL) { goto exit; } - return_value = PyHKEY_FromHKEY(module, _return_value); + return_value = PyHKEY_FromHKEY(_PyModule_GetState(module), _return_value); exit: /* Cleanup for sub_key */ @@ -1116,7 +1116,7 @@ winreg_OpenKeyEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyOb if (!args) { goto exit; } - if (!clinic_HKEY_converter(module, args[0], &key)) { + if (!clinic_HKEY_converter(_PyModule_GetState(module), args[0], &key)) { goto exit; } if (args[1] == Py_None) { @@ -1153,7 +1153,7 @@ winreg_OpenKeyEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyOb if (_return_value == NULL) { goto exit; } - return_value = PyHKEY_FromHKEY(module, _return_value); + return_value = PyHKEY_FromHKEY(_PyModule_GetState(module), _return_value); exit: /* Cleanup for sub_key */ @@ -1193,7 +1193,7 @@ winreg_QueryInfoKey(PyObject *module, PyObject *arg) PyObject *return_value = NULL; HKEY key; - if (!clinic_HKEY_converter(module, arg, &key)) { + if (!clinic_HKEY_converter(_PyModule_GetState(module), arg, &key)) { goto exit; } return_value = winreg_QueryInfoKey_impl(module, key); @@ -1242,7 +1242,7 @@ winreg_QueryValue(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("QueryValue", nargs, 2, 2)) { goto exit; } - if (!clinic_HKEY_converter(module, args[0], &key)) { + if (!clinic_HKEY_converter(_PyModule_GetState(module), args[0], &key)) { goto exit; } if (args[1] == Py_None) { @@ -1303,7 +1303,7 @@ winreg_QueryValueEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("QueryValueEx", nargs, 2, 2)) { goto exit; } - if (!clinic_HKEY_converter(module, args[0], &key)) { + if (!clinic_HKEY_converter(_PyModule_GetState(module), args[0], &key)) { goto exit; } if (args[1] == Py_None) { @@ -1369,7 +1369,7 @@ winreg_SaveKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("SaveKey", nargs, 2, 2)) { goto exit; } - if (!clinic_HKEY_converter(module, args[0], &key)) { + if (!clinic_HKEY_converter(_PyModule_GetState(module), args[0], &key)) { goto exit; } if (!PyUnicode_Check(args[1])) { @@ -1438,7 +1438,7 @@ winreg_SetValue(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("SetValue", nargs, 4, 4)) { goto exit; } - if (!clinic_HKEY_converter(module, args[0], &key)) { + if (!clinic_HKEY_converter(_PyModule_GetState(module), args[0], &key)) { goto exit; } if (args[1] == Py_None) { @@ -1542,7 +1542,7 @@ winreg_SetValueEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("SetValueEx", nargs, 5, 5)) { goto exit; } - if (!clinic_HKEY_converter(module, args[0], &key)) { + if (!clinic_HKEY_converter(_PyModule_GetState(module), args[0], &key)) { goto exit; } if (args[1] == Py_None) { @@ -1603,7 +1603,7 @@ winreg_DisableReflectionKey(PyObject *module, PyObject *arg) PyObject *return_value = NULL; HKEY key; - if (!clinic_HKEY_converter(module, arg, &key)) { + if (!clinic_HKEY_converter(_PyModule_GetState(module), arg, &key)) { goto exit; } return_value = winreg_DisableReflectionKey_impl(module, key); @@ -1641,7 +1641,7 @@ winreg_EnableReflectionKey(PyObject *module, PyObject *arg) PyObject *return_value = NULL; HKEY key; - if (!clinic_HKEY_converter(module, arg, &key)) { + if (!clinic_HKEY_converter(_PyModule_GetState(module), arg, &key)) { goto exit; } return_value = winreg_EnableReflectionKey_impl(module, key); @@ -1677,7 +1677,7 @@ winreg_QueryReflectionKey(PyObject *module, PyObject *arg) PyObject *return_value = NULL; HKEY key; - if (!clinic_HKEY_converter(module, arg, &key)) { + if (!clinic_HKEY_converter(_PyModule_GetState(module), arg, &key)) { goto exit; } return_value = winreg_QueryReflectionKey_impl(module, key); @@ -1795,4 +1795,4 @@ winreg_QueryReflectionKey(PyObject *module, PyObject *arg) #ifndef WINREG_QUERYREFLECTIONKEY_METHODDEF #define WINREG_QUERYREFLECTIONKEY_METHODDEF #endif /* !defined(WINREG_QUERYREFLECTIONKEY_METHODDEF) */ -/*[clinic end generated code: output=ad8592b2d01094e7 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=15dc2e6c4d4e2ad5 input=a9049054013a1b77]*/ diff --git a/PC/winreg.c b/PC/winreg.c index 8435df24061cb7..2f548ca991f7f1 100644 --- a/PC/winreg.c +++ b/PC/winreg.c @@ -21,10 +21,16 @@ #if defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) || defined(MS_WINDOWS_GAMES) -static BOOL PyHKEY_AsHKEY(PyObject *m, PyObject *ob, HKEY *pRes, BOOL bNoneOK); -static BOOL clinic_HKEY_converter(PyObject *m, PyObject *ob, void *p); -static PyObject *PyHKEY_FromHKEY(PyObject *m, HKEY h); -static BOOL PyHKEY_Close(PyObject *m, PyObject *obHandle); +typedef struct { + PyTypeObject *PyHKEY_Type; +} winreg_state; + +/* Forward declares */ + +static BOOL PyHKEY_AsHKEY(winreg_state *st, PyObject *ob, HKEY *pRes, BOOL bNoneOK); +static BOOL clinic_HKEY_converter(winreg_state *st, PyObject *ob, void *p); +static PyObject *PyHKEY_FromHKEY(winreg_state *st, HKEY h); +static BOOL PyHKEY_Close(winreg_state *st, PyObject *obHandle); static struct PyModuleDef winregmodule; @@ -38,12 +44,6 @@ static char errNotAHandle[] = "Object is not a handle"; #define PyErr_SetFromWindowsErrWithFunction(rc, fnname) \ PyErr_SetFromWindowsErr(rc) -/* Forward declares */ - -typedef struct { - PyTypeObject *PyHKEY_Type; -} winreg_state; - /* Doc strings */ PyDoc_STRVAR(module_doc, "This module provides access to the Windows registry API.\n" @@ -121,8 +121,7 @@ typedef struct { HKEY hkey; } PyHKEYObject; -#define PyHKEY_Check(m, op) \ - Py_IS_TYPE(op, ((winreg_state *)_PyModule_GetState(m))->PyHKEY_Type) +#define PyHKEY_Check(st, op) Py_IS_TYPE(op, st->PyHKEY_Type) static char *failMsg = "bad operand type"; @@ -250,7 +249,7 @@ class HKEY_converter(CConverter): def parse_arg(self, argname, displayname): return """ - if (!{converter}(module, {argname}, &{paramname})) {{{{ + if (!{converter}(_PyModule_GetState(module), {argname}, &{paramname})) {{{{ goto exit; }}}} """.format(argname=argname, paramname=self.parser_name, @@ -263,7 +262,7 @@ class HKEY_return_converter(CReturnConverter): self.declare(data) self.err_occurred_if_null_pointer("_return_value", data) data.return_conversion.append( - 'return_value = PyHKEY_FromHKEY(module, _return_value);\n') + 'return_value = PyHKEY_FromHKEY(_PyModule_GetState(module), _return_value);\n') # HACK: this only works for PyHKEYObjects, nothing else. # Should this be generalized and enshrined in clinic.py, @@ -276,7 +275,7 @@ class self_return_converter(CReturnConverter): data.return_conversion.append( 'return_value = (PyObject *)_return_value;\n') [python start generated code]*/ -/*[python end generated code: output=da39a3ee5e6b4b0d input=1bf6a0ebbb134810]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=17e645060c7b8ae1]*/ #include "clinic/winreg.c.h" @@ -297,9 +296,9 @@ static PyObject * winreg_HKEYType_Close_impl(PyHKEYObject *self) /*[clinic end generated code: output=fced3a624fb0c344 input=6786ac75f6b89de6]*/ { - PyObject *m = PyType_GetModule(Py_TYPE(self)); - assert(m != NULL); - if (!PyHKEY_Close(m, (PyObject *)self)) { + winreg_state *st = _PyType_GetModuleState(Py_TYPE(self)); + assert(st != NULL); + if (!PyHKEY_Close(st, (PyObject *)self)) { return NULL; } Py_RETURN_NONE; @@ -357,9 +356,9 @@ winreg_HKEYType___exit___impl(PyHKEYObject *self, PyObject *exc_type, PyObject *exc_value, PyObject *traceback) /*[clinic end generated code: output=923ebe7389e6a263 input=fb32489ee92403c7]*/ { - PyObject *m = PyType_GetModule(Py_TYPE(self)); - assert(m != NULL); - if (!PyHKEY_Close(m, (PyObject *)self)) { + winreg_state *st = _PyType_GetModuleState(Py_TYPE(self)); + assert(st != NULL); + if (!PyHKEY_Close(st, (PyObject *)self)) { return NULL; } Py_RETURN_NONE; @@ -437,15 +436,15 @@ PyHKEY_New(PyObject *m, HKEY hInit) } BOOL -PyHKEY_Close(PyObject *m, PyObject *ob_handle) +PyHKEY_Close(winreg_state *st, PyObject *ob_handle) { LONG rc; HKEY key; - if (!PyHKEY_AsHKEY(m, ob_handle, &key, TRUE)) { + if (!PyHKEY_AsHKEY(st, ob_handle, &key, TRUE)) { return FALSE; } - if (PyHKEY_Check(m, ob_handle)) { + if (PyHKEY_Check(st, ob_handle)) { ((PyHKEYObject*)ob_handle)->hkey = 0; } rc = key ? RegCloseKey(key) : ERROR_SUCCESS; @@ -455,7 +454,7 @@ PyHKEY_Close(PyObject *m, PyObject *ob_handle) } BOOL -PyHKEY_AsHKEY(PyObject *m, PyObject *ob, HKEY *pHANDLE, BOOL bNoneOK) +PyHKEY_AsHKEY(winreg_state *st, PyObject *ob, HKEY *pHANDLE, BOOL bNoneOK) { if (ob == Py_None) { if (!bNoneOK) { @@ -466,7 +465,7 @@ PyHKEY_AsHKEY(PyObject *m, PyObject *ob, HKEY *pHANDLE, BOOL bNoneOK) } *pHANDLE = (HKEY)0; } - else if (PyHKEY_Check(m ,ob)) { + else if (PyHKEY_Check(st ,ob)) { PyHKEYObject *pH = (PyHKEYObject *)ob; *pHANDLE = pH->hkey; } @@ -487,19 +486,17 @@ PyHKEY_AsHKEY(PyObject *m, PyObject *ob, HKEY *pHANDLE, BOOL bNoneOK) } BOOL -clinic_HKEY_converter(PyObject *m, PyObject *ob, void *p) +clinic_HKEY_converter(winreg_state *st, PyObject *ob, void *p) { - if (!PyHKEY_AsHKEY(m, ob, (HKEY *)p, FALSE)) { + if (!PyHKEY_AsHKEY(st, ob, (HKEY *)p, FALSE)) { return FALSE; } return TRUE; } PyObject * -PyHKEY_FromHKEY(PyObject *m, HKEY h) +PyHKEY_FromHKEY(winreg_state *st, HKEY h) { - winreg_state *st = _PyModule_GetState(m); - PyHKEYObject *op = (PyHKEYObject *)PyObject_GC_New(PyHKEYObject, st->PyHKEY_Type); op->hkey = h; @@ -512,11 +509,11 @@ PyHKEY_FromHKEY(PyObject *m, HKEY h) The module methods ************************************************************************/ BOOL -PyWinObject_CloseHKEY(PyObject *m, PyObject *obHandle) +PyWinObject_CloseHKEY(winreg_state *st, PyObject *obHandle) { BOOL ok; - if (PyHKEY_Check(m, obHandle)) { - ok = PyHKEY_Close(m, obHandle); + if (PyHKEY_Check(st, obHandle)) { + ok = PyHKEY_Close(st, obHandle); } #if SIZEOF_LONG >= SIZEOF_HKEY else if (PyLong_Check(obHandle)) { @@ -866,7 +863,7 @@ static PyObject * winreg_CloseKey(PyObject *module, PyObject *hkey) /*[clinic end generated code: output=a4fa537019a80d15 input=5b1aac65ba5127ad]*/ { - if (!PyHKEY_Close(module, hkey)) { + if (!PyHKEY_Close(_PyModule_GetState(module), hkey)) { return NULL; } Py_RETURN_NONE; From 682c419bf687dad1d5717b2a712eebe1017abcc2 Mon Sep 17 00:00:00 2001 From: AN Long Date: Tue, 11 Apr 2023 23:14:28 +0800 Subject: [PATCH 29/33] Update PC/winreg.c Co-authored-by: Erlend E. Aasland --- PC/winreg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PC/winreg.c b/PC/winreg.c index 2f548ca991f7f1..50f3f7f129c77b 100644 --- a/PC/winreg.c +++ b/PC/winreg.c @@ -412,7 +412,7 @@ static PyType_Slot pyhkey_type_slots[] = { }; static PyType_Spec pyhkey_type_spec = { - .name = "winreg.PYHkey", + .name = "winreg.PyHKEY", .basicsize = sizeof(PyHKEYObject), .flags = (Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_DISALLOW_INSTANTIATION), From 8b1aaa4b442d0cfe77f1c102878bb9e8967f7995 Mon Sep 17 00:00:00 2001 From: AN Long Date: Tue, 11 Apr 2023 23:21:32 +0800 Subject: [PATCH 30/33] check result of gc new --- PC/winreg.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/PC/winreg.c b/PC/winreg.c index 50f3f7f129c77b..7d0e0dc0c23aa2 100644 --- a/PC/winreg.c +++ b/PC/winreg.c @@ -499,6 +499,9 @@ PyHKEY_FromHKEY(winreg_state *st, HKEY h) { PyHKEYObject *op = (PyHKEYObject *)PyObject_GC_New(PyHKEYObject, st->PyHKEY_Type); + if (op == NULL) { + return NULL; + } op->hkey = h; PyObject_GC_Track(op); return (PyObject *)op; From 3ecc718b4c2b41fa6300080373c4f14ee7e37c01 Mon Sep 17 00:00:00 2001 From: AN Long Date: Wed, 12 Apr 2023 20:35:30 +0800 Subject: [PATCH 31/33] Update PC/winreg.c Co-authored-by: Erlend E. Aasland --- PC/winreg.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/PC/winreg.c b/PC/winreg.c index 698714f7293d90..e496541e0ee0a8 100644 --- a/PC/winreg.c +++ b/PC/winreg.c @@ -390,6 +390,8 @@ static PyType_Slot pyhkey_type_slots[] = { {Py_tp_traverse, PyHKEY_traverseFunc}, {Py_tp_hash, PyHKEY_hashFunc}, {Py_tp_str, PyHKEY_strFunc}, + + // Number protocol {Py_nb_add, PyHKEY_binaryFailureFunc}, {Py_nb_subtract, PyHKEY_binaryFailureFunc}, {Py_nb_multiply, PyHKEY_binaryFailureFunc}, From e279c844ef460a44352a36326af3af09b655027a Mon Sep 17 00:00:00 2001 From: AN Long Date: Wed, 12 Apr 2023 20:38:23 +0800 Subject: [PATCH 32/33] remove unused PyHKEY_NumberMethods --- PC/winreg.c | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/PC/winreg.c b/PC/winreg.c index e496541e0ee0a8..7dca094ea82c5a 100644 --- a/PC/winreg.c +++ b/PC/winreg.c @@ -207,29 +207,6 @@ PyHKEY_hashFunc(PyObject *ob) } -static PyNumberMethods PyHKEY_NumberMethods = -{ - PyHKEY_binaryFailureFunc, /* nb_add */ - PyHKEY_binaryFailureFunc, /* nb_subtract */ - PyHKEY_binaryFailureFunc, /* nb_multiply */ - PyHKEY_binaryFailureFunc, /* nb_remainder */ - PyHKEY_binaryFailureFunc, /* nb_divmod */ - PyHKEY_ternaryFailureFunc, /* nb_power */ - PyHKEY_unaryFailureFunc, /* nb_negative */ - PyHKEY_unaryFailureFunc, /* nb_positive */ - PyHKEY_unaryFailureFunc, /* nb_absolute */ - PyHKEY_boolFunc, /* nb_bool */ - PyHKEY_unaryFailureFunc, /* nb_invert */ - PyHKEY_binaryFailureFunc, /* nb_lshift */ - PyHKEY_binaryFailureFunc, /* nb_rshift */ - PyHKEY_binaryFailureFunc, /* nb_and */ - PyHKEY_binaryFailureFunc, /* nb_xor */ - PyHKEY_binaryFailureFunc, /* nb_or */ - PyHKEY_intFunc, /* nb_int */ - 0, /* nb_reserved */ - PyHKEY_unaryFailureFunc, /* nb_float */ -}; - /*[clinic input] module winreg class winreg.HKEYType "PyHKEYObject *" "&PyHKEY_Type" From d7f97fc98b349fc7331d8440853088806e28e4ee Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Thu, 13 Apr 2023 14:41:01 +0200 Subject: [PATCH 33/33] Update PC/winreg.c --- PC/winreg.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/PC/winreg.c b/PC/winreg.c index 7dca094ea82c5a..4884125c3609ad 100644 --- a/PC/winreg.c +++ b/PC/winreg.c @@ -32,8 +32,6 @@ static BOOL clinic_HKEY_converter(winreg_state *st, PyObject *ob, void *p); static PyObject *PyHKEY_FromHKEY(winreg_state *st, HKEY h); static BOOL PyHKEY_Close(winreg_state *st, PyObject *obHandle); -static struct PyModuleDef winregmodule; - static char errNotAHandle[] = "Object is not a handle"; /* The win32api module reports the function name that failed,