diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index aa6ecd69c..fb05eee83 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -154,4 +154,5 @@ jobs: - uses: jakebailey/pyright-action@v2 with: python-version: ${{ matrix.python-version }} + version: "1.1.358" annotate: errors diff --git a/CHANGES.txt b/CHANGES.txt index 101ff94f1..3a04862bd 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,4 @@ -Notable changes in recent builds. +Notable changes in recent builds. Maintained by hand, so what's "notable" is subjective! Contributors are encouraged to add entries for their work. @@ -15,6 +15,10 @@ Coming in build 307, as yet unreleased -------------------------------------- ### pywin32 +* Fixed non-overriden `pywin.scintilla.formatter.Formatter.ColorizeString` raising `TypeError` instead of `RuntimeError` due to too many parameters (#2216, @Avasam) +* Fixed broken since Python 3 tokenization in `win32comext.axdebug.codecontainer.pySourceCodeContainer.GetSyntaxColorAttributes` (#2216, @Avasam) +* Fixed a `TypeError` due to incorrect kwargs in `win32comext.axscript.client.pydumper.Register` (#2216, @Avasam) +* Fixed error reporting of file copy failure for for installing debug dlls (#2216, @Avasam) * Fixed `py.exe -m win32verstamp` command and other quote typos caused by Implied String Concatenation (#2225, @Avasam) * Fixed VT_SAFEARRAY(VT_RECORD) which were missing the last element (#2247) * Fixed `MFC redist DLLs not found` by preferring corresponding version but accepting different version (#2248, @andreabravetti) @@ -22,7 +26,7 @@ Coming in build 307, as yet unreleased * Fixed handling of `SyntaxError` exception from a Windows Scripting Host Python Script on Python 3.10+ (#2235, @nbbeatty) * Add `CredGetSessionTypes` support (#2232, @CristiFati) * Fixed `win32clipboard` increasing size of data when `SetClipboardData` used with `CF_DIB` (#2184, @CristiFati) -* Add `StoreLogoff` to `PyIMsgStore` to prevent possible hang when MAPI uninitializes or during session logoff (#2196, avivbrg) +* Add `StoreLogoff` to `PyIMsgStore` to prevent possible hang when MAPI uninitializes or during session logoff (#2196, @avivbrg) * Enhance CredDelete to work with dictionaries (#2198, @CristiFati) * Add UnregisterHotKey support (#2185, @CristiFati) * IFolderView COM client support (#2180, #2181, #2182, @CristiFati) @@ -131,17 +135,17 @@ Coming in build 307, as yet unreleased * General speed and size improvements due to all the removed code. (#2046, #1986, #2050, #1950, #2085, #2087, #2051, #1990, #2106, #2127, #2124, #2126, #2177, #2218, #2202, #2205, #2217) ### adodbapi -* Remove references to outdated IronPython (#2049) +* Remove references to outdated IronPython (#2049, @Avasam) This removes the following public names: * `adodbapi.adodbapi.onWin32` * `adodbapi.apibase.onIronPython` * `adodbapi.apibase.NullTypes` * `adodbapi.apibase.DateTime` -* Remove references to outdated `mxDateTime` (#2048) +* Remove references to outdated `mxDateTime` (#2048, @Avasam) This removes the following public names: * `adodbapi.apibase.mxDateTime` * `adodbapi.apibase.mxDateTimeConverter` -* Removed obsolete Python 2 aliases (#2088) +* Removed obsolete Python 2 aliases (#2088, @Avasam) This removes the following public names: * `adodbapi.adodbapi.unicodeType` * `adodbapi.adodbapi.longType` @@ -152,8 +156,8 @@ Coming in build 307, as yet unreleased * `adodbapi.apibase.StringTypes` * `adodbapi.apibase.makeByteBuffer` * `adodbapi.apibase.memoryViewType` -* Remove outdated and unused remote feature (#2098) -* Migrated from `distutils` to `setuptools` (#2133) +* Remove outdated and unused remote feature (#2098, @Avasam) +* Migrated from `distutils` to `setuptools` (#2133, @Avasam) Build 306, released 2023-03-26 ------------------------------ diff --git a/Pythonwin/pywin/framework/interact.py b/Pythonwin/pywin/framework/interact.py index f1c0f143c..1bd47c440 100644 --- a/Pythonwin/pywin/framework/interact.py +++ b/Pythonwin/pywin/framework/interact.py @@ -163,7 +163,7 @@ def ColorizeInteractiveCode(self, cdoc, styleStart, stylePyStart): if ch not in "\r\n": self.ColorSeg(startSeg, i - 1, state) startSeg = i - if ch in (sys.ps1[0], sys.ps2[0]): + if ch in (str(sys.ps1)[0], str(sys.ps2)[0]): state = STYLE_INTERACTIVE_PROMPT elif cdoc[i : i + len(tracebackHeader)] == tracebackHeader: state = STYLE_INTERACTIVE_ERROR diff --git a/Pythonwin/pywin/framework/startup.py b/Pythonwin/pywin/framework/startup.py index 5496063e3..d10eecf35 100644 --- a/Pythonwin/pywin/framework/startup.py +++ b/Pythonwin/pywin/framework/startup.py @@ -43,6 +43,10 @@ import pywin import pywin.framework +# Ensure we're working on __path__ as list, not Iterable +pywin.__path__ = list(pywin.__path__) +pywin.framework.__path__ = list(pywin.framework.__path__) + pywin.__path__[0] = win32ui.FullPath(pywin.__path__[0]) pywin.framework.__path__[0] = win32ui.FullPath(pywin.framework.__path__[0]) diff --git a/Pythonwin/pywin/scintilla/config.py b/Pythonwin/pywin/scintilla/config.py index f6916a733..8113a0a89 100644 --- a/Pythonwin/pywin/scintilla/config.py +++ b/Pythonwin/pywin/scintilla/config.py @@ -64,7 +64,7 @@ def get_section_header(line): def find_config_file(f): - return os.path.join(pywin.__path__[0], f + ".cfg") + return os.path.join(next(iter(pywin.__path__)), f + ".cfg") def find_config_files(): @@ -72,7 +72,7 @@ def find_config_files(): os.path.split(x)[1] for x in [ os.path.splitext(x)[0] - for x in glob.glob(os.path.join(pywin.__path__[0], "*.cfg")) + for x in glob.glob(os.path.join(next(iter(pywin.__path__)), "*.cfg")) ] ] diff --git a/Pythonwin/pywin/scintilla/formatter.py b/Pythonwin/pywin/scintilla/formatter.py index 0f91968fa..b8aad0b13 100644 --- a/Pythonwin/pywin/scintilla/formatter.py +++ b/Pythonwin/pywin/scintilla/formatter.py @@ -279,7 +279,7 @@ def RegisterStyle(self, style, stylenum=None): self.nextstylenum = self.nextstylenum + 1 FormatterBase.RegisterStyle(self, style, stylenum) - def ColorizeString(self, str, charStart, styleStart): + def ColorizeString(self, str, styleStart): raise RuntimeError("You must override this method") def Colorize(self, start=0, end=-1): diff --git a/Pythonwin/pywin/test/test_pywin.py b/Pythonwin/pywin/test/test_pywin.py index 6389de930..63178e2a1 100644 --- a/Pythonwin/pywin/test/test_pywin.py +++ b/Pythonwin/pywin/test/test_pywin.py @@ -26,7 +26,7 @@ user_interaction = getattr(__main__, "user_interaction", False) # from all.py maybe file_abs = os.path.abspath(__file__) src_dir = os.path.dirname(file_abs) -pywin_path = pywin.__path__[0] +pywin_path = next(iter(pywin.__path__)) pythonwinpy_path = os.path.dirname(pywin_path) + "\\start_pythonwin.py" Object = argparse.Namespace _indebugger = "pywin.debugger" in sys.modules diff --git a/Pythonwin/win32uimodule.cpp b/Pythonwin/win32uimodule.cpp index 8b4ae7a5d..5a22057fa 100644 --- a/Pythonwin/win32uimodule.cpp +++ b/Pythonwin/win32uimodule.cpp @@ -1603,8 +1603,8 @@ static PyObject *ui_set_dialog_bk_color(PyObject *self, PyObject *args) int clrCtlBk = RGB(192, 192, 192); int clrCtlText = RGB(0, 0, 0); - // @pyparm int|clrCtlBk|win32ui.RGB(192, 192, 192)|The color for the controls background. - // @pyparm int|clrCtlText|win32ui.RGB(0, 0, 0)|The color for the controls text. + // @pyparm int|clrCtlBk|win32api.RGB(192, 192, 192)|The color for the controls background. + // @pyparm int|clrCtlText|win32api.RGB(0, 0, 0)|The color for the controls text. if (!PyArg_ParseTuple(args, "|ii:SetDialogBkColor", &clrCtlBk, &clrCtlText)) return NULL; CProtectedWinApp *pApp = GetProtectedApp(); diff --git a/com/win32com/__init__.py b/com/win32com/__init__.py index 56d1b815c..3e42dcc10 100644 --- a/com/win32com/__init__.py +++ b/com/win32com/__init__.py @@ -1,6 +1,7 @@ # # Initialization for the win32com package # +from __future__ import annotations import os import sys @@ -26,6 +27,9 @@ ### TODO - Load _all_ \\Extensions subkeys - for now, we only read the default ### Modules will work if loaded into "win32comext" path. +# Ensure we're working on __path__ as list, not Iterable +__path__: list[str] = list(__path__) # type: ignore[no-redef] + def SetupEnvironment(): HKEY_LOCAL_MACHINE = -2147483646 # Avoid pulling in win32con for just these... @@ -96,9 +100,7 @@ def __PackageSupportBuildPath__(package_path): try: import win32com.gen_py - # hrmph - 3.3 throws: TypeError: '_NamespacePath' object does not support indexing - # attempting to get __path__[0] - but I can't quickly repro this stand-alone. - # Work around it by using an iterator. + # __path__ is only ensured to be an Iterable, not a list. __gen_path__ = next(iter(sys.modules["win32com.gen_py"].__path__)) except ImportError: # If a win32com\gen_py directory already exists, then we use it diff --git a/com/win32com/server/register.py b/com/win32com/server/register.py index 6fd412e9d..9f1e3ce49 100644 --- a/com/win32com/server/register.py +++ b/com/win32com/server/register.py @@ -130,7 +130,7 @@ def _find_localserver_exe(mustfind): def _find_localserver_module(): import win32com.server - path = win32com.server.__path__[0] + path = next(iter(win32com.server.__path__)) baseName = "localserver" pyfile = os.path.join(path, baseName + ".py") try: diff --git a/com/win32com/test/GenTestScripts.py b/com/win32com/test/GenTestScripts.py index 627560fde..079f6a984 100644 --- a/com/win32com/test/GenTestScripts.py +++ b/com/win32com/test/GenTestScripts.py @@ -19,7 +19,9 @@ def GetGenPath(): import win32api - return os.path.join(win32api.GetFullPathName(win32com.test.__path__[0]), genDir) + return os.path.join( + win32api.GetFullPathName(next(iter(win32com.test.__path__))), genDir + ) def GenerateFromRegistered(fname, *loadArgs): diff --git a/com/win32com/test/testAXScript.py b/com/win32com/test/testAXScript.py index d7a4553ed..d1dc7f11c 100644 --- a/com/win32com/test/testAXScript.py +++ b/com/win32com/test/testAXScript.py @@ -13,7 +13,7 @@ class AXScript(win32com.test.util.TestCase): def setUp(self): file = win32api.GetFullPathName( - os.path.join(win32com.axscript.client.__path__[0], "pyscript.py") + os.path.join(next(iter(win32com.axscript.client.__path__)), "pyscript.py") ) from win32com.test.util import RegisterPythonServer @@ -22,7 +22,7 @@ def setUp(self): def testHost(self): file = win32api.GetFullPathName( - os.path.join(win32com.axscript.__path__[0], "test\\testHost.py") + os.path.join(next(iter(win32com.axscript.__path__)), "test\\testHost.py") ) cmd = f'{win32api.GetModuleFileName(0)} "{file}"' if verbose: @@ -31,7 +31,9 @@ def testHost(self): def testCScript(self): file = win32api.GetFullPathName( - os.path.join(win32com.axscript.__path__[0], "Demos\\Client\\wsh\\test.pys") + os.path.join( + next(iter(win32com.axscript.__path__)), "Demos\\Client\\wsh\\test.pys" + ) ) cmd = 'cscript.exe "%s"' % (file) if verbose: diff --git a/com/win32comext/axdebug/codecontainer.py b/com/win32comext/axdebug/codecontainer.py index 2030cf695..d6d48048f 100644 --- a/com/win32comext/axdebug/codecontainer.py +++ b/com/win32comext/axdebug/codecontainer.py @@ -159,7 +159,8 @@ def GetSyntaxColorAttributes(self): self.lastPos = 0 self.attrs = [] try: - tokenize.tokenize(self.GetNextLine, self._ProcessToken) + for tokens in tokenize.tokenize(self.GetNextLine): + self._ProcessToken(*tokens) except tokenize.TokenError: pass # Ignore - will cause all subsequent text to be commented. numAtEnd = len(self.GetText()) - self.lastPos diff --git a/com/win32comext/axscript/client/pydumper.py b/com/win32comext/axscript/client/pydumper.py index 281bb9d24..0380d21be 100644 --- a/com/win32comext/axscript/client/pydumper.py +++ b/com/win32comext/axscript/client/pydumper.py @@ -60,11 +60,11 @@ def Register(): RegisterServer( clsid=clsid, pythonInstString="win32com.axscript.client.pyscript.PyDumper", - className="Python Debugging/Dumping ActiveX Scripting Engine", + desc="Python Debugging/Dumping ActiveX Scripting Engine", progID=languageName, verProgID=verProgId, - catids=categories, policy=policy, + catids=categories, dispatcher=dispatcher, ) diff --git a/mypy.ini b/mypy.ini index 7f0506d85..34ac87ef0 100644 --- a/mypy.ini +++ b/mypy.ini @@ -40,7 +40,7 @@ exclude = (?x)( | ^Pythonwin/Scintilla/ ; 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: adodbapi should be updated and fixed separatly + ; TODO: adodbapi should be updated and fixed separately | ^adodbapi/ ; TODO: Ignoring non-public APIs until all public API is typed | ([Tt]est|[Dd]emos?)/ diff --git a/pyrightconfig.json b/pyrightconfig.json index 5ea2fe279..356d749ba 100644 --- a/pyrightconfig.json +++ b/pyrightconfig.json @@ -33,15 +33,13 @@ "reportAttributeAccessIssue": "none", // FIXE: These all need to be fixed first and turned back to error // some of the fixes need to be done in types-pywin32 from typeshed - "reportAssignmentType": "warning", "reportCallIssue": "warning", - "reportIndexIssue": "warning", "reportOperatorIssue": "warning", "reportOptionalCall": "warning", "reportOptionalIterable": "warning", "reportOptionalMemberAccess": "warning", "reportOptionalSubscript": "warning", - // TODO: Leave Unbound/Undefined to its own PR(s) + // TODO: Leave Unbound/Undefined to their own PR(s) "reportUnboundVariable": "warning", "reportUndefinedVariable": "warning", // Too many dynamically generated modules. This will require type stubs to properly fix. diff --git a/win32/scripts/setup_d.py b/win32/scripts/setup_d.py index c40cd65c8..b458854d1 100644 --- a/win32/scripts/setup_d.py +++ b/win32/scripts/setup_d.py @@ -61,7 +61,7 @@ def _docopy(src, dest): return 1 except: print(f"Error copying '{src}' -> '{dest}'") - print(str(sys.exc_info[1])) + print(str(sys.exc_info()[1])) usage_and_die(3)