Skip to content
Open
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
28 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
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
64 changes: 61 additions & 3 deletions Doc/library/winreg.rst
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ This module offers the following functions:
See :ref:`above <exception-changed>`.


.. function:: CreateKeyEx(key, sub_key, reserved=0, access=KEY_WRITE)
.. function:: CreateKeyEx(key, sub_key, reserved=0, access=KEY_WRITE, options=0, create_only=False)
Copy link
Member

Choose a reason for hiding this comment

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

I think it is worth to make all new parameters keyword-only. Their order differs from the order in RegCreateKeyExW(), so passing them as positional arguments will be errorprone.

We can also deprecate passing reserved (which should not be here at first place) and access by keyword, but this is a different issue.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hi, thank you for the review. I made the newly added parameters options and create_only keyword-only-ed.


Creates or opens the specified key, returning a
:ref:`handle object <handle-object>`.
Expand All @@ -103,6 +103,13 @@ This module offers the following functions:
security access for the key. Default is :const:`KEY_WRITE`. See
:ref:`Access Rights <access-rights>` for other allowed values.

*options* is an interger and can be zero or one of the predefined
:ref:`REG_OPTION_* constants <hkey-constants>`.

*create_only* is a boolean.
When set to True, a :exc:`FileExistsError` will be raised
if the key is already exists. Default is ``False``.

If *key* is one of the predefined keys, *sub_key* may be ``None``. In that
case, the handle returned is the same key handle passed in to the function.

Expand Down Expand Up @@ -320,7 +327,6 @@ This module offers the following functions:


.. function:: OpenKey(key, sub_key, reserved=0, access=KEY_READ)
OpenKeyEx(key, sub_key, reserved=0, access=KEY_READ)

Opens the specified key, returning a :ref:`handle object <handle-object>`.

Expand All @@ -329,7 +335,11 @@ This module offers the following functions:

*sub_key* is a string that identifies the sub_key to open.

*reserved* is a reserved integer, and must be zero. The default is zero.
*reserved* is a reserved integer and should be zero. If it is not zero,
it will be treated as the options parameter in :func:`OpenKeyEx`.
You should use the :func:`OpenKeyEx` directly instead in this case,
this parameter is only included for compatibility reasons.
The default value is zero.

*access* is an integer that specifies an access mask that describes the desired
security access for the key. Default is :const:`KEY_READ`. See :ref:`Access
Expand All @@ -349,6 +359,54 @@ This module offers the following functions:
.. versionchanged:: 3.3
See :ref:`above <exception-changed>`.

.. deprecated-removed:: 3.14 3.16
*reserved* is deprecated and will be removed in the future.
Please use :func:`OpenKeyEx` instead.

.. function:: OpenKeyEx(key, sub_key, options=0, access=KEY_READ, reserved=0)

Opens the specified key, returning a :ref:`handle object <handle-object>`.

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

*sub_key* is a string that identifies the sub_key to open.

*access* is an integer that specifies an access mask that describes the desired
security access for the key. Default is :const:`KEY_READ`. See :ref:`Access
Rights <access-rights>` for other allowed values.

*options* specifies the option to apply when opening the key.
Can be zero or one of the predefined
:ref:`REG_OPTION_* constants <hkey-constants>`.

*reserved* is a reserved integer and should be zero.
If it is not zero, it will be treated as the options parameter.
You should use the *options* parameter directly instead,
this parameter is only included for compatibility reasons.
The default value is zero.

The result is a new handle to the specified key.

If the function fails, :exc:`OSError` is raised.

.. audit-event:: winreg.OpenKey key,sub_key,access winreg.OpenKey

.. audit-event:: winreg.OpenKey/result key winreg.OpenKey

.. versionchanged:: 3.2
Allow the use of named arguments.

.. versionchanged:: 3.3
See :ref:`above <exception-changed>`.

.. versionchanged:: 3.14
Added *options* parameter.

.. deprecated-removed:: 3.14 3.16
*reserved* is deprecated and will be removed in the future.
Please use *options* instead.


.. function:: QueryInfoKey(key)

Expand Down
1 change: 1 addition & 0 deletions Include/internal/pycore_global_objects_fini_generated.h

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

1 change: 1 addition & 0 deletions Include/internal/pycore_global_strings.h
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,7 @@ struct _Py_global_strings {
STRUCT_FOR_ID(coro)
STRUCT_FOR_ID(count)
STRUCT_FOR_ID(covariant)
STRUCT_FOR_ID(create_only)
STRUCT_FOR_ID(ctx)
STRUCT_FOR_ID(cwd)
STRUCT_FOR_ID(d_parameter_type)
Expand Down
1 change: 1 addition & 0 deletions Include/internal/pycore_runtime_init_generated.h

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

4 changes: 4 additions & 0 deletions Include/internal/pycore_unicodeobject_generated.h

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

27 changes: 27 additions & 0 deletions Lib/test/test_winreg.py
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,33 @@ def test_registry_works_extended_functions(self):

self._delete_test_data(HKEY_CURRENT_USER)

def test_registry_works_with_options(self):
ckeo = lambda key, sub_key: CreateKeyEx(key, sub_key, 0, KEY_ALL_ACCESS,
options=REG_OPTION_VOLATILE)
self._write_test_data(HKEY_CURRENT_USER, CreateKey=ckeo)

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

with self.assertWarns(DeprecationWarning):
okeo = lambda key, sub_key: OpenKeyEx(key, sub_key,
reserved=REG_OPTION_VOLATILE)
self._read_test_data(HKEY_CURRENT_USER, OpenKey=okeo)

with self.assertWarns(DeprecationWarning):
ok = lambda key, sub_key: OpenKey(key, sub_key,
reserved=REG_OPTION_VOLATILE)
self._read_test_data(HKEY_CURRENT_USER, OpenKey=ok)

self._delete_test_data(HKEY_CURRENT_USER)

def test_create_only(self):
CreateKeyEx(HKEY_CURRENT_USER, test_key_name)
with self.assertRaises(FileExistsError):
CreateKeyEx(HKEY_CURRENT_USER, test_key_name, create_only=True)
DeleteKey(HKEY_CURRENT_USER, test_key_name)

def test_named_arguments(self):
self._test_named_args(HKEY_CURRENT_USER, test_key_name)
# Use the regular DeleteKey to clean up
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Add *options* and *create_only* parameters to :meth:`winreg.CreateKeyEx`.
Add *options* parameter to :meth:`winreg.OpenKeyEx`.
Loading
Loading