[Python-modules-commits] [python-pex] 01/05: Import python-pex_1.0.3.orig.tar.gz

Barry Warsaw barry at moszumanska.debian.org
Thu Aug 13 21:15:05 UTC 2015


This is an automated email from the git hooks/post-receive script.

barry pushed a commit to branch master
in repository python-pex.

commit 5053627b97fcec5fe41e5714cb6b21529b46d5dd
Author: Barry Warsaw <barry at debian.org>
Date:   Thu Aug 13 17:07:25 2015 -0400

    Import python-pex_1.0.3.orig.tar.gz
---
 CHANGES.rst             | 31 +++++++++++++++++++++++++++++++
 PKG-INFO                | 33 ++++++++++++++++++++++++++++++++-
 pex.egg-info/PKG-INFO   | 33 ++++++++++++++++++++++++++++++++-
 pex/finders.py          | 14 ++++++++++++--
 pex/interpreter.py      |  5 ++++-
 pex/pex.py              | 12 ++++--------
 pex/pex_info.py         | 22 ++++++++++++----------
 pex/variables.py        | 19 +++++++++++++++----
 pex/version.py          |  2 +-
 scripts/coverage.sh     |  2 +-
 tests/test_pex.py       | 16 +++++++++++++---
 tests/test_pex_info.py  | 31 +++++++++++++++++++++++++++++++
 tests/test_variables.py | 17 +++++++++++++++++
 tox.ini                 |  4 ++--
 14 files changed, 207 insertions(+), 34 deletions(-)

diff --git a/CHANGES.rst b/CHANGES.rst
index b6f9046..a7f31a2 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -3,6 +3,37 @@ CHANGES
 =======
 
 -----
+1.0.3
+-----
+
+* Bug fix: Accommodate OSX `Python` python binaries.  Previously the OSX python distributions shipped
+  with OSX, XCode and available via https://www.python.org/downloads/ could fail to be detected using
+  the `PythonInterpreter` class.
+  Fixes `#144 <https://github.com/pantsbuild/pex/issues/144>`_.
+
+* Bug fix: PEX_SCRIPT failed when the script was from a not-zip-safe egg.
+  Original PR `#139 <https://github.com/pantsbuild/pex/pull/139>`_.
+
+* Bug fix: `sys.exit` called without arguments would cause `None` to be printed on stderr since pex 1.0.1.
+  `#143 <https://github.com/pantsbuild/pex/pull/143>`_.
+
+-----
+1.0.2
+-----
+
+* Bug fix: PEX-INFO values were overridden by environment `Variables` with default values that were
+  not explicitly set in the environment.
+  Fixes `#135 <https://github.com/pantsbuild/pex/issues/135>`_.
+
+* Bug fix: Since `69649c1 <https://github.com/pantsbuild/pex/commit/69649c1>`_ we have been unpatching
+  the side-effects of ``sys.modules`` after ``PEX.execute``.  This takes all modules imported during
+  the PEX lifecycle and sets all their attributes to ``None``.  Unfortunately, ``sys.excepthook``,
+  ``atexit`` and ``__del__`` may still try to operate using these tainted modules, causing exceptions
+  on interpreter teardown.  This reverts just the ``sys`` unpatching so that the abovementioned
+  teardown hooks behave more predictably.
+  Fixes `#141 <https://github.com/pantsbuild/pex/issues/141>`_.
+
+-----
 1.0.1
 -----
 
diff --git a/PKG-INFO b/PKG-INFO
index b0fc2ca..abb9dd1 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: pex
-Version: 1.0.1
+Version: 1.0.3
 Summary: The PEX packaging toolchain.
 Home-page: https://github.com/pantsbuild/pex
 Author: UNKNOWN
@@ -11,6 +11,37 @@ Description: =======
         =======
         
         -----
+        1.0.3
+        -----
+        
+        * Bug fix: Accommodate OSX `Python` python binaries.  Previously the OSX python distributions shipped
+          with OSX, XCode and available via https://www.python.org/downloads/ could fail to be detected using
+          the `PythonInterpreter` class.
+          Fixes `#144 <https://github.com/pantsbuild/pex/issues/144>`_.
+        
+        * Bug fix: PEX_SCRIPT failed when the script was from a not-zip-safe egg.
+          Original PR `#139 <https://github.com/pantsbuild/pex/pull/139>`_.
+        
+        * Bug fix: `sys.exit` called without arguments would cause `None` to be printed on stderr since pex 1.0.1.
+          `#143 <https://github.com/pantsbuild/pex/pull/143>`_.
+        
+        -----
+        1.0.2
+        -----
+        
+        * Bug fix: PEX-INFO values were overridden by environment `Variables` with default values that were
+          not explicitly set in the environment.
+          Fixes `#135 <https://github.com/pantsbuild/pex/issues/135>`_.
+        
+        * Bug fix: Since `69649c1 <https://github.com/pantsbuild/pex/commit/69649c1>`_ we have been unpatching
+          the side-effects of ``sys.modules`` after ``PEX.execute``.  This takes all modules imported during
+          the PEX lifecycle and sets all their attributes to ``None``.  Unfortunately, ``sys.excepthook``,
+          ``atexit`` and ``__del__`` may still try to operate using these tainted modules, causing exceptions
+          on interpreter teardown.  This reverts just the ``sys`` unpatching so that the abovementioned
+          teardown hooks behave more predictably.
+          Fixes `#141 <https://github.com/pantsbuild/pex/issues/141>`_.
+        
+        -----
         1.0.1
         -----
         
diff --git a/pex.egg-info/PKG-INFO b/pex.egg-info/PKG-INFO
index b0fc2ca..abb9dd1 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.0.1
+Version: 1.0.3
 Summary: The PEX packaging toolchain.
 Home-page: https://github.com/pantsbuild/pex
 Author: UNKNOWN
@@ -11,6 +11,37 @@ Description: =======
         =======
         
         -----
+        1.0.3
+        -----
+        
+        * Bug fix: Accommodate OSX `Python` python binaries.  Previously the OSX python distributions shipped
+          with OSX, XCode and available via https://www.python.org/downloads/ could fail to be detected using
+          the `PythonInterpreter` class.
+          Fixes `#144 <https://github.com/pantsbuild/pex/issues/144>`_.
+        
+        * Bug fix: PEX_SCRIPT failed when the script was from a not-zip-safe egg.
+          Original PR `#139 <https://github.com/pantsbuild/pex/pull/139>`_.
+        
+        * Bug fix: `sys.exit` called without arguments would cause `None` to be printed on stderr since pex 1.0.1.
+          `#143 <https://github.com/pantsbuild/pex/pull/143>`_.
+        
+        -----
+        1.0.2
+        -----
+        
+        * Bug fix: PEX-INFO values were overridden by environment `Variables` with default values that were
+          not explicitly set in the environment.
+          Fixes `#135 <https://github.com/pantsbuild/pex/issues/135>`_.
+        
+        * Bug fix: Since `69649c1 <https://github.com/pantsbuild/pex/commit/69649c1>`_ we have been unpatching
+          the side-effects of ``sys.modules`` after ``PEX.execute``.  This takes all modules imported during
+          the PEX lifecycle and sets all their attributes to ``None``.  Unfortunately, ``sys.excepthook``,
+          ``atexit`` and ``__del__`` may still try to operate using these tainted modules, causing exceptions
+          on interpreter teardown.  This reverts just the ``sys`` unpatching so that the abovementioned
+          teardown hooks behave more predictably.
+          Fixes `#141 <https://github.com/pantsbuild/pex/issues/141>`_.
+        
+        -----
         1.0.1
         -----
         
diff --git a/pex/finders.py b/pex/finders.py
index 4521e02..eb3be61 100644
--- a/pex/finders.py
+++ b/pex/finders.py
@@ -262,9 +262,19 @@ def get_script_from_whl(name, dist):
 
 
 def get_script_from_distribution(name, dist):
-  if isinstance(dist._provider, FixedEggMetadata):
+  # PathMetadata: exploded distribution on disk.
+  if isinstance(dist._provider, pkg_resources.PathMetadata):
+    if dist.egg_info.endswith('EGG-INFO'):
+      return get_script_from_egg(name, dist)
+    elif dist.egg_info.endswith('.dist-info'):
+      return get_script_from_whl(name, dist)
+    else:
+      return None, None
+  # FixedEggMetadata: Zipped egg
+  elif isinstance(dist._provider, FixedEggMetadata):
     return get_script_from_egg(name, dist)
-  elif isinstance(dist._provider, (WheelMetadata, pkg_resources.PathMetadata)):
+  # WheelMetadata: Zipped whl (in theory should not experience this at runtime.)
+  elif isinstance(dist._provider, WheelMetadata):
     return get_script_from_whl(name, dist)
   return None, None
 
diff --git a/pex/interpreter.py b/pex/interpreter.py
index 0ae3b5d..c3ea95c 100644
--- a/pex/interpreter.py
+++ b/pex/interpreter.py
@@ -178,7 +178,10 @@ class PythonIdentity(object):
 class PythonInterpreter(object):
   REGEXEN = (
     re.compile(r'jython$'),
-    re.compile(r'python$'),
+
+    # NB: OSX ships python binaries named Python so we allow for capital-P.
+    re.compile(r'[Pp]ython$'),
+
     re.compile(r'python[23].[0-9]$'),
     re.compile(r'pypy$'),
     re.compile(r'pypy-1.[0-9]$'),
diff --git a/pex/pex.py b/pex/pex.py
index b9e8602..0e6195e 100644
--- a/pex/pex.py
+++ b/pex/pex.py
@@ -160,7 +160,7 @@ class PEX(object):  # noqa: T000
         TRACER.log('Tainted path element: %s' % path_element)
         site_distributions.update(all_distribution_paths(path_element))
       else:
-        TRACER.log('Not a tained path element: %s' % path_element, V=2)
+        TRACER.log('Not a tainted path element: %s' % path_element, V=2)
 
     user_site_distributions.update(all_distribution_paths(USER_SITE))
 
@@ -243,11 +243,7 @@ class PEX(object):  # noqa: T000
     new_sys_path, new_sys_path_importer_cache, new_sys_modules = cls.minimum_sys()
 
     patch_all(new_sys_path, new_sys_path_importer_cache, new_sys_modules)
-
-    try:
-      yield
-    finally:
-      patch_all(old_sys_path, old_sys_path_importer_cache, old_sys_modules)
+    yield
 
   def _wrap_coverage(self, runner, *args):
     if not self._vars.PEX_COVERAGE and self._vars.PEX_COVERAGE_FILENAME is None:
@@ -325,7 +321,7 @@ class PEX(object):  # noqa: T000
     except SystemExit as se:
       # Print a SystemExit error message, avoiding a traceback in python3.
       # This must happen here, as sys.stderr is about to be torn down
-      if not isinstance(se.code, int):
+      if not isinstance(se.code, int) and se.code is not None:
         print(se.code, file=sys.stderr)
       raise
     finally:
@@ -396,7 +392,7 @@ class PEX(object):  # noqa: T000
     try:
       ast = compile(content, name, 'exec', flags=0, dont_inherit=1)
     except SyntaxError:
-      die('Unable to parse %s.  PEX script support only supports Python scripts.')
+      die('Unable to parse %s.  PEX script support only supports Python scripts.' % name)
     old_name, old_file = globals().get('__name__'), globals().get('__file__')
     try:
       old_argv0, sys.argv[0] = sys.argv[0], argv0
diff --git a/pex/pex_info.py b/pex/pex_info.py
index 17ba977..d4e8824 100644
--- a/pex/pex_info.py
+++ b/pex/pex_info.py
@@ -88,16 +88,18 @@ class PexInfo(object):
 
   @classmethod
   def from_env(cls, env=ENV):
+    supplied_env = env.strip_defaults()
+    zip_safe = None if supplied_env.PEX_FORCE_LOCAL is None else not supplied_env.PEX_FORCE_LOCAL
     pex_info = {
-      'pex_root': env.PEX_ROOT,
-      'entry_point': env.PEX_MODULE,
-      'script': env.PEX_SCRIPT,
-      'zip_safe': not env.PEX_FORCE_LOCAL,
-      'inherit_path': env.PEX_INHERIT_PATH,
-      'ignore_errors': env.PEX_IGNORE_ERRORS,
-      'always_write_cache': env.PEX_ALWAYS_CACHE,
+      'pex_root': supplied_env.PEX_ROOT,
+      'entry_point': supplied_env.PEX_MODULE,
+      'script': supplied_env.PEX_SCRIPT,
+      'zip_safe': zip_safe,
+      'inherit_path': supplied_env.PEX_INHERIT_PATH,
+      'ignore_errors': supplied_env.PEX_IGNORE_ERRORS,
+      'always_write_cache': supplied_env.PEX_ALWAYS_CACHE,
     }
-    # Filter out empty entries.
+    # Filter out empty entries not explicitly set in the environment.
     return cls(info=dict((k, v) for (k, v) in pex_info.items() if v is not None))
 
   @classmethod
@@ -260,10 +262,10 @@ class PexInfo(object):
     self._distributions.update(other.distributions)
     self._requirements.update(other.requirements)
 
-  def dump(self):
+  def dump(self, **kwargs):
     pex_info_copy = self._pex_info.copy()
     pex_info_copy['requirements'] = list(self._requirements)
-    return json.dumps(pex_info_copy)
+    return json.dumps(pex_info_copy, **kwargs)
 
   def copy(self):
     return PexInfo(info=self._pex_info.copy())
diff --git a/pex/variables.py b/pex/variables.py
index 2923a62..0594597 100644
--- a/pex/variables.py
+++ b/pex/variables.py
@@ -32,8 +32,9 @@ class Variables(object):
       variable_type, variable_text = cls.process_pydoc(getattr(value, '__doc__'))
       yield variable_name, variable_type, variable_text
 
-  def __init__(self, environ=None):
+  def __init__(self, environ=None, use_defaults=True):
     self._environ = environ.copy() if environ is not None else os.environ
+    self._use_defaults = use_defaults
 
   def copy(self):
     return self._environ.copy()
@@ -44,6 +45,9 @@ class Variables(object):
   def set(self, variable, value):
     self._environ[variable] = str(value)
 
+  def _defaulted(self, default):
+    return default if self._use_defaults else None
+
   def _get_bool(self, variable, default=False):
     value = self._environ.get(variable)
     if value is not None:
@@ -54,10 +58,10 @@ class Variables(object):
       else:
         die('Invalid value for %s, must be 0/1/false/true, got %r' % (variable, value))
     else:
-      return default
+      return self._defaulted(default)
 
   def _get_string(self, variable, default=None):
-    return self._environ.get(variable, default)
+    return self._environ.get(variable, self._defaulted(default))
 
   def _get_path(self, variable, default=None):
     value = self._get_string(variable, default=default)
@@ -70,7 +74,14 @@ class Variables(object):
     except ValueError:
       die('Invalid value for %s, must be an integer, got %r' % (variable, self._environ[variable]))
     except KeyError:
-      return default
+      return self._defaulted(default)
+
+  def strip_defaults(self):
+    """Returns a copy of these variables but with defaults stripped.
+
+    Any variables not explicitly set in the environment will have a value of `None`.
+    """
+    return Variables(environ=self.copy(), use_defaults=False)
 
   @contextmanager
   def patch(self, **kw):
diff --git a/pex/version.py b/pex/version.py
index 342aff8..c7d1aea 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.0.1'
+__version__ = '1.0.3'
 
 SETUPTOOLS_REQUIREMENT = 'setuptools>=2.2,<16'
 WHEEL_REQUIREMENT = 'wheel>=0.24.0,<0.25.0'
diff --git a/scripts/coverage.sh b/scripts/coverage.sh
index 680676c..095b7a5 100755
--- a/scripts/coverage.sh
+++ b/scripts/coverage.sh
@@ -4,4 +4,4 @@ coverage run -p -m py.test tests
 coverage run -p -m pex.bin.pex -v --help >&/dev/null
 coverage run -p -m pex.bin.pex -v -- scripts/do_nothing.py
 coverage run -p -m pex.bin.pex -v requests -- scripts/do_nothing.py
-coverage run -p -m pex.bin.pex -v . setuptools -- scripts/do_nothing.py
+coverage run -p -m pex.bin.pex -v . 'setuptools>=2.2,<16' -- scripts/do_nothing.py
diff --git a/tests/test_pex.py b/tests/test_pex.py
index 14bfa54..a54abce 100644
--- a/tests/test_pex.py
+++ b/tests/test_pex.py
@@ -60,6 +60,14 @@ def test_pex_sys_exit_prints_non_numeric_value_no_traceback():
   _test_sys_exit(sys_exit_arg, expected_output, 1)
 
 
+def test_pex_sys_exit_doesnt_print_none():
+  _test_sys_exit('', to_bytes(''), 0)
+
+
+def test_pex_sys_exit_prints_objects():
+  _test_sys_exit('Exception("derp")', to_bytes('derp\n'), 1)
+
+
 @pytest.mark.skipif('hasattr(sys, "pypy_version_info")')
 def test_pex_atexit_swallowing():
   body = textwrap.dedent("""
@@ -112,17 +120,19 @@ def test_minimum_sys_modules():
   assert tainted_module.__path__ == ['good_path']
 
 
+ at pytest.mark.parametrize('zip_safe', (False, True))
 @pytest.mark.parametrize('project_name', ('my_project', 'my-project'))
 @pytest.mark.parametrize('installer_impl', (EggInstaller, WheelInstaller))
-def test_pex_script(installer_impl, project_name):
-  with make_installer(name=project_name, installer_impl=installer_impl) as installer:
+def test_pex_script(installer_impl, project_name, zip_safe):
+  kw = dict(name=project_name, installer_impl=installer_impl, zip_safe=zip_safe)
+  with make_installer(**kw) as installer:
     bdist = DistributionHelper.distribution_from_path(installer.bdist())
 
     env_copy = os.environ.copy()
     env_copy['PEX_SCRIPT'] = 'hello_world'
     so, rc = run_simple_pex_test('', env=env_copy)
     assert rc == 1, so.decode('utf-8')
-    assert b'Could not find' in so
+    assert b'Could not find script hello_world' in so
 
     so, rc = run_simple_pex_test('', env=env_copy, dists=[bdist])
     assert rc == 0, so.decode('utf-8')
diff --git a/tests/test_pex_info.py b/tests/test_pex_info.py
index dd7f2e6..032b221 100644
--- a/tests/test_pex_info.py
+++ b/tests/test_pex_info.py
@@ -5,6 +5,7 @@ import pytest
 
 from pex.orderedset import OrderedSet
 from pex.pex_info import PexInfo
+from pex.variables import Variables
 
 
 def make_pex_info(requirements):
@@ -32,3 +33,33 @@ def test_backwards_incompatible_pex_info():
       ['world==0.2', False, None],
   ])
   assert pi.requirements == OrderedSet(['hello==0.1', 'world==0.2'])
+
+
+def assert_same_info(expected, actual):
+  assert expected.dump(sort_keys=True) == actual.dump(sort_keys=True)
+
+
+def test_from_empty_env():
+  environ = Variables(environ={})
+  info = {}
+  assert_same_info(PexInfo(info=info), PexInfo.from_env(env=environ))
+
+
+def test_from_env():
+  environ = dict(PEX_ROOT='/pex_root',
+                 PEX_MODULE='entry:point',
+                 PEX_SCRIPT='script.sh',
+                 PEX_FORCE_LOCAL='true',
+                 PEX_INHERIT_PATH='true',
+                 PEX_IGNORE_ERRORS='true',
+                 PEX_ALWAYS_CACHE='true')
+
+  info = dict(pex_root='/pex_root',
+              entry_point='entry:point',
+              script='script.sh',
+              zip_safe=False,
+              inherit_path=True,
+              ignore_errors=True,
+              always_write_cache=True)
+
+  assert_same_info(PexInfo(info=info), PexInfo.from_env(env=Variables(environ=environ)))
diff --git a/tests/test_variables.py b/tests/test_variables.py
index 2852678..e976985 100644
--- a/tests/test_variables.py
+++ b/tests/test_variables.py
@@ -72,3 +72,20 @@ def test_pex_vars_set():
   assert v._get_int('HELLO') == 42
   v.delete('HELLO')
   assert v._get_int('HELLO') is None
+
+
+def test_pex_vars_defaults_stripped():
+  v = Variables(environ={})
+  stripped = v.strip_defaults()
+
+  # bool
+  assert v.PEX_ALWAYS_CACHE is not None
+  assert stripped.PEX_ALWAYS_CACHE is None
+
+  # string
+  assert v.PEX_PATH is not None
+  assert stripped.PEX_PATH is None
+
+  # int
+  assert v.PEX_VERBOSE is not None
+  assert stripped.PEX_VERBOSE is None
diff --git a/tox.ini b/tox.ini
index 1c5064e..e370f81 100644
--- a/tox.ini
+++ b/tox.ini
@@ -22,7 +22,7 @@ deps =
     requests: responses
     cachecontrol: CacheControl
     cachecontrol: lockfile
-    coverage: coverage
+    coverage: coverage==3.7.1
 
 [integration]
 commands =
@@ -55,7 +55,7 @@ commands =
 [testenv:coverage]
 basepython = python2.7
 deps =
-    coverage
+    coverage==3.7.1
     tox
 commands =
     # meta

-- 
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