Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

typecheck Demos modules with mypy #2292

Open
wants to merge 14 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 4 additions & 6 deletions Pythonwin/pywin/Demos/app/customprint.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import win32con
import win32ui
from pywin.framework import app
from pywin.framework.app import CApp
from pywin.mfc import afxres, dialog, docview

PRINTDLGORD = 1538
Expand Down Expand Up @@ -132,10 +132,7 @@ def OnPrint(self, dc, pInfo):
y += cyChar


class PrintDemoApp(app.CApp):
def __init__(self):
app.CApp.__init__(self)

class PrintDemoApp(CApp):
def InitInstance(self):
template = PrintDemoTemplate(None, None, None, PrintDemoView)
self.AddDocTemplate(template)
Expand Down Expand Up @@ -173,11 +170,12 @@ def OnOK(self):


if __name__ == "__main__":
# Running under Pythonwin

def test():
template = PrintDemoTemplate(None, None, None, PrintDemoView)
template.OpenDocumentFile(None)

test()
else:
# Running under Pythonwin
app = PrintDemoApp()
2 changes: 1 addition & 1 deletion Pythonwin/pywin/Demos/cmdserver.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ def ServerThread(myout, cmd, title, bCloseOnEnd):
# assist for reloading (when debugging) - use only 1 tracer object,
# else a large chain of tracer objects will exist.
try:
writer
writer # type: ignore[has-type, used-before-def]
except NameError:
writer = ThreadWriter()
if __name__ == "__main__":
Expand Down
2 changes: 1 addition & 1 deletion Pythonwin/pywin/Demos/menutest.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
if __name__ == "__main__":
import demoutils

if demoutils.NeedGoodGUI():
if demoutils.NeedGoodGUI() and interact.edit is not None:
win = interact.edit.currentView.GetParent()
menu = win.GetSystemMenu()
id = menu.GetMenuItemID(6)
Expand Down
2 changes: 1 addition & 1 deletion Pythonwin/pywin/Demos/ocx/flash.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
raise ImportError("Flash does not appear to be installed.")


class MyFlashComponent(activex.Control, FlashModule.ShockwaveFlash):
class MyFlashComponent(activex.Control, FlashModule.ShockwaveFlash): # type: ignore[name-defined] # Generated module
def __init__(self):
activex.Control.__init__(self)
FlashModule.ShockwaveFlash.__init__(self)
Expand Down
3 changes: 1 addition & 2 deletions Pythonwin/pywin/Demos/ocx/ocxserialtest.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import pythoncom
import win32con
import win32ui
import win32uiole
from pywin.mfc import activex, dialog
from win32com.client import gencache

Expand Down Expand Up @@ -56,7 +55,7 @@ def MakeDlgTemplate():
#
# Serial Control
#
class MySerialControl(activex.Control, serialModule.MSComm):
class MySerialControl(activex.Control, serialModule.MSComm): # type: ignore[name-defined] # Generated module
def __init__(self, parent):
activex.Control.__init__(self)
serialModule.MSComm.__init__(self)
Expand Down
2 changes: 1 addition & 1 deletion Pythonwin/pywin/Demos/ocx/webbrowser.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
raise ImportError("Internet Explorer does not appear to be installed.")


class MyWebBrowser(activex.Control, WebBrowserModule.WebBrowser):
class MyWebBrowser(activex.Control, WebBrowserModule.WebBrowser): # type: ignore[name-defined] # Generated module
def OnBeforeNavigate2(
self, pDisp, URL, Flags, TargetFrameName, PostData, Headers, Cancel
):
Expand Down
12 changes: 6 additions & 6 deletions com/win32com/client/gencache.py
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ class which wraps the COM object.
return mod


def GetModuleForTypelib(typelibCLSID, lcid, major, minor):
def GetModuleForTypelib(typelibCLSID, lcid, major, minor) -> ModuleType:
"""Get a Python module for a type library ID

Given the CLSID of a typelibrary, return an imported Python module,
Expand Down Expand Up @@ -303,7 +303,7 @@ def MakeModuleForTypelib(
progressInstance=None,
bForDemand=bForDemandDefault,
bBuildHidden=1,
):
) -> ModuleType:
"""Generate support for a type library.

Given the IID, LCID and version information for a type library, generate
Expand Down Expand Up @@ -434,7 +434,7 @@ def EnsureModule(
bValidateFile=not is_readonly,
bForDemand=bForDemandDefault,
bBuildHidden=1,
):
) -> ModuleType | None:
"""Ensure Python support is loaded for a type library, generating if necessary.

Given the IID, LCID and version information for a type library, check and if
Expand Down Expand Up @@ -561,13 +561,13 @@ def EnsureModule(
try:
pyModTime = os.stat(filePath)[8]
fModTimeSet = 1
except OSError as e:
except OSError:
# If .py file fails, try .pyc file
# print("Trying pyc stat", filePathPyc)
try:
pyModTime = os.stat(filePathPyc)[8]
fModTimeSet = 1
except OSError as e:
except OSError:
pass
# print("Trying stat typelib", pyModTime)
# print(typLibPath)
Expand Down Expand Up @@ -727,7 +727,7 @@ def GetGeneratedInfos():
return ret


def _GetModule(fname):
def _GetModule(fname) -> ModuleType:
"""Given the name of a module in the gen_py directory, import and return it."""
mod_name = "win32com.gen_py.%s" % fname
mod = __import__(mod_name)
Expand Down
20 changes: 13 additions & 7 deletions mypy.ini
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,15 @@ implicit_reexport = true
explicit_package_bases = true
; Must specify top-level packages and scripts folders for mypy to work with explicit_package_bases
mypy_path =
$MYPY_CONFIG_FILE_DIR/AutoDuck,
$MYPY_CONFIG_FILE_DIR/com,
$MYPY_CONFIG_FILE_DIR/win32/Lib,
$MYPY_CONFIG_FILE_DIR/Pythonwin,
$MYPY_CONFIG_FILE_DIR/AutoDuck,
$MYPY_CONFIG_FILE_DIR/Pythonwin/pywin/Demos,
$MYPY_CONFIG_FILE_DIR/win32/Demos,
$MYPY_CONFIG_FILE_DIR/win32/Demos/security,
$MYPY_CONFIG_FILE_DIR/win32/Demos/service,
$MYPY_CONFIG_FILE_DIR/win32/Demos/win32wnet,
$MYPY_CONFIG_FILE_DIR/win32/Lib,
$MYPY_CONFIG_FILE_DIR/win32/scripts/VersionStamp,

; TODO: Gradually type classes and functions until we can turn back check_untyped_defs to true.
Expand Down Expand Up @@ -56,17 +61,18 @@ exclude = (?x)(
; Forked IDLE extensions predating Python 2.3. They now live in idlelib in https://github.com/python/cpython/tree/main/Lib/idlelib
| ^Pythonwin/pywin/idle/
; TODO: Ignoring non-public APIs until all public API is typed
| ([Tt]est|[Dd]emos?)/
| ([Tt]est|demos?)/
)

; C-modules that will need type-stubs
[mypy-adsi.*,dde,exchange,mapi,perfmon,servicemanager,win32api,win32console,win32clipboard,win32comext.adsi.adsi,win32event,win32evtlog,win32file,win32gui,win32help,win32pdh,win32process,win32ras,win32security,win32service,win32trace,win32ui,win32uiole,win32wnet,_win32sysloader,_winxptheme]
[mypy-adsi.*,dde,exchange,mapi,mmapfile,perfmon,servicemanager,timer,win32api,win32console,win32clipboard,win32comext.adsi.adsi,win32cred,win32event,win32evtlog,win32file,win32gui,win32help,win32net,win32pdh,win32pipe,win32print,win32process,win32profile,win32ras,win32security,win32service,win32trace,win32transaction,win32ts,win32ui,win32uiole,win32wnet,_win32sysloader,_winxptheme]
ignore_missing_imports = True

; Most of win32com re-exports win32comext
; Test is a local untyped module in win32comext.axdebug
; pywin32_system32 is an empty module created in setup.py to store dlls
[mypy-win32com.*,Test,pywin32_system32]
; OpenGL is untyped
; Test is a local untyped module in win32comext.axdebug
; Most of win32com re-exports win32comext
[mypy-pywin32_system32,OpenGL.*,Test,win32com.*]
ignore_missing_imports = True

; Distutils being removed from stdlib currently causes some issues on Python 3.12
Expand Down
4 changes: 3 additions & 1 deletion win32/Demos/FileSecurityTest.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# Contributed by Kelly Kranabetter.
from __future__ import annotations

import os
import sys

Expand Down Expand Up @@ -116,7 +118,7 @@
"GENERIC_ALL",
)
if os.path.isfile(name):
permissions = permissions_file
permissions: tuple[str, ...] = permissions_file
else:
permissions = permissions_dir
# directories also contain an ACE that is inherited by children (files) within them
Expand Down
27 changes: 12 additions & 15 deletions win32/Demos/OpenEncryptedFileRaw.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,37 +30,34 @@ def WriteCallback(output_buffer, data, buflen):
## create an encrypted file
fname = win32api.GetTempFileName(dst_dir, "ref")[0]
print("orig file:", fname)
f = open(fname, "w")
f.write("xxxxxxxxxxxxxxxx\n" * 32768)
f.close()
with open(fname, "w") as f:
f.write("xxxxxxxxxxxxxxxx\n" * 32768)
## add a couple of extra data streams
f = open(fname + ":stream_y", "w")
f.write("yyyyyyyyyyyyyyyy\n" * 32768)
f.close()
f = open(fname + ":stream_z", "w")
f.write("zzzzzzzzzzzzzzzz\n" * 32768)
f.close()
with open(fname + ":stream_y", "w") as f:
f.write("yyyyyyyyyyyyyyyy\n" * 32768)
with open(fname + ":stream_z", "w") as f:
f.write("zzzzzzzzzzzzzzzz\n" * 32768)
win32file.EncryptFile(fname)

## backup raw data of encrypted file
bkup_fname = win32api.GetTempFileName(dst_dir, "bef")[0]
print("backup file:", bkup_fname)
f = open(bkup_fname, "wb")
fw = open(bkup_fname, "wb")
ctxt = win32file.OpenEncryptedFileRaw(fname, 0)
try:
win32file.ReadEncryptedFileRaw(ReadCallback, (fname, bkup_fname, f), ctxt)
win32file.ReadEncryptedFileRaw(ReadCallback, (fname, bkup_fname, fw), ctxt)
finally:
## if context is not closed, file remains locked even if calling process is killed
win32file.CloseEncryptedFileRaw(ctxt)
f.close()
fw.close()

## restore data from backup to new encrypted file
dst_fname = win32api.GetTempFileName(dst_dir, "wef")[0]
print("restored file:", dst_fname)
f = open(bkup_fname, "rb")
fr = open(bkup_fname, "rb")
ctxtout = win32file.OpenEncryptedFileRaw(dst_fname, win32file.CREATE_FOR_IMPORT)
try:
win32file.WriteEncryptedFileRaw(WriteCallback, (bkup_fname, dst_fname, f), ctxtout)
win32file.WriteEncryptedFileRaw(WriteCallback, (bkup_fname, dst_fname, fr), ctxtout)
finally:
win32file.CloseEncryptedFileRaw(ctxtout)
f.close()
fr.close()
5 changes: 3 additions & 2 deletions win32/Demos/desktopmanager.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Demonstrates using a taskbar icon to create and navigate between desktops
from __future__ import annotations

import _thread
import io
Expand Down Expand Up @@ -115,7 +116,7 @@ def new_icon(hdesk, desktop_name):
flags,
win32con.WM_USER + 20,
hicon,
"Desktop Manager (%s)" % desktop_name,
f"Desktop Manager ({desktop_name})",
)
window_info[hwnd] = notify_info
## wait for explorer to initialize system tray for new desktop
Expand Down Expand Up @@ -221,7 +222,7 @@ def icon_wndproc(hwnd, msg, wp, lp):
return win32gui.DefWindowProc(hwnd, msg, wp, lp)


window_info = {}
window_info: dict[int, tuple[int, int, int, int, int, str]] = {}
origin_desktop = win32service.OpenInputDesktop(0, True, win32con.MAXIMUM_ALLOWED)
origin_desktop_name = win32service.GetUserObjectInformation(
origin_desktop, win32service.UOI_NAME
Expand Down
Loading