This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Add "exe wrapper" functionality to Windows launcher
Type: enhancement Stage: resolved
Components: Windows Versions: Python 3.4
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: vinay.sajip Nosy List: jkloth, mhammond, paul.moore, python-dev, tim.golden, vinay.sajip
Priority: normal Keywords: patch

Created on 2013-07-18 14:46 by paul.moore, last changed 2022-04-11 14:57 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
launcher_wrapper.patch paul.moore, 2013-07-21 11:04 review
Messages (12)
msg193300 - (view) Author: Paul Moore (paul.moore) * (Python committer) Date: 2013-07-18 14:46
Adds "exe wrapper" functionality to the Windows launcher. This is a preliminary patch, for comments - the code is there and works, but I need to add documentation (and maybe tests - are there any existing tests for the launcher?)

Also to be considered: should the launcher be bundled somewhere accessible to Python code (locating where the launcher has been installed is a non-trivial task) and supplementing that, should there be some sort of wrapper creation API in the standard library. The script wrapper functionality in distlib may be a good model for this, but may be too complex. I'd rather see this patch accepted without support code than see it deferred due to concerns about the quality/design of additional support code.
msg193341 - (view) Author: Vinay Sajip (vinay.sajip) * (Python committer) Date: 2013-07-19 00:07
My initial comments - seems like a reasonable approach. I think you may need to consider -script.pyw for the GUI case. I will look into it in more detail.

I'll add Mark to the nosy list, as the launcher was originally his idea and he might have a view.

What "support code" are you referring to?

Re. tests - there are tests, see the repo on BitBucket:

https://bitbucket.org/pypa/pylauncher/src/tip/tests.py?at=default

There are no tests in the Python suite; because of the specialised nature of the launcher, to do proper tests you need 2.x and 3.x installed on the test machine, preferably both 32- and 64-bit variants. This doesn't match our buildbot configurations.
msg193342 - (view) Author: Mark Hammond (mhammond) * (Python committer) Date: 2013-07-19 00:25
I don't understand the motivation for this - how will it be used in practice?
msg193343 - (view) Author: Vinay Sajip (vinay.sajip) * (Python committer) Date: 2013-07-19 00:58
> I don't understand the motivation for this - how will it be used in practice?

It allows the launcher to do double duty as an executable launcher for scripts which works in the same way as executable launchers in setuptools-installed scripts.

Its use in this way is redundant if the launcher is actually installed. However, if the launcher isn't installed, it's considered the only fool-proof way of invoking Python scripts on Windows.

This patch is a consequence of discussions ongoing on distutils-sig about bundling setuptools and pip in Python.

In practice, a Python script 'foo' in a distribution, which would be called just plain 'foo' on Unix and have a Python shebang line, would be named 'foo-script.py' with a copy of the launcher as 'foo.exe' alongside, which invokes the Python script when run. A GUI script would be called 'foo-script.pyw' and have the GUI version of the launcher in 'foo.exe'.
msg193344 - (view) Author: Mark Hammond (mhammond) * (Python committer) Date: 2013-07-19 01:11
Obviously I'm missing a little context, but it seems a little wrong for the same launcher to be doing this double-duty.  It seems we only want to use the launcher in this way as it already has some of the interesting code we need - but the vast majority of users aren't going to want to have it behave this way implicitly (ie, when they start what they consider the "launcher", they aren't going to expect this magic.  Conversely, when someone executes "foo", they are going to be expecting exactly 1 thing to happen and that isn't "do what py.exe with no args does")

So maybe this could be behind a #define, and have another .exe built from the same sources?  One exe sticks with the launcher semantics (ie, never looks for foo-script.py), and the other sticks with the wrapper semantics (ie, terminates with an error if foo-script.py can't be found)

All that said though, I'm not involved in the distutils discussions and acknowledge the general requirements as real, so do whatever you need to do :)
msg193347 - (view) Author: Paul Moore (paul.moore) * (Python committer) Date: 2013-07-19 06:55
Correct about .pyw files - I had forgotten those, I will update the patch.

The idea of "support code" was to (somewhat) alleviate Mark's question about "what is this for", I was wondering if it was worth adding a module to the stdlib which did the job of saving a renamed copy of the launcher alongside a user-specified script.

Note that (AIUI) there is still value in this even if the launcher is installed - people have suggested that other approaches don't work for one reason or another. For example, you cannot execute .py scripts directly from the command line unless you manually add .py to the PATHEXT variable (as the Python installer does not do this).
msg193348 - (view) Author: Tim Golden (tim.golden) * (Python committer) Date: 2013-07-19 07:53
Glancing back, it isn't perhaps clear to the casual reader what's being proposed here, and why. The idea is that a pip-style installer become part of core Python. For Windows users, any standalone scripts from an installed package would be placed in scripts/ with a stub .exe which is a copy of the py.exe launcher which would launch the corresponding Python file.

So, for a package Foo with a run-foo script, there would be: scripts/run-foo-script.py and scripts/run-foo.exe. The latter is a copy of the PEP397 launcher which interrogates its own filename (run-foo.exe) and looks for a corresponding Python script (run-foo-script.py) and then uses the launcher mechanics to run it, making use of all the built-in shebang-handling, command-line switches, etc.

This patch allows the py.exe launcher to be used in either way, transparently, inserting the run-foo-script.py filepath as a first parameter before the rest of the code runs.
msg193353 - (view) Author: Vinay Sajip (vinay.sajip) * (Python committer) Date: 2013-07-19 09:40
How about the following?

1. Paul updates the patch to include .pyw files, but also puts all the functionality of this patch in #if defined(SCRIPT_WRAPPER).
2. SCRIPT_WRAPPER is left undefined in the launcher Visual Studio project, so it will build identically to how it does now.
3. Once the dust has settled on distutils-sig, and we know for sure what we need for script wrappers, we add a separate Visual Studio project to the Python solution which defines SCRIPT_WRAPPER and puts the built files in whatever  destination is appropriate.

This will give the benefit that we can reuse common functionality at the source code level, without changing the existing behaviour of py.exe/pyw.exe.
msg193354 - (view) Author: Paul Moore (paul.moore) * (Python committer) Date: 2013-07-19 10:00
I've no problem with that suggestion. The patch is clean enough that ifdef-ing it out won't be hard.

Revised patch incoming :-) It's needed for the pyw support in any case.
msg193357 - (view) Author: Mark Hammond (mhammond) * (Python committer) Date: 2013-07-19 12:03
Vinay's idea makes sense to me.  Paul can also subtly change the patch such that when SCRIPT_WRAPPER is defined, failure to find the wrapper is fatal and prints a message specific to this fact rather than just starting an interactive Python (assuming I read the patch correctly, that is :)  Then a new .exe is built named something innocuous, installed in a single well-known location as the "stub" and that pip-style code creating the wrapper has a nice easy job :)
msg193434 - (view) Author: Paul Moore (paul.moore) * (Python committer) Date: 2013-07-21 11:04
Updated patch, as per discussion.
msg193692 - (view) Author: Roundup Robot (python-dev) (Python triager) Date: 2013-07-25 10:21
New changeset 4123e002a1af by Vinay Sajip in branch 'default':
Closes #18491: Added script-wrapper functionality to launcher source (but not to executable).
http://hg.python.org/cpython/rev/4123e002a1af
History
Date User Action Args
2022-04-11 14:57:48adminsetgithub: 62691
2013-07-25 10:21:07python-devsetstatus: open -> closed

nosy: + python-dev
messages: + msg193692

resolution: fixed
stage: patch review -> resolved
2013-07-21 11:05:29paul.mooresetfiles: - launcher_wrapper.patch
2013-07-21 11:04:39paul.mooresetfiles: + launcher_wrapper.patch

messages: + msg193434
2013-07-19 12:03:06mhammondsetmessages: + msg193357
2013-07-19 10:00:00paul.mooresetmessages: + msg193354
2013-07-19 09:40:34vinay.sajipsetmessages: + msg193353
2013-07-19 07:53:32tim.goldensetmessages: + msg193348
2013-07-19 06:55:45paul.mooresetmessages: + msg193347
2013-07-19 01:11:13mhammondsetmessages: + msg193344
2013-07-19 00:58:55vinay.sajipsetmessages: + msg193343
2013-07-19 00:25:20mhammondsetmessages: + msg193342
2013-07-19 00:07:27vinay.sajipsetnosy: + mhammond
messages: + msg193341
2013-07-18 19:26:35jklothsetnosy: + jkloth
2013-07-18 14:47:22paul.mooresetnosy: + tim.golden
2013-07-18 14:46:18paul.mooresetfiles: + launcher_wrapper.patch
keywords: + patch
2013-07-18 14:46:05paul.moorecreate