Skip to content

Commit

Permalink
fixed FileNotFoundError when directory isn't writable (pypa#1640)
Browse files Browse the repository at this point in the history
 - when using docker, if `user_data_dir()` isn't writable directory,
   `default_data_dir()` use `system temp directory` + `virtualenv`.
   for example, tempdir is `/tmp`, it use `/tmp/virtualenv`
  • Loading branch information
yakkle committed Feb 25, 2020
1 parent 9201422 commit 972a733
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 0 deletions.
15 changes: 15 additions & 0 deletions src/virtualenv/dirs.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import os
import tempfile

from appdirs import user_config_dir, user_data_dir

Expand All @@ -23,9 +24,23 @@ def _get_default_data_folder():
folder = os.environ[key]
else:
folder = user_data_dir(appname="virtualenv", appauthor="pypa")

if not _writable(folder):
folder = os.path.join(tempfile.gettempdir(), "virtualenv")
return folder


def _writable(folder) -> bool:
head = os.path.normpath(folder)

while not (os.path.exists(head) and os.access(head, os.W_OK)):
head, tail = os.path.split(head)
if not tail:
return False

return True


def default_config_dir():
from virtualenv.util.path import Path

Expand Down
31 changes: 31 additions & 0 deletions tests/unit/test_dirs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import logging
import os
import tempfile

import appdirs

from virtualenv import dirs
from virtualenv.dirs import _get_default_data_folder


def test_get_default_data_dir(monkeypatch):
# given
data_dirs = {
"/.local/share": os.path.join(tempfile.gettempdir(), "virtualenv"),
os.getenv('HOME'): os.path.join(os.getenv('HOME'), "virtualenv"),
"/tmp/share/": os.path.join("/tmp/share", "virtualenv")
}

def user_data_dir(data_dir):
def wrapper(appname=None, appauthor=None, version=None, roaming=False):
return os.path.join(data_dir, appname)
return wrapper

for data_dir, expected in data_dirs.items():
monkeypatch.setattr(dirs, "user_data_dir", user_data_dir(data_dir))

# when
actual = _get_default_data_folder()

# then
assert actual == expected

0 comments on commit 972a733

Please sign in to comment.