Skip to content

Commit b9a6af0

Browse files
author
Jon Wayne Parrott
authored
Truncate or warn about long virtualenv paths (#12)
1 parent 8c7193b commit b9a6af0

3 files changed

Lines changed: 48 additions & 17 deletions

File tree

appveyor.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,11 @@ install:
6464
# target Python version and architecture
6565
- "pip install wheel"
6666

67-
init:
68-
- ps: iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
67+
# init:
68+
# - ps: iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
6969

70-
on_finish:
71-
- ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
70+
# on_finish:
71+
# - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
7272

7373
build_script:
7474
- "pip install ."

nox/session.py

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15+
import hashlib
1516
import os
1617
import re
1718
import unicodedata
@@ -24,17 +25,31 @@
2425
import six
2526

2627

27-
def _normalize_path(path):
28-
"""Normalizes a string to be a "safe" filesystem path."""
28+
def _normalize_path(envdir, path):
29+
"""Normalizes a string to be a "safe" filesystem path for a virtualenv."""
2930
if isinstance(path, six.binary_type):
3031
path = path.decode('utf-8')
3132

3233
path = unicodedata.normalize('NFKD', path).encode('ascii', 'ignore')
3334
path = path.decode('ascii')
3435
path = re.sub('[^\w\s-]', '-', path).strip().lower()
3536
path = re.sub('[-\s]+', '-', path)
36-
path = path.strip('-')[:255]
37-
return path
37+
path = path.strip('-')
38+
39+
full_path = os.path.join(envdir, path)
40+
if len(full_path) > 128 - len('bin/pythonX.Y'):
41+
if len(envdir) < 128 - 9:
42+
path = hashlib.sha1(path.encode('ascii')).hexdigest()[:8]
43+
full_path = os.path.join(envdir, path)
44+
logger.warning(
45+
'The virtualenv name was hashed to avoid being too long.')
46+
else:
47+
logger.error(
48+
'The virtualenv path {} is too long and will cause issues on '
49+
'some environments. Use the --envdir path to modify where '
50+
'nox stores virtualenvs.'.format(full_path))
51+
52+
return full_path
3853

3954

4055
class _SessionQuit(Exception):
@@ -175,9 +190,8 @@ def _create_venv(self):
175190
return
176191

177192
self.venv = VirtualEnv(
178-
os.path.join(
179-
self.global_config.envdir,
180-
_normalize_path(self.signature or self.name)),
193+
_normalize_path(
194+
self.global_config.envdir, self.signature or self.name),
181195
interpreter=self.config.interpreter,
182196
reuse_existing=(
183197
self.config.reuse_existing_virtualenv or

tests/test_session.py

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,31 @@
2424

2525

2626
def test__normalize_path():
27-
assert nox.session._normalize_path(u'hello') == 'hello'
28-
assert nox.session._normalize_path(b'hello') == 'hello'
29-
assert nox.session._normalize_path('hello(world)') == 'hello-world'
27+
envdir = 'envdir'
28+
assert nox.session._normalize_path(envdir, u'hello') == 'envdir/hello'
29+
assert nox.session._normalize_path(envdir, b'hello') == 'envdir/hello'
3030
assert nox.session._normalize_path(
31-
'hello(world, meep)') == 'hello-world-meep'
31+
envdir, 'hello(world)') == 'envdir/hello-world'
3232
assert nox.session._normalize_path(
33-
'tests(interpreter="python2.7", django="1.10")') == (
34-
'tests-interpreter-python2-7-django-1-10')
33+
envdir, 'hello(world, meep)') == 'envdir/hello-world-meep'
34+
assert nox.session._normalize_path(
35+
envdir, 'tests(interpreter="python2.7", django="1.10")') == (
36+
'envdir/tests-interpreter-python2-7-django-1-10')
37+
38+
39+
def test__normalize_path_hash():
40+
envdir = 'd' * (128 - len('bin/pythonX.Y') - 10)
41+
norm_path = nox.session._normalize_path(
42+
envdir, 'a-really-long-virtualenv-path')
43+
assert 'a-really-long-virtualenv-path' not in norm_path
44+
assert len(norm_path) < 128
45+
46+
47+
def test__normalize_path_give_up():
48+
envdir = 'd' * 128
49+
norm_path = nox.session._normalize_path(
50+
envdir, 'any-path')
51+
assert 'any-path' in norm_path
3552

3653

3754
@pytest.fixture

0 commit comments

Comments
 (0)