Skip to content
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
17 changes: 5 additions & 12 deletions mypy.ini
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ python_version = 3.9

strict = true
implicit_reexport = true
allow_redefinition = true
allow_redefinition_new = true
local_partial_types = true
; Necessary to avoid "same module name" issues
explicit_package_bases = true
; Must specify top-level packages and scripts folders for mypy to work with explicit_package_bases
Expand All @@ -26,31 +29,21 @@ disallow_untyped_defs = false
disallow_incomplete_defs = false

disable_error_code =
; Module has no attribute; (Dynamic modules will be hard to type without first-party stubs, ie: pythoncom.*)
; Module has no attribute; (Dynamic modules will be hard to type without type stubs, ie: pythoncom.*)
attr-defined,
; Class cannot subclass "..." (has type "Any"); (IDEM)
; TODO: Use typeshed's types-pywin32 stubs after a few more fixes there
misc,
; These are the other error codes that would currently fail with check_untyped_defs = true
; and have no PR already open to fix them
; TODO: Gradually fix them until we can turn on check_untyped_defs
; arg-type,
; assignment,
; call-arg,
; comparison-overlap,
; has-type,
; index,
; list-item,
; operator,
; override,
; str-format,
; type-var,
; union-attr,
; valid-type,
; var-annotated,
; ; And these only happen when checking against types-pywin32
; func-returns-value,
; call-overload,
; no-redef,
exclude = (?x)(
^build/
; Vendored
Expand Down
6 changes: 3 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ checkers = [ # Keep these in sync with .pre-commit-config.yaml
"ruff ==0.14.14",
]
type-checkers = [
"types-setuptools",
"types-setuptools >=80.9.0.20251221",
"PyOpenGL",
"mypy ==1.16.*; python_version >='3.9'",
"pyright ==1.1.401",
"mypy ==1.19.*",
"pyright ==1.1.407",
]
dev = [
"pre-commit",
Expand Down
7 changes: 4 additions & 3 deletions pyrightconfig.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"typeCheckingMode": "basic",
"typeCheckingMode": "standard",
// Needs to be set for non-Windows CI runners
"pythonPlatform": "Windows",
// Target the oldest supported version in editors and default CLI
Expand Down Expand Up @@ -29,17 +29,18 @@
],
"reportConstantRedefinition": "error",
// TODO: For now this allows us to at least put pyright in place by massively reducing checked code
// it also reduces issues with the shipped types-pywin32 from typeshed
"reportGeneralTypeIssues": "none",
"reportArgumentType": "none",
"reportAttributeAccessIssue": "none",
"reportIncompatibleMethodOverride": "none",
// FIXE: These all need to be fixed first and turned back to error
"reportCallIssue": "warning",
"reportGeneralTypeIssues": "warning",
"reportOperatorIssue": "warning",
"reportOptionalCall": "warning",
"reportOptionalIterable": "warning",
"reportOptionalMemberAccess": "warning",
"reportOptionalSubscript": "warning",
"reportPossiblyUnboundVariable": "warning",
// Too many dynamically generated modules. This will require type stubs to properly fix.
"reportMissingImports": "warning",
// IDEM, but happens when pywin32 is not in site-packages but module is found from typeshed.
Expand Down
2 changes: 1 addition & 1 deletion pythonwin/pywin/framework/dbgcommands.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ def _DoOrStart(self, doMethod, startFlag):
method()
else:
scriptutils.RunScript(
defName=None, defArgs=None, bShowDialog=0, debuggingType=startFlag
defName=None, defArgs=None, bShowDialog=False, debuggingType=startFlag
)

def OnStep(self, msg, code):
Expand Down
23 changes: 6 additions & 17 deletions pythonwin/pywin/framework/intpyapp.py
Original file line number Diff line number Diff line change
Expand Up @@ -327,29 +327,18 @@ def ProcessArgs(self, args: Sequence[str], dde=None):
dde.Exec(f"win32ui.GetApp().OpenDocumentFile({fname!r})")
else:
win32ui.GetApp().OpenDocumentFile(par)
elif argType == "/rundlg":
elif argType in {"/rundlg", "/run"}:
defArgs = " ".join(args[i + 1 :])
showDialog = argType == "/rundlg"
if dde:
dde.Exec(
"from pywin.framework import scriptutils;scriptutils.RunScript({!r}, {!r}, 1)".format(
par, " ".join(args[i + 1 :])
)
"from pywin.framework import scriptutils;"
+ f"scriptutils.RunScript({par!r}, {defArgs!r}, {showDialog!r})"
)
else:
from . import scriptutils

scriptutils.RunScript(par, " ".join(args[i + 1 :]))
return
elif argType == "/run":
if dde:
dde.Exec(
"from pywin.framework import scriptutils;scriptutils.RunScript({!r}, {!r}, 0)".format(
par, " ".join(args[i + 1 :])
)
)
else:
from . import scriptutils

scriptutils.RunScript(par, " ".join(args[i + 1 :]), 0)
scriptutils.RunScript(par, defArgs, showDialog)
return
elif argType == "/app":
raise RuntimeError(
Expand Down
30 changes: 18 additions & 12 deletions pythonwin/pywin/framework/scriptutils.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
Various utilities for running/importing a script
"""

from __future__ import annotations

import bdb
import linecache
import os
Expand Down Expand Up @@ -211,9 +213,14 @@ def GetActiveFileName(bAutoSave=1):
lastDebuggingType = RS_DEBUGGER_NONE


def RunScript(defName=None, defArgs=None, bShowDialog=1, debuggingType=None):
def RunScript(
defName: str | None = None,
defArgs: str | None = None,
bShowDialog: bool = True,
debuggingType: int | None = None,
):
global lastScript, lastArgs, lastDebuggingType
_debugger_stop_frame_ = 1 # Magic variable so the debugger will hide me!
_debugger_stop_frame_ = True # Magic variable so the debugger will hide me!

# Get the debugger - may be None!
debugger = GetDebugger()
Expand Down Expand Up @@ -309,7 +316,7 @@ def RunScript(defName=None, defArgs=None, bShowDialog=1, debuggingType=None):
f = open(script, "rb")
except OSError as exc:
win32ui.MessageBox(
"The file could not be opened - %s (%d)" % (exc.strerror, exc.errno)
f"The file could not be opened - {exc.strerror} ({exc.errno})"
)
return

Expand Down Expand Up @@ -408,7 +415,7 @@ def RunScript(defName=None, defArgs=None, bShowDialog=1, debuggingType=None):
win32ui.DoWaitCursor(0)


def ImportFile():
def ImportFile() -> None:
"""This code looks for the current window, and determines if it can be imported. If not,
it will prompt for a file name, and allow it to be imported."""
try:
Expand All @@ -427,20 +434,19 @@ def ImportFile():
)
dlg.SetOFNTitle("Import Script")
if dlg.DoModal() != win32con.IDOK:
return 0
return

pathName = dlg.GetPathName()

# If already imported, don't look for package
path, modName = os.path.split(pathName)
modName, modExt = os.path.splitext(modName)
newPath = None
# note that some packages (*cough* email *cough*) use "lazy importers"
# meaning sys.modules can change as a side-effect of looking at
# module.__file__ - so we must take a copy (ie, list(items()))
for key, mod in sys.modules.items():
if getattr(mod, "__file__", None):
fname = mod.__file__
for key, mod in list(sys.modules.items()):
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Potential bugfix as mentioned by the comment

fname = getattr(mod, "__file__", None)
if fname:
base, ext = os.path.splitext(fname)
if ext.lower() in (".pyo", ".pyc"):
ext = ".py"
Expand All @@ -454,15 +460,15 @@ def ImportFile():
sys.path.append(newPath)

if modName in sys.modules:
bNeedReload = 1
bNeedReload = True
what = "reload"
else:
what = "import"
bNeedReload = 0
bNeedReload = False

win32ui.SetStatusText(what.capitalize() + "ing module...", 1)
win32ui.DoWaitCursor(1)
# win32ui.GetMainFrame().BeginWaitCursor()
# win32ui.GetMainFrame().BeginWaitCursor()

try:
# always do an import, as it is cheap if it's already loaded. This ensures
Expand Down
6 changes: 1 addition & 5 deletions pythonwin/pywin/framework/toolmenu.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
# toolmenu.py

import sys

import win32api
import win32con
import win32ui

tools = {}
tools: dict[int, tuple[str, str, str]] = {}
idPos = 100

# The default items should no tools menu exist in the INI file.
Expand Down Expand Up @@ -73,7 +71,6 @@ def WriteToolMenuItems(items):


def SetToolsMenu(menu, menuPos=None):
global tools
global idPos

# todo - check the menu does not already exist.
Expand Down Expand Up @@ -111,7 +108,6 @@ def HandleToolCommand(cmd, code):
import re
import traceback

global tools
(menuString, pyCmd, desc) = tools[cmd]
win32ui.SetStatusText("Executing tool %s" % desc, 1)
pyCmd = re.sub(r"\\n", "\n", pyCmd)
Expand Down
30 changes: 12 additions & 18 deletions pythonwin/pywin/scintilla/keycodes.py
Original file line number Diff line number Diff line change
@@ -1,34 +1,28 @@
import win32api
import win32con
import win32ui

MAPVK_VK_TO_CHAR = 2

key_name_to_vk = {}
key_code_to_name = {}

_better_names = {
"escape": "esc",
"return": "enter",
"back": "pgup",
"next": "pgdn",
}


def _fillvkmap():
# Pull the VK_names from win32con
names = [entry for entry in win32con.__dict__ if entry.startswith("VK_")]
for name in names:
code = getattr(win32con, name)
n = name[3:].lower()
# Pull the VK_names from win32con
key_name_to_vk: dict[str, int] = {}
key_code_to_name: dict[int, str] = {}
for __name in win32con.__dict__:
if not __name.startswith("VK_"):
continue
code = getattr(win32con, __name)
n = __name[3:].lower()
key_name_to_vk[n] = code
if n in _better_names:
n = _better_names[n]
key_name_to_vk[n] = code
if n in _better_names:
n = _better_names[n]
key_name_to_vk[n] = code
key_code_to_name[code] = n


_fillvkmap()
key_code_to_name[code] = n


def get_vk(chardesc):
Expand Down
Loading
Loading