Skip to content
Draft
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
76755cb
restore shipping help file
Avasam Nov 19, 2024
4b2e319
Add change entry
Avasam Nov 19, 2024
eddee6d
Update pywin32_postinstall.py
Avasam Nov 19, 2024
7a7035c
Update setup.py
Avasam Nov 19, 2024
5e6f8fa
Merge branch 'main' into restore-shipping-help-file
Avasam Dec 14, 2024
0bcde8a
Merge branch 'main' into restore-shipping-help-file
Avasam Jan 4, 2025
0003fad
Merge branch 'main' into restore-shipping-help-file
Avasam Jan 7, 2025
ad18195
post-merge fix
Avasam Jan 7, 2025
2a36e8a
add some debug logging
Avasam Jan 8, 2025
d4cbc1e
Merge branch 'restore-shipping-help-file' of https://github.com/Avasa…
Avasam Jan 8, 2025
d812230
Merge branch 'main' of https://github.com/mhammond/pywin32 into resto…
Avasam Mar 10, 2025
afa048b
Fix some typos
Avasam Mar 10, 2025
45ff7c9
Merge branch 'main' of https://github.com/mhammond/pywin32 into resto…
Avasam Mar 18, 2025
71702b5
Merge branch 'main' into restore-shipping-help-file
Avasam Mar 19, 2025
e1536ce
Missing subprocess import after merge
Avasam Mar 19, 2025
d0fc388
Merge branch 'restore-shipping-help-file' of https://github.com/Avasa…
Avasam Mar 19, 2025
6b5e473
Support cross-compilation
Avasam Mar 27, 2025
a6e4ba6
Merge branch 'main' of https://github.com/mhammond/pywin32 into resto…
Avasam Mar 27, 2025
c04737b
Merge branch 'main' of https://github.com/mhammond/pywin32 into resto…
Avasam Jun 18, 2025
8dac3c0
Merge branch 'main' into restore-shipping-help-file
Avasam Jun 24, 2025
3a15b0b
Merge branch 'main' into restore-shipping-help-file
Avasam Jul 22, 2025
91ab839
Merge branch 'main' of https://github.com/mhammond/pywin32 into resto…
Avasam Jul 24, 2025
c3a7444
Merge branch 'main' into restore-shipping-help-file
Avasam Dec 18, 2025
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
16 changes: 6 additions & 10 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@ on:
push:
branches:
- main
pull_request: # Temporary just for test
branches:
- main

jobs:
generate:
Expand All @@ -25,17 +22,16 @@ jobs:
with:
python-version: '3.9'

# We still need to install pywin32 because
# AutoDuck/py2d.py currently relies on runtime imports for introspection
# Downloading latest release is faster than re-building
# We install pywin32's latest release just to avoid re-building
# We could instead try to use a GitHub artifact
- name: Install latest release
run: pip install --user --upgrade pywin32

- name: Generate PyWin32.chm help file
run: python AutoDuck/make.py
- name: Set Python user site directory
run: python -c "import os,site; open(os.environ['GITHUB_ENV'], 'a').write(f'USER_DIR={site.USER_SITE}\n')"

- name: Decompile help file into HTML
run: hh -decompile site PyWin32.chm
- name: Decompile shipped help file
run: hh -decompile site ${env:USER_DIR}\PyWin32.chm

- name: Rename root HTML file
run: mv site\PyWin32.HTML site\index.html
Expand Down
14 changes: 7 additions & 7 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,6 @@ jobs:
- name: Build and install
run: pip install . -v --user

# This needs to happen *after* installing pywin32 since
# AutoDuck/py2d.py currently relies on runtime imports for introspection
# This isn't included in the wheel (TODO: could we?)
# and only serves as a PR test for the docs.yaml workflow
- name: Generate PyWin32.chm help file
run: python AutoDuck/make.py

# Smokescreen test to validate it doesn't crash and dlls can be found
- name: Run postinstall install/remove
run: |
Expand All @@ -57,6 +50,13 @@ jobs:
python Scripts/pywin32_postinstall.py -install -destination "$UserSite"
python Scripts/pywin32_postinstall.py -remove -destination "$UserSite"

# This needs to happen *after* installing pywin32 since
# AutoDuck/py2d.py currently relies on runtime imports for introspection
# This isn't included in the wheel (TODO: could we?)
# and only serves as a PR test for the docs.yaml workflow
- name: Generate PyWin32.chm help file
run: python AutoDuck/make.py

Comment thread
Avasam marked this conversation as resolved.
Outdated
- 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.
Expand Down
1 change: 1 addition & 0 deletions CHANGES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ https://mhammond.github.io/pywin32_installers.html.
Coming in build 309, as yet unreleased
--------------------------------------

* Restored shipping a helpfile with the wheel. Run like for pywin32 306 and before, you can run the `pywin32_postinstall` script to register it (#2432, @Avasam)
* 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)
Expand Down
11 changes: 4 additions & 7 deletions pywin32_postinstall.py
Original file line number Diff line number Diff line change
Expand Up @@ -233,13 +233,10 @@ def RegisterHelpFile(register=True, lib_dir=None):
if register:
# Register the .chm help file.
chm_file = os.path.join(lib_dir, "PyWin32.chm")
if os.path.isfile(chm_file):
# This isn't recursive, so if 'Help' doesn't exist, we croak
SetPyKeyVal("Help", None, None)
SetPyKeyVal("Help\\Pythonwin Reference", None, chm_file)
return chm_file
else:
print("NOTE: PyWin32.chm can not be located, so has not been registered")
# This isn't recursive, so if 'Help' doesn't exist, we croak
SetPyKeyVal("Help", None, None)
SetPyKeyVal("Help\\Pythonwin Reference", None, chm_file)
return chm_file
else:
UnsetPyKeyVal("Help\\Pythonwin Reference", None, delete_key=True)
return None
Expand Down
71 changes: 48 additions & 23 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import shutil
import subprocess
import sys
import sysconfig
import winreg
from pathlib import Path
from setuptools import Extension, setup
Expand Down Expand Up @@ -482,6 +483,48 @@ def _build_scintilla(self):
os.path.join(self.build_lib, "pythonwin"),
)

def _build_helpfile(self) -> None:
"""
Since AutoDuck/py2d.py relies on import,
this must be done after all extensions are built.

We can't just add to sys.path to point to the build folder,
because this uses subprocesses,
so we we create a temporary .pth file instead.
"""
build_lib_absolute = os.path.abspath(self.build_lib)
tmp_pywin32_build_pth = (
Path(sysconfig.get_paths()["platlib"]) / "tmp_pywin32_build.pth"
)

# Delete the previous helpfile to ensure that this build worked
Path("PyWin32.chm").unlink(missing_ok=True)

# Create the temporary .pth file
with open("pywin32.pth") as path_file:
# Copy paths from pywin32.pth and expand them to absolute paths
paths = [
(
path.strip()
# support the "import pywin32_bootstrap" hack
if path.startswith("import ")
else os.path.join(build_lib_absolute, path.strip())
)
for path in path_file.readlines()
if not path.startswith("#")
] + [
build_lib_absolute,
# For pythoncom.py, since it doesn't get added to the build folder
os.path.abspath("com"),
]
tmp_pywin32_build_pth.write_text("\n".join(paths))

# Actually generate the helpfile
subprocess.run((sys.executable, "AutoDuck/make.py"), check=True)

# Cleanup
tmp_pywin32_build_pth.unlink()

# find the VC base path corresponding to distutils paths, and
# potentially upgrade for extra include / lib paths (MFC)
def _check_vc(self):
Expand Down Expand Up @@ -626,6 +669,8 @@ def build_extensions(self):
for mfc_content in mfc_contents:
self.copy_file(mfc_content, target_dir)

self._build_helpfile()

def build_exefile(self, ext):
suffix = "_d" if self.debug else ""
logging.info("building exe '%s'", ext.name)
Expand Down Expand Up @@ -1980,20 +2025,6 @@ def convert_data_files(files: Iterable[str]):
return ret


def convert_optional_data_files(files):
ret = []
for file in files:
try:
temp = convert_data_files([file])
except RuntimeError as details:
if not str(details.args[0]).startswith("No file"):
raise
logging.info("NOTE: Optional file %s not found - skipping", file)
else:
ret.append(temp[0])
return ret


################################################################
if len(sys.argv) == 1:
# distutils will print usage - print our docstring first.
Expand Down Expand Up @@ -2087,11 +2118,6 @@ def convert_optional_data_files(files):
packages=packages,
py_modules=py_modules,
data_files=[("", (os.path.join(gettempdir(), "pywin32.version.txt"),))]
+ convert_optional_data_files(
[
"PyWin32.chm",
]
)
+ convert_data_files(
[
"Pythonwin/start_pythonwin.pyw",
Expand Down Expand Up @@ -2149,9 +2175,8 @@ def convert_optional_data_files(files):
"adodbapi/examples/*.py",
]
)
+
# The headers and .lib files
[
+ [
("win32/include", ("win32/src/PyWinTypes.h",)),
(
"win32com/include",
Expand All @@ -2162,14 +2187,14 @@ def convert_optional_data_files(files):
),
),
]
+
# And data files convert_data_files can't handle.
[
+ [
("win32com", ("com/License.txt",)),
# pythoncom.py doesn't quite fit anywhere else.
# Note we don't get an auto .pyc - but who cares?
("", ("com/pythoncom.py",)),
("", ("pywin32.pth",)),
("", ("PyWin32.chm",)),
],
)

Expand Down