Skip to content

Commit

Permalink
avoid copying the stats with copytree
Browse files Browse the repository at this point in the history
This information is not needed, so it's redundant work;
similarly it might not be allowed (e.g. on macOS
framework python).

Signed-off-by: Bernat Gabor <bgabor8@bloomberg.net>
  • Loading branch information
gaborbernat committed Feb 11, 2020
1 parent f7fcb42 commit 450f404
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 13 deletions.
3 changes: 3 additions & 0 deletions docs/changelog/1561.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
When copying (either files or trees) do not copy the permission bits, last access time, last modification time, and
flags as access to these might be forbidden (for example in case of the macOs Framework Python) and these are not needed
for the user to use the virtual environment - by :user:`gaborbernat`.
1 change: 0 additions & 1 deletion src/virtualenv/seed/via_app_data/pip_install/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ def install(self):
# sync image
for filename in self._image_dir.iterdir():
into = self._creator.purelib / filename.name
logging.debug("%s %s from %s", self.__class__.__name__, into, filename)
if into.exists():
if into.is_dir() and not into.is_symlink():
shutil.rmtree(str(into))
Expand Down
10 changes: 2 additions & 8 deletions src/virtualenv/seed/via_app_data/pip_install/copy.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,17 @@
from __future__ import absolute_import, unicode_literals

import os
import shutil

import six

from virtualenv.util.path import Path
from virtualenv.util.path import Path, copy

from .base import PipInstall


class CopyPipInstall(PipInstall):
def _sync(self, src, dst):
src_str = six.ensure_text(str(src))
dest_str = six.ensure_text(str(dst))
if src.is_dir():
shutil.copytree(src_str, dest_str)
else:
shutil.copy(src_str, dest_str)
copy(src, dst)

def _generate_new_files(self):
# create the pyc files
Expand Down
12 changes: 10 additions & 2 deletions src/virtualenv/util/path/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@

from ._pathlib import Path
from ._permission import make_exe
from ._sync import copy, ensure_dir, link, symlink
from ._sync import copy, copytree, ensure_dir, link, symlink

__all__ = ("ensure_dir", "link", "symlink", "copy", "Path", "make_exe")
__all__ = (
"ensure_dir",
"link",
"symlink",
"copy",
"copytree",
"Path",
"make_exe",
)
23 changes: 21 additions & 2 deletions src/virtualenv/util/path/_sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,22 @@ def symlink(src, dest):
def copy(src, dest):
ensure_safe_to_do(src, dest)
is_dir = src.is_dir()
method = shutil.copytree if is_dir else shutil.copy2
method = copytree if is_dir else shutil.copy
logging.debug("copy %s", _Debug(src, dest))
method(norm(src), norm(dest))


def copytree(src, dest):
for root, _, files in os.walk(src):
dest_dir = os.path.join(dest, os.path.relpath(src, root))
if not os.path.exists(dest_dir):
os.makedirs(dest_dir)
for name in files:
src_f = os.path.join(root, name)
dest_f = os.path.join(dest_dir, name)
shutil.copy(src_f, dest_f)


def link(src, dest):
ensure_safe_to_do(src, dest)
logging.debug("hard link %s", _Debug(src, dest.name))
Expand All @@ -67,4 +78,12 @@ def __str__(self):
)


__all__ = ("ensure_dir", "symlink", "copy", "link", "symlink", "link")
__all__ = (
"ensure_dir",
"symlink",
"copy",
"link",
"symlink",
"link",
"copytree",
)

0 comments on commit 450f404

Please sign in to comment.