Skip to content

Commit 1e88df8

Browse files
committed
Rewrite virtualenv-prefix without executing python (#132)
1 parent c61fdaa commit 1e88df8

File tree

2 files changed

+85
-69
lines changed

2 files changed

+85
-69
lines changed

bin/pyenv-virtualenv-prefix

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,6 @@ else
1919
IFS=: versions=($(pyenv-version-name))
2020
fi
2121

22-
real_prefix() { # virtualenv
23-
local version="$1"
24-
PYENV_VERSION="${version}" pyenv-exec python -c 'import sys;print(sys.real_prefix)' 2>/dev/null
25-
}
26-
27-
base_prefix() { # pyvenv
28-
# FIXME: non-pyvenv versions also have sys.base_prefix
29-
local version="$1"
30-
PYENV_VERSION="${version}" pyenv-exec python -c 'import sys;print(sys.base_prefix)' 2>/dev/null
31-
}
32-
3322
VIRTUALENV_PREFIX_PATHS=()
3423
for version in "${versions[@]}"; do
3524
if [ "$version" = "system" ]; then
@@ -39,8 +28,27 @@ for version in "${versions[@]}"; do
3928
PYENV_PREFIX_PATH="$(pyenv-prefix "${version}")"
4029
if [ -x "${PYENV_PREFIX_PATH}/bin/python" ]; then
4130
if [ -f "${PYENV_PREFIX_PATH}/bin/activate" ]; then
42-
VIRTUALENV_PREFIX_PATH="$(real_prefix "${version}" || base_prefix "${version}" || true)"
43-
VIRTUALENV_PREFIX_PATHS=("${VIRTUALENV_PREFIX_PATHS[@]}" "${VIRTUALENV_PREFIX_PATH:-${PYENV_PREFIX_PATH}}")
31+
if [ -f "${PYENV_PREFIX_PATH}/bin/conda" ]; then
32+
# conda
33+
VIRTUALENV_PREFIX_PATH="${PYENV_PREFIX_PATH}"
34+
else
35+
if [ -f "${PYENV_ROOT}/versions/${version}/pyvenv.cfg" ]; then
36+
# pyvenv
37+
virtualenv_binpath="$(cut -b 1-1024 "${PYENV_ROOT}/versions/${version}/pyvenv.cfg" | sed -n '/^ *home *= */s///p' || true)"
38+
VIRTUALENV_PREFIX_PATH="${virtualenv_binpath%/bin}"
39+
else
40+
# virtualenv
41+
shopt -s nullglob
42+
VIRTUALENV_PREFIX_PATH="$(cat "${PYENV_ROOT}/versions/${version}/lib/"*"/orig-prefix.txt" </dev/null 2>&1 || true)"
43+
shopt -u nullglob
44+
fi
45+
fi
46+
if [ -d "${VIRTUALENV_PREFIX_PATH}" ]; then
47+
VIRTUALENV_PREFIX_PATHS=("${VIRTUALENV_PREFIX_PATHS[@]}" "${VIRTUALENV_PREFIX_PATH:-${PYENV_PREFIX_PATH}}")
48+
else
49+
echo "pyenv-virtualenv: version \`${version}' is not a virtualenv" 1>&2
50+
exit 1
51+
fi
4452
else
4553
echo "pyenv-virtualenv: version \`${version}' is not a virtualenv" 1>&2
4654
exit 1

test/prefix.bats

Lines changed: 64 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -17,112 +17,125 @@ remove_version() {
1717
}
1818

1919
create_virtualenv() {
20-
create_version "$@"
20+
create_version "$1"
21+
create_version "${2:-$1}"
22+
mkdir -p "${PYENV_ROOT}/versions/$1/lib/python${2:-$1}"
23+
echo "${PYENV_ROOT}/versions/${2:-$1}" > "${PYENV_ROOT}/versions/$1/lib/python${2:-$1}/orig-prefix.txt"
2124
touch "${PYENV_ROOT}/versions/$1/bin/activate"
2225
}
2326

2427
remove_virtualenv() {
25-
remove_version "$@"
28+
remove_version "$1"
29+
remove_version "${2:-$1}"
30+
}
31+
32+
create_pyvenv() {
33+
create_version "$1"
34+
create_version "${2:-$1}"
35+
echo "home = ${PYENV_ROOT}/versions/${2:-$1}/bin" > "${PYENV_ROOT}/versions/$1/pyvenv.cfg"
36+
touch "${PYENV_ROOT}/versions/$1/bin/activate"
37+
}
38+
39+
remove_pyvenv() {
40+
remove_version "${2:-$1}"
41+
}
42+
43+
create_conda() {
44+
create_version "$1"
45+
create_version "${2:-$1}"
46+
touch "${PYENV_ROOT}/versions/$1/bin/conda"
47+
touch "${PYENV_ROOT}/versions/$1/bin/activate"
48+
}
49+
50+
remove_conda() {
51+
remove_version "${2:-$1}"
2652
}
2753

2854
@test "display prefix with using sys.real_prefix" {
2955
stub pyenv-version-name "echo venv27"
3056
stub pyenv-prefix "venv27 : echo \"${PYENV_ROOT}/versions/venv27\""
31-
stub pyenv-exec "echo \"${PYENV_ROOT}/versions/2.7.6\""
32-
create_virtualenv "venv27"
57+
create_virtualenv "venv27" "2.7.6"
3358

3459
PYENV_VERSION="venv27" run pyenv-virtualenv-prefix
3560

36-
unstub pyenv-version-name
37-
unstub pyenv-prefix
38-
unstub pyenv-exec
39-
remove_virtualenv "venv27"
40-
4161
assert_success
4262
assert_output <<OUT
4363
${PYENV_ROOT}/versions/2.7.6
4464
OUT
65+
66+
unstub pyenv-version-name
67+
unstub pyenv-prefix
68+
remove_virtualenv "venv27" "2.7.6"
4569
}
4670

4771
@test "display prefixes with using sys.real_prefix" {
4872
stub pyenv-version-name "echo venv27:venv32"
4973
stub pyenv-prefix "venv27 : echo \"${PYENV_ROOT}/versions/venv27\"" \
5074
"venv32 : echo \"${PYENV_ROOT}/versions/venv32\""
51-
stub pyenv-exec "echo \"${PYENV_ROOT}/versions/2.7.6\"" \
52-
"echo \"${PYENV_ROOT}/versions/3.2.1\""
53-
create_virtualenv "venv27"
54-
create_virtualenv "venv32"
75+
create_virtualenv "venv27" "2.7.6"
76+
create_virtualenv "venv32" "3.2.1"
5577

5678
PYENV_VERSION="venv27:venv32" run pyenv-virtualenv-prefix
5779

58-
unstub pyenv-version-name
59-
unstub pyenv-prefix
60-
unstub pyenv-exec
61-
remove_virtualenv "venv27"
62-
remove_virtualenv "venv32"
63-
6480
assert_success
6581
assert_output <<OUT
6682
${PYENV_ROOT}/versions/2.7.6:${PYENV_ROOT}/versions/3.2.1
6783
OUT
84+
85+
unstub pyenv-version-name
86+
unstub pyenv-prefix
87+
remove_virtualenv "venv27" "2.7.6"
88+
remove_virtualenv "venv32" "3.2.1"
6889
}
6990

7091
@test "display prefix with using sys.base_prefix" {
7192
stub pyenv-version-name "echo venv33"
7293
stub pyenv-prefix "venv33 : echo \"${PYENV_ROOT}/versions/venv33\""
73-
stub pyenv-exec "false" \
74-
"echo \"${PYENV_ROOT}/versions/3.3.3\""
75-
create_virtualenv "venv33"
94+
create_virtualenv "venv33" "3.3.3"
7695

7796
PYENV_VERSION="venv33" run pyenv-virtualenv-prefix
7897

79-
unstub pyenv-version-name
80-
unstub pyenv-prefix
81-
unstub pyenv-exec
82-
remove_virtualenv "venv33"
83-
8498
assert_success
8599
assert_output <<OUT
86100
${PYENV_ROOT}/versions/3.3.3
87101
OUT
102+
103+
unstub pyenv-version-name
104+
unstub pyenv-prefix
105+
remove_virtualenv "venv33" "3.3.3"
88106
}
89107

90108
@test "display prefixes with using sys.base_prefix" {
91109
stub pyenv-version-name "echo venv33:venv34"
92110
stub pyenv-prefix "venv33 : echo \"${PYENV_ROOT}/versions/venv33\"" \
93111
"venv34 : echo \"${PYENV_ROOT}/versions/venv34\""
94-
stub pyenv-exec "false" \
95-
"echo \"${PYENV_ROOT}/versions/3.3.3\"" \
96-
"false" \
97-
"echo \"${PYENV_ROOT}/versions/3.4.0\""
98-
create_virtualenv "venv33"
99-
create_virtualenv "venv34"
112+
create_virtualenv "venv33" "3.3.3"
113+
create_virtualenv "venv34" "3.4.0"
100114

101115
PYENV_VERSION="venv33:venv34" run pyenv-virtualenv-prefix
102116

103-
unstub pyenv-version-name
104-
unstub pyenv-prefix
105-
unstub pyenv-exec
106-
remove_virtualenv "venv33"
107-
remove_virtualenv "venv34"
108-
109117
assert_success
110118
assert_output <<OUT
111119
${PYENV_ROOT}/versions/3.3.3:${PYENV_ROOT}/versions/3.4.0
112120
OUT
121+
122+
unstub pyenv-version-name
123+
unstub pyenv-prefix
124+
remove_virtualenv "venv33" "3.3.3"
125+
remove_virtualenv "venv34" "3.4.0"
113126
}
114127

115128
@test "should fail if the version is the system" {
116129
stub pyenv-version-name "echo system"
117130

118131
PYENV_VERSION="system" run pyenv-virtualenv-prefix
119132

120-
unstub pyenv-version-name
121-
122133
assert_failure
123134
assert_output <<OUT
124135
pyenv-virtualenv: version \`system' is not a virtualenv
125136
OUT
137+
138+
unstub pyenv-version-name
126139
}
127140

128141
@test "should fail if the version is not a virtualenv" {
@@ -132,37 +145,32 @@ OUT
132145

133146
PYENV_VERSION="3.4.0" run pyenv-virtualenv-prefix
134147

135-
unstub pyenv-version-name
136-
unstub pyenv-prefix
137-
remove_version "3.4.0"
138-
139148
assert_failure
140149
assert_output <<OUT
141150
pyenv-virtualenv: version \`3.4.0' is not a virtualenv
142151
OUT
152+
153+
unstub pyenv-version-name
154+
unstub pyenv-prefix
155+
remove_version "3.4.0"
143156
}
144157

145158
@test "should fail if one of the versions is not a virtualenv" {
146159
stub pyenv-version-name "echo venv33:3.4.0"
147160
stub pyenv-prefix "venv33 : echo \"${PYENV_ROOT}/versions/venv33\"" \
148161
"3.4.0 : echo \"${PYENV_ROOT}/versions/3.4.0\""
149-
stub pyenv-exec "false" \
150-
"echo \"${PYENV_ROOT}/versions/3.3.3\""
151-
create_virtualenv "venv33"
162+
create_virtualenv "venv33" "3.3.3"
152163
create_version "3.4.0"
153164

154165
PYENV_VERSION="venv33:3.4.0" run pyenv-virtualenv-prefix
155166

156-
unstub pyenv-version-name
157-
unstub pyenv-prefix
158-
unstub pyenv-exec
159-
remove_virtualenv "venv33"
160-
remove_version "3.4.0"
161-
162167
assert_failure
163168
assert_output <<OUT
164169
pyenv-virtualenv: version \`3.4.0' is not a virtualenv
165170
OUT
166-
}
167-
168171

172+
unstub pyenv-version-name
173+
unstub pyenv-prefix
174+
remove_virtualenv "venv33" "3.3.3"
175+
remove_version "3.4.0"
176+
}

0 commit comments

Comments
 (0)