Skip to content

Commit 579d208

Browse files
Add deprecation decorator and comments for pywin32 (#11570)
Co-authored-by: Jelle Zijlstra <[email protected]>
1 parent 3802899 commit 579d208

11 files changed

+186
-44
lines changed

stubs/pywin32/@tests/stubtest_allowlist_win32.txt

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,8 @@ win32com(ext)?.axscript.client.debug
4848
win32com(ext)?.axscript.client.pydumper
4949
win32com(ext)?.directsound.test.*
5050

51-
# Deprecated and obsolete
52-
pythoncom.MakeIID
53-
pythoncom.MakeTime
54-
(win32.lib.)?win32pdhquery.Query.addperfcounter
5551
# Deprecated and makes a buffer of random junk. Use something like `b"\x00" * bufferSize` instead
52+
# It's safer to not even expose this method as deprecated.
5653
(win32.)?win(32|xp)gui.PyMakeBuffer
5754

5855
# Axdebug is not built on Python 3.11 anyway: https://github.com/mhammond/pywin32/blob/main/setup.py#L403-L405

stubs/pywin32/_win32typing.pyi

Lines changed: 95 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from _typeshed import Incomplete, Unused
33
from collections.abc import Iterable
44
from typing import Literal, final, overload
5-
from typing_extensions import Self
5+
from typing_extensions import Self, TypeAlias, deprecated
66

77
class ArgNotFound: ...
88
class PyOleEmpty: ...
@@ -123,7 +123,12 @@ class FORM_INFO_1:
123123
def ImageableArea(self): ...
124124

125125
class ImportCallback: ...
126-
class LARGE_INTEGER: ...
126+
127+
# Note: Don't use these, use `int` instead. Or an overload with a deprecation message on the tuple param.
128+
# We're only keeping these here as a reminder when typing from source code.
129+
# Deprecated: Support for passing 2 integers to create a 64bit value is deprecated - pass a long instead
130+
LARGE_INTEGER: TypeAlias = int | tuple[int, int]
131+
ULARGE_INTEGER: TypeAlias = int | tuple[int, int]
127132

128133
class NCB:
129134
@property
@@ -164,6 +169,12 @@ class PRINTER_DEFAULTS:
164169
class PyACL:
165170
def Initialize(self) -> None: ...
166171
def IsValid(self) -> bool: ...
172+
@deprecated(
173+
"""\
174+
Early versions of this function supported only two arguments. \
175+
This has been deprecated in preference of the three argument version, \
176+
which reflects the win32 API and the new functions in this module."""
177+
)
167178
@overload
168179
def AddAccessAllowedAce(self, access: int, sid: PySID, /) -> None: ...
169180
@overload
@@ -172,7 +183,16 @@ class PyACL:
172183
def AddAccessAllowedObjectAce(
173184
self, AceRevision, AceFlags, AccessMask, ObjectTypeGuid: PyIID, InheritedObjectTypeGuid: PyIID, sid: PySID, /
174185
) -> None: ...
175-
def AddAccessDeniedAce(self, revision: int, access: int, sid: PySID, access1: int, sid1: PySID, /) -> None: ...
186+
@deprecated(
187+
"""\
188+
Early versions of this function supported only two arguments. \
189+
This has been deprecated in preference of the three argument version, \
190+
which reflects the win32 API and the new functions in this module."""
191+
)
192+
@overload
193+
def AddAccessDeniedAce(self, access: int, sid: PySID, /) -> None: ...
194+
@overload
195+
def AddAccessDeniedAce(self, revision: int, access: int, sid: PySID, /) -> None: ...
176196
def AddAccessDeniedAceEx(self, revision: int, aceflags: int, access: int, sid: PySID, /) -> None: ...
177197
def AddMandatoryAce(self, AceRevision, AceFlags, MandatoryPolicy, LabelSid: PySID, /) -> None: ...
178198
def AddAuditAccessAce(self, dwAceRevision, dwAccessMask, sid: PySID, bAuditSuccess, bAuditFailure, /) -> None: ...
@@ -217,10 +237,17 @@ class PyCEHANDLE: ...
217237
class PyCERTSTORE:
218238
@property
219239
def HCERTSTORE(self): ...
220-
# Flags argument is deprecated.
221-
# The underlying function is now always called with `CERT_CLOSE_STORE_CHECK_FLAG`,
222-
# and support for this param will be dropped at some point in the future.
223-
def CertCloseStore(self, Flags: int = ...) -> None: ...
240+
@overload
241+
def CertCloseStore(self) -> None: ...
242+
@deprecated(
243+
"""\
244+
`Flags` argument has been deprecated as it is likely to crash the process if \
245+
`CERT_CLOSE_STORE_FORCE_FLAG` is specified. The underlying function is now \
246+
always called with `CERT_CLOSE_STORE_CHECK_FLAG`, and support for this \
247+
param will be dropped at some point in the future."""
248+
)
249+
@overload
250+
def CertCloseStore(self, Flags: int) -> None: ...
224251
def CertControlStore(self, Flags, CtrlType, CtrlPara: int) -> None: ...
225252
def CertEnumCertificatesInStore(self) -> list[PyCERT_CONTEXT]: ...
226253
def CertEnumCTLsInStore(self) -> list[PyCTL_CONTEXT]: ...
@@ -2403,7 +2430,6 @@ class SERVICE_STATUS:
24032430
def __getitem__(self, i: int, /) -> int: ...
24042431

24052432
class TRACKMOUSEEVENT: ...
2406-
class ULARGE_INTEGER: ...
24072433
class WIN32_FIND_DATA: ...
24082434
class com_error: ...
24092435

@@ -3682,7 +3708,11 @@ class PyIInternetPriority:
36823708

36833709
class PyIInternetProtocol:
36843710
def Read(self, cb, /) -> None: ...
3685-
def Seek(self, dlibMove: LARGE_INTEGER, dwOrigin, /) -> None: ...
3711+
@overload
3712+
@deprecated("Support for passing two ints to create a 64-bit value is deprecated; pass a single int instead")
3713+
def Seek(self, dlibMove: tuple[int, int], dwOrigin, /) -> None: ...
3714+
@overload
3715+
def Seek(self, dlibMove: int, dwOrigin, /) -> None: ...
36863716
def LockRequest(self, dwOptions, /) -> None: ...
36873717
def UnlockRequest(self) -> None: ...
36883718

@@ -3741,13 +3771,32 @@ class PyIKnownFolderManager:
37413771
def Redirect(self, _id: PyIID, hwnd: int, flags, TargetPath, Exclusion: tuple[PyIID, ...], /) -> None: ...
37423772

37433773
class PyILockBytes:
3744-
def ReadAt(self, ulOffset: ULARGE_INTEGER, cb, /) -> str: ...
3745-
def WriteAt(self, ulOffset: ULARGE_INTEGER, data: str, /): ...
3774+
@overload
3775+
@deprecated("Support for passing two ints to create a 64-bit value is deprecated; pass a single int instead")
3776+
def ReadAt(self, ulOffset: tuple[int, int], cb, /) -> str: ...
3777+
@overload
3778+
def ReadAt(self, ulOffset: int, cb, /) -> str: ...
3779+
@overload
3780+
@deprecated("Support for passing two ints to create a 64-bit value is deprecated; pass a single int instead")
3781+
def WriteAt(self, ulOffset: tuple[int, int], data: str, /): ...
3782+
@overload
3783+
def WriteAt(self, ulOffset: int, data: str, /): ...
37463784
def Flush(self) -> None: ...
3747-
def SetSize(self, cb: ULARGE_INTEGER, /) -> None: ...
3748-
def LockRegion(self, libOffset: ULARGE_INTEGER, cb: ULARGE_INTEGER, dwLockType, /) -> None: ...
3749-
def UnlockRegion(self, libOffset: ULARGE_INTEGER, cb: ULARGE_INTEGER, dwLockType, /) -> None: ...
3750-
def Stat(self, grfStatFlag, /) -> STATSTG: ...
3785+
@overload
3786+
@deprecated("Support for passing two ints to create a 64-bit value is deprecated; pass a single int instead")
3787+
def SetSize(self, cb: tuple[int, int], /) -> None: ...
3788+
@overload
3789+
def SetSize(self, cb: int, /) -> None: ...
3790+
@overload
3791+
@deprecated("Support for passing two ints to create a 64-bit value is deprecated; pass a single int instead")
3792+
def LockRegion(self, libOffset: tuple[int, int], cb: tuple[int, int], dwLockType, /) -> None: ...
3793+
@overload
3794+
def LockRegion(self, libOffset: int, cb: int, dwLockType, /) -> None: ...
3795+
@overload
3796+
@deprecated("Support for passing two ints to create a 64-bit value is deprecated; pass a single int instead")
3797+
def UnlockRegion(self, libOffset: tuple[int, int], cb: tuple[int, int], dwLockType, /) -> None: ...
3798+
@overload
3799+
def UnlockRegion(self, libOffset: int, cb: int, dwLockType, /) -> None: ...
37513800

37523801
class PyIMAPIContainer:
37533802
def OpenEntry(self, entryId: str, iid: PyIID, flags, /): ...
@@ -3882,6 +3931,7 @@ class PyIMsgServiceAdmin:
38823931
def GetMsgServiceTable(self, flags, /) -> PyIMAPITable: ...
38833932
def GetProviderTable(self, flags, /) -> PyIMAPITable: ...
38843933
def DeleteMsgService(self, uuid: PyIID, /) -> None: ...
3934+
@deprecated("This is deprecated, and there is no replacement referenced to use instead.")
38853935
def RenameMsgService(self, uuid: PyIID, flags, newName: str, /) -> None: ...
38863936
def OpenProfileSection(self, uuid: PyIID, iid: PyIID, flags, /): ...
38873937
def AdminProviders(self, uuid: PyIID, flags, /): ...
@@ -4104,7 +4154,7 @@ class PyIPersistStream:
41044154
def IsDirty(self) -> bool: ...
41054155
def Load(self, stream: PyIStream, /) -> None: ...
41064156
def Save(self, stream: PyIStream, bClearDirty, /) -> None: ...
4107-
def GetSizeMax(self) -> ULARGE_INTEGER: ...
4157+
def GetSizeMax(self) -> int: ...
41084158

41094159
class PyIPersistStreamInit:
41104160
def InitNew(self) -> None: ...
@@ -4539,13 +4589,33 @@ class PyIStream:
45394589
def read(self, numBytes, /) -> str: ...
45404590
def Write(self, data: str, /) -> None: ...
45414591
def write(self, data: str, /) -> None: ...
4542-
def Seek(self, offset, origin, /) -> ULARGE_INTEGER: ...
4543-
def SetSize(self, newSize: ULARGE_INTEGER, /) -> None: ...
4544-
def CopyTo(self, stream: PyIStream, cb: ULARGE_INTEGER, /) -> ULARGE_INTEGER: ...
4592+
@overload
4593+
def Seek(self, offset: int, origin: int, /) -> int: ...
4594+
@overload
4595+
@deprecated("Support for passing two ints to create a 64-bit value is deprecated; pass a single int instead")
4596+
def Seek(self, offset: tuple[int, int], origin: int, /) -> int: ...
4597+
@overload
4598+
def SetSize(self, newSize: int, /) -> None: ...
4599+
@overload
4600+
@deprecated("Support for passing two ints to create a 64-bit value is deprecated; pass a single int instead")
4601+
def SetSize(self, newSize: tuple[int, int], /) -> None: ...
4602+
@overload
4603+
def CopyTo(self, stream: PyIStream, cb: int, /) -> int: ...
4604+
@overload
4605+
@deprecated("Support for passing two ints to create a 64-bit value is deprecated; pass a single int instead")
4606+
def CopyTo(self, stream: PyIStream, cb: tuple[int, int], /) -> int: ...
45454607
def Commit(self, flags, /) -> None: ...
45464608
def Revert(self) -> None: ...
4547-
def LockRegion(self, offset: ULARGE_INTEGER, cb: ULARGE_INTEGER, lockType, /) -> None: ...
4548-
def UnLockRegion(self, offset: ULARGE_INTEGER, cb: ULARGE_INTEGER, lockType, /) -> None: ...
4609+
@overload
4610+
def LockRegion(self, offset: int, cb: int, lockType, /) -> None: ...
4611+
@overload
4612+
@deprecated("Support for passing two ints to create a 64-bit value is deprecated; pass a single int instead")
4613+
def LockRegion(self, offset: tuple[int, int], cb: tuple[int, int], lockType, /) -> None: ...
4614+
@overload
4615+
def UnLockRegion(self, offset: int, cb: int, lockType, /) -> None: ...
4616+
@overload
4617+
@deprecated("Support for passing two ints to create a 64-bit value is deprecated; pass a single int instead")
4618+
def UnLockRegion(self, offset: tuple[int, int], cb: tuple[int, int], lockType, /) -> None: ...
45494619
def Clone(self) -> PyIStream: ...
45504620
def Stat(self, grfStatFlag: int = ..., /) -> STATSTG: ...
45514621

@@ -4682,6 +4752,10 @@ class PyPROPERTYKEY: ...
46824752

46834753
@final
46844754
class PyPROPVARIANT:
4755+
@overload
4756+
@deprecated("Support for passing two ints to create a 64-bit value is deprecated; pass a single int instead")
4757+
def __init__(self, Value: tuple[int, int], Type=...) -> None: ...
4758+
@overload
46854759
def __init__(self, Value, Type=...) -> None: ...
46864760
@property
46874761
def vt(self): ...

stubs/pywin32/pythoncom.pyi

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from _typeshed import Incomplete
2-
from typing_extensions import TypeAlias
2+
from typing_extensions import TypeAlias, deprecated
33

44
import _win32typing
55
from win32.lib.pywintypes import com_error as com_error
@@ -69,6 +69,10 @@ def IsGatewayRegistered(iid: _win32typing.PyIID | None, /) -> int: ...
6969
def LoadRegTypeLib(iid: _win32typing.PyIID, versionMajor, versionMinor, lcid, /) -> _win32typing.PyITypeLib: ...
7070
def LoadTypeLib(libFileName: str, /) -> _win32typing.PyITypeLib: ...
7171
def MakePyFactory(iid: _win32typing.PyIID, /) -> _win32typing.PyIClassFactory: ...
72+
@deprecated("Use pywintypes.IID() instead.")
73+
def MakeIID(iidString: str, is_bytes: bool = ..., /) -> _win32typing.PyIID: ...
74+
@deprecated("Use pywintypes.Time() instead.")
75+
def MakeTime(timeRepr, /) -> _win32typing.PyTime: ...
7276
def MkParseDisplayName(
7377
displayName: str, bindCtx: _win32typing.PyIBindCtx | None = ..., /
7478
) -> tuple[_win32typing.PyIMoniker, Incomplete, _win32typing.PyIBindCtx]: ...

stubs/pywin32/win32/lib/pywintypes.pyi

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
# "KeyError: 'pywintypes'"
33
from _typeshed import Incomplete
44
from datetime import datetime
5-
from typing import Literal, NoReturn
6-
from typing_extensions import Never
5+
from typing import Literal, NoReturn, overload
6+
from typing_extensions import Never, deprecated
77

88
import _win32typing
99

@@ -45,7 +45,11 @@ def SECURITY_DESCRIPTOR() -> _win32typing.PySECURITY_DESCRIPTOR: ...
4545
def HANDLE() -> HANDLEType: ...
4646
def HKEY() -> _win32typing.PyHKEY: ...
4747
def WAVEFORMATEX() -> _win32typing.PyWAVEFORMATEX: ...
48-
def TimeStamp(*args): ... # incomplete
48+
@overload
49+
@deprecated("Support for passing two ints to create a 64-bit value is deprecated; pass a single int instead")
50+
def TimeStamp(timestamp: tuple[int, int], /) -> TimeType: ...
51+
@overload
52+
def TimeStamp(timestamp: int, /) -> TimeType: ...
4953

5054
FALSE: Literal[False]
5155
TRUE: Literal[True]

stubs/pywin32/win32/lib/win32pdhquery.pyi

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from _typeshed import Incomplete
2+
from typing_extensions import deprecated
23

34
class BaseQuery:
45
counters: Incomplete
@@ -24,6 +25,8 @@ class BaseQuery:
2425
class Query(BaseQuery):
2526
volatilecounters: Incomplete
2627
def __init__(self, *args, **namedargs) -> None: ...
28+
@deprecated("Use `addcounterbybrowsing` instead.")
29+
def addperfcounter(self, object, counter, machine=None): ...
2730
def addinstcounter(
2831
self, object, counter, machine: Incomplete | None = ..., objtype: str = ..., volatile: int = ..., format=...
2932
) -> None: ...

stubs/pywin32/win32/win32api.pyi

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from _typeshed import Incomplete, ReadableBuffer
22
from collections.abc import Callable, Iterable
33
from typing import TypedDict
4+
from typing_extensions import deprecated
45

56
import _win32typing
67
from win32.lib.pywintypes import error as error
@@ -111,8 +112,10 @@ def GetModuleFileName(hModule: int, /) -> str: ...
111112
def GetModuleFileNameW(hModule: int, /) -> str: ...
112113
def GetModuleHandle(fileName: str | None = ..., /) -> int: ...
113114
def GetPwrCapabilities(): ...
115+
@deprecated("This function is obsolete, applications should use the registry instead.")
114116
def GetProfileSection(section: str, iniName: str | None = ..., /): ...
115117
def GetProcAddress(hModule: int, functionName: _win32typing.PyResourceId, /): ...
118+
@deprecated("This function is obsolete, applications should use the registry instead.")
116119
def GetProfileVal(section: str, entry: str, defValue: str, iniName: str | None = ..., /) -> str: ...
117120
def GetShortPathName(path: str, /) -> str: ...
118121
def GetStdHandle(handle: int, /) -> _win32typing.PyHANDLE: ...
@@ -223,6 +226,7 @@ def SetSysColors(Elements, RgbValues, /) -> None: ...
223226
def SetLocalTime(SystemTime: _win32typing.PyTime, /) -> None: ...
224227
def SetSystemTime(year, month, dayOfWeek, day, hour, minute, second, millseconds, /): ...
225228
def SetClassLong(hwnd: int, offset, val, /): ...
229+
@deprecated("This function is obsolete, use `win32api.SetClassLong` instead")
226230
def SetClassWord(hwnd: int, offset, val, /): ...
227231
def SetCursor(hCursor: int, /) -> int: ...
228232
def SetEnvironmentVariable(Name, Value, /) -> None: ...
@@ -233,6 +237,11 @@ def SetSystemPowerState(Suspend, Force, /) -> None: ...
233237
def SetThreadLocale(lcid, /) -> None: ...
234238
def SetTimeZoneInformation(tzi, /): ...
235239
def SetWindowLong(hwnd: int | None, offset: int, value: float, /) -> int: ...
240+
241+
# This method is accidentally overwritten in source, can re-introduce once fixed:
242+
# https://github.com/mhammond/pywin32/pull/2199
243+
# @deprecated("This function is obsolete, use `win32api.SetWindowLong` instead")
244+
# def SetWindowWord(hwnd, offset: int, val: int) -> int: ...
236245
def ShellExecute(hwnd: int, op: str, file: str, params: str, _dir: str, bShow, /): ...
237246
def ShowCursor(show, /): ...
238247
def Sleep(time, bAlterable: int = ..., /): ...
@@ -250,7 +259,9 @@ def UpdateResource(
250259
def VkKeyScan(char, char1, /): ...
251260
def WinExec(cmdLine: str, arg, /) -> None: ...
252261
def WinHelp(hwnd: int, hlpFile: str, cmd, data: str | int = ..., /) -> None: ...
262+
@deprecated("This function is obsolete, applications should use the registry instead.")
253263
def WriteProfileSection(section: str, data: str, iniName: str | None = ..., /): ...
264+
@deprecated("This function is obsolete, applications should use the registry instead.")
254265
def WriteProfileVal(section: str, entry: str, value: str, iniName: str | None = ..., /) -> None: ...
255266
def HIBYTE(val: int, /) -> int: ...
256267
def LOBYTE(val: int, /) -> int: ...

stubs/pywin32/win32/win32file.pyi

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from _typeshed import Incomplete
22
from socket import socket
33
from typing import overload
4+
from typing_extensions import deprecated
45

56
import _win32typing
67
from win32.lib.pywintypes import error as error
@@ -90,7 +91,11 @@ def SetEndOfFile(hFile: int, /) -> None: ...
9091
def SetFileApisToANSI() -> None: ...
9192
def SetFileApisToOEM() -> None: ...
9293
def SetFileAttributes(filename: str, newAttributes: int, /) -> None: ...
93-
def SetFilePointer(handle: int, offset, moveMethod, /) -> None: ...
94+
@overload
95+
@deprecated("Support for passing two ints to create a 64-bit value is deprecated; pass a single int instead")
96+
def SetFilePointer(handle: int, offset: tuple[int, int], moveMethod, /) -> None: ...
97+
@overload
98+
def SetFilePointer(handle: int, offset: int, moveMethod, /) -> None: ...
9499
def SetVolumeLabel(rootPathName: str, volumeName: str, /) -> None: ...
95100
def UnlockFile(hFile: int, offsetLow, offsetHigh, nNumberOfBytesToUnlockLow, nNumberOfBytesToUnlockHigh, /) -> None: ...
96101
def TransmitFile(
@@ -162,7 +167,11 @@ def DuplicateEncryptionInfoFile(
162167
def BackupRead(
163168
hFile: int, NumberOfBytesToRead, Buffer, bAbort, bProcessSecurity, lpContext, /
164169
) -> tuple[Incomplete, Incomplete, Incomplete]: ...
165-
def BackupSeek(hFile: int, NumberOfBytesToSeek, lpContext, /): ...
170+
@overload
171+
@deprecated("Support for passing two ints to create a 64-bit value is deprecated; pass a single int instead")
172+
def BackupSeek(hFile: int, NumberOfBytesToSeek: tuple[int, int], lpContext, /): ...
173+
@overload
174+
def BackupSeek(hFile: int, NumberOfBytesToSeek: int, lpContext, /): ...
166175
def BackupWrite(
167176
hFile: int, NumberOfBytesToWrite, Buffer: str, bAbort, bProcessSecurity, lpContext, /
168177
) -> tuple[Incomplete, Incomplete]: ...
@@ -233,11 +242,26 @@ def GetFullPathName(FileName, Transaction: int | None = ...): ...
233242
def Wow64DisableWow64FsRedirection(): ...
234243
def Wow64RevertWow64FsRedirection(OldValue, /) -> None: ...
235244
def GetFileInformationByHandleEx(File: int, FileInformationClass): ...
245+
@overload
246+
@deprecated("Support for passing two ints to create a 64-bit value is deprecated; pass a single int instead")
247+
def SetFileInformationByHandle(File: int, FileInformationClass, Information: tuple[int, int]) -> None: ...
248+
@overload
236249
def SetFileInformationByHandle(File: int, FileInformationClass, Information) -> None: ...
237250
def ReOpenFile(OriginalFile: int, DesiredAccess, ShareMode, Flags) -> int: ...
251+
@overload
252+
@deprecated("Support for passing two ints to create a 64-bit value is deprecated; pass a single int instead")
253+
def OpenFileById(
254+
File: int,
255+
FileId: tuple[int, int],
256+
DesiredAccess,
257+
ShareMode,
258+
Flags,
259+
SecurityAttributes: _win32typing.PySECURITY_ATTRIBUTES | None = ...,
260+
) -> int: ...
261+
@overload
238262
def OpenFileById(
239263
File: int,
240-
FileId: _win32typing.PyIID,
264+
FileId: _win32typing.PyIID | int,
241265
DesiredAccess,
242266
ShareMode,
243267
Flags,

0 commit comments

Comments
 (0)