Skip to content

Turn SystemError.from_errno into a macro #15874

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: master
Choose a base branch
from

Conversation

straight-shoota
Copy link
Member

SystemError.from_errno calls Errno.value to retrieve the system error value from the last lib call.
But this happens in the body of the method which only executes after its arguments are evaluated (for example building the error message). This can lead to a change in Errno.value which .from_errno would then mistake for the original error.
In order to fix this, we must query Errno.value immediately after the lib call.

Changing .from_errno into a macro achieves that because it expands into a call to Errno.value before constructing the actual error object and its arguments.

We need to change the deprecated from_errno method which receives an Errno value as well because the macro would shadow the method.

One downside of the macro approach is that it won't work with file-private error types (#15496 (comment)). But this is probably not a very relevant use case.

If this is accepted, I'll do the same change to SystemError.from_winerror and SystemError.from_wsa_error.

Resolves #15496

@straight-shoota straight-shoota self-assigned this Jun 4, 2025
@straight-shoota straight-shoota added kind:bug A bug in the code. Does not apply to documentation, specs, etc. breaking-change topic:stdlib:system labels Jun 4, 2025
@HertzDevil
Copy link
Contributor

The actual method that resolves #15496 is .from_winerror. The Win32 code in stdlib pretty much never uses errno

@straight-shoota straight-shoota added kind:breaking and removed kind:bug A bug in the code. Does not apply to documentation, specs, etc. breaking-change labels Jun 5, 2025
straight-shoota and others added 3 commits June 5, 2025 22:46
This ensures we capture `Errno.value` right away and it cannot be
influenced by other code producing the arguments.
Co-authored-by: Quinton Miller <[email protected]>
@straight-shoota straight-shoota force-pushed the ci/fix/system_error-constructor-errno.value branch 2 times, most recently from e7a4962 to bfe0758 Compare June 5, 2025 21:21
@straight-shoota straight-shoota force-pushed the ci/fix/system_error-constructor-errno.value branch from bfe0758 to e48f1d1 Compare June 5, 2025 22:14
@straight-shoota straight-shoota marked this pull request as ready for review June 6, 2025 10:38
# The system message corresponding to the OS error value amends the *message*.
# Additional keyword arguments are forwarded to the exception initializer `.new_from_os_error`.
macro from_errno(message, **opts)
# This is a macro in order to retrieve `Errno.value` first before evaluating `message` and `opts`.
Copy link
Contributor

Choose a reason for hiding this comment

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

Polish: maybe move this comment outside of the macro, and be more general:

The following are macros so we can get the errno or winerror before
evaluating message and opts that may change the errno or winerror value.

@straight-shoota straight-shoota added this to the 1.17.0 milestone Jun 6, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

GC.malloc resets WinError.value on MinGW-w64
3 participants