diff --git a/Dockerfile b/Dockerfile index a4cc99fe..546e28d6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -30,6 +30,18 @@ RUN set -ex; \ rm -rf /Python-2.7.9; \ rm Python-2.7.9.tgz +# Build python 3.4 from source +RUN set -ex; \ + curl -LO https://www.python.org/ftp/python/3.4.3/Python-3.4.3.tgz; \ + tar -xzf Python-3.4.3.tgz; \ + cd Python-3.4.3; \ + ./configure --enable-shared; \ + make; \ + make install; \ + cd ..; \ + rm -rf /Python-3.4.3; \ + rm Python-3.4.3.tgz + # Make libpython findable ENV LD_LIBRARY_PATH /usr/local/lib @@ -63,6 +75,8 @@ RUN ln -s /usr/local/bin/docker-1.7.1 /usr/local/bin/docker RUN useradd -d /home/user -m -s /bin/bash user WORKDIR /code/ +RUN pip install tox + ADD requirements.txt /code/ RUN pip install -r requirements.txt diff --git a/MANIFEST.in b/MANIFEST.in index 74204859..7d48d347 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,7 +1,7 @@ include Dockerfile include LICENSE include requirements.txt -include requirements-dev*.txt +include requirements-dev.txt include tox.ini include *.md include compose/config/schema.json diff --git a/compose/container.py b/compose/container.py index 6f426532..f727c867 100644 --- a/compose/container.py +++ b/compose/container.py @@ -1,8 +1,9 @@ from __future__ import absolute_import from __future__ import unicode_literals -from six import iteritems -from six.moves import reduce +from functools import reduce + +import six from .const import LABEL_CONTAINER_NUMBER from .const import LABEL_SERVICE @@ -89,7 +90,7 @@ class Container(object): private=private, **public[0]) return ', '.join(format_port(*item) - for item in sorted(iteritems(self.ports))) + for item in sorted(six.iteritems(self.ports))) @property def labels(self): diff --git a/compose/project.py b/compose/project.py index cd88b298..a3127c6c 100644 --- a/compose/project.py +++ b/compose/project.py @@ -2,9 +2,9 @@ from __future__ import absolute_import from __future__ import unicode_literals import logging +from functools import reduce from docker.errors import APIError -from six.moves import reduce from .config import ConfigurationError from .config import get_service_name_from_net @@ -340,7 +340,7 @@ class Project(object): self.service_names, ) - return filter(matches_service_names, containers) + return [c for c in containers if matches_service_names(c)] def _inject_deps(self, acc, service): dep_names = service.get_dependency_names() diff --git a/compose/service.py b/compose/service.py index 647516ba..d8a26e73 100644 --- a/compose/service.py +++ b/compose/service.py @@ -709,7 +709,9 @@ class Service(object): def build(self, no_cache=False): log.info('Building %s...' % self.name) - path = six.binary_type(self.options['build']) + path = self.options['build'] + if not six.PY3: + path = path.encode('utf8') build_output = self.client.build( path=path, @@ -840,7 +842,7 @@ def merge_volume_bindings(volumes_option, previous_container): volume_bindings.update( get_container_data_volumes(previous_container, volumes_option)) - return volume_bindings.values() + return list(volume_bindings.values()) def get_container_data_volumes(container, volumes_option): @@ -853,7 +855,7 @@ def get_container_data_volumes(container, volumes_option): container_volumes = container.get('Volumes') or {} image_volumes = container.image_config['ContainerConfig'].get('Volumes') or {} - for volume in set(volumes_option + image_volumes.keys()): + for volume in set(volumes_option + list(image_volumes)): volume = parse_volume_spec(volume) # No need to preserve host volumes if volume.external: diff --git a/compose/utils.py b/compose/utils.py index bd892267..0cbefba9 100644 --- a/compose/utils.py +++ b/compose/utils.py @@ -97,5 +97,5 @@ def write_out_msg(stream, lines, msg_index, msg, status="done"): def json_hash(obj): dump = json.dumps(obj, sort_keys=True, separators=(',', ':')) h = hashlib.sha256() - h.update(dump) + h.update(dump.encode('utf8')) return h.hexdigest() diff --git a/requirements-dev-py2.txt b/requirements-dev-py2.txt deleted file mode 100644 index 97fc4fed..00000000 --- a/requirements-dev-py2.txt +++ /dev/null @@ -1,7 +0,0 @@ -coverage==3.7.1 -flake8==2.3.0 -git+https://github.com/pyinstaller/pyinstaller.git@12e40471c77f588ea5be352f7219c873ddaae056#egg=pyinstaller -mock >= 1.0.1 -nose==1.3.4 -pep8==1.6.1 -unittest2==0.8.0 diff --git a/requirements-dev-py3.txt b/requirements-dev-py3.txt deleted file mode 100644 index a2ba1c8b..00000000 --- a/requirements-dev-py3.txt +++ /dev/null @@ -1,2 +0,0 @@ -flake8 -nose >= 1.3.0 diff --git a/requirements-dev.txt b/requirements-dev.txt index cc984225..9e830733 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,2 +1,5 @@ -flake8 -tox +flake8==2.3.0 +git+https://github.com/pyinstaller/pyinstaller.git@12e40471c77f588ea5be352f7219c873ddaae056#egg=pyinstaller +mock >= 1.0.1 +nose==1.3.4 +pep8==1.6.1 diff --git a/script/test-versions b/script/test-versions index e2102e44..f39c17e8 100755 --- a/script/test-versions +++ b/script/test-versions @@ -24,5 +24,5 @@ for version in $DOCKER_VERSIONS; do -e "DOCKER_DAEMON_ARGS" \ --entrypoint="script/dind" \ "$TAG" \ - script/wrapdocker tox "$@" + script/wrapdocker tox -e py27,py34 -- "$@" done diff --git a/setup.py b/setup.py index cdb5686c..33335047 100644 --- a/setup.py +++ b/setup.py @@ -41,9 +41,7 @@ install_requires = [ tests_require = [ - 'mock >= 1.0.1', 'nose', - 'pyinstaller', 'flake8', ] @@ -51,7 +49,6 @@ tests_require = [ if sys.version_info < (2, 7): tests_require.append('unittest2') if sys.version_info[:1] < (3,): - tests_require.append('pyinstaller') tests_require.append('mock >= 1.0.1') diff --git a/tests/integration/resilience_test.py b/tests/integration/resilience_test.py index b1faf99d..82a4680d 100644 --- a/tests/integration/resilience_test.py +++ b/tests/integration/resilience_test.py @@ -1,8 +1,7 @@ from __future__ import absolute_import from __future__ import unicode_literals -import mock - +from .. import mock from .testcases import DockerClientTestCase from compose.project import Project diff --git a/tests/integration/service_test.py b/tests/integration/service_test.py index effd356d..f300c6d5 100644 --- a/tests/integration/service_test.py +++ b/tests/integration/service_test.py @@ -363,7 +363,7 @@ class ServiceTest(DockerClientTestCase): new_container, = service.execute_convergence_plan( ConvergencePlan('recreate', [old_container])) - self.assertEqual(new_container.get('Volumes').keys(), ['/data']) + self.assertEqual(list(new_container.get('Volumes')), ['/data']) self.assertEqual(new_container.get('Volumes')['/data'], volume_path) def test_start_container_passes_through_options(self): @@ -498,7 +498,7 @@ class ServiceTest(DockerClientTestCase): with open(os.path.join(base_dir, 'Dockerfile'), 'w') as f: f.write("FROM busybox\n") - with open(os.path.join(base_dir, b'foo\xE2bar'), 'w') as f: + with open(os.path.join(base_dir.encode('utf8'), b'foo\xE2bar'), 'w') as f: f.write("hello world\n") self.create_service('web', build=text_type(base_dir)).build() diff --git a/tests/unit/service_test.py b/tests/unit/service_test.py index 3bb3e172..f2247527 100644 --- a/tests/unit/service_test.py +++ b/tests/unit/service_test.py @@ -41,7 +41,7 @@ class ServiceTest(unittest.TestCase): dict(Name=str(i), Image='foo', Id=i) for i in range(3) ] service = Service('db', self.mock_client, 'myproject', image='foo') - self.assertEqual([c.id for c in service.containers()], range(3)) + self.assertEqual([c.id for c in service.containers()], list(range(3))) expected_labels = [ '{0}=myproject'.format(LABEL_PROJECT), diff --git a/tox.ini b/tox.ini index 2e3edd2a..a2bd6b6b 100644 --- a/tox.ini +++ b/tox.ini @@ -5,6 +5,8 @@ envlist = py27,py34,pre-commit usedevelop=True passenv = LD_LIBRARY_PATH +setenv = + HOME=/tmp deps = -rrequirements.txt commands = @@ -19,26 +21,16 @@ commands = pre-commit install pre-commit run --all-files -[testenv:py26] -deps = - {[testenv]deps} - -rrequirements-dev-py2.txt - [testenv:py27] -deps = {[testenv:py26]deps} - -[testenv:pypy] -deps = {[testenv:py26]deps} - -[testenv:py33] deps = {[testenv]deps} - -rrequirements-dev-py3.txt + -rrequirements-dev.txt [testenv:py34] -deps = {[testenv:py33]deps} - -# TODO pypy3 +deps = + {[testenv]deps} + flake8 + nose [flake8] # ignore line-length for now