[Python-Dev] PEP 370 - per-user scripts directory on Windows

Paul Moore p.f.moore at gmail.com
Fri Feb 13 12:19:54 CET 2015


On 13 February 2015 at 10:15, Glenn Linderman <v+python at g.nevcal.com> wrote:
> Maybe restricting it to running ".py" files or ".exe" files would be
> reasonable. That covers entry points (which should be the norm for
> newer projects) and Python scripts (which are the most likely things
> to be portable).
>
> The WINDOWS py launcher hardly needs to be portable.  Batch/CMD files also
> seem useful on WINDOWS. And Powershell?
>
> If a launcher is developed for or enhanced for other systems, shell scripts
> may be useful, and Batch/CMD not.

By "portable" in this sense I meant "not written by a Unix developer
who hadn't thought about Windows much". I was comparing Python files
with a .py extension and extensionless Python files, specifically (my
wording didn't make that clear, sorry). Yes, files with extensions of
.bat or .cmd or .ps1 are probably written for Windows only. But I
think it's getting out of scope of the launcher to decide to use
cmd.exe to launch .bat and .cmd files, and powershell to launch .ps1
files.

Regardless, my real point was that there can be all sorts of stuff in
the Scripts directory, and I'm not convinced that this is a direction
the launcher should be going in. Someone *could* make a case for
launching certain types of file that might be in there, but I'm not
going to be that person.

One thought - it's not hard using pkg_resources to enumerate all
available console_script entry points, pick one and run it. So you
could pretty simply write a script (that itself could be run with the
launcher) to run anything in Scripts that's built via entry points
(which is the recommended way these days).

# launch.py
import sys
import pkg_resources

# Get the script name
script = sys.argv[1]
# Remove our name from sys.argv
del sys.argv[0]

# There's probably a better API you can use
for ep in pkg_resources.working_set.iter_entry_points('console_scripts'):
    if ep.name == script:
        fn = ep.load()
        sys.exit(fn())

# Couldn't find the entry point
print("No entry point called {} available".format(script), file=sys.stderr)
sys.exit(1)

Now you can do "py launch.py pip --help" and it will run pip for you.

If a project isn't exposing its scripts as entry points, ask them to :-)

Paul

Paul


More information about the Python-Dev mailing list