py-sdl / py-sdl2

Python ctypes wrapper around SDL2
Other
303 stars 49 forks source link

Remove more misuse of SDL_GetError in tests #271

Closed a-hurst closed 1 year ago

a-hurst commented 1 year ago

PR Description

Closes #257 (for real this time, I think). This fixes a bunch of assorted unit tests to only check for SDL_GetError output when a function's return value indicates a failure, since SDL_SetError is often used internally by SDL2 to set non-fatal warning messages (leading to tests breaking unexpectedly with new SDL releases).

Merge Checklist

a-hurst commented 1 year ago

@smcv Thanks for the review! Definitely feel more confident I got it right this time with a second set of eyes on it.

Re: the added SDL_ClearError calls, my reasoning for those is that for tests with loops (e.g. testing SDL_JoystickGetVendor for each connected joystick) I wanted to be sure that there wouldn't be a situation where item i succeeds but sets a non-fatal error, and then item i+1 fails but doesn't set an error, resulting in a misleading message. Is that generally something I shouldn't have to worry about with how SDL2 handles errors?

smcv commented 1 year ago

Re: the added SDL_ClearError calls, my reasoning for those is that for tests with loops (e.g. testing SDL_JoystickGetVendor for each connected joystick) I wanted to be sure that there wouldn't be a situation where item i succeeds but sets a non-fatal error, and then item i+1 fails but doesn't set an error, resulting in a misleading message. Is that generally something I shouldn't have to worry about with how SDL2 handles errors?

You're the maintainer, and if you prefer to do it like this, do it like this. As I said, it's harmless, even if unnecessary.

I believe the intention is that if a SDL function fails (not just "returns an empty result" if that's a thing that is possible, but actually fails), then it is guaranteed to set the error indicator, so that if it didn't, that would be considered to be a SDL bug.

I'm actually more familiar with GLib and CPython than SDL, and in those C APIs, it is certainly intended to be an API guarantee that: if you call a function in a way that is not already considered to be a programming error (undefined behaviour), and it fails, then the error indicator will be set.

Similarly, in the ISO/POSIX C library interface, most functions have it as an API guarantee that if you call the function and it fails, then errno will be set to the reason for failure. Like SDL, the converse is not true: if the function succeeds, then the state of errno is unspecified (might have been changed, might be 0, might be some unrelated value left over from a previous function call). SDL's error indicator is modelled on errno, but with strings instead of integer codes.

a-hurst commented 1 year ago

I believe the intention is that if a SDL function fails (not just "returns an empty result" if that's a thing that is possible, but actually fails), then it is guaranteed to set the error indicator, so that if it didn't, that would be considered to be a SDL bug.

That makes sense, thanks for the explanation! I'll leave the extra ClearErrors in if for now if they're harmless, but now I know that if I ever hit an error return value and it doesn't set a message it's something to report upstream to SDL proper.