@@ -797,51 +797,61 @@ def __exit__(self, *ignore_exc):
797797
798798try :
799799 if support .MS_WINDOWS :
800- import ctypes
800+ import ctypes . util
801801 kernel32 = ctypes .WinDLL ('kernel32' , use_last_error = True )
802-
803- ERROR_FILE_NOT_FOUND = 2
804- DDD_REMOVE_DEFINITION = 2
805- DDD_EXACT_MATCH_ON_REMOVE = 4
806- DDD_NO_BROADCAST_SYSTEM = 8
807802 else :
808803 raise AttributeError
809804except (ImportError , AttributeError ):
810805 def subst_drive (path ):
811806 raise unittest .SkipTest ('ctypes or kernel32 is not available' )
807+
808+ def handle_count ():
809+ return 0
812810else :
811+ ERROR_FILE_NOT_FOUND = 2
812+ DDD_REMOVE_DEFINITION = 2
813+ DDD_EXACT_MATCH_ON_REMOVE = 4
814+ DDD_NO_BROADCAST_SYSTEM = 8
815+
816+
817+ @ctypes .util .wrap_dll_function (kernel32 )
818+ def DefineDosDeviceW (
819+ dwFlags : ctypes .wintypes .DWORD ,
820+ lpDeviceName : ctypes .c_wchar_p ,
821+ lpTargetPath : ctypes .c_wchar_p ,
822+ ) -> ctypes .wintypes .BOOL :
823+ pass
824+
825+ @ctypes .util .wrap_dll_function (kernel32 )
826+ def QueryDosDeviceW (
827+ lpDeviceName : ctypes .c_wchar_p ,
828+ lpTargetPath : ctypes .c_wchar_p ,
829+ ucchMax : ctypes .wintypes .DWORD ,
830+ ) -> ctypes .wintypes .DWORD :
831+ pass
832+
813833 @contextlib .contextmanager
814834 def subst_drive (path ):
815835 """Temporarily yield a substitute drive for a given path."""
816836 for c in reversed (string .ascii_uppercase ):
817837 drive = f'{ c } :'
818- if (not kernel32 . QueryDosDeviceW (drive , None , 0 ) and
838+ if (not QueryDosDeviceW (drive , None , 0 ) and
819839 ctypes .get_last_error () == ERROR_FILE_NOT_FOUND ):
820840 break
821841 else :
822842 raise unittest .SkipTest ('no available logical drive' )
823- if not kernel32 . DefineDosDeviceW (
824- DDD_NO_BROADCAST_SYSTEM , drive , path ):
843+
844+ if not DefineDosDeviceW ( DDD_NO_BROADCAST_SYSTEM , drive , path ):
825845 raise ctypes .WinError (ctypes .get_last_error ())
846+
826847 try :
827848 yield drive
828849 finally :
829- if not kernel32 .DefineDosDeviceW (
830- DDD_REMOVE_DEFINITION | DDD_EXACT_MATCH_ON_REMOVE ,
831- drive , path ):
850+ flags = DDD_REMOVE_DEFINITION | DDD_EXACT_MATCH_ON_REMOVE
851+ if not DefineDosDeviceW (flags , drive , path ):
832852 raise ctypes .WinError (ctypes .get_last_error ())
833853
834854
835- try :
836- if support .MS_WINDOWS :
837- import ctypes .util
838- kernel32 = ctypes .WinDLL ('kernel32' , use_last_error = True )
839- else :
840- raise AttributeError
841- except (ImportError , AttributeError ):
842- def handle_count ():
843- return 0
844- else :
845855 @ctypes .util .wrap_dll_function (kernel32 )
846856 def GetCurrentProcess () -> ctypes .wintypes .HANDLE :
847857 pass
@@ -859,6 +869,6 @@ def handle_count():
859869
860870 handle_count = ctypes .wintypes .DWORD ()
861871 if not GetProcessHandleCount (hproc , ctypes .byref (handle_count )):
862- raise ctypes .WinError ()
872+ raise ctypes .WinError (ctypes . get_last_error () )
863873
864874 return handle_count .value
0 commit comments