From ff04863e5b3b70513ff95e2b04aa304e46888da8 Mon Sep 17 00:00:00 2001 From: Mike Kaplinskiy Date: Mon, 11 Jan 2016 16:04:40 -0800 Subject: [PATCH] More pex fixes for windows. Aside from the two issues @sdwilsh found, the last bit was convincing pex to not remove sys.prefix from sys.path. --- bin/buck.bat | 1 + third-party/py/pex/pex/common.py | 13 ++----------- third-party/py/pex/pex/compiler.py | 15 ++++++++++++++- third-party/py/pex/pex/pex.py | 3 +++ 4 files changed, 20 insertions(+), 12 deletions(-) diff --git a/bin/buck.bat b/bin/buck.bat index 698c24e9a9e..07c0b986500 100644 --- a/bin/buck.bat +++ b/bin/buck.bat @@ -1,2 +1,3 @@ @echo off +set PYTHONPATH=%~dp0..\third-party\nailgun python %~dp0..\programs\buck.py %* diff --git a/third-party/py/pex/pex/common.py b/third-party/py/pex/pex/common.py index f34e6f7aeff..8de396895b6 100644 --- a/third-party/py/pex/pex/common.py +++ b/third-party/py/pex/pex/common.py @@ -269,17 +269,8 @@ def link(self, src, dst, label=None): self._ensure_parent(dst) abs_src = src abs_dst = os.path.join(self.chroot, dst) - try: - os.link(abs_src, abs_dst) - except OSError as e: - if e.errno == errno.EEXIST: - # File already exists, skip XXX -- ensure target and dest are same? - pass - elif e.errno == errno.EXDEV: - # Hard link across devices, fall back on copying - shutil.copyfile(abs_src, abs_dst) - else: - raise + safe_copy(abs_src, abs_dst, overwrite=False) + # If the file already exists, skip XXX -- ensure target and dest are same? def write(self, data, dst, label=None, mode='wb'): """Write data to ``chroot/dst`` with optional label. diff --git a/third-party/py/pex/pex/compiler.py b/third-party/py/pex/pex/compiler.py index 6346d0ff29d..baf7c00f04d 100644 --- a/third-party/py/pex/pex/compiler.py +++ b/third-party/py/pex/pex/compiler.py @@ -3,6 +3,8 @@ from __future__ import absolute_import +import contextlib +import os import subprocess import tempfile @@ -58,6 +60,17 @@ def main(root, relpaths): """ +@contextlib.contextmanager +def named_temporary_file(): + fp, path = tempfile.mkstemp() + os.close(fp) + try: + with open(path, 'w') as fp: + yield fp + finally: + os.remove(path) + + class Compiler(object): class Error(Exception): """Indicates an error compiling one or more python source files.""" @@ -78,7 +91,7 @@ def compile(self, root, relpaths): :returns: A list of relative paths of the compiled bytecode files. :raises: A :class:`Compiler.Error` if there was a problem bytecode compiling any of the files. """ - with tempfile.NamedTemporaryFile() as fp: + with named_temporary_file() as fp: fp.write(to_bytes(_COMPILER_MAIN % {'root': root, 'relpaths': relpaths}, encoding='utf-8')) fp.flush() process = subprocess.Popen([self._interpreter.binary, fp.name], diff --git a/third-party/py/pex/pex/pex.py b/third-party/py/pex/pex/pex.py index 111ef0f8a94..7afd617cd02 100644 --- a/third-party/py/pex/pex/pex.py +++ b/third-party/py/pex/pex/pex.py @@ -104,6 +104,9 @@ def _site_libs(cls): site_libs = set() site_libs.update([sysconfig.get_python_lib(plat_specific=False), sysconfig.get_python_lib(plat_specific=True)]) + # On windows getsitepackages() returns the python stdlib too. + if sys.prefix in site_libs: + site_libs.remove(sys.prefix) real_site_libs = set(os.path.realpath(path) for path in site_libs) return site_libs | real_site_libs