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

Make py2 and py3 aliases also resolve via py on windows #858

Merged
merged 1 commit into from
Jun 25, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog/856.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Make ``py2`` and ``py3`` aliases also resolve via ``py`` on windows
13 changes: 7 additions & 6 deletions src/tox/interpreters.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,11 +143,12 @@ def tox_get_python_executable(envconfig):
return p
actual = None
# Is this a standard PythonX.Y name?
m = re.match(r"python(\d)\.(\d)", name)
m = re.match(r"python(\d)(?:\.(\d))?", name)
groups = [g for g in m.groups() if g] if m else []
if m:
# The standard names are in predictable places.
actual = r"c:\python{}{}\python.exe".format(*m.groups())
if not actual:
actual = r"c:\python{}\python.exe".format("".join(groups))
else:
actual = win32map.get(name, None)
if actual:
actual = py.path.local(actual)
Expand All @@ -156,13 +157,13 @@ def tox_get_python_executable(envconfig):
# The standard executables can be found as a last resort via the
# Python launcher py.exe
if m:
return locate_via_py(*m.groups())
return locate_via_py(*groups)

# Exceptions to the usual windows mapping
win32map = {"python": sys.executable, "jython": r"c:\jython2.5.1\jython.bat"}

def locate_via_py(v_maj, v_min):
ver = "-{}.{}".format(v_maj, v_min)
def locate_via_py(*parts):
ver = "-{}".format(".".join(parts))
script = "import sys; print(sys.executable)"
py_exe = distutils.spawn.find_executable("py")
if py_exe:
Expand Down
41 changes: 29 additions & 12 deletions tests/test_interpreters.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ def fake_find_exe(exe):
return "py"

def fake_popen(cmd, stdout, stderr):
assert cmd[:3] == ("py", "-3.2", "-c")
fake_popen.last_call = cmd[:3]

# need to pipe all stdout to collect the version information & need to
# do the same for stderr output to avoid it being forwarded as the
Expand All @@ -56,35 +56,52 @@ def communicate():

monkeypatch.setattr(distutils.spawn, "find_executable", fake_find_exe)
monkeypatch.setattr(subprocess, "Popen", fake_popen)
assert locate_via_py("3", "2") == sys.executable
assert locate_via_py("3", "6") == sys.executable
assert fake_popen.last_call == ("py", "-3.6", "-c")
assert locate_via_py("3") == sys.executable
assert fake_popen.last_call == ("py", "-3", "-c")


def test_tox_get_python_executable():
class envconfig:
basepython = sys.executable
envname = "pyxx"

def get_exe(name):
envconfig.basepython = name
p = tox_get_python_executable(envconfig)
assert p
return str(p)

def assert_version_in_output(exe, version):
out = subprocess.check_output((exe, "-V"), stderr=subprocess.STDOUT)
assert version in out.decode()

p = tox_get_python_executable(envconfig)
assert p == py.path.local(sys.executable)
for major, minor in tox.PYTHON.CPYTHON_VERSION_TUPLES:
name = "python{}.{}".format(major, minor)
if tox.INFO.IS_WIN:
pydir = "python{}{}".format(major, minor)
x = py.path.local(r"c:\{}".format(pydir))
print(x)
if not x.check():
continue
else:
if not py.path.local.sysfind(name):
if not py.path.local.sysfind(name) or subprocess.call((name, "-c", "")):
continue
envconfig.basepython = name
p = tox_get_python_executable(envconfig)
assert p
popen = subprocess.Popen([str(p), "-V"], stderr=subprocess.PIPE, stdout=subprocess.PIPE)
stdout, stderr = popen.communicate()
assert not stdout or not stderr
all_output = stderr.decode("ascii") + stdout.decode("ascii")
assert "{}.{}".format(major, minor) in all_output
exe = get_exe(name)
assert_version_in_output(exe, "{}.{}".format(major, minor))

for major in (2, 3):
name = "python{}".format(major)
if tox.INFO.IS_WIN:
if subprocess.call(("py", "-{}".format(major), "-c", "")):
continue
elif not py.path.local.sysfind(name):
continue

exe = get_exe(name)
assert_version_in_output(exe, str(major))


def test_find_executable_extra(monkeypatch):
Expand Down