Skip to content

Commit a21d4f2

Browse files
committed
Detect if symlinks are supported on target file system
This detects symlink suppot on destination filesystem and not only in Python interpreter or OS. If symlinks are not supported, falls back to copy behavior.
1 parent 97ba981 commit a21d4f2

File tree

1 file changed

+22
-1
lines changed

1 file changed

+22
-1
lines changed

virtualenv.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1100,6 +1100,27 @@ def install_python(home_dir, lib_dir, inc_dir, bin_dir, site_packages, clear, sy
11001100
## Maybe it should delete everything with #!/path/to/venv/python in it
11011101
logger.notify('Not deleting %s', bin_dir)
11021102

1103+
# Check if symlinks are really supported by destination filesystem
1104+
if symlink:
1105+
if not hasattr(os, 'symlink'):
1106+
symlink = False
1107+
logger.info('Symlinks are not supported in this Python version')
1108+
else:
1109+
name = join(home_dir + '.symlink.test.file')
1110+
open(name, 'w').close()
1111+
try:
1112+
os.symlink(name, name + '.link')
1113+
except OSError as exc:
1114+
if exc.errno == 71: # [Errno 71] Protocol error
1115+
symlink = False
1116+
logger.notify('Symlinks are not supported on target file system')
1117+
else:
1118+
raise
1119+
else:
1120+
os.remove(name + '.link')
1121+
finally:
1122+
os.remove(name)
1123+
11031124
if hasattr(sys, 'real_prefix'):
11041125
logger.notify('Using real prefix %r' % sys.real_prefix)
11051126
prefix = sys.real_prefix
@@ -1115,7 +1136,7 @@ def install_python(home_dir, lib_dir, inc_dir, bin_dir, site_packages, clear, sy
11151136
stdlib_dirs.append(join(os.path.dirname(stdlib_dirs[0]), 'DLLs'))
11161137
elif is_darwin:
11171138
stdlib_dirs.append(join(stdlib_dirs[0], 'site-packages'))
1118-
if hasattr(os, 'symlink'):
1139+
if symlink:
11191140
logger.info('Symlinking Python bootstrap modules')
11201141
else:
11211142
logger.info('Copying Python bootstrap modules')

0 commit comments

Comments
 (0)