Merge branch 'master' into non-existent-dotenv-message

This commit is contained in:
Dan Ryan
2018-08-24 21:57:13 -04:00
committed by GitHub
9 changed files with 91 additions and 19 deletions
+1
View File
@@ -0,0 +1 @@
Fallback to shell mode if `run` fails with Windows error 193 to handle non-executable commands. This should improve usability on Windows, where some users run non-executable files without specifying a command, relying on Windows file association to choose the current command.
+21 -5
View File
@@ -2102,15 +2102,31 @@ def inline_activate_virtual_environment():
os.environ["VIRTUAL_ENV"] = root
def do_run_nt(script):
def _launch_windows_subprocess(script):
import subprocess
command = system_which(script.command)
options = {"universal_newlines": True}
if command: # Try to use CreateProcess directly if possible.
p = subprocess.Popen([command] + script.args, **options)
else: # Command not found, maybe this is a shell built-in?
p = subprocess.Popen(script.cmdify(), shell=True, **options)
# Command not found, maybe this is a shell built-in?
if not command:
return subprocess.Popen(script.cmdify(), shell=True, **options)
# Try to use CreateProcess directly if possible. Specifically catch
# Windows error 193 "Command is not a valid Win32 application" to handle
# a "command" that is non-executable. See pypa/pipenv#2727.
try:
return subprocess.Popen([command] + script.args, **options)
except WindowsError as e:
if e.winerror != 193:
raise
# Try shell mode to use Windows's file association for file launch.
return subprocess.Popen(script.cmdify(), shell=True, **options)
def do_run_nt(script):
p = _launch_windows_subprocess(script)
p.communicate()
sys.exit(p.returncode)
+12 -1
View File
@@ -34,6 +34,7 @@ from .utils import (
is_star,
get_workon_home,
is_virtual_environment,
looks_like_dir
)
from .environments import (
PIPENV_MAX_DEPTH,
@@ -267,7 +268,17 @@ class Project(object):
def get_location_for_virtualenv(self):
if self.is_venv_in_project():
return os.path.join(self.project_directory, ".venv")
return str(get_workon_home().joinpath(self.virtualenv_name))
name = self.virtualenv_name
if self.project_directory:
venv_path = os.path.join(self.project_directory, ".venv")
if os.path.exists(venv_path) and not os.path.isdir(".venv"):
with io.open(venv_path, "r") as f:
name = f.read().strip()
# Assume file's contents is a path if it contains slashes.
if looks_like_dir(name):
return Path(name).absolute().as_posix()
return str(get_workon_home().joinpath(name))
def get_installed_packages(self):
from . import PIPENV_ROOT, PIPENV_VENDOR, PIPENV_PATCHED
+5
View File
@@ -1376,3 +1376,8 @@ def chdir(path):
yield
finally:
os.chdir(prev_cwd)
def looks_like_dir(path):
seps = (sep for sep in (os.path.sep, os.path.altsep) if sep is not None)
return any(sep in path for sep in seps)
+1
View File
@@ -6,6 +6,7 @@ set -eo pipefail
export PYTHONIOENCODING="utf-8"
export LANG=C.UTF-8
export PIP_PROCESS_DEPENDENCY_LINKS="1"
prefix() {
sed "s/^/ $1: /"
+6 -1
View File
@@ -16,6 +16,9 @@ if six.PY2:
pass
HAS_WARNED_GITHUB = False
def check_internet():
try:
# Kenneth represents the Internet LGTM.
@@ -40,13 +43,15 @@ def check_github_ssh():
res = True if c.return_code == 1 else False
except Exception:
pass
if not res:
global HAS_WARNED_GITHUB
if not res and not HAS_WARNED_GITHUB:
warnings.warn(
'Cannot connect to GitHub via SSH', ResourceWarning
)
warnings.warn(
'Will skip tests requiring SSH access to GitHub', ResourceWarning
)
HAS_WARNED_GITHUB = True
return res
+43 -10
View File
@@ -41,15 +41,17 @@ def test_reuse_previous_venv(PipenvInstance, pypi):
assert c.return_code == 0
assert normalize_drive(p.path) in p.pipenv('--venv').out
@pytest.mark.dotvenv
def test_venv_file_exists(PipenvInstance, pypi):
"""Tests virtualenv creation & package installation when a .venv file exists
at the project root.
@pytest.mark.parametrize('venv_name', ('test-venv', os.path.join('foo', 'test-venv')))
def test_venv_file(venv_name, PipenvInstance, pypi):
"""Tests virtualenv creation when a .venv file exists at the project root
and contains a venv name.
"""
with PipenvInstance(pypi=pypi, chdir=True) as p:
file_path = os.path.join(p.path, '.venv')
with open(file_path, 'w') as f:
f.write('')
f.write(venv_name)
with temp_environ(), TemporaryDirectory(
prefix='pipenv-', suffix='temp_workon_home'
@@ -58,12 +60,43 @@ def test_venv_file_exists(PipenvInstance, pypi):
if 'PIPENV_VENV_IN_PROJECT' in os.environ:
del os.environ['PIPENV_VENV_IN_PROJECT']
c = p.pipenv('install requests')
c = p.pipenv('install')
assert c.return_code == 0
venv_loc = None
for line in c.err.splitlines():
if line.startswith('Virtualenv location:'):
venv_loc = Path(line.split(':', 1)[-1].strip())
assert venv_loc is not None
c = p.pipenv('--venv')
assert c.return_code == 0
venv_loc = Path(c.out.strip()).absolute()
assert venv_loc.exists()
assert venv_loc.joinpath('.project').exists()
venv_path = venv_loc.as_posix()
if os.path.sep in venv_name:
venv_expected_path = Path(p.path).joinpath(venv_name).absolute().as_posix()
else:
venv_expected_path = Path(workon_home.name).joinpath(venv_name).absolute().as_posix()
assert venv_path == venv_expected_path
@pytest.mark.dotvenv
def test_venv_file_with_path(PipenvInstance, pypi):
"""Tests virtualenv creation when a .venv file exists at the project root
and contains an absolute path.
"""
with temp_environ(), PipenvInstance(chdir=True, pypi=pypi) as p:
with TemporaryDirectory(
prefix='pipenv-', suffix='-test_venv'
) as venv_path:
if 'PIPENV_VENV_IN_PROJECT' in os.environ:
del os.environ['PIPENV_VENV_IN_PROJECT']
file_path = os.path.join(p.path, '.venv')
with open(file_path, 'w') as f:
f.write(venv_path.name)
c = p.pipenv('install')
assert c.return_code == 0
c = p.pipenv('--venv')
assert c.return_code == 0
venv_loc = Path(c.out.strip())
assert venv_loc.joinpath('.project').exists()
assert venv_loc == Path(venv_path.name)
+1 -1
View File
@@ -44,7 +44,7 @@ def test_basic_install(PipenvInstance, pypi):
@pytest.mark.install
@flaky
def test_mirror_install(PipenvInstance, pypi):
with temp_environ(), PipenvInstance(chdir=True) as p:
with temp_environ(), PipenvInstance(chdir=True, pypi=pypi) as p:
mirror_url = os.environ.pop(
"PIPENV_TEST_INDEX", "https://pypi.python.org/simple"
)
+1 -1
View File
@@ -15,7 +15,7 @@ import os.path
def where():
"""Return the preferred certificate bundle."""
# vendored bundle inside Requests
return os.path.join(os.path.dirname(__file__), 'certs', 'cacert.pem')
return os.path.join(os.path.abspath(os.path.dirname(__file__)), 'certs', 'cacert.pem')
if __name__ == '__main__':
print(where())