[Python-modules-commits] [python-pex] 04/10: Import python-pex_1.1.4.orig.tar.gz
Barry Warsaw
barry at moszumanska.debian.org
Tue Mar 22 17:19:18 UTC 2016
This is an automated email from the git hooks/post-receive script.
barry pushed a commit to branch master
in repository python-pex.
commit 29506132c8cc219ccd6293ea037df31210fab499
Author: Barry Warsaw <barry at python.org>
Date: Tue Mar 22 13:09:44 2016 -0400
Import python-pex_1.1.4.orig.tar.gz
---
CHANGES.rst | 31 ++++++++++++++
PKG-INFO | 33 ++++++++++++++-
pex.egg-info/PKG-INFO | 33 ++++++++++++++-
pex.egg-info/SOURCES.txt | 3 +-
pex/commands/bdist_pex.py | 2 +-
pex/common.py | 41 +++++++++---------
pex/compatibility.py | 13 ++++++
pex/compiler.py | 4 +-
pex/crawler.py | 6 +--
pex/http.py | 2 +-
pex/installer.py | 6 ++-
pex/link.py | 21 ++++++---
pex/package.py | 4 +-
pex/pep425.py | 10 +++--
pex/pex.py | 15 +++++--
pex/resolver.py | 6 +--
pex/testing.py | 20 +++++++--
pex/translator.py | 4 +-
pex/util.py | 23 +++++++++-
pex/version.py | 2 +-
tests/example_packages/setuptools-18.0.1-py2.7.egg | Bin 0 -> 356249 bytes
tests/test_environment.py | 37 ++++++++--------
tests/test_http.py | 6 +--
tests/test_integration.py | 8 +++-
tests/test_link.py | 12 +++++-
tests/test_package.py | 9 ++++
tests/test_pep425.py | 14 +++++-
tests/test_pex.py | 47 ++++++++++++++++++++-
tests/test_pex_builder.py | 4 +-
tests/test_pex_info.py | 7 ++-
tests/test_util.py | 45 +++++++++++++-------
tests/test_variables.py | 9 ++--
tox.ini | 2 +-
33 files changed, 371 insertions(+), 108 deletions(-)
diff --git a/CHANGES.rst b/CHANGES.rst
index fa242f8..b6af105 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -3,6 +3,37 @@ CHANGES
=======
-----
+1.1.4
+-----
+
+This release is a quick fix for a regression that inadvertently went out in 1.1.3 (Issue #216).
+
+* Add a test for the regression in `FixedEggMetadata._zipinfo_name` and revert the breaking commit.
+ `Fixes #216 <https://github.com/pantsbuild/pex/issues/216>`_
+
+-----
+1.1.3
+-----
+
+This release includes an initial body of work towards Windows support, ABI tag support for CPython 2.x and a fix for version number normalization.
+
+* Add python 2.x abi tag support.
+ `#214 <https://github.com/pantsbuild/pex/pull/214>`_
+ `Fixes #213 <https://github.com/pantsbuild/pex/issues/213>`_
+
+* Add .idea to .gitignore.
+ `#205 <https://github.com/pantsbuild/pex/pull/205>`_
+
+* Don't normalize version numbers as names.
+ `#204 <https://github.com/pantsbuild/pex/pull/204>`_
+
+* More fixes for windows.
+ `#202 <https://github.com/pantsbuild/pex/pull/202>`_
+
+* Fixes to get pex to work on windows.
+ `#198 <https://github.com/pantsbuild/pex/pull/198>`_
+
+-----
1.1.2
-----
diff --git a/PKG-INFO b/PKG-INFO
index c236fe2..49867c0 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: pex
-Version: 1.1.2
+Version: 1.1.4
Summary: The PEX packaging toolchain.
Home-page: https://github.com/pantsbuild/pex
Author: UNKNOWN
@@ -11,6 +11,37 @@ Description: =======
=======
-----
+ 1.1.4
+ -----
+
+ This release is a quick fix for a regression that inadvertently went out in 1.1.3 (Issue #216).
+
+ * Add a test for the regression in `FixedEggMetadata._zipinfo_name` and revert the breaking commit.
+ `Fixes #216 <https://github.com/pantsbuild/pex/issues/216>`_
+
+ -----
+ 1.1.3
+ -----
+
+ This release includes an initial body of work towards Windows support, ABI tag support for CPython 2.x and a fix for version number normalization.
+
+ * Add python 2.x abi tag support.
+ `#214 <https://github.com/pantsbuild/pex/pull/214>`_
+ `Fixes #213 <https://github.com/pantsbuild/pex/issues/213>`_
+
+ * Add .idea to .gitignore.
+ `#205 <https://github.com/pantsbuild/pex/pull/205>`_
+
+ * Don't normalize version numbers as names.
+ `#204 <https://github.com/pantsbuild/pex/pull/204>`_
+
+ * More fixes for windows.
+ `#202 <https://github.com/pantsbuild/pex/pull/202>`_
+
+ * Fixes to get pex to work on windows.
+ `#198 <https://github.com/pantsbuild/pex/pull/198>`_
+
+ -----
1.1.2
-----
diff --git a/pex.egg-info/PKG-INFO b/pex.egg-info/PKG-INFO
index c236fe2..49867c0 100644
--- a/pex.egg-info/PKG-INFO
+++ b/pex.egg-info/PKG-INFO
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: pex
-Version: 1.1.2
+Version: 1.1.4
Summary: The PEX packaging toolchain.
Home-page: https://github.com/pantsbuild/pex
Author: UNKNOWN
@@ -11,6 +11,37 @@ Description: =======
=======
-----
+ 1.1.4
+ -----
+
+ This release is a quick fix for a regression that inadvertently went out in 1.1.3 (Issue #216).
+
+ * Add a test for the regression in `FixedEggMetadata._zipinfo_name` and revert the breaking commit.
+ `Fixes #216 <https://github.com/pantsbuild/pex/issues/216>`_
+
+ -----
+ 1.1.3
+ -----
+
+ This release includes an initial body of work towards Windows support, ABI tag support for CPython 2.x and a fix for version number normalization.
+
+ * Add python 2.x abi tag support.
+ `#214 <https://github.com/pantsbuild/pex/pull/214>`_
+ `Fixes #213 <https://github.com/pantsbuild/pex/issues/213>`_
+
+ * Add .idea to .gitignore.
+ `#205 <https://github.com/pantsbuild/pex/pull/205>`_
+
+ * Don't normalize version numbers as names.
+ `#204 <https://github.com/pantsbuild/pex/pull/204>`_
+
+ * More fixes for windows.
+ `#202 <https://github.com/pantsbuild/pex/pull/202>`_
+
+ * Fixes to get pex to work on windows.
+ `#198 <https://github.com/pantsbuild/pex/pull/198>`_
+
+ -----
1.1.2
-----
diff --git a/pex.egg-info/SOURCES.txt b/pex.egg-info/SOURCES.txt
index 60c4df3..6f48eac 100644
--- a/pex.egg-info/SOURCES.txt
+++ b/pex.egg-info/SOURCES.txt
@@ -86,4 +86,5 @@ tests/test_resolver.py
tests/test_sorter.py
tests/test_translator.py
tests/test_util.py
-tests/test_variables.py
\ No newline at end of file
+tests/test_variables.py
+tests/example_packages/setuptools-18.0.1-py2.7.egg
\ No newline at end of file
diff --git a/pex/commands/bdist_pex.py b/pex/commands/bdist_pex.py
index 4f7950f..7a261f2 100644
--- a/pex/commands/bdist_pex.py
+++ b/pex/commands/bdist_pex.py
@@ -68,6 +68,7 @@ class bdist_pex(Command): # noqa
except ValueError:
console_scripts = {}
+ target = os.path.join(self.bdist_dir, name + '-' + version + '.pex')
if self.bdist_all:
# Write all entry points into unversioned pex files.
for script_name in console_scripts:
@@ -76,7 +77,6 @@ class bdist_pex(Command): # noqa
self._write(pex_builder, target, script=script_name)
elif name in console_scripts:
# The package has a namesake entry point, so use it.
- target = os.path.join(self.bdist_dir, name + '-' + version + '.pex')
log.info('Writing %s to %s' % (name, target))
self._write(pex_builder, target, script=name)
else:
diff --git a/pex/common.py b/pex/common.py
index 89f1941..acdad91 100644
--- a/pex/common.py
+++ b/pex/common.py
@@ -28,18 +28,26 @@ def safe_copy(source, dest, overwrite=False):
shutil.copyfile(source, temp_dest)
os.rename(temp_dest, dest)
- try:
- os.link(source, dest)
- except OSError as e:
- if e.errno == errno.EEXIST:
- # File already exists. If overwrite=True, write otherwise skip.
- if overwrite:
+ # If the platform supports hard-linking, use that and fall back to copying.
+ # Windows does not support hard-linking.
+ if hasattr(os, 'link'):
+ try:
+ os.link(source, dest)
+ except OSError as e:
+ if e.errno == errno.EEXIST:
+ # File already exists. If overwrite=True, write otherwise skip.
+ if overwrite:
+ do_copy()
+ elif e.errno == errno.EXDEV:
+ # Hard link across devices, fall back on copying
do_copy()
- elif e.errno == errno.EXDEV:
- # Hard link across devices, fall back on copying
+ else:
+ raise
+ elif os.path.exists(dest):
+ if overwrite:
do_copy()
- else:
- raise
+ else:
+ do_copy()
# See http://stackoverflow.com/questions/2572172/referencing-other-modules-in-atexit
@@ -264,17 +272,8 @@ class Chroot(object):
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)
+ # TODO: Ensure the target and dest are the same if the file already exists.
def write(self, data, dst, label=None, mode='wb'):
"""Write data to ``chroot/dst`` with optional label.
diff --git a/pex/compatibility.py b/pex/compatibility.py
index 1a86d5f..97139e1 100644
--- a/pex/compatibility.py
+++ b/pex/compatibility.py
@@ -4,6 +4,7 @@
# This file contains several 2.x/3.x compatibility checkstyle violations for a reason
# checkstyle: noqa
+import os
from abc import ABCMeta
from numbers import Integral, Real
from sys import version_info as sys_version_info
@@ -81,15 +82,27 @@ else:
from contextlib import nested
+if PY3:
+ from urllib.request import pathname2url, url2pathname
+else:
+ from urllib import pathname2url, url2pathname
+
+
+WINDOWS = os.name == 'nt'
+
+
__all__ = (
'AbstractClass',
'BytesIO',
'PY2',
'PY3',
'StringIO',
+ 'WINDOWS',
'bytes',
'exec_function',
'nested',
+ 'pathname2url',
'string',
'to_bytes',
+ 'url2pathname',
)
diff --git a/pex/compiler.py b/pex/compiler.py
index 6346d0f..d301de8 100644
--- a/pex/compiler.py
+++ b/pex/compiler.py
@@ -4,9 +4,9 @@
from __future__ import absolute_import
import subprocess
-import tempfile
from .compatibility import to_bytes
+from .util import named_temporary_file
_COMPILER_MAIN = """
@@ -78,7 +78,7 @@ class Compiler(object):
: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/pex/crawler.py b/pex/crawler.py
index 00b70fb..ee89d7f 100644
--- a/pex/crawler.py
+++ b/pex/crawler.py
@@ -85,11 +85,11 @@ class Crawler(object):
@classmethod
def crawl_local(cls, link):
try:
- dirents = os.listdir(link.path)
+ dirents = os.listdir(link.local_path)
except OSError as e:
- TRACER.log('Failed to read %s: %s' % (link.path, e), V=1)
+ TRACER.log('Failed to read %s: %s' % (link.local_path, e), V=1)
return set(), set()
- files, dirs = partition([os.path.join(link.path, fn) for fn in dirents], os.path.isdir)
+ files, dirs = partition([os.path.join(link.local_path, fn) for fn in dirents], os.path.isdir)
return set(map(Link.from_filename, files)), set(map(Link.from_filename, dirs))
@classmethod
diff --git a/pex/http.py b/pex/http.py
index 1166615..5b91a5c 100644
--- a/pex/http.py
+++ b/pex/http.py
@@ -212,7 +212,7 @@ class RequestsContext(Context):
def open(self, link):
# requests does not support file:// -- so we must short-circuit manually
if link.local:
- return open(link.path, 'rb') # noqa: T802
+ return open(link.local_path, 'rb') # noqa: T802
for attempt in range(self._max_retries + 1):
try:
return StreamFilelike(self._session.get(
diff --git a/pex/installer.py b/pex/installer.py
index acb0bf0..e2e955a 100644
--- a/pex/installer.py
+++ b/pex/installer.py
@@ -11,6 +11,7 @@ import tempfile
from pkg_resources import Distribution, PathMetadata
from .common import safe_mkdtemp, safe_rmtree
+from .compatibility import WINDOWS
from .interpreter import PythonInterpreter
from .tracer import TRACER
from .version import SETUPTOOLS_REQUIREMENT, WHEEL_REQUIREMENT
@@ -209,7 +210,10 @@ class Packager(DistributionPackager):
"""
def _setup_command(self):
- return ['sdist', '--formats=gztar', '--dist-dir=%s' % self._install_tmp]
+ if WINDOWS:
+ return ['sdist', '--formats=zip', '--dist-dir=%s' % self._install_tmp]
+ else:
+ return ['sdist', '--formats=gztar', '--dist-dir=%s' % self._install_tmp]
@after_installation
def sdist(self):
diff --git a/pex/link.py b/pex/link.py
index 2146a7f..c8f8664 100644
--- a/pex/link.py
+++ b/pex/link.py
@@ -8,7 +8,7 @@ import posixpath
from collections import Iterable
from .compatibility import string as compatible_string
-from .compatibility import PY3
+from .compatibility import PY3, WINDOWS, pathname2url, url2pathname
from .util import Memoizer
if PY3:
@@ -52,7 +52,8 @@ class Link(object):
@classmethod
def _normalize(cls, filename):
- return 'file://' + os.path.realpath(os.path.expanduser(filename))
+ return urlparse.urljoin('file:', pathname2url(
+ os.path.realpath(os.path.expanduser(filename))))
# A cache for the result of from_filename
_FROM_FILENAME_CACHE = Memoizer()
@@ -72,8 +73,10 @@ class Link(object):
:param url: A string-like object representing a url.
"""
purl = urlparse.urlparse(url)
- if purl.scheme == '':
+ if purl.scheme == '' or (
+ WINDOWS and len(purl.scheme) == 1): # This is likely a drive letter.
purl = urlparse.urlparse(self._normalize(url))
+
self._url = purl
def __ne__(self, other):
@@ -95,12 +98,18 @@ class Link(object):
@property
def filename(self):
"""The basename of this url."""
- return posixpath.basename(self._url.path)
+ return urlparse.unquote(posixpath.basename(self._url.path))
@property
def path(self):
"""The full path of this url with any hostname and scheme components removed."""
- return self._url.path
+ return urlparse.unquote(self._url.path)
+
+ @property
+ def local_path(self):
+ """Returns the local filesystem path (only works for file:// urls)."""
+ assert self.local, 'local_path called on a non-file:// url %s' % (self.url,)
+ return url2pathname(self.path)
@property
def url(self):
@@ -110,7 +119,7 @@ class Link(object):
@property
def fragment(self):
"""The url fragment following '#' if any."""
- return self._url.fragment
+ return urlparse.unquote(self._url.fragment)
@property
def scheme(self):
diff --git a/pex/package.py b/pex/package.py
index f50f2c7..a432aed 100644
--- a/pex/package.py
+++ b/pex/package.py
@@ -133,7 +133,7 @@ class SourcePackage(Package):
@property
def raw_version(self):
- return safe_name(self._raw_version)
+ return self._raw_version
# SourcePackages are always compatible as they can be translated to a distribution.
def compatible(self, identity, platform=Platform.current()):
@@ -167,7 +167,7 @@ class EggPackage(Package):
@property
def raw_version(self):
- return safe_name(self._raw_version)
+ return self._raw_version
@property
def py_version(self):
diff --git a/pex/pep425.py b/pex/pep425.py
index 6689f6e..a859b13 100644
--- a/pex/pep425.py
+++ b/pex/pep425.py
@@ -99,15 +99,19 @@ class PEP425(object): # noqa
"""
# Predict soabi for reasonable interpreters. This is technically wrong but essentially right.
abis = []
- if impl == 'cp' and version.startswith('3'):
+ if impl == 'cp' and (version.startswith('2') or version.startswith('3')):
abis.extend([
'cp%s' % version,
'cp%sdmu' % version, 'cp%sdm' % version, 'cp%sdu' % version, 'cp%sd' % version,
'cp%smu' % version, 'cp%sm' % version,
- 'cp%su' % version,
- 'abi3'
+ 'cp%su' % version
])
+ if version.startswith('3'):
+ abis.extend([
+ 'abi3'
+ ])
+
major_version = int(version[0])
minor_versions = []
for minor in range(int(version[1]), -1, -1):
diff --git a/pex/pex.py b/pex/pex.py
index 111ef0f..d338769 100644
--- a/pex/pex.py
+++ b/pex/pex.py
@@ -96,14 +96,21 @@ class PEX(object): # noqa: T000
yield os.path.join(standard_lib, path)
@classmethod
- def _site_libs(cls):
+ def _get_site_packages(cls):
try:
from site import getsitepackages
- site_libs = set(getsitepackages())
+ return set(getsitepackages())
except ImportError:
- site_libs = set()
+ return set()
+
+ @classmethod
+ def site_libs(cls):
+ site_libs = cls._get_site_packages()
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
@@ -190,7 +197,7 @@ class PEX(object): # noqa: T000
:returns: (sys.path, sys.path_importer_cache, sys.modules) tuple of a
bare python installation.
"""
- site_libs = set(cls._site_libs())
+ site_libs = set(cls.site_libs())
for site_lib in site_libs:
TRACER.log('Found site-library: %s' % site_lib)
for extras_path in cls._extras_paths():
diff --git a/pex/resolver.py b/pex/resolver.py
index b65fcc1..e7669c4 100644
--- a/pex/resolver.py
+++ b/pex/resolver.py
@@ -162,7 +162,7 @@ class Resolver(object):
local_package = Package.from_href(context.fetch(package))
if local_package is None:
raise Untranslateable('Could not fetch package %s' % package)
- with TRACER.timed('Translating %s into distribution' % local_package.path, V=2):
+ with TRACER.timed('Translating %s into distribution' % local_package.local_path, V=2):
dist = translator.translate(local_package)
if dist is None:
raise Untranslateable('Package %s is not translateable by %s' % (package, translator))
@@ -221,7 +221,7 @@ class CachingResolver(Resolver):
def filter_packages_by_ttl(cls, packages, ttl, now=None):
now = now if now is not None else time.time()
return [package for package in packages
- if package.remote or package.local and (now - os.path.getmtime(package.path)) < ttl]
+ if package.remote or package.local and (now - os.path.getmtime(package.local_path)) < ttl]
def __init__(self, cache, cache_ttl, *args, **kw):
self.__cache = cache
@@ -251,7 +251,7 @@ class CachingResolver(Resolver):
# cache package locally
if package.remote:
package = Package.from_href(options.get_context().fetch(package, into=self.__cache))
- os.utime(package.path, None)
+ os.utime(package.local_path, None)
# build into distribution
dist = super(CachingResolver, self).build(package, options)
diff --git a/pex/testing.py b/pex/testing.py
index cded62c..2726486 100644
--- a/pex/testing.py
+++ b/pex/testing.py
@@ -5,6 +5,7 @@ import contextlib
import os
import random
import subprocess
+import sys
import tempfile
import zipfile
from textwrap import dedent
@@ -13,7 +14,7 @@ from .common import safe_mkdir, safe_rmtree
from .compatibility import nested
from .installer import EggInstaller, Packager
from .pex_builder import PEXBuilder
-from .util import DistributionHelper
+from .util import DistributionHelper, named_temporary_file
@contextlib.contextmanager
@@ -25,6 +26,19 @@ def temporary_dir():
safe_rmtree(td)
+ at contextlib.contextmanager
+def temporary_filename():
+ """Creates a temporary filename.
+
+ This is useful when you need to pass a filename to an API. Windows requires all
+ handles to a file be closed before deleting/renaming it, so this makes it a bit
+ simpler."""
+ with named_temporary_file() as fp:
+ fp.write(b'')
+ fp.close()
+ yield fp.name
+
+
def random_bytes(length):
return ''.join(
map(chr, (random.randint(ord('a'), ord('z')) for _ in range(length)))).encode('utf-8')
@@ -162,12 +176,12 @@ def write_simple_pex(td, exe_contents, dists=None, coverage=False):
# TODO(wickman) Why not PEX.run?
def run_simple_pex(pex, args=(), env=None):
po = subprocess.Popen(
- [pex] + list(args),
+ [sys.executable, pex] + list(args),
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
env=env)
po.wait()
- return po.stdout.read(), po.returncode
+ return po.stdout.read().replace(b'\r', b''), po.returncode
def run_simple_pex_test(body, args=(), env=None, dists=None, coverage=False):
diff --git a/pex/translator.py b/pex/translator.py
index 8800343..67bb84b 100644
--- a/pex/translator.py
+++ b/pex/translator.py
@@ -88,7 +88,7 @@ class SourceTranslator(TranslatorBase):
installer = None
version = self._interpreter.version
- unpack_path = Archiver.unpack(package.path)
+ unpack_path = Archiver.unpack(package.local_path)
into = into or safe_mkdtemp()
try:
@@ -147,7 +147,7 @@ class BinaryTranslator(TranslatorBase):
return None
into = into or safe_mkdtemp()
target_path = os.path.join(into, package.filename)
- safe_copy(package.path, target_path)
+ safe_copy(package.local_path, target_path)
return DistributionHelper.distribution_from_path(target_path)
diff --git a/pex/util.py b/pex/util.py
index d9dbe2e..00e4f63 100644
--- a/pex/util.py
+++ b/pex/util.py
@@ -7,6 +7,7 @@ import contextlib
import errno
import os
import shutil
+import tempfile
import uuid
from hashlib import sha1
from threading import Lock
@@ -118,7 +119,9 @@ class CacheHelper(object):
@classmethod
def _compute_hash(cls, names, stream_factory):
digest = sha1()
- digest.update(''.join(names).encode('utf-8'))
+ # Always use / as the path separator, since that's what zip uses.
+ hashed_names = [n.replace(os.sep, '/') for n in names]
+ digest.update(''.join(hashed_names).encode('utf-8'))
for name in names:
with contextlib.closing(stream_factory(name)) as fp:
cls.update_hash(fp, digest)
@@ -136,7 +139,7 @@ class CacheHelper(object):
@classmethod
def _iter_files(cls, directory):
- normpath = os.path.normpath(directory)
+ normpath = os.path.realpath(os.path.normpath(directory))
for root, _, files in os.walk(normpath):
for f in files:
yield os.path.relpath(os.path.join(root, f), normpath)
@@ -200,3 +203,19 @@ class Memoizer(object):
def store(self, key, value):
with self._lock:
self._data[key] = value
+
+
+ at contextlib.contextmanager
+def named_temporary_file(*args, **kwargs):
+ """
+ Due to a bug in python (https://bugs.python.org/issue14243), we need
+ this to be able to use the temporary file without deleting it.
+ """
+ assert 'delete' not in kwargs
+ kwargs['delete'] = False
+ fp = tempfile.NamedTemporaryFile(*args, **kwargs)
+ try:
+ with fp:
+ yield fp
+ finally:
+ os.remove(fp.name)
diff --git a/pex/version.py b/pex/version.py
index 51862fa..1366236 100644
--- a/pex/version.py
+++ b/pex/version.py
@@ -1,7 +1,7 @@
# Copyright 2015 Pants project contributors (see CONTRIBUTORS.md).
# Licensed under the Apache License, Version 2.0 (see LICENSE).
-__version__ = '1.1.2'
+__version__ = '1.1.4'
SETUPTOOLS_REQUIREMENT = 'setuptools>=2.2,<20'
WHEEL_REQUIREMENT = 'wheel>=0.24.0,<0.27.0'
diff --git a/tests/example_packages/setuptools-18.0.1-py2.7.egg b/tests/example_packages/setuptools-18.0.1-py2.7.egg
new file mode 100644
index 0000000..aba6783
Binary files /dev/null and b/tests/example_packages/setuptools-18.0.1-py2.7.egg differ
diff --git a/tests/test_environment.py b/tests/test_environment.py
index 0c3baaa..adf06e4 100644
--- a/tests/test_environment.py
+++ b/tests/test_environment.py
@@ -4,13 +4,13 @@
import os
from contextlib import contextmanager
-from twitter.common.contextutil import temporary_dir, temporary_file
+from twitter.common.contextutil import temporary_dir
from pex.compatibility import nested
from pex.environment import PEXEnvironment
from pex.pex_builder import PEXBuilder
from pex.pex_info import PexInfo
-from pex.testing import make_bdist
+from pex.testing import make_bdist, temporary_filename
@contextmanager
@@ -22,64 +22,65 @@ def yield_pex_builder(zip_safe=True):
def test_force_local():
- with nested(yield_pex_builder(), temporary_dir(), temporary_file()) as (pb, pex_root, pex_file):
+ with nested(yield_pex_builder(), temporary_dir(), temporary_filename()) as (
+ pb, pex_root, pex_file):
pb.info.pex_root = pex_root
- pb.build(pex_file.name)
+ pb.build(pex_file)
- code_cache = PEXEnvironment.force_local(pex_file.name, pb.info)
+ code_cache = PEXEnvironment.force_local(pex_file, pb.info)
assert os.path.exists(pb.info.zip_unsafe_cache)
assert len(os.listdir(pb.info.zip_unsafe_cache)) == 1
assert [os.path.basename(code_cache)] == os.listdir(pb.info.zip_unsafe_cache)
assert set(os.listdir(code_cache)) == set([PexInfo.PATH, '__main__.py', '__main__.pyc'])
# idempotence
- assert PEXEnvironment.force_local(pex_file.name, pb.info) == code_cache
+ assert PEXEnvironment.force_local(pex_file, pb.info) == code_cache
def normalize(path):
- return os.path.normpath(os.path.realpath(path))
+ return os.path.normpath(os.path.realpath(path)).lower()
def test_write_zipped_internal_cache():
# zip_safe pex will not be written to install cache unless always_write_cache
- with nested(yield_pex_builder(zip_safe=True), temporary_dir(), temporary_file()) as (
+ with nested(yield_pex_builder(zip_safe=True), temporary_dir(), temporary_filename()) as (
pb, pex_root, pex_file):
pb.info.pex_root = pex_root
- pb.build(pex_file.name)
+ pb.build(pex_file)
- existing, new, zip_safe = PEXEnvironment.write_zipped_internal_cache(pex_file.name, pb.info)
+ existing, new, zip_safe = PEXEnvironment.write_zipped_internal_cache(pex_file, pb.info)
assert len(zip_safe) == 1
assert normalize(zip_safe[0].location).startswith(
- normalize(os.path.join(pex_file.name, pb.info.internal_cache))), (
+ normalize(os.path.join(pex_file, pb.info.internal_cache))), (
'loc: %s, cache: %s' % (
normalize(zip_safe[0].location),
- normalize(os.path.join(pex_file.name, pb.info.internal_cache))))
+ normalize(os.path.join(pex_file, pb.info.internal_cache))))
pb.info.always_write_cache = True
- existing, new, zip_safe = PEXEnvironment.write_zipped_internal_cache(pex_file.name, pb.info)
+ existing, new, zip_safe = PEXEnvironment.write_zipped_internal_cache(pex_file, pb.info)
assert len(new) == 1
assert normalize(new[0].location).startswith(normalize(pb.info.install_cache))
# Check that we can read from the cache
- existing, new, zip_safe = PEXEnvironment.write_zipped_internal_cache(pex_file.name, pb.info)
+ existing, new, zip_safe = PEXEnvironment.write_zipped_internal_cache(pex_file, pb.info)
assert len(existing) == 1
assert normalize(existing[0].location).startswith(normalize(pb.info.install_cache))
# non-zip_safe pex will be written to install cache
- with nested(yield_pex_builder(zip_safe=False), temporary_dir(), temporary_file()) as (
+ with nested(yield_pex_builder(zip_safe=False), temporary_dir(), temporary_filename()) as (
pb, pex_root, pex_file):
pb.info.pex_root = pex_root
- pb.build(pex_file.name)
+ pb.build(pex_file)
- existing, new, zip_safe = PEXEnvironment.write_zipped_internal_cache(pex_file.name, pb.info)
+ existing, new, zip_safe = PEXEnvironment.write_zipped_internal_cache(pex_file, pb.info)
assert len(new) == 1
assert normalize(new[0].location).startswith(normalize(pb.info.install_cache))
original_location = normalize(new[0].location)
# do the second time to validate idempotence of caching
- existing, new, zip_safe = PEXEnvironment.write_zipped_internal_cache(pex_file.name, pb.info)
+ existing, new, zip_safe = PEXEnvironment.write_zipped_internal_cache(pex_file, pb.info)
assert len(existing) == 1
assert normalize(existing[0].location) == original_location
diff --git a/tests/test_http.py b/tests/test_http.py
index e5ab82b..b07f207 100644
--- a/tests/test_http.py
+++ b/tests/test_http.py
@@ -6,11 +6,11 @@ from contextlib import contextmanager
from io import BytesIO
import pytest
-from twitter.common.contextutil import temporary_file
from pex.compatibility import PY2
from pex.http import Context, RequestsContext, StreamFilelike, UrllibContext
from pex.link import Link
+from pex.util import named_temporary_file
from pex.variables import Variables
try:
@@ -107,7 +107,7 @@ def test_requests_context():
assert fp.read() == BLOB
# test local reading
- with temporary_file() as tf:
+ with named_temporary_file() as tf:
tf.write(b'goop')
tf.flush()
assert context.read(Link.wrap(tf.name)) == b'goop'
@@ -225,7 +225,7 @@ def test_requests_context_retries_read_timeout_retries_exhausted():
def test_urllib_context_utf8_encoding():
BYTES = b'this is a decoded utf8 string'
- with temporary_file() as tf:
+ with named_temporary_file() as tf:
tf.write(BYTES)
tf.flush()
local_link = Link.wrap(tf.name)
diff --git a/tests/test_integration.py b/tests/test_integration.py
index f53b8f5..81386a7 100644
--- a/tests/test_integration.py
+++ b/tests/test_integration.py
@@ -4,9 +4,12 @@
import os
import sys
-from twitter.common.contextutil import environment_as, temporary_dir, temporary_file
+import pytest
+from twitter.common.contextutil import environment_as, temporary_dir
+from pex.compatibility import WINDOWS
from pex.testing import run_simple_pex_test
+from pex.util import named_temporary_file
def test_pex_execute():
@@ -21,7 +24,7 @@ def test_pex_raise():
def test_pex_interpreter():
- with temporary_file() as fp:
+ with named_temporary_file() as fp:
fp.write(b"print('Hello world')")
fp.flush()
@@ -33,6 +36,7 @@ def test_pex_interpreter():
assert rc == 0
+ at pytest.mark.skipif(WINDOWS, reason='No symlinks on windows')
def test_pex_python_symlink():
with temporary_dir() as td:
with environment_as(HOME=td):
diff --git a/tests/test_link.py b/tests/test_link.py
index 586dada..e3bd981 100644
--- a/tests/test_link.py
+++ b/tests/test_link.py
@@ -51,7 +51,17 @@ def test_link_schemes():
link = Link('/foo/bar')
assert link.scheme == 'file'
assert link.local
- assert link.path == os.path.realpath('/foo/bar')
+ assert link.local_path == os.path.realpath('/foo/bar')
+
+
+def test_link_escaping():
+ link = Link('/foo/bar#baz.pex')
+ assert link.scheme == 'file'
+ assert link.local
+ assert link.local_path == os.path.realpath('/foo/bar#baz.pex')
+
+ link = Link('http://www.google.com/%20/%3Afile+%2B2.tar.gz')
+ assert link.filename == ':file++2.tar.gz'
def test_link_equality():
diff --git a/tests/test_package.py b/tests/test_package.py
index d7748b7..87a7dbf 100644
--- a/tests/test_package.py
+++ b/tests/test_package.py
@@ -24,6 +24,15 @@ def test_source_packages():
assert sl.raw_version == '1.5'
+def test_local_specifier():
+ for ext in ('.tar.gz', '.tar', '.tgz', '.zip', '.tar.bz2'):
+ sl = SourcePackage('a_p_r-3.1.3+pexed.1' + ext)
+ assert sl.name == 'a-p-r'
+ assert sl.raw_version == '3.1.3+pexed.1'
+ assert sl.version == parse_version(sl.raw_version)
+ assert sl.satisfies('a_p_r==3.1.3+pexed.1')
+
+
def test_egg_packages():
el = EggPackage('psutil-0.4.1-py2.6-macosx-10.7-intel.egg')
assert el.name == 'psutil'
diff --git a/tests/test_pep425.py b/tests/test_pep425.py
index 87caedd..1b8ca36 100644
--- a/tests/test_pep425.py
+++ b/tests/test_pep425.py
@@ -46,6 +46,18 @@ def test_iter_supported_tags():
for interp in ('cp', 'py'):
for interp_suffix in ('2', '20', '21', '22', '23', '24', '25', '26'):
for platform in ('linux_x86_64', 'any'):
- yield (interp + interp_suffix, 'none', platform)
+ abis = ['none']
+
+ if interp == 'cp' and interp_suffix == '26' and platform == 'linux_x86_64':
+ abis.extend([
+ 'cp%s' % interp_suffix,
+ 'cp%sdmu' % interp_suffix, 'cp%sdm' % interp_suffix,
+ 'cp%sdu' % interp_suffix, 'cp%sd' % interp_suffix,
+ 'cp%smu' % interp_suffix, 'cp%sm' % interp_suffix,
+ 'cp%su' % interp_suffix
+ ])
+
+ for abi in abis:
+ yield (interp + interp_suffix, abi, platform)
assert set(PEP425.iter_supported_tags(identity, platform)) == set(iter_solutions())
diff --git a/tests/test_pex.py b/tests/test_pex.py
index a54abce..c923b49 100644
--- a/tests/test_pex.py
+++ b/tests/test_pex.py
@@ -2,17 +2,24 @@
# Licensed under the Apache License, Version 2.0 (see LICENSE).
import os
+import sys
import textwrap
from types import ModuleType
import pytest
+from twitter.common.contextutil import temporary_dir
-from pex.compatibility import to_bytes
+from pex.compatibility import WINDOWS, nested, to_bytes
from pex.installer import EggInstaller, WheelInstaller
from pex.pex import PEX
from pex.testing import make_installer, run_simple_pex_test
from pex.util import DistributionHelper
+try:
+ from unittest import mock
+except ImportError:
+ import mock
+
@pytest.mark.skipif('sys.version_info > (3,)')
def test_pex_uncaught_exceptions():
@@ -120,6 +127,44 @@ def test_minimum_sys_modules():
assert tainted_module.__path__ == ['good_path']
... 250 lines suppressed ...
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/python-pex.git
More information about the Python-modules-commits
mailing list