mhammond / pywin32

Python for Windows (pywin32) Extensions
4.9k stars 783 forks source link

Last error code errorneously set by some modules #2301

Open CristiFati opened 6 days ago

CristiFati commented 6 days ago

Was 1st reported in https://github.com/mhammond/pywin32/issues/2163#issuecomment-2184175764.

One might be tricked to think that it has something to do with my EnumWindows functions family related changes, but it turns out it's a subtle issue, and it's more generic.

After half hour of trying I was able to come up with a (related) MCVE.

err.py:

import ctypes as cts
import ctypes.wintypes as wts

GetLastError = cts.windll.kernel32.GetLastError
GetLastError.argtypes = ()
GetLastError.restype = wts.DWORD

print(f"GetLastError (cts): {GetLastError()}")

print("import pywintypes")
import pywintypes as pwts
print(f"GetLastError (cts): {GetLastError()}")

print("import win32api")
import win32api as wapi
print(f"GetLastError (cts): {GetLastError()}")
print(f"GetLastError (wapi): {wapi.GetLastError()}")

print(f"GetLastError (cts): {GetLastError()}")
last_err = 0
print(f"Setting (wapi) error to {last_err}")
wapi.SetLastError(last_err)

print(f"GetLastError (wapi): {wapi.GetLastError()}")
print(f"GetLastError (cts): {GetLastError()}")

Output:

   (py_pc064_03.10_test1_pw32) [cfati@CFATI-5510-0:e:\Work\Dev\Repos\GitHub\CristiFati\pywin32]> python err.py
   GetLastError (cts): 0
   import pywintypes
   GetLastError (cts): 0
   import win32api
   GetLastError (cts): 126
   GetLastError (wapi): 126
   GetLastError (cts): 126
   Setting (wapi) error to 0
   GetLastError (wapi): 0
   GetLastError (cts): 0

So, for some reason, win32api sets the last error code. Same thing happens for win32gui, yielding my (PyWin_SetAPIErrorOrReturnNone) changes a nop.

Also, this has probably been present since forever (also reproduced with v304).