diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 1b004b1f3..2958c9173 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -18,7 +18,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13-dev"] + python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] architecture: ["x64", "x86"] steps: @@ -53,7 +53,7 @@ jobs: - name: Run tests # Run the tests directly from the source dir so support files (eg, .wav files etc) # can be found - they aren't installed into the Python tree. - run: python pywin32_testall.py -v -skip-adodbapi + run: python -X dev pywin32_testall.py -v -skip-adodbapi - name: Build wheels run: | @@ -76,7 +76,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["3.10", "3.11", "3.12", "3.13-dev"] + python-version: ["3.10", "3.11", "3.12", "3.13"] steps: - uses: actions/checkout@v4 @@ -118,7 +118,7 @@ jobs: - uses: actions/setup-python@v5 with: # This job only needs to target the oldest supported version - python-version: "3.8" + python-version: "3.9" cache: pip cache-dependency-path: .github/workflows/main.yml - run: pip install clang-format pycln @@ -140,8 +140,7 @@ jobs: strategy: fail-fast: false matrix: - # mypy won't understand "3.13-dev", keeping the CI simple by just omitting it - python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"] + python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 @@ -159,7 +158,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13-dev"] + python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 diff --git a/Pythonwin/pywin/framework/app.py b/Pythonwin/pywin/framework/app.py index 4b19a5b71..bfcd11155 100644 --- a/Pythonwin/pywin/framework/app.py +++ b/Pythonwin/pywin/framework/app.py @@ -10,7 +10,7 @@ import os import sys import traceback -from typing import TYPE_CHECKING +from typing import Literal import regutil import win32api @@ -21,9 +21,6 @@ from . import scriptutils -if TYPE_CHECKING: - from typing_extensions import Literal - # Helper for writing a Window position by name, and later loading it. def SaveWindowSize(section, rect, state=""): diff --git a/Pythonwin/pywin/framework/intpyapp.py b/Pythonwin/pywin/framework/intpyapp.py index de02fdace..05244b4cc 100644 --- a/Pythonwin/pywin/framework/intpyapp.py +++ b/Pythonwin/pywin/framework/intpyapp.py @@ -3,6 +3,7 @@ import os import sys import traceback +from collections.abc import Sequence import __main__ import commctrl @@ -268,7 +269,7 @@ def Activate(self): if frame.GetWindowPlacement()[1] == win32con.SW_SHOWMINIMIZED: frame.ShowWindow(win32con.SW_RESTORE) - def ProcessArgs(self, args, dde=None): + def ProcessArgs(self, args: Sequence[str], dde=None): # If we are going to talk to a remote app via DDE, then # activate it! if ( @@ -290,7 +291,7 @@ def ProcessArgs(self, args, dde=None): ).lower() i -= 1 # arg is /edit's parameter par = i < len(args) and args[i] or "MISSING" - if argType in ("/nodde", "/new", "-nodde", "-new"): + if argType in ("/nodde", "/new"): # Already handled pass elif argType.startswith("/goto:"): diff --git a/Pythonwin/pywin/idle/CallTips.py b/Pythonwin/pywin/idle/CallTips.py index c15847955..21b16de53 100644 --- a/Pythonwin/pywin/idle/CallTips.py +++ b/Pythonwin/pywin/idle/CallTips.py @@ -94,10 +94,8 @@ def get_object_at_cursor( # How is this for a hack! import __main__ - namespace = sys.modules.copy() - namespace.update(__main__.__dict__) try: - return eval(word, namespace) + return eval(word, sys.modules | __main__.__dict__) except: pass return None # Can't find an object. diff --git a/Pythonwin/pywin/scintilla/view.py b/Pythonwin/pywin/scintilla/view.py index 0134f3151..b4da1146a 100644 --- a/Pythonwin/pywin/scintilla/view.py +++ b/Pythonwin/pywin/scintilla/view.py @@ -480,7 +480,7 @@ def list2dict(l): # extra attributes of win32ui objects if hasattr(ob, "_obj_"): try: - items_dict.update(list2dict(dir(ob._obj_))) + items_dict = list2dict(dir(ob._obj_)) except AttributeError: pass # object has no __dict__ @@ -650,8 +650,7 @@ def _GetObjectAtPos(self, pos=-1, bAllowCalls=0): left, right = self._GetWordSplit(pos, bAllowCalls) if left: # It is an attribute lookup # How is this for a hack! - namespace = sys.modules.copy() - namespace.update(__main__.__dict__) + namespace = sys.modules | __main__.__dict__ # Get the debugger's context. try: from pywin.framework import interact diff --git a/Pythonwin/pywin/test/test_pywin.py b/Pythonwin/pywin/test/test_pywin.py index 49acc9d5e..b2802795f 100644 --- a/Pythonwin/pywin/test/test_pywin.py +++ b/Pythonwin/pywin/test/test_pywin.py @@ -139,9 +139,13 @@ def t_Browse(*args): if __name__ != "__main__": # make T findable by browser in __main__ namespace setattr(__main__, __class__.__qualname__, __class__) - with mock.patch( - "pywin.mfc.dialog.GetSimpleInput", (lambda *args: __class__.__qualname__) - ), mock.patch("pywin.tools.browser.Browse", t_Browse): + with ( + mock.patch( + "pywin.mfc.dialog.GetSimpleInput", + (lambda *args: __class__.__qualname__), + ), + mock.patch("pywin.tools.browser.Browse", t_Browse), + ): self.app.OnViewBrowse(0, 0) hl = o.dlg.hier_list self.assertGreater(len(hl.itemHandleMap), 10) @@ -443,8 +447,9 @@ def t_brk(self): GUIAboutToBreak() dmod = types.ModuleType("__main__", "debugger test main") - with mock.patch("pywin.framework.scriptutils.__main__", dmod), mock.patch( - "pywin.debugger.debugger.Debugger.GUIAboutToBreak", t_brk + with ( + mock.patch("pywin.framework.scriptutils.__main__", dmod), + mock.patch("pywin.debugger.debugger.Debugger.GUIAboutToBreak", t_brk), ): mf.SendMessage(wc.WM_COMMAND, cmGo) # debh.OnGo(0, 0) self.assertFalse(cmds_brk_next, "break commands remaining") diff --git a/Pythonwin/win32cmdui.cpp b/Pythonwin/win32cmdui.cpp index 617c8e5f6..247314652 100644 --- a/Pythonwin/win32cmdui.cpp +++ b/Pythonwin/win32cmdui.cpp @@ -27,19 +27,6 @@ inline void *GetPythonOleProcAddress(const char *procName) #endif hMod = GetModuleHandle(buf); - // XXX It is unclear why the code previously tried to identify a loaded PythonCOM DLL of - // any Python version 1.5 .. 3.9. If some InprocServer would load the DLL of a different - // Python version that would likely cause a crash. Thus deactivated. - // - // for (int i = 0; hMod == NULL && i < 40; i++) { - // #ifdef _DEBUG - // wsprintf(buf, _T("PythonCOM3%d_d.dll"), i); - // #else - // wsprintf(buf, _T("PythonCOM3%d.dll"), i); - // #endif - // hMod = GetModuleHandle(buf); - // } - if (hMod) { void *rc = GetProcAddress(hMod, procName); if (rc == NULL) diff --git a/Pythonwin/win32uimodule.cpp b/Pythonwin/win32uimodule.cpp index e5e03878f..c9a0a214d 100644 --- a/Pythonwin/win32uimodule.cpp +++ b/Pythonwin/win32uimodule.cpp @@ -2559,9 +2559,9 @@ extern "C" PYW_EXPORT BOOL Win32uiApplicationInit(Win32uiHostGlue *pGlue, const PyObject *argv = PySys_GetObject("argv"); PyInit_win32ui(); // Decide if we render sys.argv from command line. - // PY3.6- Py_Initialize sets sys.argv=NULL . - // PY3.7 Py_Initialize or intentional script triggers set sys.argv=[] . - // PY3.8+ Py_Initialize sets sys.argv=[''] - cannot be distinguished + // Python 3.6- Py_Initialize sets sys.argv=NULL . + // Python 3.7 Py_Initialize or intentional script triggers set sys.argv=[] . + // Python 3.8+ Py_Initialize sets sys.argv=[''] - cannot be distinguished // from a pre-existing command line setup anymore. So we need to check // another flag regarding the intended type of invokation, e.g. `cmd` // (or untangle all that crossover startup + module + app init here) diff --git a/build_all.bat b/build_all.bat index ec8cbbaa2..2260a6682 100644 --- a/build_all.bat +++ b/build_all.bat @@ -1,7 +1,3 @@ -py -3.8-32 setup.py -q build -@if errorlevel 1 goto failed -py -3.8 setup.py -q build -@if errorlevel 1 goto failed py -3.9-32 setup.py -q build @if errorlevel 1 goto failed py -3.9 setup.py -q build diff --git a/build_env.md b/build_env.md index 7e166c4d9..61443b3fa 100644 --- a/build_env.md +++ b/build_env.md @@ -5,7 +5,7 @@ This describes how to setup the build environment for pywin32. Double check the compiler version you need in the [Python wiki](https://wiki.python.org/moin/WindowsCompilers) but note that Python 3.5 -> 3.13 all use version 14.X of the compiler, which, confusingly, report themselves as V.19XX (eg, note in Python's banner, -3.5's "MSC v.1900", even 3.9b4's "MSC v.1924") +3.5's "MSC v.1900", even 3.13's "MSC v.1941") This compiler first shipped with Visual Studio 2015, although Visual Studio 2017, 2019 and 2022 all have this compiler available, just not installed diff --git a/com/win32com/client/gencache.py b/com/win32com/client/gencache.py index 717f2a9c7..c445c38c6 100644 --- a/com/win32com/client/gencache.py +++ b/com/win32com/client/gencache.py @@ -97,6 +97,7 @@ def _LoadDicts(): arc_path = loader.archive dicts_path = os.path.join(win32com.__gen_path__, "dicts.dat") if dicts_path.startswith(arc_path): + # Remove the leading slash as well dicts_path = dicts_path[len(arc_path) + 1 :] else: # Hm. See below. diff --git a/isapi/install.py b/isapi/install.py index aa861bbfc..c4c61fb76 100644 --- a/isapi/install.py +++ b/isapi/install.py @@ -626,7 +626,7 @@ def _PatchParamsModule(params, dll_name, file_must_exist=True): sm.Module = dll_name -def GetLoaderModuleName(mod_name, check_module=None): +def GetLoaderModuleName(mod_name: str, check_module=None): # find the name of the DLL hosting us. # By default, this is "_{module_base_name}.dll" if hasattr(sys, "frozen"): @@ -635,8 +635,7 @@ def GetLoaderModuleName(mod_name, check_module=None): base, ext = os.path.splitext(mod_name) path, base = os.path.split(base) # handle the common case of 'foo.exe'/'foow.exe' - if base.endswith("w"): - base = base[:-1] + base.removesuffix("w") # For py2exe, we have '_foo.dll' as the standard pyisapi loader - but # 'foo.dll' is what we use (it just delegates). # So no leading '_' on the installed name. @@ -760,8 +759,7 @@ def HandleCommandLine( # build a usage string if we don't have one. if not parser.get_usage(): - all_handlers = standard_arguments.copy() - all_handlers.update(custom_arg_handlers) + all_handlers = standard_arguments | custom_arg_handlers parser.set_usage(build_usage(all_handlers)) # allow the user to use uninstall as a synonym for remove if it wasn't diff --git a/make_all.bat b/make_all.bat index 05855ddfb..433a79545 100644 --- a/make_all.bat +++ b/make_all.bat @@ -13,11 +13,6 @@ rem Now the binaries. rem Check /build_env.md#build-environment to make sure you have all the required components installed rem (bdist_wininst needs --target-version to name the installers correctly!) -py -3.8-32 setup.py -q bdist_wininst --skip-build --target-version=3.8 -py -3.8-32 setup.py -q bdist_wheel --skip-build -py -3.8 setup.py -q bdist_wininst --skip-build --target-version=3.8 -py -3.8 setup.py -q bdist_wheel --skip-build - py -3.9-32 setup.py -q bdist_wininst --skip-build --target-version=3.9 py -3.9-32 setup.py -q bdist_wheel --skip-build py -3.9 setup.py -q bdist_wininst --skip-build --target-version=3.9 diff --git a/mypy.ini b/mypy.ini index e4676e0c7..4a70beb4e 100644 --- a/mypy.ini +++ b/mypy.ini @@ -1,7 +1,7 @@ [mypy] show_column_numbers = true ; Target the oldest supported version in editors and default CLI -python_version = 3.8 +python_version = 3.9 strict = true implicit_reexport = true diff --git a/pyrightconfig.json b/pyrightconfig.json index c35e4a565..87fddbc9c 100644 --- a/pyrightconfig.json +++ b/pyrightconfig.json @@ -1,12 +1,12 @@ { "typeCheckingMode": "basic", // Target the oldest supported version in editors and default CLI - "pythonVersion": "3.8", + "pythonVersion": "3.9", // Keep it simple for now by allowing both mypy and pyright to use `type: ignore` "enableTypeIgnoreComments": true, // Exclude from scanning when running pyright "exclude": [ - ".git/", + ".git/", // Avoids scanning git branch names ending in ".py" "build/", // Vendored "Pythonwin/Scintilla/", @@ -38,7 +38,7 @@ "reportOptionalIterable": "warning", "reportOptionalMemberAccess": "warning", "reportOptionalSubscript": "warning", - // Needs fixes in types-pywin32 and requires Python 3.8 to annotate ambiguous global variables + // Needs fixes in types-pywin32 to annotate ambiguous global variables "reportUnnecessaryComparison": "warning", // Too many dynamically generated modules. This will require type stubs to properly fix. "reportMissingImports": "warning", diff --git a/ruff.toml b/ruff.toml index 315a9d41f..199733005 100644 --- a/ruff.toml +++ b/ruff.toml @@ -1,4 +1,4 @@ -target-version = "py38" # Target the oldest supported version in editors and default CLI +target-version = "py39" # Target the oldest supported version in editors and default CLI # This file is not UTF-8 extend-exclude = ["Pythonwin/pywin/test/_dbgscript.py"] @@ -16,12 +16,7 @@ select = [ # String formatting, concatenating, interpolation, ... "FLY", # static-join-to-f-string "G", # flake8-logging-format - # Note, we still want to allow multiline ISC - "UP025", # Remove unicode literals from strings - "UP030", # Use implicit references for positional format fields - # TODO: Still lots of manual fixes needed - # "UP031", # Use format specifiers instead of percent format - # "UP032", # Use f-string instead of format call + "UP", # pyupgrade # Ensure modern type annotation syntax and best practices # Not including those covered by type-checkers @@ -31,21 +26,38 @@ select = [ "UP006", # non-pep585-annotation "UP007", # non-pep604-annotation "UP010", # unnecessary-future-import + "UP035", # deprecated-import "UP037", # quoted-annotation # Helps prevent circular imports and other unneeded imports "TCH", # flake8-type-checking ] extend-ignore = [ + # We prefer explicit open mode parameter + "UP015", # redundant-open-modes # No such concerns for stdlib "TCH003", # typing-only-standard-library-import + # TODO: Still lots of manual fixes needed + "UP031", # Use format specifiers instead of percent format + "UP032", # Use f-string instead of format call ] [lint.per-file-ignores] # Explicit re-exports is fine in __init__.py, still a code smell elsewhere. "__init__.py" = ["PLC0414"] # TODO: Make adodbapi changes in their own PRs -"adodbapi/*" = ["C4", "YTT301", "UP031", "UP032"] +"adodbapi/*" = [ + "C4", + "UP031", + "UP032", + # Dropping Python 3.8 support + "UP005", + "UP006", + "UP018", + "UP035", + "UP036", + "YTT301", +] [lint.isort] combine-as-imports = true diff --git a/setup.py b/setup.py index bd63dead1..6b448af6e 100644 --- a/setup.py +++ b/setup.py @@ -34,6 +34,7 @@ import subprocess import sys import winreg +from collections.abc import Iterable from pathlib import Path from setuptools import Extension, setup from setuptools.command.build import build @@ -42,7 +43,6 @@ from setuptools.command.install_lib import install_lib from setuptools.modified import newer_group from tempfile import gettempdir -from typing import Iterable from distutils import ccompiler from distutils._msvccompiler import MSVCCompiler @@ -381,7 +381,7 @@ def _why_cant_build_extension(self, ext): # axdebug fails to build on 3.11 due to Python "frame" objects changing. # This could be fixed, but is almost certainly not in use any more, so # just skip it. - if ext.name == "axdebug" and sys.version_info > (3, 10): + if ext.name == "axdebug" and sys.version_info >= (3, 11): return "AXDebug no longer builds on 3.11 and up" include_dirs = self.compiler.include_dirs + os.environ.get("INCLUDE", "").split( @@ -896,8 +896,8 @@ def install(self): # This is crazy - in setuptools 61.1.0 (and probably some earlier versions), the # install_lib and build comments don't agree on where the .py files to install can # be found, so we end up with a warning logged: - # `warning: my_install_lib: 'build\lib.win-amd64-3.8' does not exist -- no Python modules to install` - # (because they are actually in `build\lib.win-amd64-cpython-38`!) + # `warning: my_install_lib: 'build\lib.win-amd64-3.XX' does not exist -- no Python modules to install` + # (because they are actually in `build\lib.win-amd64-cpython-3XX`!) # It's not an error though, so we end up with .exe installers lacking our lib files! builder = self.get_finalized_command("build") if os.path.isdir(builder.build_platlib) and not os.path.isdir(self.build_dir): @@ -934,7 +934,7 @@ def link( debug=0, *args, **kw, - ): + ) -> None: super().link( target_desc, objects, @@ -952,18 +952,18 @@ def link( # target. Do this externally to avoid suddenly dragging in the # modules needed by this process, and which we will soon try and # update. - args = [ - sys.executable, - # NOTE: On Python 3.7, all args must be str - str(Path(__file__).parent / "win32" / "Lib" / "win32verstamp.py"), - f"--version={pywin32_version}", - "--comments=https://github.com/mhammond/pywin32", - f"--original-filename={os.path.basename(output_filename)}", - "--product=PyWin32", - "--quiet" if "-v" not in sys.argv else "", - output_filename, - ] - self.spawn(args) + self.spawn( + [ + sys.executable, + str(Path(__file__).parent / "win32" / "Lib" / "win32verstamp.py"), + f"--version={pywin32_version}", + "--comments=https://github.com/mhammond/pywin32", + f"--original-filename={os.path.basename(output_filename)}", + "--product=PyWin32", + "--quiet" if "-v" not in sys.argv else "", + output_filename, + ] + ) # Work around bpo-36302/bpo-42009 - it sorts sources but this breaks # support for building .mc files etc :( @@ -2017,9 +2017,7 @@ def convert_data_files(files: Iterable[str]): raise RuntimeError("No file '%s'" % file) files_use = (file,) for fname in files_use: - path_use = os.path.dirname(fname) - if path_use.startswith("com\\"): - path_use = path_use[4:] + path_use = os.path.dirname(fname).removeprefix("com\\") ret.append((path_use, (fname,))) return ret @@ -2101,7 +2099,6 @@ def convert_optional_data_files(files): "Intended Audience :: Developers", "License :: OSI Approved :: Python Software Foundation License", "Operating System :: Microsoft :: Windows", - "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", diff --git a/win32/Demos/win32netdemo.py b/win32/Demos/win32netdemo.py index 6c0a55776..6b8750ced 100644 --- a/win32/Demos/win32netdemo.py +++ b/win32/Demos/win32netdemo.py @@ -194,8 +194,7 @@ def SetInfo(userName=None): userName = win32api.GetUserName() oldData = win32net.NetUserGetInfo(server, userName, 3) try: - d = oldData.copy() - d["usr_comment"] = "Test comment" + d = oldData | {"usr_comment": "Test comment"} win32net.NetUserSetInfo(server, userName, 3, d) new = win32net.NetUserGetInfo(server, userName, 3)["usr_comment"] if str(new) != "Test comment": diff --git a/win32/Lib/_win32verstamp_pywin32ctypes.py b/win32/Lib/_win32verstamp_pywin32ctypes.py index b878809b7..33333422f 100644 --- a/win32/Lib/_win32verstamp_pywin32ctypes.py +++ b/win32/Lib/_win32verstamp_pywin32ctypes.py @@ -30,13 +30,12 @@ LPVOID, WORD, ) -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Literal, SupportsBytes, SupportsIndex if TYPE_CHECKING: from ctypes import _NamedFuncPointer from _typeshed import ReadableBuffer - from typing_extensions import Literal, SupportsBytes, SupportsIndex kernel32 = WinDLL("kernel32", use_last_error=True) diff --git a/win32/Lib/win32timezone.py b/win32/Lib/win32timezone.py index 01aa08d79..e7d815eda 100644 --- a/win32/Lib/win32timezone.py +++ b/win32/Lib/win32timezone.py @@ -246,7 +246,6 @@ import struct import winreg from itertools import count -from typing import Dict import win32api @@ -855,7 +854,7 @@ def get_sorted_time_zones(key=None): return zones -class _RegKeyDict(Dict[str, int]): +class _RegKeyDict(dict[str, int]): def __init__(self, key: winreg.HKEYType): dict.__init__(self) self.key = key diff --git a/win32/scripts/VersionStamp/bulkstamp.py b/win32/scripts/VersionStamp/bulkstamp.py index 89be6347d..0500745bf 100644 --- a/win32/scripts/VersionStamp/bulkstamp.py +++ b/win32/scripts/VersionStamp/bulkstamp.py @@ -33,7 +33,7 @@ import fnmatch import os import sys -from collections.abc import Mapping +from collections.abc import Iterable, Mapping from optparse import Values try: @@ -51,7 +51,9 @@ ] -def walk(vars: Mapping[str, str], debug, descriptions, dirname, names) -> int: +def walk( + vars: Mapping[str, str], debug, descriptions, dirname, names: Iterable[str] +) -> int: """Returns the number of stamped files.""" numStamped = 0 for name in names: @@ -60,8 +62,7 @@ def walk(vars: Mapping[str, str], debug, descriptions, dirname, names) -> int: # Handle the "_d" thing. pathname = os.path.join(dirname, name) base, ext = os.path.splitext(name) - if base.endswith("_d"): - name = base[:-2] + ext + name = base.removesuffix("_d") + ext is_dll = ext.lower() != ".exe" if os.path.normcase(name) in descriptions: description = descriptions[os.path.normcase(name)] diff --git a/win32/test/test_win32cred.py b/win32/test/test_win32cred.py index 4b9fe08d7..840263bad 100644 --- a/win32/test/test_win32cred.py +++ b/win32/test/test_win32cred.py @@ -14,12 +14,10 @@ def setUp(self): } def create_dummy_cred(self): - cred = copy.deepcopy(self.dummy_cred) - cred.update( - { - "Persist": win32cred.CRED_PERSIST_SESSION, - } - ) + cred = copy.deepcopy(self.dummy_cred) | { + "Persist": win32cred.CRED_PERSIST_SESSION, + } + try: win32cred.CredWrite(cred, self.flags) except Exception as e: diff --git a/win32/test/test_win32crypt.py b/win32/test/test_win32crypt.py index 9360cfbe2..f6f656caa 100644 --- a/win32/test/test_win32crypt.py +++ b/win32/test/test_win32crypt.py @@ -2,7 +2,8 @@ import contextlib import unittest -from typing import Any, Iterator +from collections.abc import Iterator +from typing import Any import win32crypt from pywin32_testutil import find_test_fixture, testmain diff --git a/win32/test/test_win32file.py b/win32/test/test_win32file.py index 12ba8c31d..b0eee2e3b 100644 --- a/win32/test/test_win32file.py +++ b/win32/test/test_win32file.py @@ -556,8 +556,7 @@ class TestFindFiles(unittest.TestCase): def testIter(self): dir = os.path.join(os.getcwd(), "*") files = win32file.FindFilesW(dir) - set1 = set() - set1.update(files) + set1 = set(files) set2 = set() for file in win32file.FindFilesIterator(dir): set2.add(file) diff --git a/win32/test/test_win32gui.py b/win32/test/test_win32gui.py index bc91a7add..b71ee8ad5 100644 --- a/win32/test/test_win32gui.py +++ b/win32/test/test_win32gui.py @@ -102,11 +102,7 @@ def test_enumwindows(self): ): for data in self.type_data_set: self.assertRaises(TypeError, win32gui.EnumWindows, func, data) - if sys.version_info >= (3, 10): - for func in ( - self.enum_callback, - self.enum_callback_sle, - ): + if sys.version_info >= (3, 10): self.assertRaises( TypeError, win32gui.EnumWindows, func, self.enum_callback, 2.718282 ) @@ -136,11 +132,7 @@ def test_enumchildwindows(self): self.assertRaises( TypeError, win32gui.EnumChildWindows, None, func, data ) - if sys.version_info >= (3, 10): - for func in ( - self.enum_callback, - self.enum_callback_sle, - ): + if sys.version_info >= (3, 10): self.assertRaises( TypeError, win32gui.EnumChildWindows, @@ -197,11 +189,7 @@ def test_enumdesktopwindows(self): self.assertRaises( TypeError, win32gui.EnumDesktopWindows, 0, func, data ) - if sys.version_info >= (3, 10): - for func in ( - self.enum_callback, - self.enum_callback_sle, - ): + if sys.version_info >= (3, 10): for desktop in desktops: self.assertRaises( TypeError, win32gui.EnumDesktopWindows, 0, func, 2.718282