From 1771b54bed1faa2d8216d3d9d76d3f604e93336d Mon Sep 17 00:00:00 2001 From: Brian Curtin Date: Mon, 27 Sep 2010 17:56:36 +0000 Subject: Implement #8521. Added named argument handling to winreg's CreateKeyEx, DeleteKeyEx, and OpenKeyEx. Note that CKE and DKE are new functions for 3.2 so I didn't give them a versionchanged because of the existing versionadded. OpenKeyEx already existed so it gets a versionchanged tag. --- Doc/library/winreg.rst | 8 ++++-- Lib/test/test_winreg.py | 22 ++++++++++++++ Misc/NEWS | 3 ++ PC/winreg.c | 76 ++++++++++++++++++++++++++++--------------------- 4 files changed, 73 insertions(+), 36 deletions(-) diff --git a/Doc/library/winreg.rst b/Doc/library/winreg.rst index 9bd12ed..5cf30ee 100644 --- a/Doc/library/winreg.rst +++ b/Doc/library/winreg.rst @@ -60,7 +60,7 @@ This module offers the following functions: :exc:`WindowsError` exception is raised. -.. function:: CreateKeyEx(key, sub_key[, res[, sam]]) +.. function:: CreateKeyEx(key, sub_key, reserved=0, access=KEY_ALL_ACCESS) Creates or opens the specified key, returning a :ref:`handle object `. @@ -103,7 +103,7 @@ This module offers the following functions: If the method fails, a :exc:`WindowsError` exception is raised. -.. function:: DeleteKeyEx(key, sub_key[, sam[, res]]) +.. function:: DeleteKeyEx(key, sub_key, access=KEY_ALL_ACCESS, reserved=0) Deletes the specified key. @@ -243,7 +243,7 @@ This module offers the following functions: specified in *file_name* is relative to the remote computer. -.. function:: OpenKey(key, sub_key[, res[, sam]]) +.. function:: OpenKey(key, sub_key, reserved=0, access=KEY_ALL_ACCESS) Opens the specified key, returning a :ref:`handle object `. @@ -262,6 +262,8 @@ This module offers the following functions: If the function fails, :exc:`WindowsError` is raised. + .. versionchanged:: 3.2 Allow the use of named arguments. + .. function:: OpenKeyEx() diff --git a/Lib/test/test_winreg.py b/Lib/test/test_winreg.py index c5ee846..4757038 100644 --- a/Lib/test/test_winreg.py +++ b/Lib/test/test_winreg.py @@ -185,6 +185,16 @@ class BaseWinregTests(unittest.TestCase): self._read_test_data(root_key, subkeystr) self._delete_test_data(root_key, subkeystr) + def _test_named_args(self, key, sub_key): + with CreateKeyEx(key=key, sub_key=sub_key, reserved=0, + access=KEY_ALL_ACCESS) as ckey: + self.assertTrue(ckey.handle != 0) + + with OpenKeyEx(key=key, sub_key=sub_key, reserved=0, + access=KEY_ALL_ACCESS) as okey: + self.assertTrue(okey.handle != 0) + + class LocalWinregTests(BaseWinregTests): def test_registry_works(self): @@ -203,6 +213,12 @@ class LocalWinregTests(BaseWinregTests): self._delete_test_data(HKEY_CURRENT_USER) + def test_named_arguments(self): + self._test_named_args(HKEY_CURRENT_USER, test_key_name) + # Use the regular DeleteKey to clean up + # DeleteKeyEx takes named args and is tested separately + DeleteKey(HKEY_CURRENT_USER, test_key_name) + def test_connect_registry_to_local_machine_works(self): # perform minimal ConnectRegistry test which just invokes it h = ConnectRegistry(None, HKEY_LOCAL_MACHINE) @@ -314,6 +330,12 @@ class RemoteWinregTests(BaseWinregTests): @unittest.skipUnless(WIN64_MACHINE, "x64 specific registry tests") class Win64WinregTests(BaseWinregTests): + def test_named_arguments(self): + self._test_named_args(HKEY_CURRENT_USER, test_key_name) + # Clean up and also exercise the named arguments + DeleteKeyEx(key=HKEY_CURRENT_USER, sub_key=test_key_name, + access=KEY_ALL_ACCESS, reserved=0) + def test_reflection_functions(self): # Test that we can call the query, enable, and disable functions # on a key which isn't on the reflection list with no consequences. diff --git a/Misc/NEWS b/Misc/NEWS index 2fb3b95..4bfd534 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,9 @@ What's New in Python 3.2 Alpha 3? Core and Builtins ----------------- +- Issue #8521: Allow CreateKeyEx, OpenKeyEx, and DeleteKeyEx functions + of winreg to use named arguments. + - Issue #9930: Remove bogus subtype check that was causing (e.g.) float.__rdiv__(2.0, 3) to return NotImplemented instead of the expected 1.5. diff --git a/PC/winreg.c b/PC/winreg.c index 390a9ce..c283b44 100644 --- a/PC/winreg.c +++ b/PC/winreg.c @@ -989,23 +989,26 @@ PyCreateKey(PyObject *self, PyObject *args) } static PyObject * -PyCreateKeyEx(PyObject *self, PyObject *args) +PyCreateKeyEx(PyObject *self, PyObject *args, PyObject *kwargs) { HKEY hKey; - PyObject *obKey; - wchar_t *subKey; + PyObject *key; + wchar_t *sub_key; HKEY retKey; - int res = 0; - REGSAM sam = KEY_WRITE; + int reserved = 0; + REGSAM access = KEY_WRITE; long rc; - if (!PyArg_ParseTuple(args, "OZ|ii:CreateKeyEx", &obKey, &subKey, - &res, &sam)) + + char *kwlist[] = {"key", "sub_key", "reserved", "access", NULL}; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OZ|ii:CreateKeyEx", kwlist, + &key, &sub_key, &reserved, &access)) return NULL; - if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE)) + if (!PyHKEY_AsHKEY(key, &hKey, FALSE)) return NULL; - rc = RegCreateKeyExW(hKey, subKey, res, NULL, (DWORD)NULL, - sam, NULL, &retKey, NULL); + rc = RegCreateKeyExW(hKey, sub_key, reserved, NULL, (DWORD)NULL, + access, NULL, &retKey, NULL); if (rc != ERROR_SUCCESS) return PyErr_SetFromWindowsErrWithFunction(rc, "CreateKeyEx"); return PyHKEY_FromHKEY(retKey); @@ -1030,22 +1033,23 @@ PyDeleteKey(PyObject *self, PyObject *args) } static PyObject * -PyDeleteKeyEx(PyObject *self, PyObject *args) +PyDeleteKeyEx(PyObject *self, PyObject *args, PyObject *kwargs) { HKEY hKey; - PyObject *obKey; + PyObject *key; HMODULE hMod; typedef LONG (WINAPI *RDKEFunc)(HKEY, const wchar_t*, REGSAM, int); RDKEFunc pfn = NULL; - wchar_t *subKey; + wchar_t *sub_key; long rc; - int res = 0; - REGSAM sam = KEY_WOW64_64KEY; + int reserved = 0; + REGSAM access = KEY_WOW64_64KEY; - if (!PyArg_ParseTuple(args, "Ou|ii:DeleteKeyEx", - &obKey, &subKey, &sam, &res)) + char *kwlist[] = {"key", "sub_key", "access", "reserved", NULL}; + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Ou|ii:DeleteKeyEx", kwlist, + &key, &sub_key, &access, &reserved)) return NULL; - if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE)) + if (!PyHKEY_AsHKEY(key, &hKey, FALSE)) return NULL; /* Only available on 64bit platforms, so we must load it @@ -1060,7 +1064,7 @@ PyDeleteKeyEx(PyObject *self, PyObject *args) return NULL; } Py_BEGIN_ALLOW_THREADS - rc = (*pfn)(hKey, subKey, sam, res); + rc = (*pfn)(hKey, sub_key, access, reserved); Py_END_ALLOW_THREADS if (rc != ERROR_SUCCESS) @@ -1282,24 +1286,26 @@ PyLoadKey(PyObject *self, PyObject *args) } static PyObject * -PyOpenKey(PyObject *self, PyObject *args) +PyOpenKey(PyObject *self, PyObject *args, PyObject *kwargs) { HKEY hKey; - PyObject *obKey; - - wchar_t *subKey; - int res = 0; + PyObject *key; + wchar_t *sub_key; + int reserved = 0; HKEY retKey; long rc; - REGSAM sam = KEY_READ; - if (!PyArg_ParseTuple(args, "OZ|ii:OpenKey", &obKey, &subKey, - &res, &sam)) + REGSAM access = KEY_READ; + + char *kwlist[] = {"key", "sub_key", "reserved", "access", NULL}; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OZ|ii:OpenKey", kwlist, + &key, &sub_key, &reserved, &access)) return NULL; - if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE)) + if (!PyHKEY_AsHKEY(key, &hKey, FALSE)) return NULL; Py_BEGIN_ALLOW_THREADS - rc = RegOpenKeyExW(hKey, subKey, res, sam, &retKey); + rc = RegOpenKeyExW(hKey, sub_key, reserved, access, &retKey); Py_END_ALLOW_THREADS if (rc != ERROR_SUCCESS) return PyErr_SetFromWindowsErrWithFunction(rc, "RegOpenKeyEx"); @@ -1667,9 +1673,11 @@ static struct PyMethodDef winreg_methods[] = { {"CloseKey", PyCloseKey, METH_VARARGS, CloseKey_doc}, {"ConnectRegistry", PyConnectRegistry, METH_VARARGS, ConnectRegistry_doc}, {"CreateKey", PyCreateKey, METH_VARARGS, CreateKey_doc}, - {"CreateKeyEx", PyCreateKeyEx, METH_VARARGS, CreateKeyEx_doc}, + {"CreateKeyEx", (PyCFunction)PyCreateKeyEx, + METH_VARARGS | METH_KEYWORDS, CreateKeyEx_doc}, {"DeleteKey", PyDeleteKey, METH_VARARGS, DeleteKey_doc}, - {"DeleteKeyEx", PyDeleteKeyEx, METH_VARARGS, DeleteKeyEx_doc}, + {"DeleteKeyEx", (PyCFunction)PyDeleteKeyEx, + METH_VARARGS | METH_KEYWORDS, DeleteKeyEx_doc}, {"DeleteValue", PyDeleteValue, METH_VARARGS, DeleteValue_doc}, {"DisableReflectionKey", PyDisableReflectionKey, METH_VARARGS, DisableReflectionKey_doc}, {"EnableReflectionKey", PyEnableReflectionKey, METH_VARARGS, EnableReflectionKey_doc}, @@ -1679,8 +1687,10 @@ static struct PyMethodDef winreg_methods[] = { ExpandEnvironmentStrings_doc }, {"FlushKey", PyFlushKey, METH_VARARGS, FlushKey_doc}, {"LoadKey", PyLoadKey, METH_VARARGS, LoadKey_doc}, - {"OpenKey", PyOpenKey, METH_VARARGS, OpenKey_doc}, - {"OpenKeyEx", PyOpenKey, METH_VARARGS, OpenKeyEx_doc}, + {"OpenKey", (PyCFunction)PyOpenKey, METH_VARARGS | METH_KEYWORDS, + OpenKey_doc}, + {"OpenKeyEx", (PyCFunction)PyOpenKey, METH_VARARGS | METH_KEYWORDS, + OpenKeyEx_doc}, {"QueryValue", PyQueryValue, METH_VARARGS, QueryValue_doc}, {"QueryValueEx", PyQueryValueEx, METH_VARARGS, QueryValueEx_doc}, {"QueryInfoKey", PyQueryInfoKey, METH_VARARGS, QueryInfoKey_doc}, -- cgit v0.12