From bc7ad11b2d65509504499bfc89941df9a290f9a4 Mon Sep 17 00:00:00 2001 From: Avasam Date: Tue, 15 Oct 2024 18:16:59 -0400 Subject: [PATCH 1/7] Make pywin32_postinstall and pywin32_testall into console_scripts --- .github/workflows/main.yml | 2 +- README.md | 4 ++-- setup.py | 13 ++++++++++++- .../scripts/pywin32_postinstall.py | 4 ++++ .../scripts/pywin32_testall.py | 0 5 files changed, 19 insertions(+), 4 deletions(-) rename pywin32_postinstall.py => win32/scripts/pywin32_postinstall.py (99%) rename pywin32_testall.py => win32/scripts/pywin32_testall.py (100%) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index aa1049f062..5106b15a85 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -46,7 +46,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 -m win32.scripts.pywin32_testall -v -skip-adodbapi - name: Build wheels run: | diff --git a/README.md b/README.md index b03454e45f..de76e05fc0 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,7 @@ Outside of a virtual environment you might want to install COM objects, services this by executing: ```shell -python Scripts/pywin32_postinstall.py -install +pywin32_postinstall -install ``` From the root of your Python installation. @@ -91,7 +91,7 @@ It usually means one of 2 things: So you should run it again: ```shell - python Scripts/pywin32_postinstall.py -install + pywin32_postinstall -install ``` This will make some small attempts to cleanup older conflicting installs. diff --git a/setup.py b/setup.py index ce0120e249..1a1af46982 100644 --- a/setup.py +++ b/setup.py @@ -2222,7 +2222,18 @@ def maybe_fixup_exes(): "user_access_control": "auto", }, }, - scripts=["pywin32_postinstall.py", "pywin32_testall.py"], + # This adds the scripts under Python3XX/Scripts, but doesn't actually do much + scripts=[ + "win32/scripts/pywin32_postinstall.py", + "win32/scripts/pywin32_testall.py", + ], + # This shortcuts `python -m win32.scripts.some_script` to just `some_script` + entry_points={ + "console_scripts": [ + "pywin32_postinstall = win32.scripts.pywin32_postinstall:main", + "pywin32_testall = win32.scripts.pywin32_testall:main", + ] + }, ext_modules=ext_modules, package_dir={ "win32com": "com/win32com", diff --git a/pywin32_postinstall.py b/win32/scripts/pywin32_postinstall.py similarity index 99% rename from pywin32_postinstall.py rename to win32/scripts/pywin32_postinstall.py index a9dd85645d..a6395ee35d 100644 --- a/pywin32_postinstall.py +++ b/win32/scripts/pywin32_postinstall.py @@ -702,6 +702,10 @@ def main(): > python pywin32_postinstall.py -install + * or if pywin32 is already installed: + + > pywin32_postinstall -install + If you installed pywin32 via a .exe installer, this should be run automatically after installation, but if it fails you can run it again. diff --git a/pywin32_testall.py b/win32/scripts/pywin32_testall.py similarity index 100% rename from pywin32_testall.py rename to win32/scripts/pywin32_testall.py From d3f9f60a11ffe51632f1759f956ee626ab529efe Mon Sep 17 00:00:00 2001 From: Avasam Date: Sat, 14 Dec 2024 13:07:16 -0500 Subject: [PATCH 2/7] Run tests from source --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 22f792a05a..df5718104d 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -52,7 +52,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 -m win32.scripts.pywin32_testall -v -skip-adodbapi + run: python win32/scripts/pywin32_testall.py -v -skip-adodbapi - name: Build wheels run: pip wheel . -v --wheel-dir=dist From 9e55aa43c830de13bb4f1b8a0134b7ae33a10e85 Mon Sep 17 00:00:00 2001 From: Avasam Date: Sun, 22 Dec 2024 22:16:09 -0500 Subject: [PATCH 3/7] fix project root location --- win32/scripts/pywin32_testall.py | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/win32/scripts/pywin32_testall.py b/win32/scripts/pywin32_testall.py index 2aa92098cb..345d6413fe 100644 --- a/win32/scripts/pywin32_testall.py +++ b/win32/scripts/pywin32_testall.py @@ -7,10 +7,8 @@ # locate the dirs based on where this script is - it may be either in the # source tree, or in an installed Python 'Scripts' tree. -this_dir = os.path.dirname(__file__) -site_packages = [ - site.getusersitepackages(), -] + site.getsitepackages() +project_root = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) +site_packages = [site.getusersitepackages()] + site.getsitepackages() failures = [] @@ -45,7 +43,7 @@ def find_and_run(possible_locations, extras): def main(): import argparse - code_directories = [this_dir] + site_packages + code_directories = [project_root] + site_packages parser = argparse.ArgumentParser( description="A script to trigger tests in all subprojects of PyWin32." @@ -89,10 +87,7 @@ def main(): # win32com maybes = [ os.path.join(directory, "win32com", "test", "testall.py") - for directory in [ - os.path.join(this_dir, "com"), - ] - + site_packages + for directory in [os.path.join(project_root, "com")] + site_packages ] extras = remains + ["1"] # only run "level 1" tests in CI find_and_run(maybes, extras) From ad237b313febf2ea191810ac711692b93da3b50a Mon Sep 17 00:00:00 2001 From: Avasam Date: Sun, 5 Jan 2025 14:54:31 -0500 Subject: [PATCH 4/7] Simplify old postinstall cleanup and improve recommended usage --- README.md | 16 +++++++++++++--- win32/scripts/pywin32_postinstall.py | 24 +++++++++++++----------- 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index b1593ebed2..4108a4e65e 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,7 @@ There is a post-install script (see below) which should *not* be run inside virt it should only be run in "global" installs. For unreleased changes, you can download builds made by [github actions](https://github.com/mhammond/pywin32/actions/) - -choose any "workflow" from the `main` branch and download its "artifacts") +choose any "workflow" from the `main` branch and download its "artifacts" ### Installing globally @@ -57,10 +57,14 @@ Outside of a virtual environment you might want to install COM objects, services this by executing: ```shell -pywin32_postinstall -install +python -m pywin32_postinstall -install ``` -From the root of your Python installation. +or (shorter but you don't have control over which python environment is used) + +```shell +pywin32_postinstall -install +``` If you do this with normal permissions it will be global for your user (a few files will be copied to the root of your Python install and some changes made to HKCU). If you execute this from @@ -90,6 +94,12 @@ It usually means one of 2 things: * You've upgraded an install where the post-install script has previously run. So you should run it again: + ```shell + python -m pywin32_postinstall -install + ``` + + or (shorter but you don't have control over which python environment is used) + ```shell pywin32_postinstall -install ``` diff --git a/win32/scripts/pywin32_postinstall.py b/win32/scripts/pywin32_postinstall.py index 387d9a2ac9..3537b2d5e8 100644 --- a/win32/scripts/pywin32_postinstall.py +++ b/win32/scripts/pywin32_postinstall.py @@ -378,18 +378,13 @@ def fixup_dbi(): print(f"FAILED to rename '{this_pyd}': {exc}") -def install(lib_dir): - import traceback - +def cleanup_old_installs(): # The .pth file is now installed as a regular file. # Create the .pth file in the site-packages dir, and use only relative paths # We used to write a .pth directly to sys.prefix - clobber it. if os.path.isfile(os.path.join(sys.prefix, "pywin32.pth")): os.unlink(os.path.join(sys.prefix, "pywin32.pth")) - # The .pth may be new and therefore not loaded in this session. - # Setup the paths just in case. - for name in "win32 win32\\lib Pythonwin".split(): - sys.path.append(os.path.join(lib_dir, name)) + # It is possible people with old versions installed with still have # pywintypes and pythoncom registered. We no longer need this, and stale # entries hurt us. @@ -404,9 +399,16 @@ def install(lib_dir): winreg.DeleteKey(root, keyname) except OSError: pass + + +def install(lib_dir): + import traceback + + import win32api + + cleanup_old_installs() LoadSystemModule(lib_dir, "pywintypes") LoadSystemModule(lib_dir, "pythoncom") - import win32api # and now we can get the system directory: files = glob.glob(os.path.join(lib_dir, "pywin32_system32\\*.*")) @@ -655,13 +657,13 @@ def main(): * Typical usage: - > python pywin32_postinstall.py -install + > python -m pywin32_postinstall -install - * or if pywin32 is already installed: + * or (shorter but you don't have control over which python environment is used) > pywin32_postinstall -install - This should be run automatically after installation, + This should be run automatically after installation when installing from source, but if it fails you can run it again. Given EXE installers are no longer provided, From 52a3dfb5436ad7168ee410d8ac01363db9532530 Mon Sep 17 00:00:00 2001 From: Avasam Date: Sun, 5 Jan 2025 15:20:26 -0500 Subject: [PATCH 5/7] Leave def install simplification to another PR --- win32/scripts/pywin32_postinstall.py | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/win32/scripts/pywin32_postinstall.py b/win32/scripts/pywin32_postinstall.py index 3537b2d5e8..95773a4a35 100644 --- a/win32/scripts/pywin32_postinstall.py +++ b/win32/scripts/pywin32_postinstall.py @@ -378,13 +378,18 @@ def fixup_dbi(): print(f"FAILED to rename '{this_pyd}': {exc}") -def cleanup_old_installs(): +def install(lib_dir): + import traceback + # The .pth file is now installed as a regular file. # Create the .pth file in the site-packages dir, and use only relative paths # We used to write a .pth directly to sys.prefix - clobber it. if os.path.isfile(os.path.join(sys.prefix, "pywin32.pth")): os.unlink(os.path.join(sys.prefix, "pywin32.pth")) - + # The .pth may be new and therefore not loaded in this session. + # Setup the paths just in case. + for name in "win32 win32\\lib Pythonwin".split(): + sys.path.append(os.path.join(lib_dir, name)) # It is possible people with old versions installed with still have # pywintypes and pythoncom registered. We no longer need this, and stale # entries hurt us. @@ -399,16 +404,9 @@ def cleanup_old_installs(): winreg.DeleteKey(root, keyname) except OSError: pass - - -def install(lib_dir): - import traceback - - import win32api - - cleanup_old_installs() LoadSystemModule(lib_dir, "pywintypes") LoadSystemModule(lib_dir, "pythoncom") + import win32api # and now we can get the system directory: files = glob.glob(os.path.join(lib_dir, "pywin32_system32\\*.*")) From bdb89f426d5a78c44a303c8a6088e9570660788a Mon Sep 17 00:00:00 2001 From: Avasam Date: Sun, 5 Jan 2025 15:23:35 -0500 Subject: [PATCH 6/7] Update win32/scripts/pywin32_postinstall.py --- win32/scripts/pywin32_postinstall.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/win32/scripts/pywin32_postinstall.py b/win32/scripts/pywin32_postinstall.py index 95773a4a35..295818a825 100644 --- a/win32/scripts/pywin32_postinstall.py +++ b/win32/scripts/pywin32_postinstall.py @@ -661,9 +661,6 @@ def main(): > pywin32_postinstall -install - This should be run automatically after installation when installing from source, - but if it fails you can run it again. - Given EXE installers are no longer provided, and wheel installs can't run postinstall scripts, you almost certainly need to run this to From b2acc3b59731541a9a217fec92df82ad1f034b46 Mon Sep 17 00:00:00 2001 From: Avasam Date: Tue, 7 Jan 2025 22:39:07 -0500 Subject: [PATCH 7/7] Fix PATH issues --- .github/workflows/main.yml | 15 +++++++++++---- CHANGES.txt | 5 ++++- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 2ef7cb6e84..1533195731 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -39,6 +39,14 @@ jobs: pip --version pip install --upgrade setuptools>=74 wheel + - name: Fix user Scripts missing from PATH + if: matrix.architecture == 'x86' + run: | + # Work around https://github.com/actions/setup-python/issues/1005 + $ScriptsPath = python -c "import sysconfig,os; print(sysconfig.get_path('scripts', f'{os.name}_user'))" + echo $ScriptsPath + Add-Content $env:GITHUB_PATH $ScriptsPath + - name: Build and install run: pip install . -v --user @@ -49,13 +57,12 @@ jobs: - name: Generate PyWin32.chm help file run: python AutoDuck/make.py - # Smokescreen test to validate it doesn't crash and dlls can be found + # Smokescreen test to validate postinstall doesn't crash, dlls can be found, and both pathless invocation methods work - name: Run postinstall install/remove run: | $UserSite = "$(python -m site --user-site)" - cd "$UserSite/.." - python Scripts/pywin32_postinstall.py -install -destination "$UserSite" - python Scripts/pywin32_postinstall.py -remove -destination "$UserSite" + python -m win32.scripts.pywin32_postinstall -install -destination "$UserSite" + pywin32_postinstall -remove -destination "$UserSite" - name: Run tests # Run the tests directly from the source dir so support files (eg, .wav files etc) diff --git a/CHANGES.txt b/CHANGES.txt index 4452068337..c4f2027a5d 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. @@ -14,6 +14,9 @@ https://mhammond.github.io/pywin32_installers.html. Coming in build 309, as yet unreleased -------------------------------------- +* The postinstall script is now available as a console script. You can invoke it in one of two new methods: + 1. `python -m pywin32_postinstall -install` (recommended) + 2. `pywin32_postinstall -install` (shorter but you don't have control over which python environment is used) * Removed param `hIcon` from `win32comext.shell.ShellExecuteEx`. It was unusable since Windows Vista (#2423, @Avasam) * Fixed `nbios.NCBStruct` packing (#2406, @Avasam) * Restored axdebug builds on Python 3.10 (#2416, @Avasam)