Created
November 16, 2017 11:34
-
-
Save westurner/80e81cd4bf9b79acb5989622f2621655 to your computer and use it in GitHub Desktop.
find all python*.exe and pip*.exe binaries on os.environ['PATH']
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
""" | |
Something like this as e.g site.discover | |
(for use as ``python -m site.discover``) | |
could be helpful for explaining and diagnosing multiple pythons and pips | |
""" | |
import os | |
import re | |
from distutils.spawn import find_executable | |
from subprocess import check_output, STDOUT | |
import collections | |
def discover(path=None, printsite=False, uniques=True): | |
""" | |
Find all ``python*`` and ``pip*`` executables and their version strings | |
within ``os.environ['PATH']`` | |
Kwargs: | |
path (str): os.pathsep-delimited path str | |
(defaults to ``os.environ['PATH']``) | |
printsite (bool): call ``<python> -m site`` | |
with each found python binary | |
uniques (bool): print uniques according to ``os.realpath`` at the end | |
Returns: | |
None | |
""" | |
if path is None: | |
path = os.environ['PATH'] | |
rgx = re.compile(r'(python|pip)\-?(\d?\.?\d?)$') | |
uniques = collections.OrderedDict() | |
for directory in path.split(os.pathsep): | |
paths = sorted( | |
((match.group(0), match.group(2)) for match in | |
(rgx.match(name) for name in os.listdir(directory)) | |
if match), | |
key=lambda x: x[::-1], | |
reverse=True) | |
print(u'# %s' % directory) | |
for (name, ver) in paths: | |
pathjoined = os.path.join(directory, name) | |
binpath = find_executable(pathjoined, directory) | |
realpath = os.path.realpath(binpath) | |
if binpath is None: | |
continue | |
if os.path.exists(pathjoined): | |
if os.path.islink(pathjoined): | |
print(( | |
u"%r is a symlink to %r, which doesn't exist" | |
% (pathjoined, binpath))) | |
# TODO: %r exists but isnt executable | |
verstring = check_output((binpath, '-V'), | |
stderr=STDOUT).rstrip() | |
uniques.setdefault(realpath, collections.OrderedDict()) \ | |
.setdefault(binpath, verstring) | |
print(u'%-11r %-5r %r' % (name, ver, verstring)) | |
if printsite and name.startswith('python'): | |
sitestring = check_output((binpath, '-m', 'site')) | |
lines = (u'> %s' % l for l in sitestring.splitlines()) | |
for line in lines: | |
print(line) | |
# TODO: check_output((binpath, '-m', 'pip')) | |
# TODO: AND/OR (?) only print uniques at the end | |
if uniques: | |
print('### UNIQUES') | |
for path in uniques: | |
print('## %s' % path) | |
paths = uniques.get(path) | |
for otherpath in sorted(paths): | |
print(otherpath) | |
print('') | |
if __name__ == '__main__': | |
discover() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment