typeshed icon indicating copy to clipboard operation
typeshed copied to clipboard

Wrong `win32clipboard.GetClipboardData` return type annotations

Open Avasam opened this issue 1 year ago • 2 comments

Transferred from https://github.com/mhammond/pywin32/issues/2411 by @KJH-x


Expected behavior and actual behavior

In vscode pylance lint (hover hint), the description of function GetClipboardData is:

(function) def GetClipboardData(
    _format: Unknown,
    /
) -> str

But infact, the type of clipboard data is not only string, for example the CF_DIB (and other dib formats, are bitmaps), it should be bytes rather than a string.

截图_20241016164133

Steps to reproduce the problem

This is not a runtime bug, This type annotations can be locate at file: ~\.vscode\extensions\ms-python.vscode-pylance-2024.10.1\dist\typeshed-fallback\stubs\pywin32\win32\win32clipboard.pyi line 8

to confirm this type, copy an image and run

import win32clipboard
from win32.win32clipboard import CF_DIB

win32clipboard.OpenClipboard()
# Get the clipboard data in CF_DIB format
# CF_DIB = 8
if win32clipboard.IsClipboardFormatAvailable(CF_DIB):
    dib_data = win32clipboard.GetClipboardData(CF_DIB)
    print(type(dib_data))
win32clipboard.CloseClipboard()

After further searching, I found the relevant document: standard-clipboard-formats(MS doc)

After testing, I think it would be better to return typing.Any, since the clipboard format can be customized.

I asked ai for help and tried to validate the format I came across.

Format Name Format ID Format Return Type (AI generated) Detail Format Using Python Typing Manual Check? example
CF_BITMAP 2 HBITMAP int yes -1257946354
CF_DIB 8 BITMAPINFO and bitmap bits bytes
(a fp can be read by PIL image.open(BytesIO( data ))
yes b'(...\x07...\x05...\x01. .\x03...\x8c.....................*..*..*......*...*...*...*...*...*...*...*...*...*...*...*...*...*...*...*...*...*...*...*...*...*...*...*...*...*...*...*...*...*...*...*...*...*...*'
.=\x00, *=\xff
CF_DIBV5 17 BITMAPV5HEADER, color space, bits bytes
(a fp can be read by PIL image.open(BytesIO( data ))
yes b'|...\x01...\x07...\x01. .\x03...\x1c.....................*..*..*.......BGRs................................................\x04.................*..*..*......*...*...*...*...*...*...*'
.=\x00, *=\xff
CF_DIF 5 Software Arts' Data Interchange str
CF_DSPBITMAP 0x0082 Data in bitmap display format bytes
CF_DSPENHMETAFILE 0x008E Data in enhanced metafile format bytes
CF_DSPMETAFILEPICT 0x0083 Data in metafile-picture format bytes
CF_DSPTEXT 0x0081 Data in text format str
CF_ENHMETAFILE 14 HENHMETAFILE int
CF_GDIOBJFIRST 0x0300 Application-defined GDI object Any
CF_GDIOBJLAST 0x03FF Application-defined GDI object Any
CF_HDROP 15 HDROP (file list) tuple[str] ('C:\Users\...',)
CF_LOCALE 16 HGLOBAL (locale identifier) LCID bytes yes b'\x04\x08\x00\x00'
CF_METAFILEPICT 3 Handle to metafile picture format int
CF_OEMTEXT 7 OEM character set text bytes yes b'example string'
CF_OWNERDISPLAY 0x0080 Owner-display format None
CF_PALETTE 9 Handle to color palette int
CF_PENDATA 10 Pen data bytes
CF_PRIVATEFIRST 0x0200 Private clipboard format Any
CF_PRIVATELAST 0x02FF Private clipboard format Any
CF_RIFF 11 Complex audio data (RIFF) bytes
CF_SYLK 4 Microsoft Symbolic Link (SYLK) str
CF_TEXT 1 ANSI text bytes yes b'example string'
CF_TIFF 6 Tagged Image File Format (TIFF) bytes
CF_UNICODETEXT 13 Unicode text str yes 'example string'
CF_WAVE 12 Standard WAVE audio data bytes
UNICODE True Not in doc but in win32clipboard.pyi bytes yes b'example string'

Avasam avatar Oct 16 '24 16:10 Avasam

W/o overloads I agree for a return type Any. But it shouldn't be too hard to overload, although those constants should also be made literal with Final in https://github.com/python/typeshed/blob/main/stubs/pywin32/win32/win32clipboard.pyi to be truly useful.

Avasam avatar Oct 16 '24 16:10 Avasam

Sidenote: The CF_METAFILEPICT format is currently not supported by pywin32 and will always raise. See: https://github.com/mhammond/pywin32/issues/1589

Avasam avatar Oct 18 '24 01:10 Avasam