diff --git a/.travis.yml b/.travis.yml index 9896b753c..fbfb621d2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -43,7 +43,7 @@ before_script: script: - python ./tests.py - cd test_project - - coverage run --source ../modoboa manage.py test modoboa.core modoboa.admin modoboa.limits modoboa.relaydomains + - coverage run --source ../modoboa manage.py test modoboa.core modoboa.lib modoboa.admin modoboa.limits modoboa.relaydomains after_success: - codecov diff --git a/modoboa/core/commands/__init__.py b/modoboa/core/commands/__init__.py index a45b85a9d..f21b36fa7 100644 --- a/modoboa/core/commands/__init__.py +++ b/modoboa/core/commands/__init__.py @@ -8,7 +8,7 @@ import sys from django.conf import settings from django.template import Context, Template -from django.utils import six +from django.utils.encoding import smart_str class Command(object): @@ -66,12 +66,8 @@ def scan_for_commands(dirname=""): if os.path.isfile(f): continue cmdname = f.replace(".py", "") - if six.PY2: - fromlist = [cmdname.encode()] - else: - fromlist = [cmdname] cmdmod = __import__("modoboa.core.commands", globals(), locals(), - fromlist) + [smart_str(cmdname)]) cmdmod = getattr(cmdmod, cmdname) if "_" in cmdname: cmdclassname = "".join( diff --git a/modoboa/core/commands/deploy.py b/modoboa/core/commands/deploy.py index 6f07ef462..5a21e4fbf 100644 --- a/modoboa/core/commands/deploy.py +++ b/modoboa/core/commands/deploy.py @@ -21,7 +21,7 @@ except ImportError: import django from django.core import management from django.template import Context, Template -from django.utils import six +from django.utils.encoding import smart_str import dj_database_url from modoboa.core.commands import Command @@ -232,11 +232,9 @@ class DeployCommand(Command): os.path.join(os.path.dirname(__file__), "../../bower_components") ) - if six.PY2: - fromlist = ['settings'.encode()] - else: - fromlist = ['settings'] - mod = __import__(parsed_args.name, globals(), locals(), fromlist) + mod = __import__( + parsed_args.name, globals(), locals(), [smart_str('settings')] + ) tpl = self._render_template( "%s/settings.py.tpl" % self._templates_dir, { 'db_connections': connections, diff --git a/modoboa/core/extensions.py b/modoboa/core/extensions.py index 5b4732204..a6ea04909 100644 --- a/modoboa/core/extensions.py +++ b/modoboa/core/extensions.py @@ -4,7 +4,7 @@ from __future__ import unicode_literals from django.conf import settings from django.conf.urls import include, url -from django.utils import six +from django.utils.encoding import smart_str class ModoExtension(object): @@ -79,11 +79,7 @@ class ExtensionsPool(object): def load_extension(self, name): """Load a registered extension.""" - if six.PY2: - fromlist = ["modo_extension".encode()] - else: - fromlist = ["modo_extension"] - __import__(name, locals(), globals(), fromlist) + __import__(name, locals(), globals(), [smart_str('modo_extension')]) extinstance = self.get_extension(name) if extinstance is None: return None @@ -137,4 +133,5 @@ class ExtensionsPool(object): result += [infos] return sorted(result, key=lambda i: i["name"]) + exts_pool = ExtensionsPool() diff --git a/modoboa/core/views/user.py b/modoboa/core/views/user.py index dd01f270b..91acaff35 100644 --- a/modoboa/core/views/user.py +++ b/modoboa/core/views/user.py @@ -6,6 +6,7 @@ from django.shortcuts import render from django.template.loader import render_to_string from django.utils import translation from django.utils.translation import ugettext as _ +from django.utils.encoding import force_text from django.contrib.auth.decorators import login_required, user_passes_test @@ -41,8 +42,9 @@ def profile(request, tplname='core/user_profile.html'): if form.is_valid(): form.save() if update_password and form.cleaned_data["confirmation"] != "": - request.session["password"] = encrypt( - form.cleaned_data["confirmation"]) + request.session["password"] = force_text(encrypt( + form.cleaned_data["confirmation"] + )) translation.activate(request.user.language) request.session[translation.LANGUAGE_SESSION_KEY] = ( request.user.language) diff --git a/modoboa/lib/cryptutils.py b/modoboa/lib/cryptutils.py index 16e8a82ca..717ef7f73 100644 --- a/modoboa/lib/cryptutils.py +++ b/modoboa/lib/cryptutils.py @@ -7,6 +7,8 @@ import base64 import random import string +from django.utils.encoding import force_bytes + from Crypto.Cipher import AES from modoboa.parameters import tools as param_tools @@ -32,7 +34,9 @@ def encrypt(clear): if type(clear) is str: clear = clear.encode("utf-8") if len(clear) % AES.block_size: - clear += " " * (AES.block_size - len(clear) % AES.block_size) + clear += ( + force_bytes(" ") * (AES.block_size - len(clear) % AES.block_size) + ) ciph = obj.encrypt(clear) ciph = base64.b64encode(ciph) return ciph diff --git a/modoboa/lib/form_utils.py b/modoboa/lib/form_utils.py index 31b6dc421..e2b7144b1 100644 --- a/modoboa/lib/form_utils.py +++ b/modoboa/lib/form_utils.py @@ -13,8 +13,7 @@ from django.forms.fields import Field from django.forms.widgets import RadioSelect from django.forms.widgets import RadioChoiceInput from django.shortcuts import render -from django.utils import six -from django.utils.encoding import force_text +from django.utils.encoding import force_text, force_str from django.utils.html import conditional_escape from django.utils.safestring import mark_safe from django.utils.translation import ugettext as _, ugettext_lazy @@ -22,11 +21,8 @@ from django.utils.translation import ugettext as _, ugettext_lazy from modoboa.lib.exceptions import BadRequest from modoboa.lib.web_utils import render_to_json_response -if six.PY2: - meta_name = b"ABC" -else: - meta_name = "ABC" -ABC = abc.ABCMeta(meta_name, (object,), {}) # compatible with Python 2 *and* 3 + +ABC = abc.ABCMeta(force_str('ABC'), (object,), {}) class WizardStep(object): diff --git a/modoboa/lib/ldap_utils.py b/modoboa/lib/ldap_utils.py index 6ec1316fe..2952f0198 100644 --- a/modoboa/lib/ldap_utils.py +++ b/modoboa/lib/ldap_utils.py @@ -39,7 +39,7 @@ import ldap from django.conf import settings from django.utils.translation import ugettext as _ -from django.utils.encoding import smart_bytes +from django.utils.encoding import force_bytes from modoboa.core.password_hashers import get_password_hasher from modoboa.lib.exceptions import InternalError @@ -69,7 +69,7 @@ class LDAPAuthBackend(object): def _get_conn(self, dn, password): """Get a connection from the server.""" - conn = ldap.initialize(self.server_uri) + conn = ldap.initialize(self.server_uri, bytes_mode=False) conn.set_option(ldap.OPT_X_TLS_DEMAND, True) conn.set_option(ldap.OPT_DEBUG_LEVEL, 255) conn.simple_bind_s(dn, password) @@ -120,8 +120,8 @@ class LDAPAuthBackend(object): ('"%s"' % newpassword).encode('utf-16').lstrip('\377\376') ) ldif = [(ldap.MOD_REPLACE, - smart_bytes(self.pwd_attr), - smart_bytes(self._crypt_password(newpassword)))] + self.pwd_attr, + force_bytes(self._crypt_password(newpassword)))] try: self.conn.modify_s(user_dn, ldif) except ldap.LDAPError as e: diff --git a/modoboa/limits/tests/test_api.py b/modoboa/limits/tests/test_api.py index b13a2246f..d671c0c2c 100644 --- a/modoboa/limits/tests/test_api.py +++ b/modoboa/limits/tests/test_api.py @@ -103,7 +103,9 @@ class APIAdminLimitsTestCase(lib_tests.ModoAPITestCase): data["name"] = "test5.com" response = self.client.post(url, data, format="json") self.assertEqual(response.status_code, 403) - self.assertEqual(response.content, '"Domains: limit reached"') + self.assertEqual( + response.content.decode('utf-8'), '"Domains: limit reached"' + ) self.client.delete( reverse("api:domain-detail", diff --git a/modoboa/relaydomains/tests.py b/modoboa/relaydomains/tests.py index 957a165c1..fe773212f 100644 --- a/modoboa/relaydomains/tests.py +++ b/modoboa/relaydomains/tests.py @@ -2,8 +2,6 @@ from __future__ import unicode_literals -import json - from django.core.files.base import ContentFile from django.core.urlresolvers import reverse from django.test import TestCase @@ -88,7 +86,7 @@ class RelayDomainsTestCase(ModoTestCase, Operations): url = reverse("admin:_domain_list") response = self.client.get(url) self.assertEqual(response.status_code, 200) - content = json.loads(response.content) + content = response.json() self.assertIn("relaydomain.tld", content["rows"]) self.assertIn("Relay Domain", content["rows"]) diff --git a/tox.ini b/tox.ini index 370af28f5..6d4ef5c08 100644 --- a/tox.ini +++ b/tox.ini @@ -5,7 +5,7 @@ envlist = py27,py34 changedir=test_project commands = python ../tests.py - coverage run --source modoboa manage.py test modoboa.core modoboa.lib modoboa.admin.tests modoboa.limits modoboa.relaydomains + coverage run --source modoboa manage.py test modoboa.core modoboa.lib modoboa.admin modoboa.limits modoboa.relaydomains coverage report --show-missing deps = -r{toxinidir}/test-requirements.txt