Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions Doc/library/winreg.rst
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,24 @@ This module offers the following functions:
See :ref:`above <exception-changed>`.


.. function:: DeleteTree(key, sub_key=None)

Deletes the specified key and all its subkeys and values recursively.

*key* is an already open key, or one of the predefined
:ref:`HKEY_* constants <hkey-constants>`.

*sub_key* is a string that names the subkey to delete. If ``None``,
deletes all subkeys and values of the specified key.

This function deletes a key and all its descendants. If *sub_key* is
``None``, all subkeys and values of the specified key are deleted.

.. audit-event:: winreg.DeleteTree key,sub_key winreg.DeleteTree

.. versionadded:: next


.. function:: DeleteValue(key, value)

Removes a named value from a registry key.
Expand Down
15 changes: 15 additions & 0 deletions Lib/test/test_winreg.py
Original file line number Diff line number Diff line change
Expand Up @@ -517,6 +517,21 @@ def test_exception_numbers(self):
with self.assertRaises(FileNotFoundError) as ctx:
QueryValue(HKEY_CLASSES_ROOT, 'some_value_that_does_not_exist')

def test_delete_tree(self):
with CreateKey(HKEY_CURRENT_USER, test_key_name) as main_key:
with CreateKey(main_key, "subkey1") as subkey1:
SetValueEx(subkey1, "value1", 0, REG_SZ, "test_value1")
with CreateKey(subkey1, "subsubkey1") as subsubkey1:
SetValueEx(subsubkey1, "value2", 0, REG_DWORD, 42)

with CreateKey(main_key, "subkey2") as subkey2:
SetValueEx(subkey2, "value3", 0, REG_SZ, "test_value3")

DeleteTree(HKEY_CURRENT_USER, test_key_name)

with self.assertRaises(OSError):
OpenKey(HKEY_CURRENT_USER, test_key_name)


if __name__ == "__main__":
if not REMOTE_NAME:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add :func:`winreg.DeleteTree`.
70 changes: 69 additions & 1 deletion PC/clinic/winreg.c.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

40 changes: 40 additions & 0 deletions PC/winreg.c
Original file line number Diff line number Diff line change
Expand Up @@ -2019,6 +2019,45 @@ winreg_EnableReflectionKey_impl(PyObject *module, HKEY key)
Py_RETURN_NONE;
}

/*[clinic input]
winreg.DeleteTree

key: HKEY
An already open key, or any one of the predefined HKEY_* constants.
sub_key: Py_UNICODE(accept={str, NoneType}) = None
A string that names the subkey to delete. If None, deletes all subkeys
and values of the specified key.
/

Deletes the specified key and all its subkeys and values recursively.

This function deletes a key and all its descendants. If sub_key is None,
all subkeys and values of the specified key are deleted.
[clinic start generated code]*/

static PyObject *
winreg_DeleteTree_impl(PyObject *module, HKEY key, const wchar_t *sub_key)
/*[clinic end generated code: output=c34395ee59290501 input=419ef9bb8b06e4bf]*/
{
LONG rc;

if (PySys_Audit("winreg.DeleteTree", "nu",
(Py_ssize_t)key, sub_key) < 0) {
return NULL;
}

Py_BEGIN_ALLOW_THREADS
rc = RegDeleteTreeW(key, sub_key);
Py_END_ALLOW_THREADS

if (rc != ERROR_SUCCESS) {
PyErr_SetFromWindowsErrWithFunction(rc, "RegDeleteTreeW");
return NULL;
}

Py_RETURN_NONE;
}

/*[clinic input]
winreg.QueryReflectionKey

Expand Down Expand Up @@ -2077,6 +2116,7 @@ static struct PyMethodDef winreg_methods[] = {
WINREG_DELETEKEY_METHODDEF
WINREG_DELETEKEYEX_METHODDEF
WINREG_DELETEVALUE_METHODDEF
WINREG_DELETETREE_METHODDEF
WINREG_DISABLEREFLECTIONKEY_METHODDEF
WINREG_ENABLEREFLECTIONKEY_METHODDEF
WINREG_ENUMKEY_METHODDEF
Expand Down
Loading