Skip to content

Commit

Permalink
Kill support for python 2.6. (#408)
Browse files Browse the repository at this point in the history
Also introduce a `to_unicode` complement to `to_bytes` to aid in
removal of `ByteIO`/`StringIO` re-directs.

Closes #405
  • Loading branch information
jsirois authored Sep 1, 2017
1 parent 616dc9c commit e7ff4be
Show file tree
Hide file tree
Showing 14 changed files with 65 additions and 62 deletions.
4 changes: 0 additions & 4 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,6 @@ matrix:
python: "2.7"
env: TOXENV=isort-check

- language: python
python: "2.6"
env: TOXENV=py26

- language: python
python: "2.7"
env: TOXENV=py27
Expand Down
28 changes: 18 additions & 10 deletions docs/buildingpex.rst
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ and invoke it. When no entry point is specified, "invocation" means starting an
.. code-block:: bash
$ pex
Python 2.6.9 (unknown, Jan 2 2014, 14:52:48)
[GCC 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.11.00)] on darwin
Python 3.6.2 (default, Jul 20 2017, 03:52:27)
[GCC 7.1.1 20170630] on linux
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>>
Expand All @@ -51,16 +51,24 @@ absolute path of a Python binary or the name of a Python interpreter within the

.. code-block:: bash
$ pex --python=python3.3
Python 3.3.3 (default, Jan 2 2014, 14:57:01)
[GCC 4.2.1 Compatible Apple Clang 4.0 ((tags/Apple/clang-421.0.60))] on darwin
$ pex
Python 3.6.2 (default, Jul 20 2017, 03:52:27)
[GCC 7.1.1 20170630] on linux
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> print "this won't work!"
>>> print "This won't work!"
File "<console>", line 1
print "this won't work!"
print "This won't work!"
^
SyntaxError: invalid syntax
SyntaxError: Missing parentheses in call to 'print'
>>>
$ pex --python=python2.7
Python 2.7.13 (default, Jul 21 2017, 03:24:34)
[GCC 7.1.1 20170630] on linux2
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> print "This works."
This works.
Specifying requirements
Expand All @@ -74,8 +82,8 @@ and ``psutil>1``:
.. code-block:: bash
$ pex flask 'psutil>1'
Python 2.6.9 (unknown, Jan 2 2014, 14:52:48)
[GCC 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.11.00)] on darwin
Python 3.6.2 (default, Jul 20 2017, 03:52:27)
[GCC 7.1.1 20170630] on linux
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>>
Expand Down
4 changes: 2 additions & 2 deletions pex/commands/bdist_pex.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

from pex.bin.pex import build_pex, configure_clp, make_relative_to_root
from pex.common import die
from pex.compatibility import ConfigParser, StringIO, string
from pex.compatibility import ConfigParser, StringIO, string, to_unicode
from pex.variables import ENV


Expand Down Expand Up @@ -49,7 +49,7 @@ def split_and_strip(entry_point):

if isinstance(raw_entry_points, string):
parser = ConfigParser()
parser.readfp(StringIO(raw_entry_points))
parser.readfp(StringIO(to_unicode(raw_entry_points)))
if parser.has_section('console_scripts'):
return dict(parser.items('console_scripts'))
elif isinstance(raw_entry_points, dict):
Expand Down
34 changes: 18 additions & 16 deletions pex/compatibility.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,10 @@

import os
from abc import ABCMeta
from io import BytesIO, StringIO
from numbers import Integral, Real
from sys import version_info as sys_version_info

# TODO(wickman) Since the io package is available in 2.6.x, use that instead of
# cStringIO/StringIO
try:
# CPython 2.x
from cStringIO import StringIO
except ImportError:
try:
# Python 2.x
from StringIO import StringIO
except:
# Python 3.x
from io import StringIO
from io import BytesIO

try:
# Python 2.x
from ConfigParser import ConfigParser
Expand All @@ -33,13 +20,12 @@
AbstractClass = ABCMeta('AbstractClass', (object,), {})
PY2 = sys_version_info[0] == 2
PY3 = sys_version_info[0] == 3
StringIO = StringIO
BytesIO = BytesIO if PY3 else StringIO

integer = (Integral,)
real = (Real,)
numeric = integer + real
string = (str,) if PY3 else (str, unicode)
unicode_string = (str,) if PY3 else (unicode,)
bytes = (bytes,)

if PY2:
Expand All @@ -50,6 +36,14 @@ def to_bytes(st, encoding='utf-8'):
return st
else:
raise ValueError('Cannot convert %s to bytes' % type(st))

def to_unicode(st, encoding='utf-8'):
if isinstance(st, unicode):
return st
elif isinstance(st, (str, bytes)):
return unicode(st, encoding)
else:
raise ValueError('Cannot convert %s to a unicode string' % type(st))
else:
def to_bytes(st, encoding='utf-8'):
if isinstance(st, str):
Expand All @@ -59,6 +53,14 @@ def to_bytes(st, encoding='utf-8'):
else:
raise ValueError('Cannot convert %s to bytes.' % type(st))

def to_unicode(st, encoding='utf-8'):
if isinstance(st, str):
return st
elif isinstance(st, bytes):
return str(st, encoding)
else:
raise ValueError('Cannot convert %s to a unicode string' % type(st))

_PY3_EXEC_FUNCTION = """
def exec_function(ast, globals_map):
locals_map = globals_map
Expand Down
10 changes: 6 additions & 4 deletions pex/http.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,12 @@
else:
import urllib2 as urllib_request

# This is available as hashlib.algorithms_guaranteed in >=3.2 and as
# hashlib.algorithms in >=2.7, but not available in 2.6, so we enumerate
# here.
HASHLIB_ALGORITHMS = frozenset(['md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512'])
try:
# The hashlib.algorithms_guaranteed function is available in >=2.7.9 and >=3.2.
HASHLIB_ALGORITHMS = frozenset(hashlib.algorithms_guaranteed)
except AttributeError:
# And the hashlib.algorithms function covers the rest of the 2.7 versions we support.
HASHLIB_ALGORITHMS = frozenset(hashlib.algorithms)


class Context(AbstractClass):
Expand Down
8 changes: 2 additions & 6 deletions pex/interpreter.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ def hashbang(self):
@property
def python(self):
# return the python version in the format of the 'python' key for distributions
# specifically, '2.6', '2.7', '3.2', etc.
# specifically, '2.7', '3.2', etc.
return '%d.%d' % (self.version[0:2])

def __str__(self):
Expand Down Expand Up @@ -328,7 +328,7 @@ def version_filter(version):
@classmethod
def sanitized_environment(cls):
# N.B. This is merely a hack because sysconfig.py on the default OS X
# installation of 2.6/2.7 breaks.
# installation of 2.7 breaks.
env_copy = os.environ.copy()
env_copy.pop('MACOSX_DEPLOYMENT_TARGET', None)
return env_copy
Expand Down Expand Up @@ -400,10 +400,6 @@ def get_location(self, req):
if req.key == dist_name and dist_version in req:
return location

def supports_wheel_install(self):
"""Wheel installs are broken in python 2.6"""
return self.version >= (2, 7)

def __hash__(self):
return hash((self._binary, self._identity))

Expand Down
2 changes: 1 addition & 1 deletion pex/pep425.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ def _iter_supported_tags(cls, impl, version, platform):
"""Given a set of tags, iterate over supported tags.
:param impl: Python implementation tag e.g. cp, jy, pp.
:param version: E.g. '26', '33'
:param version: E.g. '27', '33'
:param platform: Platform as from :function:`pkg_resources.get_supported_platform`,
for example 'linux-x86_64' or 'macosx-10.4-x86_64'.
:returns: Iterator over (pyver, abi, platform) tuples.
Expand Down
6 changes: 1 addition & 5 deletions pex/pex_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -271,11 +271,7 @@ def _add_dist_zip(self, path, dist_name):
# But wheels don't have to be importable, so we need to force them
# into an importable shape. We can do that by installing it into its own
# wheel dir.
if not self.interpreter.supports_wheel_install():
self._logger.warn("Wheel dependency on %s may not work correctly with Python 2.6." %
dist_name)

if self.interpreter.supports_wheel_install() and dist_name.endswith("whl"):
if dist_name.endswith("whl"):
from wheel.install import WheelFile
tmp = safe_mkdtemp()
whltmp = os.path.join(tmp, dist_name)
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,12 @@
'Operating System :: MacOS :: MacOS X',
'Programming Language :: Python',
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
],
packages = [
'pex',
Expand Down
18 changes: 15 additions & 3 deletions tests/test_compatibility.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import pytest

from pex.compatibility import to_bytes
from pex.compatibility import to_bytes, to_unicode, unicode_string


def test_to_bytes():
Expand All @@ -13,6 +13,18 @@ def test_to_bytes():
assert isinstance(to_bytes(u'abc'), bytes)
assert isinstance(to_bytes(b'abc'.decode('latin-1'), encoding='utf-8'), bytes)

for bad_values in (123, None):
for bad_value in (123, None):
with pytest.raises(ValueError):
to_bytes(bad_values)
to_bytes(bad_value)


def test_to_unicode():
assert isinstance(to_unicode(''), unicode_string)
assert isinstance(to_unicode('abc'), unicode_string)
assert isinstance(to_unicode(b'abc'), unicode_string)
assert isinstance(to_unicode(u'abc'), unicode_string)
assert isinstance(to_unicode(u'abc'.encode('latin-1'), encoding='latin-1'), unicode_string)

for bad_value in (123, None):
with pytest.raises(ValueError):
to_unicode(bad_value)
2 changes: 1 addition & 1 deletion tests/test_http.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ def __init__(self, data):
self.version = 'HTTP/1.1'
self.reason = 'OK'
if PY2:
self.msg = HTTPMessage(BytesIO('Content-Type: application/x-compressed\r\n'))
self.msg = HTTPMessage(BytesIO(b'Content-Type: application/x-compressed\r\n'))
else:
self.msg = HTTPMessage()
self.msg.add_header('Content-Type', 'application/x-compressed')
Expand Down
2 changes: 0 additions & 2 deletions tests/test_pex.py
Original file line number Diff line number Diff line change
Expand Up @@ -186,8 +186,6 @@ def test_site_libs_excludes_prefix():
assert sys.prefix not in site_libs


@pytest.mark.skipif(sys.version_info < (2, 7),
reason="wheel script installation is broken on python 2.6")
@pytest.mark.parametrize('zip_safe', (False, True))
@pytest.mark.parametrize('project_name', ('my_project', 'my-project'))
@pytest.mark.parametrize('installer_impl', (EggInstaller, WheelInstaller))
Expand Down
3 changes: 0 additions & 3 deletions tests/test_pex_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

import os
import stat
import sys

import pytest
from twitter.common.contextutil import temporary_dir
Expand Down Expand Up @@ -67,8 +66,6 @@ def test_pex_builder():
assert fp.read() == 'success'


@pytest.mark.skipif(sys.version_info < (2, 7),
reason="wheel script installation is broken on python 2.6")
def test_pex_builder_wheeldep():
"""Repeat the pex_builder test, but this time include an import of
something from a wheel that doesn't come in importable form.
Expand Down
4 changes: 0 additions & 4 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ deps =
twitter.common.testing>=0.3.1,<0.4.0
wheel==0.29.0
packaging==16.8
py26: mock
py27: mock
pypy: mock
run: requests
Expand Down Expand Up @@ -135,9 +134,6 @@ commands = pex --cache-dir {envtmpdir}/buildcache wheel requests . -o dist/pex35
commands = pex --cache-dir {envtmpdir}/buildcache wheel requests . -o dist/pex36 -e pex.bin.pex:main -v

# Would love if you didn't have to enumerate environments here :-\
[testenv:py26]
[testenv:py26-requests]
[testenv:py26-requests-cachecontrol]
[testenv:py27]
[testenv:py27-requests]
[testenv:py27-requests-cachecontrol]
Expand Down

0 comments on commit e7ff4be

Please sign in to comment.