From 37875dde423b03b0cc80a5cc8f0e7501679daaec Mon Sep 17 00:00:00 2001 From: Thomas Geppert Date: Tue, 15 Oct 2024 03:31:09 +0200 Subject: [PATCH 1/9] Check for the class attribute 'CLSID' instead of the instance attribute (#2353) to decide if building makepy support is required. --- com/win32com/client/gencache.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/com/win32com/client/gencache.py b/com/win32com/client/gencache.py index e64449b8b..717f2a9c7 100644 --- a/com/win32com/client/gencache.py +++ b/com/win32com/client/gencache.py @@ -626,7 +626,7 @@ def EnsureDispatch( ): # New fn, so we default the new demand feature to on! """Given a COM prog_id, return an object that is using makepy support, building if necessary""" disp = win32com.client.Dispatch(prog_id) - if not disp.__dict__.get("CLSID"): # Eeek - no makepy support - try and build it. + if not hasattr(disp, "CLSID"): # Eeek - no makepy support - try and build it. try: ti = disp._oleobj_.GetTypeInfo() disp_clsid = ti.GetTypeAttr()[0] From e79a6e3ed4fb36a05bdc9f10f5da289747809829 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Mon, 14 Oct 2024 21:35:25 -0400 Subject: [PATCH 2/9] Add test for TimeZoneInfo.tzname and fix bugs in the implementation. (#2337) Co-authored-by: Avasam --- win32/Lib/win32timezone.py | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/win32/Lib/win32timezone.py b/win32/Lib/win32timezone.py index 53107542d..fdd71c855 100644 --- a/win32/Lib/win32timezone.py +++ b/win32/Lib/win32timezone.py @@ -642,11 +642,27 @@ def __str__(self): return self.displayName def tzname(self, dt): - winInfo = self.getWinInfo(dt) - if self.dst(dt) == winInfo.daylight_bias: + """ + >>> MST = TimeZoneInfo('Mountain Standard Time') + >>> MST.tzname(datetime.datetime(2003, 8, 2)) + 'Mountain Daylight Time' + >>> MST.tzname(datetime.datetime(2003, 11, 25)) + 'Mountain Standard Time' + """ + + winInfo = self.getWinInfo(dt.year) + if self.dst(dt) == -winInfo.daylight_bias: result = self.daylightName - elif self.dst(dt) == winInfo.standard_bias: + elif self.dst(dt) == -winInfo.standard_bias: result = self.standardName + else: + raise ValueError( + "Unexpected daylight bias", + dt, + self.dst(dt), + winInfo.daylight_bias, + winInfo.standard_bias, + ) return result def getWinInfo(self, targetYear): From c717bfa4b06bab5984ba4c9eb62fcc4e6dcf99ef Mon Sep 17 00:00:00 2001 From: Avasam Date: Mon, 14 Oct 2024 22:35:55 -0400 Subject: [PATCH 3/9] Include StackOverflow's link about MREs in issue_template.md (#2404) Co-authored-by: Mark Hammond --- .github/issue_template.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/issue_template.md b/.github/issue_template.md index 733bf9343..601614eae 100644 --- a/.github/issue_template.md +++ b/.github/issue_template.md @@ -9,7 +9,7 @@ For all bugs, please provide the following information: ## Expected behavior and actual behavior ## Steps to reproduce the problem - + 1. ... 2. ... From 636e4c00d1b011f21e7d968200da083200cf7ce8 Mon Sep 17 00:00:00 2001 From: Kyle Johnson Date: Thu, 17 Oct 2024 20:50:42 -0500 Subject: [PATCH 4/9] Fixing memory leak converting to PyObject from some SAFEARRAY elements (#2316) Some SAFEARRAY element types require ownership change when converted to PyObjects. This includes the BSTR, IUnknown and IDispatch types. Otherwise the memory gets leaked upon garbage collection. Co-authored-by: Kyle Johnson --- com/win32com/src/oleargs.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/com/win32com/src/oleargs.cpp b/com/win32com/src/oleargs.cpp index 33c925987..0e565ae5e 100644 --- a/com/win32com/src/oleargs.cpp +++ b/com/win32com/src/oleargs.cpp @@ -860,7 +860,7 @@ static PyObject *PyCom_PyObjectFromSAFEARRAYDimensionItem(SAFEARRAY *psa, VARENU hres = SafeArrayGetElement(psa, arrayIndices, &str); if (FAILED(hres)) break; - subitem = PyWinObject_FromBstr(str); + subitem = PyWinObject_FromBstr(str, TRUE); break; } case VT_DISPATCH: { @@ -868,7 +868,7 @@ static PyObject *PyCom_PyObjectFromSAFEARRAYDimensionItem(SAFEARRAY *psa, VARENU hres = SafeArrayGetElement(psa, arrayIndices, &pDisp); if (FAILED(hres)) break; - subitem = PyCom_PyObjectFromIUnknown(pDisp, IID_IDispatch, TRUE); + subitem = PyCom_PyObjectFromIUnknown(pDisp, IID_IDispatch, FALSE); break; } // case VT_ERROR - handled above with I4 @@ -895,7 +895,7 @@ static PyObject *PyCom_PyObjectFromSAFEARRAYDimensionItem(SAFEARRAY *psa, VARENU hres = SafeArrayGetElement(psa, arrayIndices, &pUnk); if (FAILED(hres)) break; - subitem = PyCom_PyObjectFromIUnknown(pUnk, IID_IUnknown, TRUE); + subitem = PyCom_PyObjectFromIUnknown(pUnk, IID_IUnknown, FALSE); break; } // case VT_DECIMAL From 3be4f697c59eb2cb5e08ff7fa8de6613288f1d21 Mon Sep 17 00:00:00 2001 From: Thomas Geppert Date: Fri, 18 Oct 2024 03:56:18 +0200 Subject: [PATCH 5/9] Implement record pointers as [in, out] method parameters of a Dispatch Interface (#2310) * Implement record pointers as method parameters of a Dispatch Interface to get server side modifications of a record marshaled back to the client. * Added a untitest for record pointers as [ in, out ] method parameters. --- com/TestSources/PyCOMTest/PyCOMImpl.cpp | 8 ++++++++ com/TestSources/PyCOMTest/PyCOMImpl.h | 2 ++ com/TestSources/PyCOMTest/PyCOMTest.idl | 2 ++ com/win32com/client/build.py | 1 - com/win32com/src/oleargs.cpp | 1 + com/win32com/test/testPyComTest.py | 12 ++++++++++++ 6 files changed, 25 insertions(+), 1 deletion(-) diff --git a/com/TestSources/PyCOMTest/PyCOMImpl.cpp b/com/TestSources/PyCOMTest/PyCOMImpl.cpp index a4616fef0..d58c00f99 100644 --- a/com/TestSources/PyCOMTest/PyCOMImpl.cpp +++ b/com/TestSources/PyCOMTest/PyCOMImpl.cpp @@ -618,6 +618,14 @@ HRESULT CPyCOMTest::GetStruct(TestStruct1 *ret) *ret = r; return S_OK; } + +HRESULT CPyCOMTest::ModifyStruct(TestStruct1 *prec) +{ + prec->int_value = 100; + prec->str_value = SysAllocString(L"Nothing is as constant as change"); + return S_OK; +} + HRESULT CPyCOMTest::DoubleString(BSTR in, BSTR *out) { *out = SysAllocStringLen(NULL, SysStringLen(in) * 2); diff --git a/com/TestSources/PyCOMTest/PyCOMImpl.h b/com/TestSources/PyCOMTest/PyCOMImpl.h index e285268f1..50eb8dd0d 100644 --- a/com/TestSources/PyCOMTest/PyCOMImpl.h +++ b/com/TestSources/PyCOMTest/PyCOMImpl.h @@ -119,6 +119,8 @@ class CPyCOMTest : public IDispatchImpl Date: Mon, 14 Oct 2024 22:25:14 -0400 Subject: [PATCH 6/9] Add missing CHANGELOG entries --- CHANGES.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGES.txt b/CHANGES.txt index a88445e9b..8d1012619 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -14,6 +14,9 @@ https://mhammond.github.io/pywin32_installers.html. Coming in build 309, as yet unreleased -------------------------------------- +* Implement record pointers as [in, out] method parameters of a Dispatch Interface (#2310) +* Fix memory leak converting to PyObject from some SAFEARRAY elements (#2316) +* Fix bug where makepy support was unnecessarily generated (#2354, #2353, @geppi) * Fail sooner on invalid `win32timezone.TimeZoneInfo` creation (#2338, @Avasam) * Removed temporary `win32com.server.policy` reexports hack (#2344, @Avasam) Import `DispatcherWin32trace` and `DispatcherTrace` from `win32com.server.dispatcher` instead. From ad3a991202d5d352488218d3419d03768c5a787e Mon Sep 17 00:00:00 2001 From: petur-keystrike <148981503+petur-keystrike@users.noreply.github.com> Date: Fri, 18 Oct 2024 02:49:41 +0000 Subject: [PATCH 7/9] Add support for WTSIsRemoteSession flag. (#2152) When WTSIsRemoteSession is passed to WTSQuerySessionInformation, it returns a single byte containing the return value. --- win32/src/win32tsmodule.cpp | 4 ++++ win32/test/test_win32ts.py | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 win32/test/test_win32ts.py diff --git a/win32/src/win32tsmodule.cpp b/win32/src/win32tsmodule.cpp index c4156f9f5..ddd383dee 100644 --- a/win32/src/win32tsmodule.cpp +++ b/win32/src/win32tsmodule.cpp @@ -409,6 +409,9 @@ static PyObject *PyWTSQuerySessionInformation(PyObject *self, PyObject *args, Py case WTSConnectState: // @flag WTSConnectState|Int, from WTS_CONNECTSTATE_CLASS ret = PyLong_FromLong(*(INT *)buf); break; + case WTSIsRemoteSession: // @flag WTSIsRemoteSession|Boolean + ret = PyBool_FromLong(*(BYTE *)buf); + break; case WTSClientDisplay: { // @flag WTSClientDisplay|Dict containing client's display settings WTS_CLIENT_DISPLAY *wcd = (WTS_CLIENT_DISPLAY *)buf; ret = Py_BuildValue("{s:k, s:k, s:k}", "HorizontalResolution", wcd->HorizontalResolution, @@ -768,6 +771,7 @@ PYWIN_MODULE_INIT_FUNC(win32ts) PyModule_AddIntConstant(module, "WTSClientAddress", WTSClientAddress); PyModule_AddIntConstant(module, "WTSClientDisplay", WTSClientDisplay); PyModule_AddIntConstant(module, "WTSClientProtocolType", WTSClientProtocolType); + PyModule_AddIntConstant(module, "WTSIsRemoteSession", WTSIsRemoteSession); // WTS_CONFIG_CLASS PyModule_AddIntConstant(module, "WTSUserConfigInitialProgram", WTSUserConfigInitialProgram); diff --git a/win32/test/test_win32ts.py b/win32/test/test_win32ts.py new file mode 100644 index 000000000..712b99272 --- /dev/null +++ b/win32/test/test_win32ts.py @@ -0,0 +1,19 @@ +# Tests for win32ts module + +import unittest + +import win32ts + + +class Win32TsTestCase(unittest.TestCase): + def test_is_remote_session(self): + ret = win32ts.WTSQuerySessionInformation( + win32ts.WTS_CURRENT_SERVER_HANDLE, + win32ts.WTS_CURRENT_SESSION, + win32ts.WTSIsRemoteSession, + ) + self.assertIsInstance(ret, bool) + + +if __name__ == "__main__": + unittest.main() From a940d6872130fe37d1019dde52f79e19256716d8 Mon Sep 17 00:00:00 2001 From: Alexander Reznikov Date: Fri, 18 Oct 2024 06:01:58 +0300 Subject: [PATCH 8/9] Added support for DBT_DEVTYP_PORT in UnpackDEV_BROADCAST (#2074) * Update win32gui_struct.py: Added support for DBT_DEVTYP_PORT in UnpackDEV_BROADCAST --- win32/Lib/win32gui_struct.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/win32/Lib/win32gui_struct.py b/win32/Lib/win32gui_struct.py index 945ededc9..41ef815fd 100644 --- a/win32/Lib/win32gui_struct.py +++ b/win32/Lib/win32gui_struct.py @@ -952,6 +952,8 @@ def UnpackDEV_BROADCAST(lparam): _, _, _, x["unitmask"], x["flags"] = struct.unpack( fmt, buf[: struct.calcsize(fmt)] ) + elif devtype == win32con.DBT_DEVTYP_PORT: + x["name"] = win32gui.PyGetString(lparam + struct.calcsize(hdr_format)) else: raise NotImplementedError("unknown device type %d" % (devtype,)) return DEV_BROADCAST_INFO(devtype, **extra) From 49c52f93d505feeb1f5f46c93b8f9af9ea3f2f42 Mon Sep 17 00:00:00 2001 From: Avasam Date: Thu, 17 Oct 2024 23:52:21 -0400 Subject: [PATCH 9/9] Dropping support for Python 3.7 (#2207) --- .github/workflows/download-arm64-libs.py | 12 ++++++------ .github/workflows/main.yml | 11 +++++------ CHANGES.txt | 1 + Pythonwin/pywin/test/test_pywin.py | 5 ++--- build_all.bat | 4 ---- build_env.md | 1 - com/win32com/test/pippo_server.py | 5 +---- make_all.bat | 5 ----- mypy.ini | 1 - pyrightconfig.json | 2 +- ruff.toml | 2 +- setup.py | 20 +++++--------------- win32/Lib/pywin32_bootstrap.py | 10 +--------- win32/src/_win32sysloader.cpp | 6 ------ 14 files changed, 23 insertions(+), 62 deletions(-) diff --git a/.github/workflows/download-arm64-libs.py b/.github/workflows/download-arm64-libs.py index 51c5bcd02..841673f98 100644 --- a/.github/workflows/download-arm64-libs.py +++ b/.github/workflows/download-arm64-libs.py @@ -28,16 +28,16 @@ VERSION += f"-rc{sys.version_info.serial}" URL = f"https://www.nuget.org/api/v2/package/pythonarm64/{VERSION}" -PATH = dest / f"pythonarm64.{VERSION}.zip" +DEST_PATH = dest / f"pythonarm64.{VERSION}.zip" -if PATH.is_file(): - print("Skipping download because", PATH, "exists") +if DEST_PATH.is_file(): + print("Skipping download because", DEST_PATH, "exists") else: print("Downloading", URL) - urlretrieve(URL, PATH) - print("Downloaded", PATH) + urlretrieve(URL, DEST_PATH) + print("Downloaded", DEST_PATH) -with ZipFile(PATH, "r") as zf: +with ZipFile(DEST_PATH, "r") as zf: for name in zf.namelist(): zip_path = pathlib.PurePath(name) if zip_path.parts[:2] == ("tools", "libs"): diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index aa1049f06..2af0d70a0 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -18,7 +18,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12", "3.13-dev"] + python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13-dev"] architecture: ["x64", "x86"] steps: @@ -37,7 +37,7 @@ jobs: run: | python --version pip --version - pip install --upgrade setuptools wheel + pip install --upgrade setuptools>=74 wheel - name: Build and install run: | @@ -86,7 +86,7 @@ jobs: run: | python --version pip --version - pip install --upgrade setuptools wheel + pip install --upgrade setuptools>=74 wheel - name: Obtain ARM64 library files run: | @@ -117,7 +117,7 @@ jobs: cache-dependency-path: .github/workflows/main.yml - run: pip install clang-format pycln - run: pycln . --config=pycln.toml --check - - uses: chartboost/ruff-action@v1 + - uses: astral-sh/ruff-action@v1 with: version: "0.4.5" - uses: psf/black@stable @@ -134,7 +134,6 @@ jobs: strategy: fail-fast: false matrix: - # mypy 1.5 dropped support for Python 3.7 # 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"] steps: @@ -154,7 +153,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12", "3.13-dev"] + python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13-dev"] steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 diff --git a/CHANGES.txt b/CHANGES.txt index 8d1012619..d8978afd5 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -14,6 +14,7 @@ https://mhammond.github.io/pywin32_installers.html. Coming in build 309, as yet unreleased -------------------------------------- +* Dropped support for Python 3.7 (#2207, @Avasam) * Implement record pointers as [in, out] method parameters of a Dispatch Interface (#2310) * Fix memory leak converting to PyObject from some SAFEARRAY elements (#2316) * Fix bug where makepy support was unnecessarily generated (#2354, #2353, @geppi) diff --git a/Pythonwin/pywin/test/test_pywin.py b/Pythonwin/pywin/test/test_pywin.py index 6cf973a92..49acc9d5e 100644 --- a/Pythonwin/pywin/test/test_pywin.py +++ b/Pythonwin/pywin/test/test_pywin.py @@ -47,8 +47,7 @@ def setUpClass(cls): def _restore_oe(): sys.stdout, sys.stderr = cls.std_oe_orig - if sys.version_info >= (3, 8): - cls.addClassCleanup(_restore_oe) + cls.addClassCleanup(_restore_oe) sys.argv[1:] = ["/new", src_dir + "\\_dbgscript.py"] if not _indebugger: thisApp.InitInstance() @@ -65,7 +64,7 @@ def tearDownClass(cls): win32api.PostQuitMessage() win32gui.PumpWaitingMessages() cls.app.ExitInstance() - sys.stdout, sys.stderr = cls.std_oe_orig # py3.7 + sys.stdout, sys.stderr = cls.std_oe_orig def test_1_pydocs_and_finddlg(self): mf = win32ui.GetMainFrame() diff --git a/build_all.bat b/build_all.bat index 536aee00d..ec8cbbaa2 100644 --- a/build_all.bat +++ b/build_all.bat @@ -1,7 +1,3 @@ -py -3.7-32 setup.py -q build -@if errorlevel 1 goto failed -py -3.7 setup.py -q build -@if errorlevel 1 goto failed py -3.8-32 setup.py -q build @if errorlevel 1 goto failed py -3.8 setup.py -q build diff --git a/build_env.md b/build_env.md index d9c55ac10..4f616bf99 100644 --- a/build_env.md +++ b/build_env.md @@ -149,7 +149,6 @@ from the pywin32 directory. - Update `setuptools` and set the following environment variables to ensure it is used: ```shell - set SETUPTOOLS_USE_DISTUTILS=1 set DISTUTILS_USE_SDK=1 ``` diff --git a/com/win32com/test/pippo_server.py b/com/win32com/test/pippo_server.py index c5ae2df40..d8e964623 100644 --- a/com/win32com/test/pippo_server.py +++ b/com/win32com/test/pippo_server.py @@ -41,10 +41,7 @@ def Method3(self, in1): def BuildTypelib(): - if sys.version_info >= (3, 8): - from setuptools.modified import newer - else: - from distutils.dep_util import newer + from setuptools.modified import newer this_dir = os.path.dirname(__file__) idl = os.path.abspath(os.path.join(this_dir, "pippo.idl")) diff --git a/make_all.bat b/make_all.bat index c6d6a2b33..05855ddfb 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.7-32 setup.py -q bdist_wininst --skip-build --target-version=3.7 -py -3.7-32 setup.py -q bdist_wheel --skip-build -py -3.7 setup.py -q bdist_wininst --skip-build --target-version=3.7 -py -3.7 setup.py -q bdist_wheel --skip-build - 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 diff --git a/mypy.ini b/mypy.ini index bd1cd4316..e4676e0c7 100644 --- a/mypy.ini +++ b/mypy.ini @@ -1,7 +1,6 @@ [mypy] show_column_numbers = true ; Target the oldest supported version in editors and default CLI -; mypy 1.5 dropped support for Python 3.7 python_version = 3.8 strict = true diff --git a/pyrightconfig.json b/pyrightconfig.json index 1721da1a2..d96b3fc9d 100644 --- a/pyrightconfig.json +++ b/pyrightconfig.json @@ -1,7 +1,7 @@ { "typeCheckingMode": "basic", // Target the oldest supported version in editors and default CLI - "pythonVersion": "3.7", + "pythonVersion": "3.8", // Keep it simple for now by allowing both mypy and pyright to use `type: ignore` "enableTypeIgnoreComments": true, // Exclude from scanning when running pyright diff --git a/ruff.toml b/ruff.toml index 603043e8f..eab7fcce1 100644 --- a/ruff.toml +++ b/ruff.toml @@ -1,4 +1,4 @@ -target-version = "py37" # Target the oldest supported version +target-version = "py38" # Target the oldest supported version in editors and default CLI [lint] select = [ diff --git a/setup.py b/setup.py index ce0120e24..e25465fd7 100644 --- a/setup.py +++ b/setup.py @@ -40,6 +40,7 @@ from setuptools.command.build_ext import build_ext from setuptools.command.install import install from setuptools.command.install_lib import install_lib +from setuptools.modified import newer_group from tempfile import gettempdir from typing import Iterable @@ -47,11 +48,6 @@ from distutils._msvccompiler import MSVCCompiler from distutils.command.install_data import install_data -if sys.version_info >= (3, 8): - from setuptools.modified import newer_group -else: - from distutils.dep_util import newer_group - build_id_patch = build_id if not "." in build_id_patch: build_id_patch += ".0" @@ -868,12 +864,6 @@ def run(self): install.run(self) # Custom script we run at the end of installing - this is the same script # run by bdist_wininst - # This child process won't be able to install the system DLLs until our - # process has terminated (as distutils imports win32api!), so we must use - # some 'no wait' executor - spawn seems fine! We pass the PID of this - # process so the child will wait for us. - # XXX - hmm - a closer look at distutils shows it only uses win32api - # if _winreg fails - and this never should. Need to revisit this! # If self.root has a value, it means we are being "installed" into # some other directory than Python itself (eg, into a temp directory # for bdist_wininst to use) - in which case we must *not* run our @@ -885,7 +875,8 @@ def run(self): if not os.path.isfile(filename): raise RuntimeError(f"Can't find '{filename}'") print("Executing post install script...") - # What executable to use? This one I guess. + # As of setuptools>=74.0.0, we no longer need to + # be concerned about distutils calling win32api subprocess.Popen( [ sys.executable, @@ -905,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.7' does not exist -- no Python modules to install` - # (because they are actually in `build\lib.win-amd64-cpython-37`!) + # `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`!) # 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): @@ -2151,7 +2142,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.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", diff --git a/win32/Lib/pywin32_bootstrap.py b/win32/Lib/pywin32_bootstrap.py index fbc4f7be4..c9f59a56d 100644 --- a/win32/Lib/pywin32_bootstrap.py +++ b/win32/Lib/pywin32_bootstrap.py @@ -4,8 +4,6 @@ # In short, there's a directory installed by pywin32 named 'pywin32_system32' # with some important DLLs which need to be found by Python when some pywin32 # modules are imported. -# If Python has `os.add_dll_directory()`, we need to call it with this path. -# Otherwise, we add this path to PATH. try: @@ -19,11 +17,5 @@ # https://docs.python.org/3/reference/import.html#__path__ for path in pywin32_system32.__path__: if os.path.isdir(path): - if hasattr(os, "add_dll_directory"): - os.add_dll_directory(path) - # This is to ensure the pywin32 path is in the beginning to find the - # pywin32 DLLs first and prevent other PATH entries to shadow them - elif not os.environ["PATH"].startswith(path): - os.environ["PATH"] = os.environ["PATH"].replace(os.pathsep + path, "") - os.environ["PATH"] = path + os.pathsep + os.environ["PATH"] + os.add_dll_directory(path) break diff --git a/win32/src/_win32sysloader.cpp b/win32/src/_win32sysloader.cpp index 0a9e4dcac..9a9ef7c27 100644 --- a/win32/src/_win32sysloader.cpp +++ b/win32/src/_win32sysloader.cpp @@ -52,13 +52,7 @@ static PyObject *PyLoadModule(PyObject *self, PyObject *args) if (!modName) return NULL; - // Python 3.7 vs 3.8 use different flags for LoadLibraryEx and we match them. - // See github issue 1787. -#if (PY_VERSION_HEX < 0x03080000) - HINSTANCE hinst = LoadLibraryEx(modName, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); -#else HINSTANCE hinst = LoadLibraryEx(modName, NULL, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS | LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR); -#endif PyMem_Free(modName); if (hinst == NULL) { Py_INCREF(Py_None);