From a58bd6b7bd475d5a1e7d537c2b939c428edb96d5 Mon Sep 17 00:00:00 2001
From: gnaponie <gnaponie@redhat.com>
Date: Sep 23 2019 11:58:27 +0000
Subject: Drop py2 support


Signed-off-by: gnaponie <gnaponie@redhat.com>

---

diff --git a/.copr/freshmaker.spec.in b/.copr/freshmaker.spec.in
index 3c5ce5b..ec22adb 100644
--- a/.copr/freshmaker.spec.in
+++ b/.copr/freshmaker.spec.in
@@ -14,84 +14,74 @@ BuildRequires:    fedmsg-hub
 BuildRequires:    help2man
 BuildRequires:    kobo
 BuildRequires:    kobo-rpmlib
-BuildRequires:    python2-devel
-BuildRequires:    python2-flask-migrate
-BuildRequires:    python2-funcsigs
-BuildRequires:    python2-futures
-BuildRequires:    python2-pdc-client
-BuildRequires:    python-enum34
-BuildRequires:    python-flask-script
-BuildRequires:    python-httplib2
-BuildRequires:    python-m2ext
-BuildRequires:    python-munch
-BuildRequires:    python2-odcs-client
-BuildRequires:    python-dogpile-cache
-BuildRequires:    python2-krbcontext
-BuildRequires:    python-flask-login
-BuildRequires:    python-ldap
-BuildRequires:    PyYAML
+BuildRequires:    python3-devel
+BuildRequires:    python3-flask-migrate
+BuildRequires:    python3-pdc-client
+BuildRequires:    python3-flask-script
+BuildRequires:    python3-httplib2
+BuildRequires:    python3-munch
+BuildRequires:    python3-odcs-client
+BuildRequires:    python3-dogpile-cache
+BuildRequires:    python3-krbcontext
+BuildRequires:    python3-flask-login
+BuildRequires:    python3-ldap
+BuildRequires:    python3-pyyaml
 BuildRequires:    git
-BuildRequires:    python-qpid-proton
-BuildRequires:    python2-tabulate
-BuildRequires:    python2-kerberos
-
-BuildRequires:    python2-setuptools
-BuildRequires:    python2-fedora
-BuildRequires:    python2-flask
-BuildRequires:    python2-flask-sqlalchemy
-BuildRequires:    python2-mock
-BuildRequires:    python2-nose
-BuildRequires:    python2-psutil
-BuildRequires:    python2-pytest
-BuildRequires:    python2-pyOpenSSL
-BuildRequires:    python2-six
-BuildRequires:    python2-sqlalchemy
-BuildRequires:    python2-koji
-BuildRequires:    python2-psycopg2
-BuildRequires:    python2-defusedxml
-BuildRequires:    python2-prometheus_client
+BuildRequires:    python3-qpid-proton
+BuildRequires:    python3-tabulate
+BuildRequires:    python3-kerberos
+
+BuildRequires:    python3-setuptools
+BuildRequires:    python3-fedora
+BuildRequires:    python3-flask
+BuildRequires:    python3-flask-sqlalchemy
+BuildRequires:    python3-mock
+BuildRequires:    python3-nose
+BuildRequires:    python3-psutil
+BuildRequires:    python3-pytest
+BuildRequires:    python3-pyOpenSSL
+BuildRequires:    python3-sqlalchemy
+BuildRequires:    python3-koji
+BuildRequires:    python3-psycopg2
+BuildRequires:    python3-defusedxml
+BuildRequires:    python3-prometheus_client
 
 BuildRequires:    systemd
 %{?systemd_requires}
 
-Requires:    fedmsg-hub
+Requires:    python3-fedmsg
 Requires:    systemd
-Requires:    kobo
-Requires:    kobo-rpmlib
-Requires:    python2-funcsigs
-Requires:    python2-futures
-Requires:    python2-openidc-client
-Requires:    python2-pdc-client
-Requires:    python-enum34
-Requires:    python-flask-script
-Requires:    python-httplib2
-Requires:    python-m2ext
-Requires:    python-munch
-Requires:    python2-odcs-client
-Requires:    python-dogpile-cache
-Requires:    python2-krbcontext
-Requires:    python-flask-login
-Requires:    python-ldap
-Requires:    PyYAML
+Requires:    python3-kobo
+Requires:    python3-kobo-rpmlib
+Requires:    python3-openidc-client
+Requires:    python3-pdc-client
+Requires:    python3-flask-script
+Requires:    python3-httplib2
+Requires:    python3-munch
+Requires:    python3-odcs-client
+Requires:    python3-dogpile-cache
+Requires:    python3-krbcontext
+Requires:    python3-flask-login
+Requires:    python3-ldap
+Requires:    python3-pyyaml
 Requires:    git
-Requires:    python-qpid-proton
-Requires:    python2-tabulate
-
-Requires:    python2-koji
-Requires:    python2-fedora
-Requires:    python2-flask
-Requires:    python2-flask-migrate
-Requires:    python2-flask-sqlalchemy
-Requires:    python2-mock
-Requires:    python2-psutil
-Requires:    python2-pyOpenSSL
-Requires:    python2-six
-Requires:    python2-sqlalchemy
-Requires:    python2-systemd
-Requires:    python2-psycopg2
-Requires:    python2-defusedxml
-Requires:    python2-prometheus_client
-Requires:    python2-kerberos
+Requires:    python3-qpid-proton
+Requires:    python3-tabulate
+
+Requires:    python3-koji
+Requires:    python3-fedora
+Requires:    python3-flask
+Requires:    python3-flask-migrate
+Requires:    python3-flask-sqlalchemy
+Requires:    python3-mock
+Requires:    python3-psutil
+Requires:    python3-pyOpenSSL
+Requires:    python3-sqlalchemy
+Requires:    python3-systemd
+Requires:    python3-psycopg2
+Requires:    python3-defusedxml
+Requires:    python3-prometheus_client
+Requires:    python3-kerberos
 
 
 %description
@@ -106,13 +96,13 @@ sed -i '/koji/d' requirements.txt
 
 
 %build
-%py2_build
+%py3_build
 
 
 %install
-%py2_install
+%py3_install
 
-export PYTHONPATH=%{buildroot}%{python2_sitelib}
+export PYTHONPATH=%{buildroot}%{python3_sitelib}
 mkdir -p %{buildroot}%{_mandir}/man1
 for command in freshmaker-manager freshmaker-frontend freshmaker-gencert freshmaker-upgradedb ; do
 FRESHMAKER_CONFIG_FILE=conf/config.py %{buildroot}%{_bindir}/$command --help || true
@@ -125,13 +115,13 @@ install -d -m 0755 %{buildroot}%{_datadir}/freshmaker
 install -p -m 0644 contrib/freshmaker.wsgi %{buildroot}%{_datadir}/freshmaker
 
 # %check
-# nosetests-%{python2_version} -v
+# nosetests-%{python3_version} -v
 
 
 %files
 %doc README.md
 %license LICENSE
-%{python2_sitelib}/freshmaker*
+%{python3_sitelib}/freshmaker*
 %{_bindir}/freshmaker-*
 %{_mandir}/man1/freshmaker-*.1*
 %dir %{_sysconfdir}/freshmaker
@@ -140,7 +130,7 @@ install -p -m 0644 contrib/freshmaker.wsgi %{buildroot}%{_datadir}/freshmaker
 %config(noreplace) %{_sysconfdir}/freshmaker/config.py
 %exclude %{_sysconfdir}/freshmaker/*.py[co]
 %exclude %{_sysconfdir}/fedmsg.d/*.py[co]
-%exclude %{python2_sitelib}/conf/
+%exclude %{python3_sitelib}/conf/
 
 
 %changelog
diff --git a/Dockerfile b/Dockerfile
index 2252022..bc8fe8e 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -14,10 +14,8 @@ RUN cd /etc/yum.repos.d/ \
     && dnf config-manager --add-repo http://download-ipv4.eng.brq.redhat.com/rel-eng/RCMTOOLS/latest-RCMTOOLS-2-F-29/compose/Everything/x86_64/os/ \
     && dnf -y clean all \
     && dnf -v --nogpg -y install \
-    httpd mod_wsgi mod_auth_gssapi python2-rhmsg mod_ssl \
+    httpd mod_wsgi mod_auth_gssapi python3-rhmsg mod_ssl python3-odcs-client \
     /tmp/$(basename $freshmaker_rpm) \
-    && dnf config-manager --add-repo http://download-ipv4.eng.brq.redhat.com/rel-eng/repos/eng-rhel-7/x86_64 \
-    && dnf --nogpg -y upgrade python2-odcs-client \
     && dnf -y -v downgrade https://kojipkgs.fedoraproject.org//packages/qpid-proton/0.26.0/1.fc29/x86_64/qpid-proton-c-0.26.0-1.fc29.x86_64.rpm \
     https://kojipkgs.fedoraproject.org//packages/qpid-proton/0.26.0/1.fc29/x86_64/python2-qpid-proton-0.26.0-1.fc29.x86_64.rpm \
     https://kojipkgs.fedoraproject.org//packages/qpid-proton/0.26.0/1.fc29/x86_64/python3-qpid-proton-0.26.0-1.fc29.x86_64.rpm \
diff --git a/contrib/freshmaker-cli b/contrib/freshmaker-cli
index f4c3e1c..f074959 100755
--- a/contrib/freshmaker-cli
+++ b/contrib/freshmaker-cli
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 """ freshmaker-cli - Read-only client for Freshmaker REST API
 
diff --git a/contrib/generate_report.py b/contrib/generate_report.py
index 81784d1..ebb947c 100644
--- a/contrib/generate_report.py
+++ b/contrib/generate_report.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/python3
 from __future__ import print_function
 
 import argparse
diff --git a/contrib/get_freshmaker_stats.py b/contrib/get_freshmaker_stats.py
index d6ffa18..c6720aa 100644
--- a/contrib/get_freshmaker_stats.py
+++ b/contrib/get_freshmaker_stats.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/python3
 from __future__ import print_function
 
 import argparse
diff --git a/dev_scripts/template_errata.py b/dev_scripts/template_errata.py
index 8ac1a9d..3b23ddf 100755
--- a/dev_scripts/template_errata.py
+++ b/dev_scripts/template_errata.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/python3
 from __future__ import print_function
 import os
 import sys
diff --git a/dev_scripts/template_pulp.py b/dev_scripts/template_pulp.py
index afdf49b..4bc7974 100755
--- a/dev_scripts/template_pulp.py
+++ b/dev_scripts/template_pulp.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/python3
 from __future__ import print_function
 import os
 import sys
diff --git a/dev_scripts/templates_lightblue.py b/dev_scripts/templates_lightblue.py
index 4f4ceed..8c657d2 100755
--- a/dev_scripts/templates_lightblue.py
+++ b/dev_scripts/templates_lightblue.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/python3
 from __future__ import print_function
 import os
 import sys
diff --git a/freshmaker/errata.py b/freshmaker/errata.py
index c0df41b..fa1cf01 100644
--- a/freshmaker/errata.py
+++ b/freshmaker/errata.py
@@ -25,7 +25,7 @@ import os
 import requests
 import dogpile.cache
 from requests_kerberos import HTTPKerberosAuth
-from six.moves.xmlrpc_client import ServerProxy
+from xmlrpc.client import ServerProxy
 from kobo.xmlrpc import SafeCookieTransport
 
 from freshmaker.events import (
diff --git a/freshmaker/events.py b/freshmaker/events.py
index 3f5c16c..77b6181 100644
--- a/freshmaker/events.py
+++ b/freshmaker/events.py
@@ -26,10 +26,7 @@ import itertools
 from freshmaker import conf
 from freshmaker.types import ArtifactType
 
-try:
-    from inspect import signature
-except ImportError:
-    from funcsigs import signature
+from inspect import signature
 
 
 class BaseEvent(object):
diff --git a/freshmaker/handlers/__init__.py b/freshmaker/handlers/__init__.py
index dae76c1..25d49d9 100644
--- a/freshmaker/handlers/__init__.py
+++ b/freshmaker/handlers/__init__.py
@@ -24,7 +24,6 @@
 import abc
 import json
 import re
-import six
 import copy
 from functools import wraps
 
@@ -339,7 +338,7 @@ class BaseHandler(object):
             if not rule:
                 return False
 
-            if not isinstance(rule[0], six.string_types):
+            if not isinstance(rule[0], str):
                 raise TypeError(
                     "Rule does not have any operator, use any_() or all_() "
                     "methods to construct the rule: %r" % rule)
@@ -627,4 +626,4 @@ class ContainerBuildHandler(BaseHandler):
             db.session.add(build)
             db.session.commit()
 
-        list(six.moves.map(build_image, builds))
+        list(map(build_image, builds))
diff --git a/freshmaker/handlers/koji/rebuild_images_on_odcs_compose_done.py b/freshmaker/handlers/koji/rebuild_images_on_odcs_compose_done.py
index 04e9c4e..736cbae 100644
--- a/freshmaker/handlers/koji/rebuild_images_on_odcs_compose_done.py
+++ b/freshmaker/handlers/koji/rebuild_images_on_odcs_compose_done.py
@@ -21,8 +21,6 @@
 #
 # Written by Chenxiong Qi <cqi@redhat.com>
 
-import six
-
 from freshmaker import db
 from freshmaker.models import (
     ArtifactBuild, ArtifactBuildState, Compose, ArtifactBuildCompose)
@@ -65,7 +63,7 @@ class RebuildImagesOnODCSComposeDone(ContainerBuildHandler):
         if not self.dry_run:
             # In non-dry-run mode, check that all the composes are ready.
             # In dry-run mode, the composes are fake, so they are always ready.
-            builds_ready_to_rebuild = six.moves.filter(
+            builds_ready_to_rebuild = filter(
                 lambda build: build.composes_ready, builds_ready_to_rebuild)
 
         # Start the rebuild.
diff --git a/freshmaker/lightblue.py b/freshmaker/lightblue.py
index 645aec1..1eb7024 100644
--- a/freshmaker/lightblue.py
+++ b/freshmaker/lightblue.py
@@ -28,12 +28,12 @@ import json
 import os
 import re
 import requests
-import six
+import io
 import dogpile.cache
 import kobo.rpmlib
 from itertools import groupby
 
-from six.moves import http_client
+import http.client
 import concurrent.futures
 from freshmaker import log, conf
 from freshmaker.kojiservice import koji_service
@@ -88,7 +88,7 @@ class LightBlueSystemError(LightBlueError):
         except ValueError as e:
             log.exception(e)
         # If no JSON is returned, try to get the title of HTML page.
-        buf = six.StringIO(self.raw)
+        buf = io.StringIO(self.raw)
         html = ''.join((line.strip('\n') for line in buf))
         match = re.search('<title>(.+)</title>', html)
         return match.groups()[0]
@@ -572,15 +572,15 @@ class LightBlue(object):
         """
         status_code = response.status_code
 
-        if status_code == http_client.OK:
+        if status_code == http.client.OK:
             return
 
         # Warn early, in case there is an error in the error handling code below
         log.warning("Request to %s gave %r" % (response.request.url, response))
 
-        if status_code in (http_client.NOT_FOUND,
-                           http_client.INTERNAL_SERVER_ERROR,
-                           http_client.UNAUTHORIZED):
+        if status_code in (http.client.NOT_FOUND,
+                           http.client.INTERNAL_SERVER_ERROR,
+                           http.client.UNAUTHORIZED):
             raise LightBlueSystemError(status_code, response.content)
 
         raise LightBlueRequestError(status_code, response.json())
@@ -1314,7 +1314,7 @@ class LightBlue(object):
             images, get_nvr=lambda image: image['brew']['build'], reverse=True)
         images = []
         for k, v in groupby(sorted_images, key=lambda x: x['brew']['build']):
-            images.append(six.next(v))
+            images.append(next(v))
 
         # In case we query for unpublished images, we need to return just
         # the latest NVR for given name-version, otherwise images would
diff --git a/freshmaker/migrations/versions/b17231ee8220_remove_event_compose_id.py b/freshmaker/migrations/versions/b17231ee8220_remove_event_compose_id.py
index 1469cc4..e0f9695 100644
--- a/freshmaker/migrations/versions/b17231ee8220_remove_event_compose_id.py
+++ b/freshmaker/migrations/versions/b17231ee8220_remove_event_compose_id.py
@@ -14,7 +14,6 @@ import logging
 logger = logging.getLogger(__name__)
 
 from itertools import count
-from six import next
 import sqlalchemy as sa
 from alembic import op
 from sqlalchemy import text
diff --git a/freshmaker/odcsclient.py b/freshmaker/odcsclient.py
index 8d6380c..0e103a9 100644
--- a/freshmaker/odcsclient.py
+++ b/freshmaker/odcsclient.py
@@ -22,10 +22,10 @@
 # Written by Jan Kaluza <jkaluza@redhat.com>
 
 # We have name conflict between two modules here:
-#  - "odcs" module provided by python2-odcs-client
+#  - "odcs" module provided by python3-odcs-client
 #  - "odcs" submodule in freshmaker.handlers.odcs
 #
-# Unfortunatelly we want to use "odcs" provided by python2-odcs-client
+# Unfortunatelly we want to use "odcs" provided by python3-odcs-client
 # in freshmaker.handlers __init__.py. We cannot  "import odcs" there, because
 # it would import freshmaker.handlers.odcs, so instead, we import it here
 # and in freshmaker.handler do "from freshmaker.odcsclient import ODCS".
diff --git a/freshmaker/views.py b/freshmaker/views.py
index ab15db2..b1389de 100644
--- a/freshmaker/views.py
+++ b/freshmaker/views.py
@@ -22,7 +22,6 @@
 # Written by Jan Kaluza <jkaluza@redhat.com>
 
 import json
-import six
 from flask import request, jsonify
 from flask.views import MethodView
 from flask import g
@@ -158,7 +157,7 @@ api_v1 = {
 class EventTypeAPI(MethodView):
     def get(self, id):
         event_types = []
-        for cls, val in six.iteritems(models.EVENT_TYPES):
+        for cls, val in models.EVENT_TYPES.items():
             event_types.append({'name': cls.__name__, 'id': val})
 
         if id is None:
diff --git a/requirements.txt b/requirements.txt
index c4c9d56..5910e49 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,7 +1,6 @@
 fedmsg
 moksha.hub
 psutil
-funcsigs  # Python2 only
 httplib2
 kobo
 mock
@@ -9,16 +8,13 @@ munch
 pdc-client
 pyOpenSSL
 python-fedora
-six
 sqlalchemy
-futures  # Python 2 only
 Flask
 Flask-Migrate
 Flask-SQLAlchemy
 Flask-Script
 Flask-Login
 requests
-enum34 ; python_version <= '2.7'
 odcs[client]
 dogpile.cache
 pyldap
diff --git a/start_backend_from_here b/start_backend_from_here
index 0018c66..b73a179 100755
--- a/start_backend_from_here
+++ b/start_backend_from_here
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 __requires__ = 'fedmsg'
 import sys, os
 from pkg_resources import load_entry_point
diff --git a/tests/handlers/koji/test_rebuild_images_on_odcs_compose_done.py b/tests/handlers/koji/test_rebuild_images_on_odcs_compose_done.py
index 6fe57cd..63b056d 100644
--- a/tests/handlers/koji/test_rebuild_images_on_odcs_compose_done.py
+++ b/tests/handlers/koji/test_rebuild_images_on_odcs_compose_done.py
@@ -21,8 +21,6 @@
 #
 # Written by Chenxiong Qi <cqi@redhat.com>
 
-import six
-
 from mock import patch, PropertyMock
 
 from freshmaker import db
@@ -90,7 +88,7 @@ class TestRebuildImagesOnODCSComposeDone(helpers.ModelsTestCase):
         builds = [self.build_1, self.build_2, self.build_3,
                   self.build_4, self.build_5, self.build_6]
         composes = [self.compose_1] * 6
-        for build, compose in six.moves.zip(builds, composes):
+        for build, compose in zip(builds, composes):
             db.session.add(ArtifactBuildCompose(
                 build_id=build.id, compose_id=compose.id))
         db.session.commit()
diff --git a/tests/handlers/koji/test_rebuild_images_on_parent_image_build.py b/tests/handlers/koji/test_rebuild_images_on_parent_image_build.py
index d1d5b53..1f8e3a5 100644
--- a/tests/handlers/koji/test_rebuild_images_on_parent_image_build.py
+++ b/tests/handlers/koji/test_rebuild_images_on_parent_image_build.py
@@ -22,7 +22,6 @@
 import json
 import mock
 import os
-import six
 import sys
 import unittest
 
@@ -267,7 +266,7 @@ class TestRebuildImagesOnParentImageBuild(helpers.ModelsTestCase):
 
         self.handler.handle(event)
         self.assertEqual(build.state, ArtifactBuildState.FAILED.value)
-        six.assertRegex(self, build.state_reason, r"The following RPMs in container build.*")
+        self.assertRegex(build.state_reason, r"The following RPMs in container build.*")
 
     @mock.patch('freshmaker.handlers.ContainerBuildHandler.build_image_artifact_build')
     @mock.patch('freshmaker.handlers.ContainerBuildHandler.get_repo_urls')
diff --git a/tests/helpers.py b/tests/helpers.py
index 1a620cd..41944d6 100644
--- a/tests/helpers.py
+++ b/tests/helpers.py
@@ -18,14 +18,13 @@
 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 # SOFTWARE.
 
+import queue
 import random
-import six
 import string
 import time
 import uuid
 import unittest
 import koji
-from six.moves import queue
 
 from mock import patch, MagicMock
 from functools import wraps
@@ -343,7 +342,7 @@ class ModuleStateChangeMessage(FedMsgFactory):
         self.scmurl = "git://pkgs.fedoraproject.org/modules/%s?#%s" % (self.name, '123')
 
         self._states_dict = {}
-        for state, code in six.iteritems(BUILD_STATES):
+        for state, code in BUILD_STATES.items():
             self._states_dict[state] = {'state_name': state, 'state': code}
 
     @property
diff --git a/tests/test_image_verifier.py b/tests/test_image_verifier.py
index eb55fb9..6946308 100644
--- a/tests/test_image_verifier.py
+++ b/tests/test_image_verifier.py
@@ -21,7 +21,6 @@
 #
 # Written by Jan Kaluza <jkaluza@redhat.com>
 
-import six
 from mock import MagicMock
 
 from freshmaker.image_verifier import ImageVerifier
@@ -37,14 +36,14 @@ class TestImageVerifier(helpers.FreshmakerTestCase):
 
     def test_verify_repository_no_repo(self):
         self.lb.find_container_repositories.return_value = None
-        six.assertRaisesRegex(
-            self, ValueError, r'Cannot get repository.*',
+        self.assertRaisesRegex(
+            ValueError, r'Cannot get repository.*',
             self.verifier.verify_repository, "foo/bar")
 
     def test_get_verify_repository_multiple_repos(self):
         self.lb.find_container_repositories.return_value = ["foo", "bar"]
-        six.assertRaisesRegex(
-            self, ValueError, r'Multiple records found.*',
+        self.assertRaisesRegex(
+            ValueError, r'Multiple records found.*',
             self.verifier.verify_repository, "foo/bar")
 
     def test_verify_repository_deprecated(self):
@@ -52,8 +51,8 @@ class TestImageVerifier(helpers.FreshmakerTestCase):
             "release_categories": ["Deprecated"],
             "published": True,
             "auto_rebuild_tags": "latest"}]
-        six.assertRaisesRegex(
-            self, ValueError, r'.*but found \[\'Deprecated\'\].',
+        self.assertRaisesRegex(
+            ValueError, r'.*but found \[\'Deprecated\'\].',
             self.verifier.verify_repository, "foo/bar")
 
     def test_verify_repository_not_published(self):
@@ -61,8 +60,8 @@ class TestImageVerifier(helpers.FreshmakerTestCase):
             "release_categories": ["Generally Available"],
             "published": False,
             "auto_rebuild_tags": "latest"}]
-        six.assertRaisesRegex(
-            self, ValueError, r'.*is not published.',
+        self.assertRaisesRegex(
+            ValueError, r'.*is not published.',
             self.verifier.verify_repository, "foo/bar")
 
     def test_verify_repository_no_auto_rebuild_tags(self):
@@ -70,8 +69,8 @@ class TestImageVerifier(helpers.FreshmakerTestCase):
             "release_categories": ["Generally Available"],
             "published": True,
             "auto_rebuild_tags": []}]
-        six.assertRaisesRegex(
-            self, ValueError, r'.*this repository are disabled.',
+        self.assertRaisesRegex(
+            ValueError, r'.*this repository are disabled.',
             self.verifier.verify_repository, "foo/bar")
 
     def test_verify_repository_no_images(self):
@@ -81,8 +80,8 @@ class TestImageVerifier(helpers.FreshmakerTestCase):
             "published": True,
             "auto_rebuild_tags": ["latest"]}]
         self.lb.get_images_by_nvrs.return_value = []
-        six.assertRaisesRegex(
-            self, ValueError, r'No published images tagged by.*',
+        self.assertRaisesRegex(
+            ValueError, r'No published images tagged by.*',
             self.verifier.verify_repository, "foo/bar")
 
     def test_verify_repository_no_content_sets(self):
@@ -94,8 +93,8 @@ class TestImageVerifier(helpers.FreshmakerTestCase):
         self.lb.find_images_with_included_srpms.return_value = [{
             "brew": {"build": "foo-1-1"},
             "content_sets": []}]
-        six.assertRaisesRegex(
-            self, ValueError, r'.*are not set for this image.',
+        self.assertRaisesRegex(
+            ValueError, r'.*are not set for this image.',
             self.verifier.verify_repository, "foo/bar")
 
     def test_verify_repository(self):
@@ -124,14 +123,14 @@ class TestImageVerifier(helpers.FreshmakerTestCase):
 
     def test_get_verify_image_no_repo(self):
         self.lb.find_container_repositories.return_value = []
-        six.assertRaisesRegex(
-            self, ValueError, r'Cannot get repository.*',
+        self.assertRaisesRegex(
+            ValueError, r'Cannot get repository.*',
             self.verifier.verify_image, "foo/bar")
 
     def test_get_verify_image_multiple_repos(self):
         self.lb.find_container_repositories.return_value = ["foo", "bar"]
-        six.assertRaisesRegex(
-            self, ValueError, r'.*found in multiple repositories in Lightblue.',
+        self.assertRaisesRegex(
+            ValueError, r'.*found in multiple repositories in Lightblue.',
             self.verifier.verify_image, "foo/bar")
 
     def test_verify_image_no_images(self):
@@ -141,6 +140,6 @@ class TestImageVerifier(helpers.FreshmakerTestCase):
             "published": True,
             "auto_rebuild_tags": ["latest"]}]
         self.lb.get_images_by_nvrs.return_value = []
-        six.assertRaisesRegex(
-            self, ValueError, r'No published images tagged by.*',
+        self.assertRaisesRegex(
+            ValueError, r'No published images tagged by.*',
             self.verifier.verify_image, "foo/bar")
diff --git a/tests/test_lightblue.py b/tests/test_lightblue.py
index f669048..d6c16e4 100644
--- a/tests/test_lightblue.py
+++ b/tests/test_lightblue.py
@@ -21,10 +21,10 @@
 # SOFTWARE.
 
 import json
-import six
+import io
+import http.client
 
 from mock import call, patch, Mock
-from six.moves import http_client
 
 import freshmaker
 
@@ -60,14 +60,14 @@ class TestLightBlueRequestError(helpers.FreshmakerTestCase):
             'modifiedCount': 0,
             'status': 'ERROR'
         }
-        self.e = LightBlueRequestError(http_client.BAD_REQUEST,
+        self.e = LightBlueRequestError(http.client.BAD_REQUEST,
                                        self.fake_error_data)
 
     def test_get_raw_error_json_data(self):
         self.assertEqual(self.fake_error_data, self.e.raw)
 
     def test_get_status_code(self):
-        self.assertEqual(http_client.BAD_REQUEST, self.e.status_code)
+        self.assertEqual(http.client.BAD_REQUEST, self.e.status_code)
 
     def test_get_inner_errors(self):
         self.assertEqual(self.fake_error_data['errors'], self.e.raw['errors'])
@@ -83,7 +83,7 @@ class TestLightBlueSystemError(helpers.FreshmakerTestCase):
 
     def setUp(self):
         super(TestLightBlueSystemError, self).setUp()
-        buf = six.StringIO('''
+        buf = io.StringIO('''
 <html><head><title>JBWEB000065: HTTP Status 401 - JBWEB000009: No client
 certificate chain in this request</title><style><!--H1 {font-family:Tahoma,
 Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} H2
@@ -102,11 +102,11 @@ description</b> <u>JBWEB000121: This request requires HTTP authentication.</u>
 </p><HR size="1" noshade="noshade"></body></html>
 ''')
         self.fake_error_data = ' '.join((line.strip() for line in buf))
-        self.e = LightBlueSystemError(http_client.UNAUTHORIZED,
+        self.e = LightBlueSystemError(http.client.UNAUTHORIZED,
                                       self.fake_error_data)
 
     def test_get_status_code(self):
-        self.assertEqual(http_client.UNAUTHORIZED, self.e.status_code)
+        self.assertEqual(http.client.UNAUTHORIZED, self.e.status_code)
 
     def test_raw(self):
         self.assertEqual(self.fake_error_data, self.e.raw)
@@ -122,7 +122,7 @@ description</b> <u>JBWEB000121: This request requires HTTP authentication.</u>
             '"includes_multiple_content_streams in '
             'includes_multiple_content_streams"}]}')
         e = LightBlueSystemError(
-            http_client.BAD_REQUEST, content)
+            http.client.BAD_REQUEST, content)
         self.assertEqual(
             'metadata:InvalidFieldReference: includes_multiple_content_streams'
             ' in includes_multiple_content_streams\n', str(e))
@@ -800,7 +800,7 @@ class TestQueryEntityFromLightBlue(helpers.FreshmakerTestCase):
 
     @patch('freshmaker.lightblue.requests.post')
     def test_find_container_images(self, post):
-        post.return_value.status_code = http_client.OK
+        post.return_value.status_code = http.client.OK
         post.return_value.json.return_value = {
             'modifiedCount': 0,
             'resultMetadata': [],
@@ -862,7 +862,7 @@ class TestQueryEntityFromLightBlue(helpers.FreshmakerTestCase):
 
     @patch('freshmaker.lightblue.requests.post')
     def test_find_container_repositories(self, post):
-        post.return_value.status_code = http_client.OK
+        post.return_value.status_code = http.client.OK
         post.return_value.json.return_value = {
             'entity': 'containerRepository',
             'status': 'COMPLETE',
@@ -938,7 +938,7 @@ class TestQueryEntityFromLightBlue(helpers.FreshmakerTestCase):
 
     @patch('freshmaker.lightblue.requests.post')
     def test_raise_error_if_request_data_is_incorrect(self, post):
-        post.return_value.status_code = http_client.BAD_REQUEST
+        post.return_value.status_code = http.client.BAD_REQUEST
         post.return_value.json.return_value = {
             'entity': 'containerImage',
             'entityVersion': '0.0.11',
@@ -1609,7 +1609,7 @@ class TestQueryEntityFromLightBlue(helpers.FreshmakerTestCase):
 
         exists.return_value = True
         cont_repos.side_effect = LightBlueRequestError(
-            {"errors": [{"msg": "dummy error"}]}, http_client.REQUEST_TIMEOUT)
+            {"errors": [{"msg": "dummy error"}]}, http.client.REQUEST_TIMEOUT)
         cont_images.return_value = self.fake_images_with_parsed_data
 
         lb = LightBlue(server_url=self.fake_server_url,
@@ -1622,7 +1622,7 @@ class TestQueryEntityFromLightBlue(helpers.FreshmakerTestCase):
 
         cont_repos.return_value = self.fake_repositories_with_content_sets
         cont_images.side_effect = LightBlueRequestError(
-            {"errors": [{"msg": "dummy error"}]}, http_client.REQUEST_TIMEOUT)
+            {"errors": [{"msg": "dummy error"}]}, http.client.REQUEST_TIMEOUT)
 
         with self.assertRaises(LightBlueRequestError):
             lb.find_images_with_packages_from_content_set(
diff --git a/tests/test_messaging.py b/tests/test_messaging.py
index 233866c..5b8e8c5 100644
--- a/tests/test_messaging.py
+++ b/tests/test_messaging.py
@@ -21,7 +21,6 @@
 # Written by Chenxiong Qi <cqi@redhat.com>
 
 
-import six
 import unittest
 
 from mock import patch
@@ -83,8 +82,8 @@ class TestSelectMessagingBackend(BaseMessagingTest):
 
     def test_raise_error_if_backend_not_exists(self):
         messaging_patcher = patch.object(conf, 'messaging_sender', new='XXXX')
-        six.assertRaisesRegex(
-            self, ValueError, 'Unsupported messaging system',
+        self.assertRaisesRegex(
+            ValueError, 'Unsupported messaging system',
             messaging_patcher.start)
 
 
@@ -104,7 +103,6 @@ class TestPublishToFedmsg(BaseMessagingTest):
 
 
 @unittest.skipUnless(rhmsg, 'rhmsg is not available in Fedora yet.')
-@unittest.skipIf(six.PY3, 'rhmsg has no Python 3 package so far.')
 class TestPublishToRhmsg(BaseMessagingTest):
     """Test publish message to UMB using _rhmsg_publish backend"""
 
diff --git a/tests/test_monitor.py b/tests/test_monitor.py
index b1668ea..5d2f6c0 100644
--- a/tests/test_monitor.py
+++ b/tests/test_monitor.py
@@ -24,8 +24,8 @@ import mock
 import pytest
 import freshmaker
 import requests
+import importlib
 
-from six.moves import reload_module
 from freshmaker import app, db, events, models, login_manager
 from tests import helpers
 
@@ -122,7 +122,7 @@ def test_standalone_metrics_server_disabled_by_default():
 
 def test_standalone_metrics_server():
     os.environ['MONITOR_STANDALONE_METRICS_SERVER_ENABLE'] = 'true'
-    reload_module(freshmaker.monitor)
+    importlib.reload(freshmaker.monitor)
 
     r = requests.get('http://127.0.0.1:10040/metrics')
 
diff --git a/tests/test_odcsclient.py b/tests/test_odcsclient.py
index 12c5416..61817a8 100644
--- a/tests/test_odcsclient.py
+++ b/tests/test_odcsclient.py
@@ -22,8 +22,6 @@
 # Written by Chenxiong Qi <cqi@redhat.com>
 #            Jan kaluza <jkaluza@redhat.com>
 
-import six
-
 from mock import patch, Mock
 from odcs.client.odcs import AuthMech
 
@@ -63,8 +61,8 @@ class TestCreateODCSClient(helpers.FreshmakerTestCase):
 
     @patch.object(conf, 'odcs_auth_mech', new='fas')
     def test_error_if_unsupported_auth_configured(self):
-        six.assertRaisesRegex(
-            self, ValueError, r'.*fas is not supported yet.',
+        self.assertRaisesRegex(
+            ValueError, r'.*fas is not supported yet.',
             create_odcs_client)
 
     @patch.object(conf, 'odcs_auth_mech', new='openidc')
@@ -82,8 +80,8 @@ class TestCreateODCSClient(helpers.FreshmakerTestCase):
 
     @patch.object(conf, 'odcs_auth_mech', new='openidc')
     def test_error_if_missing_openidc_token(self):
-        six.assertRaisesRegex(
-            self, ValueError, r'Missing OpenIDC token.*',
+        self.assertRaisesRegex(
+            ValueError, r'Missing OpenIDC token.*',
             create_odcs_client)
 
 
diff --git a/tests/test_producer.py b/tests/test_producer.py
index 70fe56c..1d5118c 100644
--- a/tests/test_producer.py
+++ b/tests/test_producer.py
@@ -25,7 +25,7 @@
 import koji
 
 from mock import patch, MagicMock
-from six.moves import queue
+import queue
 
 from freshmaker import db
 from freshmaker.events import ErrataAdvisoryRPMsSignedEvent
diff --git a/tests/test_views.py b/tests/test_views.py
index 67a649d..b47abf2 100644
--- a/tests/test_views.py
+++ b/tests/test_views.py
@@ -22,7 +22,6 @@
 import unittest
 import json
 import datetime
-import six
 import contextlib
 import flask
 
@@ -474,7 +473,7 @@ class TestViews(helpers.ModelsTestCase):
         self.assertEqual(len(event_types), len(models.EVENT_TYPES))
 
     def test_query_event_type(self):
-        for cls, val in six.iteritems(models.EVENT_TYPES):
+        for cls, val in models.EVENT_TYPES.items():
             resp = self.client.get('/api/1/event-types/%s' % val)
             event = json.loads(resp.get_data(as_text=True))
             self.assertEqual(event['id'], val)
diff --git a/tox.ini b/tox.ini
index 3d71cab..2c0952d 100644
--- a/tox.ini
+++ b/tox.ini
@@ -4,7 +4,7 @@
 # and then run "tox" from this directory.
 
 [tox]
-envlist = py27, py35, flake8, bandit
+envlist = py35, flake8, bandit
 
 [testenv]
 skip_install = True

