Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
e3fac96
Enhance winreg.OpenKeyEx and winreg.CreateKeyEx
aisk Feb 9, 2025
59dfa3d
Add tests
aisk Feb 9, 2025
bba8ba6
Update sys.audit
aisk Feb 9, 2025
47ea0ba
Add news entry
aisk Feb 9, 2025
d6251e0
Add documents
aisk Feb 9, 2025
f4f4fff
Fix sphinx error
aisk Feb 9, 2025
1fd89db
Fix typo
aisk Feb 9, 2025
28bf171
Regenerate files
aisk Feb 9, 2025
94ed98b
Revert the changes on sys.audit
aisk Feb 11, 2025
b8261bb
Update comment
aisk Feb 11, 2025
2475c0b
Apply suggestions from code review
aisk Mar 1, 2025
913b21a
Update document for OpenKeyEx
aisk Mar 1, 2025
483849a
Add document for CreateKeyEx
aisk Mar 1, 2025
bd57ba7
Fix CI
aisk Mar 1, 2025
6eae434
Split OpenKey and OpenKeyEx
aisk Mar 12, 2025
1b473ad
Check deprecated warning in test
aisk Mar 12, 2025
5badb7a
Update document
aisk Mar 12, 2025
7b9ffec
Fix rst lint errors
aisk Mar 12, 2025
b4e8d8b
Update generated files
aisk Mar 12, 2025
580a348
Remove macro define by accident
aisk Mar 13, 2025
76b947f
Merge branch 'main' into enhance-winreg
zooba Mar 13, 2025
9e64cb2
Deprecate options in CreateKey too
aisk Mar 15, 2025
5fab221
Remove the macro define again
aisk Mar 15, 2025
c4c2704
Merge remote-tracking branch 'upstream/main' into enhance-winreg
aisk Nov 6, 2025
26b4e82
Update generate files
aisk Nov 13, 2025
e457112
Merge branch 'main' into enhance-winreg
serhiy-storchaka Nov 23, 2025
7900598
Make options and create_only keyword-only for CreateKeyEx
aisk Nov 24, 2025
acc01c7
Make reserved keyword-only for OpenKeyEx
aisk Nov 24, 2025
d069662
Merge upstream and resolve conflict
aisk Feb 2, 2026
195511f
Add more tests and check if reversed and options are set both
aisk Feb 3, 2026
5e05ff4
Remove magic number in test and update deprecated message
aisk Feb 5, 2026
2f75055
Update news entry
aisk Feb 5, 2026
93feda1
Change create_only to exist_ok in OpenKeyEx
aisk Feb 6, 2026
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
3 changes: 1 addition & 2 deletions Lib/test/test_winreg.py
Original file line number Diff line number Diff line change
Expand Up @@ -233,8 +233,7 @@ def test_registry_works_with_options(self):
options=REG_OPTION_VOLATILE)
self._write_test_data(HKEY_CURRENT_USER, CreateKey=ckeo)

okeo = lambda key, sub_key: OpenKeyEx(key, sub_key, 0, KEY_READ,
options=REG_OPTION_VOLATILE)
okeo = lambda key, sub_key: OpenKeyEx(key, sub_key, REG_OPTION_VOLATILE, KEY_READ)
self._read_test_data(HKEY_CURRENT_USER, OpenKey=okeo)

self._delete_test_data(HKEY_CURRENT_USER)
Expand Down
69 changes: 28 additions & 41 deletions PC/clinic/winreg.c.h

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

62 changes: 40 additions & 22 deletions PC/winreg.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

#include <windows.h>

#define MS_WINDOWS_DESKTOP
Comment thread
zooba marked this conversation as resolved.
Outdated
#if defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) || defined(MS_WINDOWS_GAMES)

typedef struct {
Expand Down Expand Up @@ -1417,8 +1418,37 @@ winreg.OpenKey -> HKEY
access: REGSAM(c_default='KEY_READ') = winreg.KEY_READ
An integer that specifies an access mask that describes the desired
security access for the key. Default is KEY_READ.

Opens the specified key.

The result is a new handle to the specified key.
If the function fails, an OSError exception is raised.
[clinic start generated code]*/

static HKEY
winreg_OpenKey_impl(PyObject *module, HKEY key, const wchar_t *sub_key,
int reserved, REGSAM access)
/*[clinic end generated code: output=5efbad23b3ffe2e7 input=7fb70c602dd114dd]*/
{
return winreg_OpenKeyEx_impl(module, key, sub_key, reserved, access, 0);
}

/*[clinic input]
winreg.OpenKeyEx -> HKEY

key: HKEY
An already open key, or any one of the predefined HKEY_* constants.
sub_key: Py_UNICODE(accept={str, NoneType})
A string that identifies the sub_key to open.
options: int = 0
Can be one of the REG_OPTION_* constants.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should probably document the interaction with reserved here. I'm not sure what the history is of reserved becoming a meaningful parameter, but it's meaningful now, so we should say that here (and in the real docs, Doc\library\winreg.rst). (I mean "here" as in a few lines above, but I can't comment on it because it hasn't been updated yet).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could make all optional parameters keyword-only. If there are many optional parameters, passing positional arguments is error-prone.

Also, imagine the code that calls CreateKeyEx(key, sub_key, options, access) was executed in the old Python version. It will silently ignore the third argument.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi, I updated and changed the newly added reversed to keyword-only. Change all the optional parameters to keyword-only should be in another PR I think?

access: REGSAM(c_default='KEY_READ') = winreg.KEY_READ
An integer that specifies an access mask that describes the desired
security access for the key. Default is KEY_READ.
reserved: int = 0
A reserved integer that be should zero. If it is not zero,
it will be used as the options parameter for compatibility reasons.
Default is zero.

Opens the specified key.

Expand All @@ -1427,9 +1457,9 @@ If the function fails, an OSError exception is raised.
[clinic start generated code]*/

static HKEY
winreg_OpenKey_impl(PyObject *module, HKEY key, const wchar_t *sub_key,
int reserved, REGSAM access, int options)
/*[clinic end generated code: output=1cb0239fad9672e0 input=2fff042272bfc4f6]*/
winreg_OpenKeyEx_impl(PyObject *module, HKEY key, const wchar_t *sub_key,
int options, REGSAM access, int reserved)
/*[clinic end generated code: output=db8d3dc70876a046 input=d997970b48ac2e30]*/
{
HKEY retKey;
long rc;
Expand All @@ -1439,8 +1469,13 @@ winreg_OpenKey_impl(PyObject *module, HKEY key, const wchar_t *sub_key,
(Py_ssize_t)access) < 0) {
return NULL;
}
if (options != 0) {
reserved = options;
if (reserved != 0) {
if (PyErr_WarnEx(PyExc_DeprecationWarning,
"reserved is deprecated, use options instead.", 1))
Comment thread
aisk marked this conversation as resolved.
Outdated
{
return NULL;
}
options = reserved;
}
Py_BEGIN_ALLOW_THREADS
rc = RegOpenKeyExW(key, sub_key, reserved, access, &retKey);
Expand All @@ -1456,23 +1491,6 @@ winreg_OpenKey_impl(PyObject *module, HKEY key, const wchar_t *sub_key,
return retKey;
}

/*[clinic input]
winreg.OpenKeyEx = winreg.OpenKey

Opens the specified key.

The result is a new handle to the specified key.
If the function fails, an OSError exception is raised.
[clinic start generated code]*/

static HKEY
winreg_OpenKeyEx_impl(PyObject *module, HKEY key, const wchar_t *sub_key,
int reserved, REGSAM access, int options)
/*[clinic end generated code: output=08a607e6a6385ed4 input=c6c4972af8622959]*/
{
return winreg_OpenKey_impl(module, key, sub_key, reserved, access, options);
}

/*[clinic input]
winreg.QueryInfoKey

Expand Down