<div dir="ltr">Would something like this be helpful?<div>(`python -m pip` seems to work fine after `conda install pip` after a miniconda install)<br><div><br></div><div><a href="https://gist.github.com/westurner/80e81cd4bf9b79acb5989622f2621655">https://gist.github.com/westurner/80e81cd4bf9b79acb5989622f2621655</a><br></div><div><br></div><div>```python</div><div><div>#!/usr/bin/env python</div><div>"""</div><div>Something like this as e.g site.discover</div><div>(for use as ``python -m site.discover``)</div><div>could be helpful for explaining and diagnosing multiple pythons and pips</div><div>"""</div><div><br></div><div>import os</div><div>import re</div><div>from distutils.spawn import find_executable</div><div>from subprocess import check_output, STDOUT</div><div>import collections</div><div><br></div><div><br></div><div>def discover(path=None, printsite=False, uniques=True):</div><div>    """</div><div>    Find all ``python*`` and ``pip*`` executables and their version strings</div><div>    within ``os.environ['PATH']``</div><div><br></div><div>    Kwargs:</div><div>        path (str): os.pathsep-delimited path str</div><div>            (defaults to ``os.environ['PATH']``)</div><div>        printsite (bool): call ``<python> -m site``</div><div>            with each found python binary</div><div>        uniques (bool): print uniques according to ``os.realpath`` at the end</div><div><br></div><div>    Returns:</div><div>        None</div><div>    """</div><div>    if path is None:</div><div>        path = os.environ['PATH']</div><div>    rgx = re.compile(r'(python|pip)\-?(\d?\.?\d?)$')</div><div>    uniques = collections.OrderedDict()</div><div>    for directory in path.split(os.pathsep):</div><div>        paths = sorted(</div><div>            ((match.group(0), match.group(2)) for match in</div><div>                (rgx.match(name) for name in os.listdir(directory))</div><div>             if match),</div><div>            key=lambda x: x[::-1],</div><div>            reverse=True)</div><div>        print(u'# %s' % directory)</div><div>        for (name, ver) in paths:</div><div>            pathjoined = os.path.join(directory, name)</div><div>            binpath = find_executable(pathjoined, directory)</div><div>            realpath = os.path.realpath(binpath)</div><div>            if binpath is None:</div><div>                continue</div><div>                if os.path.exists(pathjoined):</div><div>                    if os.path.islink(pathjoined):</div><div>                        print((</div><div>                            u"%r is a symlink to %r, which doesn't exist"</div><div>                            % (pathjoined, binpath)))</div><div>                    # TODO: %r exists but isnt executable</div><div>            verstring = check_output((binpath, '-V'),</div><div>                                     stderr=STDOUT).rstrip()</div><div>            uniques.setdefault(realpath, collections.OrderedDict()) \</div><div>                .setdefault(binpath, verstring)</div><div>            print(u'%-11r %-5r %r' % (name, ver, verstring))</div><div>            if printsite and name.startswith('python'):</div><div>                sitestring = check_output((binpath, '-m', 'site'))</div><div>                lines = (u'> %s' % l for l in sitestring.splitlines())</div><div>                for line in lines:</div><div>                    print(line)</div><div>                # TODO: check_output((binpath, '-m', 'pip'))</div><div><br></div><div>    # TODO: AND/OR (?) only print uniques at the end</div><div>    if uniques:</div><div>        print('### UNIQUES')</div><div>        for path in uniques:</div><div>            print('## %s' % path)</div><div>            paths = uniques.get(path)</div><div>            for otherpath in sorted(paths):</div><div>                print(otherpath)</div><div>            print('')</div><div><br></div><div><br></div><div>if __name__ == '__main__':</div><div>    discover()</div></div><div><br></div><div>```</div><div><div><br><br>On Wednesday, November 15, 2017, Steve Dower <<a href="mailto:steve.dower@python.org" target="_blank">steve.dower@python.org</a>> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On 15Nov2017 0617, Nick Coghlan wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
On 15 November 2017 at 22:46, Michel Desmoulin <<a>desmoulinmichel@gmail.com</a> <mailto:<a>desmoulinmichel@gmail.<wbr>com</a>>> wrote:<br>
    Should I do a PEP with a summary of all the stuff we discussed ?<br>
I think a Windows-specific PEP covering adding PATH updates back to the default installer behaviour, and adding pythonX and pythonX.Y commands would be useful (and Guido would presumably delegate resolving that to Steve Dower as the Windows installer maintainer).<br>
</blockquote>
<br>
If you write such a PEP, please also research and write up the issues with modifying PATH on Windows (they're largely scattered throughout bugs.p.o and earlier discussions on python-dev).<br>
<br>
Once you realise the tradeoff involved in modifying these global settings, you'll either come around to my point of view or be volunteering to take *all* the support questions when they come in :)<br>
<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
The one thing I'd ask is that any such PEP *not* advocate for promoting ther variants as the preferred way of invoking Python on Windows - rather, they should be positioned as a way of making online instructions written for Linux more likely to "just work" for folks on Windows (similar to the utf-8 encoding changes in <a href="https://www.python.org/dev/peps/pep-0529/" target="_blank">https://www.python.org/dev/pep<wbr>s/pep-0529/</a>)<br>
<br>
Instead, the focus should be on ensuring the "python -m pip install" and "pip install" both work after clicking through the installer without changing any settings, and devising a troubleshooting guide to help folks that are familiar with computers and Python, but perhaps not with Windows, guide folks to a properly working environment.<br>
</blockquote>
<br>
My preferred solution for this is to rename "py.exe" to "python.exe" (or rather, make a copy of it with the new name), and extend (or more likely, rewrite) the launcher such that:<br>
<br>
* if argv[0] == "py.exe", use PEP 514 company/tag resolution to find and launch Python based on first command line argument<br>
* if argv[0] == "python<numeric tag>.exe", find the matching PythonCore/<tag> install (where tag may be a partial match - e.g. "python3.exe" finds the latest PythonCore/3.x)<br>
* else, if argv[0] == "<module><numeric tag>.exe, find the matching PythonCore/<tag> install and launch "-m <module>"<br>
<br>
With the launcher behaving like this, we can make as many hard links as we want in its install directory (it only gets installed once, so only needs one PATH entry, and this is C:\Windows for admin installs):<br>
* python.exe<br>
* python2.exe<br>
* python3.exe<br>
* python3.6.exe<br>
* pip.exe<br>
* pip2.exe<br>
* pip3.exe<br>
<br>
As well as allowing e.g. "py.exe -anaconda36-64 ..." to reliably locate and run non-Python.org installs.<br>
<br>
It needs to be fully specced out, obviously, and we may want to move the all-users install to its own directory to reduce clutter, but part of the reason behind PEP 514 was to enable this sort of launcher. It could even extend to "you don't have this version right now, want to download and install it?"<br>
<br>
And finally it should be fairly obvious that this doesn't have to be a core Python tool. It has no reliance on anything in core (that isn't already specified in a PEP) and could be written totally independently. I've tried (weakly) to get work time allocated to this in the past, and if it's genuinely not going to get done unless I do it then I'll try again.<br>
<br>
Cheers,<br>
Steve<br>
______________________________<wbr>_________________<br>
Python-ideas mailing list<br>
<a>Python-ideas@python.org</a><br>
<a href="https://mail.python.org/mailman/listinfo/python-ideas" target="_blank">https://mail.python.org/mailma<wbr>n/listinfo/python-ideas</a><br>
Code of Conduct: <a href="http://python.org/psf/codeofconduct/" target="_blank">http://python.org/psf/codeofco<wbr>nduct/</a><br>
</blockquote></div></div>
</div></div>