Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Automatically run pywin32_postinstall.py for "local"/"from source" installs #2447

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

Avasam
Copy link
Collaborator

@Avasam Avasam commented Jan 5, 2025

  • Automatically run pywin32_postinstall.py for "local"/"from source" installs (pip install .)
  • Fail the install if postinstall fails from a local install
  • Added support for relative path for the -destination argument

Resolves #2408 (comment)

If you don't think that pywin32_postinstall should be run at all for installs from source, then the entire my_install class should be removed instead.

…alls (`pip install .`)

- Also respect the verbose flag instead of always running quiet
- Added support for relative path for the `-destination` argument
@Avasam Avasam force-pushed the run-postinstall-on-local-installs branch from 5219ca8 to 9ff63c2 Compare January 5, 2025 21:18
sys.executable,
filename,
"-install",
"-destination",
self.install_lib,
"-quiet",
Copy link
Collaborator Author

@Avasam Avasam Jan 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At first I did

Suggested change
"-quiet",
*([] if self.verbose else ["-quiet"]),

but realized pip without -v isn't printing any of this anyway.

@Avasam Avasam requested a review from mhammond January 5, 2025 21:22
@@ -874,17 +864,16 @@ def _postinstall(self):
raise RuntimeError(f"Can't find '{filename}'")
# As of setuptools>=74.0.0, we no longer need to
# be concerned about distutils calling win32api
subprocess.Popen(
Copy link
Collaborator Author

@Avasam Avasam Jan 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: This wouldn't replace #2392
That other PR also tests uninstalling
In fact both together should be better as it would test the install under 2 different contexts, and test a re-install.

Copy link
Owner

@mhammond mhammond left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand this. I think the "when installed from source" comments were not about "source" so much as "not from the installer"

)
return
self.execute(self._postinstall, (), msg="Executing post install script...")
# Hacky, skip for build-only commands
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand this. Doesn't "setup.py build install" work? I don't think this check is related to the old check though, that's just about the target?

Copy link
Collaborator Author

@Avasam Avasam Jan 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As a clarification, calling setup.py directly should no longer be done. It has been long deprecated and setuptools is no longer in the business of acting as a build frontend and installer. (that's what #2396 / #2208 was about)
You should see setup.py as a dynamic configuration file, rather than a script to be run.

We currently use a mix of pip wheel (for regular builds + local installs) and https://github.com/pypa/build + https://github.com/pypa/wheel (for cross-compiled ARM64) as build frontends to create wheels.

For historical and backwards compatibility reasons, setuptools.build_meta:__legacy__ is the default fallback backend (https://peps.python.org/pep-0517/#summary-of-changes-to-pep-517), which is why that part hasn't broken for us, despite not specifying anywhere (in a pyproject.toml file) that we use setuptools as a build backend.


Now why change this code?

At the moment in the main branch, this my_install class is complete dead code. Installing from a wheel (which is what all pywin32 users installing from PyPI do, since we don't provide a source distribution) doesn't run any code from setup.py (it's all static and metadata).

Even when installing from source, that is, downloading the source code/cloning the repository, and running pip install ., (or whichever package manager, be it poetry, PDM, uv, etc.). This _postinstall method wouldn't trigger because the if self.root branch is always taken when running pip install .

So this PR restores automatically running the postinstall script only for those who install pywin32 from building the source code.

The hacky condition is because setuptool's bdist_wheel will internally call self.run_command("install") to install to the temporary build folder. Which is an issue for the ARM64 steps as they otherwise try to run the postinstall script, which obviously fail due to trying to load a DLL for a different architecture. And I don't know how to differentiate between "just build a distribution" and "build to install" pypa/setuptools#4791


That all being said. I'm also considering just removing this custom install command and any leftover assumption in comments/doc that there's a case in which the pywin32_postinstall script can be run automatically.
Edit: I went ahead and created said PR that is the inverse of this one: #2453

Copy link
Collaborator Author

@Avasam Avasam Jan 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got a reply: pypa/setuptools#4791 (comment)
I'm really tempted to prefer #2453 over this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants