diff --git a/weblate/formats/models.py b/weblate/formats/models.py index ade1aa37ec33..c1972a30aa02 100644 --- a/weblate/formats/models.py +++ b/weblate/formats/models.py @@ -19,7 +19,6 @@ # -import six from appconf import AppConf from django.utils.functional import cached_property @@ -50,7 +49,7 @@ def load_data(self): fileformat.get_class() except (AttributeError, ImportError) as error: result.pop(fileformat.format_id) - if fileformat.format_id != 'rc' or not six.PY3: + if fileformat.format_id != 'rc': self.errors[fileformat.format_id] = str(error) return result diff --git a/weblate/formats/tests/test_formats.py b/weblate/formats/tests/test_formats.py index 2e985ed03a3c..911ef23221a9 100644 --- a/weblate/formats/tests/test_formats.py +++ b/weblate/formats/tests/test_formats.py @@ -24,7 +24,6 @@ from io import BytesIO from unittest import SkipTest, TestCase -import six import translate.__version__ from django.utils.encoding import force_text from translate.storage.po import pofile @@ -561,8 +560,6 @@ class PoXliffFormatTest2(PoXliffFormatTest): FIND_MATCH = 'Ahoj světe!\n' def test_save(self, edit=False): - if six.PY2: - raise SkipTest('Known to be broken on Python 2') super(PoXliffFormatTest2, self).test_save(edit) diff --git a/weblate/formats/ttkit.py b/weblate/formats/ttkit.py index 48c2da6e42ab..1299e3aeed65 100644 --- a/weblate/formats/ttkit.py +++ b/weblate/formats/ttkit.py @@ -1174,9 +1174,7 @@ def extension(): @classmethod def get_class(cls): """Return class for handling this module.""" - if six.PY3: - raise ImportError('Windows RC file format unsupported on Python 3') - return importlib.import_module('translate.storage.rc').rcfile + raise ImportError('Windows RC file format unsupported on Python 3') class SubtitleUnit(MonolingualIDUnit): diff --git a/weblate/lang/tests.py b/weblate/lang/tests.py index edee87260cc2..2d441e40bb82 100644 --- a/weblate/lang/tests.py +++ b/weblate/lang/tests.py @@ -28,7 +28,7 @@ from django.urls import reverse from django.utils.encoding import force_text from django.utils.translation import activate -from six import PY2, StringIO, with_metaclass +from six import StringIO, with_metaclass from weblate.lang import data from weblate.lang.models import Language, Plural, get_plural_type @@ -228,10 +228,7 @@ def test_setuplang_noupdate(self): def check_list(self, **kwargs): output = StringIO() call_command('list_languages', 'cs', stdout=output, **kwargs) - if PY2: - self.assertIn(b'Czech', output.getvalue()) - else: - self.assertIn('Czech', output.getvalue()) + self.assertIn('Czech', output.getvalue()) def test_list_languages(self): self.check_list() diff --git a/weblate/machinery/saptranslationhub.py b/weblate/machinery/saptranslationhub.py index 68b10b51f997..4c938115b6ce 100644 --- a/weblate/machinery/saptranslationhub.py +++ b/weblate/machinery/saptranslationhub.py @@ -21,7 +21,6 @@ import base64 import json -import six from django.conf import settings from six.moves.urllib.request import Request, urlopen @@ -90,9 +89,7 @@ def download_translations(self, source, language, text, unit, user): # create the request translation_url = settings.MT_SAP_BASE_URL + 'translate' - request = Request( - translation_url if six.PY3 else translation_url.encode("utf-8") - ) + request = Request(translation_url) request.add_header('User-Agent', USER_AGENT.encode('utf-8')) request.add_header('Referer', get_site_url().encode('utf-8')) request.add_header('Content-Type', 'application/json; charset=utf-8') diff --git a/weblate/trans/tests/test_selenium.py b/weblate/trans/tests/test_selenium.py index 6a709a721171..bd4300cf84ac 100644 --- a/weblate/trans/tests/test_selenium.py +++ b/weblate/trans/tests/test_selenium.py @@ -25,7 +25,7 @@ from contextlib import contextmanager from datetime import timedelta from io import BytesIO -from unittest import SkipTest, skipIf +from unittest import SkipTest import six import social_django.utils @@ -1048,7 +1048,6 @@ def test_fonts(self): self.screenshot("font-group-list.png") - @skipIf(six.PY2, "borgbackup does not support Python 2") def test_backup(self): self.create_temp() try: diff --git a/weblate/trans/util.py b/weblate/trans/util.py index 7fe5f348fe99..6f815e0261e8 100644 --- a/weblate/trans/util.py +++ b/weblate/trans/util.py @@ -23,7 +23,6 @@ import os import sys -import six from django.apps import apps from django.core.cache import cache from django.db.utils import OperationalError, ProgrammingError @@ -204,10 +203,6 @@ def get_clean_env(extra=None): venv_path = os.path.join(sys.exec_prefix, "bin") if venv_path not in environ['PATH']: environ['PATH'] = '{}:{}'.format(venv_path, environ['PATH']) - # Python 2 on Windows doesn't handle Unicode objects in environment - # even if they can be converted to ASCII string, let's fix it here - if six.PY2 and sys.platform == 'win32': - return {str(key): str(val) for key, val in environ.items()} return environ @@ -270,8 +265,6 @@ def path_separator(path): def sort_unicode(choices, key): """Unicode aware sorting if available.""" - if six.PY2: - return sorted(choices, key=lambda tup: locale.strxfrm(key(tup).encode('utf-8'))) return sorted(choices, key=lambda tup: locale.strxfrm(key(tup))) diff --git a/weblate/trans/views/api.py b/weblate/trans/views/api.py index 5a3356d08f3b..99c4226f584d 100644 --- a/weblate/trans/views/api.py +++ b/weblate/trans/views/api.py @@ -21,7 +21,6 @@ import csv -import six from django.http import HttpResponse, JsonResponse from weblate.trans.stats import get_project_stats @@ -92,14 +91,7 @@ def export_response(request, filename, fields, data): writer = csv.DictWriter(response, fields) writer.writeheader() - if six.PY2: - for row in data: - for item in row: - if isinstance(row[item], six.text_type): - row[item] = row[item].encode('utf-8') - writer.writerow(row) - else: - for row in data: - writer.writerow(row) + for row in data: + writer.writerow(row) return response return JsonResponse(data=data, safe=False, json_dumps_params={'indent': 2}) diff --git a/weblate/trans/views/changes.py b/weblate/trans/views/changes.py index 72d952b49be8..1fe698350a87 100644 --- a/weblate/trans/views/changes.py +++ b/weblate/trans/views/changes.py @@ -18,7 +18,8 @@ # along with this program. If not, see . # -import six +import csv + from django.contrib.auth.decorators import login_required from django.core.exceptions import PermissionDenied from django.db.models import Q @@ -39,11 +40,6 @@ from weblate.utils.site import get_site_url from weblate.utils.views import get_project_translation -if six.PY2: - from backports import csv -else: - import csv - class ChangesView(ListView): """Browser for changes.""" diff --git a/weblate/utils/apps.py b/weblate/utils/apps.py index 467348656cf7..e3c1dc1b1184 100644 --- a/weblate/utils/apps.py +++ b/weblate/utils/apps.py @@ -29,7 +29,6 @@ check_errors, check_mail_connection, check_perms, - check_python, check_settings, check_site, check_templates, @@ -56,7 +55,6 @@ def ready(self): register(check_site, deploy=True) register(check_perms, deploy=True) register(check_errors, deploy=True) - register(check_python, deploy=True) register(check_version) monkey_patch_translate() diff --git a/weblate/utils/checks.py b/weblate/utils/checks.py index 40ac09e86cae..76976bdd4ad7 100644 --- a/weblate/utils/checks.py +++ b/weblate/utils/checks.py @@ -346,18 +346,3 @@ def check_errors(app_configs=None, **kwargs): id='weblate.I021', ) ] - - -def check_python(app_configs=None, **kwargs): - """Early warning for users needing to migrate to Python 3.""" - if six.PY3: - return [] - return [ - Error( - 'Please upgrade your installation to Python 3. ' - 'Python 2 support will be dropped in Weblate 4.0 ' - 'currently sheduled on April 2020.', - hint=get_doc_url('admin/upgrade', 'py3'), - id='weblate.W023', - ) - ] diff --git a/weblate/utils/requirements.py b/weblate/utils/requirements.py index e45315f91d59..79d201062225 100644 --- a/weblate/utils/requirements.py +++ b/weblate/utils/requirements.py @@ -23,7 +23,6 @@ import sys import pkg_resources -import six from django.core.exceptions import ImproperlyConfigured import weblate @@ -73,9 +72,8 @@ "Cython", "misaka", "GitPython", + "borgbackup", ] -if six.PY3: - REQUIRES.append("borgbackup") OPTIONAL = [ "psycopg2", diff --git a/weblate/utils/tests/test_backup.py b/weblate/utils/tests/test_backup.py index 8a86c11e5548..6c4032d0f7f3 100644 --- a/weblate/utils/tests/test_backup.py +++ b/weblate/utils/tests/test_backup.py @@ -20,9 +20,7 @@ import json import os -from unittest import skipIf -import six from django.conf import settings from django.test import SimpleTestCase from django.test.utils import override_settings @@ -36,7 +34,6 @@ class BackupTest(SimpleTestCase): @tempdir_setting("DATA_DIR") - @skipIf(six.PY2, 'override_settings seems to be broken on Python 2') def test_settings_backup(self): settings_backup() filename = data_dir("backups", "settings.py") @@ -53,7 +50,6 @@ def test_memory_backup(self): @tempdir_setting("DATA_DIR") @tempdir_setting("BACKUP_DIR") - @skipIf(six.PY2, 'borgbackup does not support Python 2') def test_backup(self): initialize(settings.BACKUP_DIR, "key") output = get_paper_key(settings.BACKUP_DIR) diff --git a/weblate/utils/tests/test_search.py b/weblate/utils/tests/test_search.py index 48f21343399e..ad876754a874 100644 --- a/weblate/utils/tests/test_search.py +++ b/weblate/utils/tests/test_search.py @@ -20,9 +20,7 @@ from datetime import datetime -from unittest import SkipTest -import six from django.db.models import Q from django.test import SimpleTestCase, TestCase from pytz import utc @@ -51,10 +49,6 @@ def test_long(self): class QueryParserTest(TestCase): - def setUp(self): - if six.PY2: - raise SkipTest("Test not working on Python 2") - def assert_query(self, string, expected): result = parse_query(string) self.assertEqual(result, expected) diff --git a/weblate/vcs/base.py b/weblate/vcs/base.py index c88fea2c0317..e303d6512543 100644 --- a/weblate/vcs/base.py +++ b/weblate/vcs/base.py @@ -27,7 +27,6 @@ import subprocess from distutils.version import LooseVersion -import six from dateutil import parser from django.conf import settings from django.core.cache import cache @@ -150,8 +149,6 @@ def _popen( if not fullcmd: args = [cls._cmd] + list(args) text_cmd = ' '.join(args) - if six.PY2: - args = [arg.encode('utf-8') for arg in args] process = subprocess.Popen( args, cwd=cwd, diff --git a/weblate/vcs/mercurial.py b/weblate/vcs/mercurial.py index eb5f7c4e6c0d..70f643b7f96e 100644 --- a/weblate/vcs/mercurial.py +++ b/weblate/vcs/mercurial.py @@ -24,7 +24,6 @@ import os.path import re -import six from six.moves.configparser import RawConfigParser from weblate.vcs.base import Repository, RepositoryException @@ -85,8 +84,6 @@ def get_config(self, path): config.read(filename) if config.has_option(section, option): result = config.get(section, option) - if six.PY2: - result = result.decode('utf-8') return result def set_config(self, path, value): @@ -95,10 +92,6 @@ def set_config(self, path, value): raise RuntimeError('Repository operation without lock held!') section, option = path.split('.', 1) filename = os.path.join(self.path, '.hg', 'hgrc') - if six.PY2: - value = value.encode('utf-8') - section = section.encode('utf-8') - option = option.encode('utf-8') config = RawConfigParser() config.read(filename) if not config.has_section(section): diff --git a/weblate/wladmin/tests.py b/weblate/wladmin/tests.py index fa1f145a6b4d..3a286ee5fec9 100644 --- a/weblate/wladmin/tests.py +++ b/weblate/wladmin/tests.py @@ -20,11 +20,9 @@ import json import os -from unittest import skipIf import django import httpretty -import six from django.conf import settings from django.core.serializers.json import DjangoJSONEncoder from django.test.utils import override_settings @@ -96,7 +94,6 @@ def test_ssh_add(self): self.assertIn("github.com", handle.read()) @tempdir_setting("BACKUP_DIR") - @skipIf(six.PY2, "borgbackup does not support Python 2") def test_backup(self): def do_post(**payload): return self.client.post(reverse("manage-backups"), payload, follow=True)