Remove all usage of 'six' and as much compat code as I could f… (#11730)

* Remove all usage of 'six' and as much compat code as I could find.

Cleans up some imports along the way.

Fixes #11728

* Fix typo

* Fix rta related code paths, I actually misread the comment…

* Move ResourceWarning filtering to setup.cfg
This commit is contained in:
Christopher Grebs 2019-07-16 12:01:31 +02:00 коммит произвёл GitHub
Родитель 17d4886b14
Коммит 2de22598bd
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
148 изменённых файлов: 562 добавлений и 912 удалений

Просмотреть файл

@ -10,7 +10,6 @@ import warnings
import pytest import pytest
import responses import responses
import six
@pytest.fixture(autouse=True) @pytest.fixture(autouse=True)
@ -138,11 +137,6 @@ def test_pre_setup(request, tmpdir, settings):
from waffle.utils import get_cache as waffle_get_cache from waffle.utils import get_cache as waffle_get_cache
from waffle import models as waffle_models from waffle import models as waffle_models
# Ignore ResourceWarning for now. It's a Python 3 thing so it's done
# dynamically here.
if six.PY3:
warnings.filterwarnings('ignore', category=ResourceWarning) # noqa
# Clear all cache-instances. They'll be re-initialized by Django # Clear all cache-instances. They'll be re-initialized by Django
# This will make sure that our random `KEY_PREFIX` is applied # This will make sure that our random `KEY_PREFIX` is applied
# appropriately. # appropriately.

Просмотреть файл

@ -3,7 +3,7 @@ Turn :src:`file.py` into a link to `file.py` in your online source browser.
Requires src_base_url to be set in conf.py. Requires src_base_url to be set in conf.py.
""" """
from six.moves.urllib_parse import urljoin from urllib.parse import urljoin
from docutils import nodes from docutils import nodes

Просмотреть файл

@ -3,7 +3,7 @@ import sys
from django.utils.encoding import force_bytes from django.utils.encoding import force_bytes
from email.utils import formatdate from email.utils import formatdate
from six.moves.urllib.parse import parse_qsl from urllib.parse import parse_qsl
from time import time from time import time
from services.utils import ( from services.utils import (

Просмотреть файл

@ -8,7 +8,7 @@ import sys
import MySQLdb as mysql import MySQLdb as mysql
import sqlalchemy.pool as pool import sqlalchemy.pool as pool
from six.moves.urllib.parse import urlencode from urllib.parse import urlencode
from services.settings import settings from services.settings import settings

Просмотреть файл

@ -5,7 +5,7 @@ won't be tracked in git).
""" """
import os import os
from six.moves.urllib_parse import urlparse from urllib.parse import urlparse
from olympia.lib.settings_base import * # noqa from olympia.lib.settings_base import * # noqa

Просмотреть файл

@ -17,6 +17,8 @@ DJANGO_SETTINGS_MODULE = settings_test
filterwarnings = filterwarnings =
default default
ignore:::csp.utils ignore:::csp.utils
# Ignore ResourceWarning for now. It's a Python 3 thing :-/
ignore::ResourceWarning
[flake8] [flake8]
ignore = F999,F405,W504 ignore = F999,F405,W504

Просмотреть файл

@ -4,9 +4,6 @@ from django.contrib.gis.geoip2 import GeoIP2, GeoIP2Exception
from django.core.validators import validate_ipv46_address from django.core.validators import validate_ipv46_address
from django.db import models from django.db import models
from django.utils import translation from django.utils import translation
from django.utils.encoding import python_2_unicode_compatible
import six
from extended_choices import Choices from extended_choices import Choices
from geoip2.errors import GeoIP2Error from geoip2.errors import GeoIP2Error
@ -34,7 +31,6 @@ class AbuseReportManager(ManagerBase):
return qs return qs
@python_2_unicode_compatible
class AbuseReport(ModelBase): class AbuseReport(ModelBase):
# Note: those choices don't need to be translated for now, the # Note: those choices don't need to be translated for now, the
# human-readable values are only exposed in the admin. # human-readable values are only exposed in the admin.
@ -188,8 +184,7 @@ class AbuseReport(ModelBase):
) )
msg = '%s reported abuse for %s (%s).\n\n%s\n\n%s' % ( msg = '%s reported abuse for %s (%s).\n\n%s\n\n%s' % (
user_name, target_name, target_url, metadata, self.message) user_name, target_name, target_url, metadata, self.message)
send_mail( send_mail(str(self), msg, recipient_list=(settings.ABUSE_EMAIL,))
six.text_type(self), msg, recipient_list=(settings.ABUSE_EMAIL,))
@property @property
def metadata(self): def metadata(self):

Просмотреть файл

@ -1,5 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from datetime import date, datetime from datetime import date, datetime
from urllib.parse import parse_qsl, urlparse
from django.conf import settings from django.conf import settings
from django.contrib import admin from django.contrib import admin
@ -9,7 +10,6 @@ from django.test import RequestFactory
from django.urls import reverse from django.urls import reverse
from pyquery import PyQuery as pq from pyquery import PyQuery as pq
from six.moves.urllib_parse import parse_qsl, urlparse
from olympia import amo from olympia import amo
from olympia.abuse.admin import AbuseReportAdmin from olympia.abuse.admin import AbuseReportAdmin

Просмотреть файл

@ -1,10 +1,9 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from unittest import mock
from django.conf import settings from django.conf import settings
from django.core import mail from django.core import mail
from unittest import mock
import six
from olympia.abuse.models import AbuseReport, GeoIP2Error, GeoIP2Exception from olympia.abuse.models import AbuseReport, GeoIP2Error, GeoIP2Exception
from olympia.addons.models import Addon from olympia.addons.models import Addon
from olympia.amo.tests import addon_factory, TestCase from olympia.amo.tests import addon_factory, TestCase
@ -123,9 +122,7 @@ class TestAbuse(TestCase):
user = UserProfile.objects.get(pk=999) user = UserProfile.objects.get(pk=999)
report = AbuseReport.objects.create(user=user) report = AbuseReport.objects.create(user=user)
report.send() report.send()
assert ( assert str(report) == u'[User] Abuse Report for regularuser التطب'
six.text_type(report) ==
u'[User] Abuse Report for regularuser التطب')
assert ( assert (
mail.outbox[0].subject == mail.outbox[0].subject ==
u'[User] Abuse Report for regularuser التطب') u'[User] Abuse Report for regularuser التطب')
@ -137,7 +134,7 @@ class TestAbuse(TestCase):
addon = Addon.objects.get(pk=3615) addon = Addon.objects.get(pk=3615)
report = AbuseReport.objects.create(addon=addon) report = AbuseReport.objects.create(addon=addon)
assert ( assert (
six.text_type(report) == str(report) ==
u'[Extension] Abuse Report for Delicious Bookmarks') u'[Extension] Abuse Report for Delicious Bookmarks')
report.send() report.send()
assert ( assert (
@ -184,7 +181,7 @@ reason => Damages computer and/or data
with self.activate(locale='fr'): with self.activate(locale='fr'):
report = AbuseReport(addon_id=3615) report = AbuseReport(addon_id=3615)
assert ( assert (
six.text_type(report) == str(report) ==
u'[Extension] Abuse Report for Delicious Bookmarks') u'[Extension] Abuse Report for Delicious Bookmarks')
report.send() report.send()
assert ( assert (
@ -194,9 +191,7 @@ reason => Damages computer and/or data
def test_guid(self): def test_guid(self):
report = AbuseReport.objects.create(guid='foo@bar.org') report = AbuseReport.objects.create(guid='foo@bar.org')
report.send() report.send()
assert ( assert str(report) == u'[Addon] Abuse Report for foo@bar.org'
six.text_type(report) ==
u'[Addon] Abuse Report for foo@bar.org')
assert ( assert (
mail.outbox[0].subject == mail.outbox[0].subject ==
u'[Addon] Abuse Report for foo@bar.org') u'[Addon] Abuse Report for foo@bar.org')

Просмотреть файл

@ -5,7 +5,6 @@ from datetime import datetime
from django.core import mail from django.core import mail
from unittest import mock from unittest import mock
import six
from olympia import amo from olympia import amo
from olympia.abuse.models import AbuseReport from olympia.abuse.models import AbuseReport
@ -27,7 +26,7 @@ class AddonAbuseViewSetTestBase(object):
raise NotImplementedError raise NotImplementedError
def check_report(self, report, text): def check_report(self, report, text):
assert six.text_type(report) == text assert str(report) == text
assert report.country_code == 'ZZ' assert report.country_code == 'ZZ'
assert mail.outbox[0].subject == text assert mail.outbox[0].subject == text
self.check_reporter(report) self.check_reporter(report)
@ -36,7 +35,7 @@ class AddonAbuseViewSetTestBase(object):
addon = addon_factory() addon = addon_factory()
response = self.client.post( response = self.client.post(
self.url, self.url,
data={'addon': six.text_type(addon.id), 'message': 'abuse!'}, data={'addon': str(addon.id), 'message': 'abuse!'},
REMOTE_ADDR='123.45.67.89') REMOTE_ADDR='123.45.67.89')
assert response.status_code == 201 assert response.status_code == 201
@ -101,7 +100,7 @@ class AddonAbuseViewSetTestBase(object):
addon = addon_factory(status=amo.STATUS_NULL) addon = addon_factory(status=amo.STATUS_NULL)
response = self.client.post( response = self.client.post(
self.url, self.url,
data={'addon': six.text_type(addon.id), 'message': 'abuse!'}, data={'addon': str(addon.id), 'message': 'abuse!'},
REMOTE_ADDR='123.45.67.89') REMOTE_ADDR='123.45.67.89')
assert response.status_code == 201 assert response.status_code == 201
@ -123,7 +122,7 @@ class AddonAbuseViewSetTestBase(object):
addon = addon_factory() addon = addon_factory()
response = self.client.post( response = self.client.post(
self.url, self.url,
data={'addon': six.text_type(addon.id), data={'addon': str(addon.id),
'message': ''}) 'message': ''})
assert response.status_code == 400 assert response.status_code == 400
assert json.loads(response.content) == { assert json.loads(response.content) == {
@ -133,7 +132,7 @@ class AddonAbuseViewSetTestBase(object):
addon = addon_factory() addon = addon_factory()
response = self.client.post( response = self.client.post(
self.url, self.url,
data={'addon': six.text_type(addon.id)}) data={'addon': str(addon.id)})
assert response.status_code == 400 assert response.status_code == 400
assert json.loads(response.content) == { assert json.loads(response.content) == {
'message': ['This field is required.']} 'message': ['This field is required.']}
@ -142,7 +141,7 @@ class AddonAbuseViewSetTestBase(object):
addon = addon_factory() addon = addon_factory()
response = self.client.post( response = self.client.post(
self.url, self.url,
data={'addon': six.text_type(addon.id), 'reason': 'broken'}, data={'addon': str(addon.id), 'reason': 'broken'},
REMOTE_ADDR='123.45.67.89') REMOTE_ADDR='123.45.67.89')
assert response.status_code == 201 assert response.status_code == 201
@ -156,7 +155,7 @@ class AddonAbuseViewSetTestBase(object):
addon = addon_factory() addon = addon_factory()
response = self.client.post( response = self.client.post(
self.url, self.url,
data={'addon': six.text_type(addon.id), 'reason': 'broken', data={'addon': str(addon.id), 'reason': 'broken',
'message': ''}, 'message': ''},
REMOTE_ADDR='123.45.67.89') REMOTE_ADDR='123.45.67.89')
assert response.status_code == 201 assert response.status_code == 201
@ -172,13 +171,13 @@ class AddonAbuseViewSetTestBase(object):
for x in range(20): for x in range(20):
response = self.client.post( response = self.client.post(
self.url, self.url,
data={'addon': six.text_type(addon.id), 'message': 'abuse!'}, data={'addon': str(addon.id), 'message': 'abuse!'},
REMOTE_ADDR='123.45.67.89') REMOTE_ADDR='123.45.67.89')
assert response.status_code == 201, x assert response.status_code == 201, x
response = self.client.post( response = self.client.post(
self.url, self.url,
data={'addon': six.text_type(addon.id), 'message': 'abuse!'}, data={'addon': str(addon.id), 'message': 'abuse!'},
REMOTE_ADDR='123.45.67.89') REMOTE_ADDR='123.45.67.89')
assert response.status_code == 429 assert response.status_code == 429
@ -306,7 +305,7 @@ class UserAbuseViewSetTestBase(object):
raise NotImplementedError raise NotImplementedError
def check_report(self, report, text): def check_report(self, report, text):
assert six.text_type(report) == text assert str(report) == text
assert report.country_code == 'ZZ' assert report.country_code == 'ZZ'
assert mail.outbox[0].subject == text assert mail.outbox[0].subject == text
self.check_reporter(report) self.check_reporter(report)
@ -315,7 +314,7 @@ class UserAbuseViewSetTestBase(object):
user = user_factory() user = user_factory()
response = self.client.post( response = self.client.post(
self.url, self.url,
data={'user': six.text_type(user.id), 'message': 'abuse!'}, data={'user': str(user.id), 'message': 'abuse!'},
REMOTE_ADDR='123.45.67.89') REMOTE_ADDR='123.45.67.89')
assert response.status_code == 201 assert response.status_code == 201
@ -328,7 +327,7 @@ class UserAbuseViewSetTestBase(object):
user = user_factory() user = user_factory()
response = self.client.post( response = self.client.post(
self.url, self.url,
data={'user': six.text_type(user.username), 'message': 'abuse!'}, data={'user': str(user.username), 'message': 'abuse!'},
REMOTE_ADDR='123.45.67.89') REMOTE_ADDR='123.45.67.89')
assert response.status_code == 201 assert response.status_code == 201
@ -349,7 +348,7 @@ class UserAbuseViewSetTestBase(object):
user = user_factory() user = user_factory()
response = self.client.post( response = self.client.post(
self.url, self.url,
data={'user': six.text_type(user.username), 'message': ''}) data={'user': str(user.username), 'message': ''})
assert response.status_code == 400 assert response.status_code == 400
assert json.loads(response.content) == { assert json.loads(response.content) == {
'message': ['This field may not be blank.']} 'message': ['This field may not be blank.']}
@ -358,7 +357,7 @@ class UserAbuseViewSetTestBase(object):
user = user_factory() user = user_factory()
response = self.client.post( response = self.client.post(
self.url, self.url,
data={'user': six.text_type(user.username)}) data={'user': str(user.username)})
assert response.status_code == 400 assert response.status_code == 400
assert json.loads(response.content) == { assert json.loads(response.content) == {
'message': ['This field is required.']} 'message': ['This field is required.']}
@ -368,14 +367,14 @@ class UserAbuseViewSetTestBase(object):
for x in range(20): for x in range(20):
response = self.client.post( response = self.client.post(
self.url, self.url,
data={'user': six.text_type( data={'user': str(
user.username), 'message': 'abuse!'}, user.username), 'message': 'abuse!'},
REMOTE_ADDR='123.45.67.89') REMOTE_ADDR='123.45.67.89')
assert response.status_code == 201, x assert response.status_code == 201, x
response = self.client.post( response = self.client.post(
self.url, self.url,
data={'user': six.text_type(user.username), 'message': 'abuse!'}, data={'user': str(user.username), 'message': 'abuse!'},
REMOTE_ADDR='123.45.67.89') REMOTE_ADDR='123.45.67.89')
assert response.status_code == 429 assert response.status_code == 429

Просмотреть файл

@ -1,7 +1,6 @@
from django import dispatch from django import dispatch
from django.db import models from django.db import models
from django.db.models import signals from django.db.models import signals
from django.utils.encoding import python_2_unicode_compatible
import olympia.core.logger import olympia.core.logger
@ -13,7 +12,6 @@ from olympia.amo.models import ModelBase
log = olympia.core.logger.getLogger('z.users') log = olympia.core.logger.getLogger('z.users')
@python_2_unicode_compatible
class Group(ModelBase): class Group(ModelBase):
# If `id` is changed from PositiveAutoField, update TestPositiveAutoField. # If `id` is changed from PositiveAutoField, update TestPositiveAutoField.
id = PositiveAutoField(primary_key=True) id = PositiveAutoField(primary_key=True)

Просмотреть файл

@ -2,8 +2,6 @@ from django.conf import settings
from django.core.files.storage import default_storage from django.core.files.storage import default_storage
from django.utils.translation import ugettext from django.utils.translation import ugettext
import six
from rest_framework import serializers from rest_framework import serializers
import olympia.core.logger import olympia.core.logger
@ -108,7 +106,7 @@ class UserProfileSerializer(PublicUserProfileSerializer):
entrypoint='addons') entrypoint='addons')
def validate_biography(self, value): def validate_biography(self, value):
if has_links(clean_nl(six.text_type(value))): if has_links(clean_nl(str(value))):
# There's some links, we don't want them. # There's some links, we don't want them.
raise serializers.ValidationError( raise serializers.ValidationError(
ugettext(u'No links are allowed.')) ugettext(u'No links are allowed.'))

Просмотреть файл

@ -1,8 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from django.test.utils import override_settings from django.test.utils import override_settings
import six
from rest_framework import serializers from rest_framework import serializers
from rest_framework.test import APIRequestFactory from rest_framework.test import APIRequestFactory
@ -97,7 +95,7 @@ class TestPublicUserProfileSerializer(TestCase):
def test_basic(self): def test_basic(self):
data = self.serialize() data = self.serialize()
for prop, val in self.user_kwargs.items(): for prop, val in self.user_kwargs.items():
assert data[prop] == six.text_type(val), prop assert data[prop] == str(val), prop
for prop, val in self.user_private_kwargs.items(): for prop, val in self.user_private_kwargs.items():
assert prop not in data assert prop not in data
return data return data
@ -211,10 +209,10 @@ class TestUserProfileSerializer(TestPublicUserProfileSerializer,
self.grant_permission(self.user, 'Addons:PostReview') self.grant_permission(self.user, 'Addons:PostReview')
data = self.serialize() data = self.serialize()
for prop, val in self.user_kwargs.items(): for prop, val in self.user_kwargs.items():
assert data[prop] == six.text_type(val), prop assert data[prop] == str(val), prop
# We can also see private stuff, it's the same user. # We can also see private stuff, it's the same user.
for prop, val in self.user_private_kwargs.items(): for prop, val in self.user_private_kwargs.items():
assert data[prop] == six.text_type(val), prop assert data[prop] == str(val), prop
def test_expose_fxa_edit_email_url(self): def test_expose_fxa_edit_email_url(self):
fxa_host = 'http://example.com' fxa_host = 'http://example.com'

Просмотреть файл

@ -1,11 +1,11 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import json import json
from unittest import mock
import time import time
from base64 import urlsafe_b64decode, urlsafe_b64encode from base64 import urlsafe_b64decode, urlsafe_b64encode
from datetime import datetime from datetime import datetime
from six.moves.urllib_parse import parse_qs, urlparse from urllib.parse import parse_qs, urlparse
from unittest import mock
from django.contrib.auth.models import AnonymousUser from django.contrib.auth.models import AnonymousUser
from django.test import RequestFactory from django.test import RequestFactory

Просмотреть файл

@ -2,10 +2,9 @@
import base64 import base64
import json import json
from unittest import mock from unittest import mock
import six
from os import path from os import path
from six.moves.urllib_parse import parse_qs, urlparse from urllib.parse import parse_qs, urlparse
from django import http from django import http
from django.conf import settings from django.conf import settings
@ -1150,7 +1149,7 @@ class TestAccountViewSetUpdate(TestCase):
assert response.content != original assert response.content != original
modified_json = json.loads(force_text(response.content)) modified_json = json.loads(force_text(response.content))
self.user = self.user.reload() self.user = self.user.reload()
for prop, value in six.iteritems(self.update_data): for prop, value in self.update_data.items():
assert modified_json[prop] == value assert modified_json[prop] == value
assert getattr(self.user, prop) == value assert getattr(self.user, prop) == value
@ -1175,7 +1174,7 @@ class TestAccountViewSetUpdate(TestCase):
assert response.content != original assert response.content != original
modified_json = json.loads(force_text(response.content)) modified_json = json.loads(force_text(response.content))
random_user = random_user.reload() random_user = random_user.reload()
for prop, value in six.iteritems(self.update_data): for prop, value in self.update_data.items():
assert modified_json[prop] == value assert modified_json[prop] == value
assert getattr(random_user, prop) == value assert getattr(random_user, prop) == value

Просмотреть файл

@ -3,6 +3,7 @@ import json
import os import os
from base64 import urlsafe_b64encode from base64 import urlsafe_b64encode
from urllib.parse import urlencode, urlparse
from django.conf import settings from django.conf import settings
from django.http import HttpResponseRedirect from django.http import HttpResponseRedirect
@ -10,8 +11,6 @@ from django.utils.encoding import force_text
from django.utils.http import is_safe_url from django.utils.http import is_safe_url
import boto3 import boto3
import six
from six.moves.urllib_parse import urlencode, urlparse
from olympia.accounts.tasks import primary_email_change_event from olympia.accounts.tasks import primary_email_change_event
from olympia.core.logger import getLogger from olympia.core.logger import getLogger
@ -31,7 +30,7 @@ def _is_safe_url(url, request):
def fxa_config(request): def fxa_config(request):
config = {camel_case(key): value config = {camel_case(key): value
for key, value in six.iteritems(settings.FXA_CONFIG['default']) for key, value in settings.FXA_CONFIG['default'].items()
if key != 'client_secret'} if key != 'client_secret'}
if request.user.is_authenticated: if request.user.is_authenticated:
config['email'] = request.user.email config['email'] = request.user.email

Просмотреть файл

@ -14,7 +14,6 @@ from django.utils.encoding import force_bytes, force_text
from django.utils.html import format_html from django.utils.html import format_html
from django.utils.translation import ugettext, ugettext_lazy as _ from django.utils.translation import ugettext, ugettext_lazy as _
import six
import waffle import waffle
from corsheaders.conf import conf as corsheaders_conf from corsheaders.conf import conf as corsheaders_conf
@ -540,7 +539,7 @@ class ProfileView(APIView):
account_viewset = AccountViewSet( account_viewset = AccountViewSet(
request=request, request=request,
permission_classes=self.permission_classes, permission_classes=self.permission_classes,
kwargs={'pk': six.text_type(self.request.user.pk)}) kwargs={'pk': str(self.request.user.pk)})
account_viewset.format_kwarg = self.format_kwarg account_viewset.format_kwarg = self.format_kwarg
return account_viewset.retrieve(request) return account_viewset.retrieve(request)

Просмотреть файл

@ -10,11 +10,9 @@ from django.conf import settings
from django.db import models from django.db import models
from django.urls import reverse from django.urls import reverse
from django.utils import timezone from django.utils import timezone
from django.utils.encoding import python_2_unicode_compatible
from django.utils.translation import ugettext from django.utils.translation import ugettext
import jinja2 import jinja2
import six
import olympia.core.logger import olympia.core.logger
@ -296,7 +294,6 @@ class SafeFormatter(string.Formatter):
return jinja2.escape(obj), used_key return jinja2.escape(obj), used_key
@python_2_unicode_compatible
class ActivityLog(ModelBase): class ActivityLog(ModelBase):
TYPES = sorted( TYPES = sorted(
[(value.id, key) [(value.id, key)
@ -363,18 +360,16 @@ class ActivityLog(ModelBase):
serialize_me = [] serialize_me = []
for arg in args: for arg in args:
if isinstance(arg, six.string_types): if isinstance(arg, str):
serialize_me.append({'str': arg}) serialize_me.append({'str': arg})
elif isinstance(arg, six.integer_types): elif isinstance(arg, int):
serialize_me.append({'int': arg}) serialize_me.append({'int': arg})
elif isinstance(arg, tuple): elif isinstance(arg, tuple):
# Instead of passing an addon instance you can pass a tuple: # Instead of passing an addon instance you can pass a tuple:
# (Addon, 3) for Addon with pk=3 # (Addon, 3) for Addon with pk=3
serialize_me.append( serialize_me.append(dict(((str(arg[0]._meta), arg[1]),)))
dict(((six.text_type(arg[0]._meta), arg[1]),)))
else: else:
serialize_me.append( serialize_me.append(dict(((str(arg._meta), arg.pk),)))
dict(((six.text_type(arg._meta), arg.pk),)))
self._arguments = json.dumps(serialize_me) self._arguments = json.dumps(serialize_me)
@ -485,7 +480,7 @@ class ActivityLog(ModelBase):
'file': file_, 'file': file_,
'status': status, 'status': status,
} }
return self.f(six.text_type(format), *arguments, **kw) return self.f(str(format), *arguments, **kw)
except (AttributeError, KeyError, IndexError): except (AttributeError, KeyError, IndexError):
log.warning('%d contains garbage data' % (self.id or 0)) log.warning('%d contains garbage data' % (self.id or 0))
return 'Something magical happened.' return 'Something magical happened.'

Просмотреть файл

@ -1,8 +1,6 @@
from datetime import datetime, timedelta from datetime import datetime, timedelta
from uuid import UUID from uuid import UUID
import six
from unittest.mock import Mock from unittest.mock import Mock
from pyquery import PyQuery as pq from pyquery import PyQuery as pq
@ -103,7 +101,7 @@ class TestActivityLog(TestCase):
assert len(entries) == 1 assert len(entries) == 1
assert entries[0].arguments[0] == addon assert entries[0].arguments[0] == addon
for x in ('Delicious Bookmarks', 'was created.'): for x in ('Delicious Bookmarks', 'was created.'):
assert x in six.text_type(entries[0]) assert x in str(entries[0])
def test_no_user(self): def test_no_user(self):
core.set_user(None) core.set_user(None)
@ -133,7 +131,7 @@ class TestActivityLog(TestCase):
ActivityLog.create(amo.LOG.CREATE_ADDON, (Addon, addon.id)) ActivityLog.create(amo.LOG.CREATE_ADDON, (Addon, addon.id))
entries = ActivityLog.objects.for_addons(addon) entries = ActivityLog.objects.for_addons(addon)
assert len(entries) == 1 assert len(entries) == 1
assert addon.get_url_path() in six.text_type(entries[0]) assert addon.get_url_path() in str(entries[0])
def test_addon_log_unlisted_addon(self): def test_addon_log_unlisted_addon(self):
addon = Addon.objects.get() addon = Addon.objects.get()
@ -145,7 +143,7 @@ class TestActivityLog(TestCase):
ActivityLog.create(amo.LOG.CREATE_ADDON, (Addon, addon.id)) ActivityLog.create(amo.LOG.CREATE_ADDON, (Addon, addon.id))
entries = ActivityLog.objects.for_addons(addon) entries = ActivityLog.objects.for_addons(addon)
assert len(entries) == 1 assert len(entries) == 1
assert url_path not in six.text_type(entries[0]) assert url_path not in str(entries[0])
def test_fancy_rendering(self): def test_fancy_rendering(self):
"""HTML for Rating, and Collection.""" """HTML for Rating, and Collection."""
@ -192,7 +190,7 @@ class TestActivityLog(TestCase):
def test_output(self): def test_output(self):
ActivityLog.create(amo.LOG.CUSTOM_TEXT, 'hi there') ActivityLog.create(amo.LOG.CUSTOM_TEXT, 'hi there')
entry = ActivityLog.objects.get() entry = ActivityLog.objects.get()
assert six.text_type(entry) == 'hi there' assert str(entry) == 'hi there'
def test_user_log(self): def test_user_log(self):
request = self.request request = self.request
@ -220,7 +218,7 @@ class TestActivityLog(TestCase):
user=self.request.user) user=self.request.user)
entries = ActivityLog.objects.for_version(version) entries = ActivityLog.objects.for_version(version)
assert len(entries) == 1 assert len(entries) == 1
assert version.get_url_path() in six.text_type(entries[0]) assert version.get_url_path() in str(entries[0])
def test_version_log_unlisted_addon(self): def test_version_log_unlisted_addon(self):
version = Version.objects.all()[0] version = Version.objects.all()[0]
@ -231,7 +229,7 @@ class TestActivityLog(TestCase):
user=self.request.user) user=self.request.user)
entries = ActivityLog.objects.for_version(version) entries = ActivityLog.objects.for_version(version)
assert len(entries) == 1 assert len(entries) == 1
assert url_path not in six.text_type(entries[0]) assert url_path not in str(entries[0])
def test_version_log_transformer(self): def test_version_log_transformer(self):
addon = Addon.objects.get() addon = Addon.objects.get()
@ -260,7 +258,7 @@ class TestActivityLog(TestCase):
au = AddonUser(addon=addon, user=self.user) au = AddonUser(addon=addon, user=self.user)
ActivityLog.create( ActivityLog.create(
amo.LOG.CHANGE_USER_WITH_ROLE, au.user, amo.LOG.CHANGE_USER_WITH_ROLE, au.user,
six.text_type(au.get_role_display()), addon) str(au.get_role_display()), addon)
log = ActivityLog.objects.get() log = ActivityLog.objects.get()
log_expected = ('Yolo role changed to Owner for <a href="/en-US/' log_expected = ('Yolo role changed to Owner for <a href="/en-US/'
@ -287,28 +285,28 @@ class TestActivityLog(TestCase):
amo.LOG.CHANGE_STATUS, addon, amo.STATUS_APPROVED) amo.LOG.CHANGE_STATUS, addon, amo.STATUS_APPROVED)
expected = ('<a href="/en-US/firefox/addon/a3615/">' expected = ('<a href="/en-US/firefox/addon/a3615/">'
'Delicious Bookmarks</a> status changed to Approved.') 'Delicious Bookmarks</a> status changed to Approved.')
assert six.text_type(log) == expected assert str(log) == expected
log.arguments = [amo.STATUS_DISABLED, addon] log.arguments = [amo.STATUS_DISABLED, addon]
expected = ('<a href="/en-US/firefox/addon/a3615/">' expected = ('<a href="/en-US/firefox/addon/a3615/">'
'Delicious Bookmarks</a> status changed to ' 'Delicious Bookmarks</a> status changed to '
'Disabled by Mozilla.') 'Disabled by Mozilla.')
assert six.text_type(log) == expected assert str(log) == expected
log.arguments = [addon, amo.STATUS_REJECTED] log.arguments = [addon, amo.STATUS_REJECTED]
expected = ('<a href="/en-US/firefox/addon/a3615/">' expected = ('<a href="/en-US/firefox/addon/a3615/">'
'Delicious Bookmarks</a> status changed to Rejected.') 'Delicious Bookmarks</a> status changed to Rejected.')
assert six.text_type(log) == expected assert str(log) == expected
log.arguments = [addon, 666] log.arguments = [addon, 666]
expected = ('<a href="/en-US/firefox/addon/a3615/">' expected = ('<a href="/en-US/firefox/addon/a3615/">'
'Delicious Bookmarks</a> status changed to 666.') 'Delicious Bookmarks</a> status changed to 666.')
assert six.text_type(log) == expected assert str(log) == expected
log.arguments = [addon, 'Some String'] log.arguments = [addon, 'Some String']
expected = ('<a href="/en-US/firefox/addon/a3615/">' expected = ('<a href="/en-US/firefox/addon/a3615/">'
'Delicious Bookmarks</a> status changed to Some String.') 'Delicious Bookmarks</a> status changed to Some String.')
assert six.text_type(log) == expected assert str(log) == expected
class TestActivityLogCount(TestCase): class TestActivityLogCount(TestCase):

Просмотреть файл

@ -1,11 +1,10 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import json import json
import io
from unittest import mock
from django.test.utils import override_settings from django.test.utils import override_settings
from unittest import mock
import six
from olympia import amo from olympia import amo
from olympia.activity.models import ActivityLog, ActivityLogToken from olympia.activity.models import ActivityLog, ActivityLogToken
from olympia.activity.tests.test_serializers import LogMixin from olympia.activity.tests.test_serializers import LogMixin
@ -276,7 +275,7 @@ class TestReviewNotesViewSetCreate(TestCase):
rdata = response.data rdata = response.data
assert reply.pk == rdata['id'] assert reply.pk == rdata['id']
assert ( assert (
six.text_type(reply.details['comments']) == rdata['comments'] == str(reply.details['comments']) == rdata['comments'] ==
u'comménty McCómm€nt') u'comménty McCómm€nt')
assert reply.user == self.user assert reply.user == self.user
assert reply.user.name == rdata['user']['name'] == self.user.name assert reply.user.name == rdata['user']['name'] == self.user.name
@ -302,7 +301,7 @@ class TestReviewNotesViewSetCreate(TestCase):
rdata = response.data rdata = response.data
assert reply.pk == rdata['id'] assert reply.pk == rdata['id']
assert ( assert (
six.text_type(reply.details['comments']) == rdata['comments'] == str(reply.details['comments']) == rdata['comments'] ==
u'comménty McCómm€nt') u'comménty McCómm€nt')
assert reply.user == self.user assert reply.user == self.user
assert reply.user.name == rdata['user']['name'] == self.user.name assert reply.user.name == rdata['user']['name'] == self.user.name
@ -396,7 +395,7 @@ class TestEmailApi(TestCase):
req.META['REMOTE_ADDR'] = '10.10.10.10' req.META['REMOTE_ADDR'] = '10.10.10.10'
req.META['CONTENT_LENGTH'] = len(datastr) req.META['CONTENT_LENGTH'] = len(datastr)
req.META['CONTENT_TYPE'] = 'application/json' req.META['CONTENT_TYPE'] = 'application/json'
req._stream = six.BytesIO(datastr) req._stream = io.BytesIO(datastr)
return req return req
def get_validation_request(self, data): def get_validation_request(self, data):

Просмотреть файл

@ -2,7 +2,7 @@ import re
from datetime import datetime, timedelta from datetime import datetime, timedelta
from email.utils import formataddr from email.utils import formataddr
from six.moves.html_parser import HTMLParser from html.parser import HTMLParser
from django.conf import settings from django.conf import settings
from django.forms import ValidationError from django.forms import ValidationError

Просмотреть файл

@ -1,4 +1,4 @@
from six.moves.urllib_parse import urlencode from urllib.parse import urlencode
from django import http, forms from django import http, forms
from django.conf import settings from django.conf import settings

Просмотреть файл

@ -9,6 +9,7 @@ import time
import uuid import uuid
from datetime import datetime from datetime import datetime
from urllib.parse import urlsplit
from django.conf import settings from django.conf import settings
from django.core.exceptions import ObjectDoesNotExist from django.core.exceptions import ObjectDoesNotExist
@ -16,16 +17,13 @@ from django.db import IntegrityError, models, transaction
from django.db.models import F, Max, Q, signals as dbsignals from django.db.models import F, Max, Q, signals as dbsignals
from django.dispatch import receiver from django.dispatch import receiver
from django.utils import translation from django.utils import translation
from django.utils.encoding import force_text, python_2_unicode_compatible from django.utils.encoding import force_text
from django.utils.functional import cached_property from django.utils.functional import cached_property
from django.utils.translation import trans_real, ugettext_lazy as _ from django.utils.translation import trans_real, ugettext_lazy as _
import six
from django_extensions.db.fields.json import JSONField from django_extensions.db.fields.json import JSONField
from django_statsd.clients import statsd from django_statsd.clients import statsd
from jinja2.filters import do_dictsort from jinja2.filters import do_dictsort
from six.moves.urllib_parse import urlsplit
import olympia.core.logger import olympia.core.logger
@ -154,7 +152,7 @@ def clean_slug(instance, slug_field='slug'):
class AddonQuerySet(BaseQuerySet): class AddonQuerySet(BaseQuerySet):
def id_or_slug(self, val): def id_or_slug(self, val):
"""Get add-ons by id or slug.""" """Get add-ons by id or slug."""
if isinstance(val, six.string_types) and not val.isdigit(): if isinstance(val, str) and not val.isdigit():
return self.filter(slug=val) return self.filter(slug=val)
return self.filter(id=val) return self.filter(id=val)
@ -339,7 +337,6 @@ class AddonManager(ManagerBase):
return qs return qs
@python_2_unicode_compatible
class Addon(OnChangeMixin, ModelBase): class Addon(OnChangeMixin, ModelBase):
id = PositiveAutoField(primary_key=True) id = PositiveAutoField(primary_key=True)
STATUS_CHOICES = amo.STATUS_CHOICES_ADDON STATUS_CHOICES = amo.STATUS_CHOICES_ADDON
@ -574,7 +571,7 @@ class Addon(OnChangeMixin, ModelBase):
self._ratings.all().delete() self._ratings.all().delete()
# The last parameter is needed to automagically create an AddonLog. # The last parameter is needed to automagically create an AddonLog.
activity.log_create(amo.LOG.DELETE_ADDON, self.pk, activity.log_create(amo.LOG.DELETE_ADDON, self.pk,
six.text_type(self.guid), self) str(self.guid), self)
self.update(status=amo.STATUS_DELETED, slug=None, self.update(status=amo.STATUS_DELETED, slug=None,
_current_version=None, modified=datetime.now()) _current_version=None, modified=datetime.now())
models.signals.post_delete.send(sender=Addon, instance=self) models.signals.post_delete.send(sender=Addon, instance=self)
@ -856,7 +853,7 @@ class Addon(OnChangeMixin, ModelBase):
# as File's) when deleting a version. If so, we should avoid putting # as File's) when deleting a version. If so, we should avoid putting
# that version-being-deleted in any fields. # that version-being-deleted in any fields.
if ignore is not None: if ignore is not None:
updated = {k: v for k, v in six.iteritems(updated) if v != ignore} updated = {k: v for k, v in updated.items() if v != ignore}
if updated: if updated:
diff = [self._current_version, new_current_version] diff = [self._current_version, new_current_version]
@ -1600,7 +1597,6 @@ class AddonReviewerFlags(ModelBase):
notified_about_expiring_info_request = models.BooleanField(default=False) notified_about_expiring_info_request = models.BooleanField(default=False)
@python_2_unicode_compatible
class Persona(models.Model): class Persona(models.Model):
"""Personas-specific additions to the add-on model.""" """Personas-specific additions to the add-on model."""
STATUS_CHOICES = amo.STATUS_CHOICES_PERSONA STATUS_CHOICES = amo.STATUS_CHOICES_PERSONA
@ -1632,7 +1628,7 @@ class Persona(models.Model):
db_table = 'personas' db_table = 'personas'
def __str__(self): def __str__(self):
return six.text_type(self.addon.name) return str(self.addon.name)
def is_new(self): def is_new(self):
return self.persona_id == 0 return self.persona_id == 0
@ -1741,15 +1737,15 @@ class Persona(models.Model):
addon = self.addon addon = self.addon
return { return {
'id': six.text_type(self.addon.id), # Personas dislikes ints 'id': str(self.addon.id), # Personas dislikes ints
'name': six.text_type(addon.name), 'name': str(addon.name),
'accentcolor': hexcolor(self.accentcolor), 'accentcolor': hexcolor(self.accentcolor),
'textcolor': hexcolor(self.textcolor), 'textcolor': hexcolor(self.textcolor),
'category': (six.text_type(addon.all_categories[0].name) if 'category': (str(addon.all_categories[0].name) if
addon.all_categories else ''), addon.all_categories else ''),
# TODO: Change this to be `addons_users.user.display_name`. # TODO: Change this to be `addons_users.user.display_name`.
'author': self.display_username, 'author': self.display_username,
'description': (six.text_type(addon.description) 'description': (str(addon.description)
if addon.description is not None if addon.description is not None
else addon.description), else addon.description),
'header': self.header_url, 'header': self.header_url,
@ -1845,7 +1841,6 @@ def watch_addon_user(old_attr=None, new_attr=None, instance=None, sender=None,
update_search_index(sender=sender, instance=instance.addon, **kwargs) update_search_index(sender=sender, instance=instance.addon, **kwargs)
@python_2_unicode_compatible
class AddonApprovalsCounter(ModelBase): class AddonApprovalsCounter(ModelBase):
"""Model holding a counter of the number of times a listed version """Model holding a counter of the number of times a listed version
belonging to an add-on has been approved by a human. Reset everytime a belonging to an add-on has been approved by a human. Reset everytime a
@ -1864,8 +1859,7 @@ class AddonApprovalsCounter(ModelBase):
last_content_review = models.DateTimeField(null=True) last_content_review = models.DateTimeField(null=True)
def __str__(self): def __str__(self):
return u'%s: %d' % ( return u'%s: %d' % (str(self.pk), self.counter) if self.pk else u''
six.text_type(self.pk), self.counter) if self.pk else u''
@classmethod @classmethod
def increment_for_addon(cls, addon): def increment_for_addon(cls, addon):
@ -1909,7 +1903,6 @@ class AddonApprovalsCounter(ModelBase):
return obj return obj
@python_2_unicode_compatible
class DeniedGuid(ModelBase): class DeniedGuid(ModelBase):
id = PositiveAutoField(primary_key=True) id = PositiveAutoField(primary_key=True)
guid = models.CharField(max_length=255, unique=True) guid = models.CharField(max_length=255, unique=True)
@ -1922,7 +1915,6 @@ class DeniedGuid(ModelBase):
return self.guid return self.guid
@python_2_unicode_compatible
class Category(OnChangeMixin, ModelBase): class Category(OnChangeMixin, ModelBase):
id = PositiveAutoField(primary_key=True) id = PositiveAutoField(primary_key=True)
slug = SlugField(max_length=50, help_text='Used in Category URLs.') slug = SlugField(max_length=50, help_text='Used in Category URLs.')
@ -1950,10 +1942,10 @@ class Category(OnChangeMixin, ModelBase):
# We can't find the category in the constants dict. This shouldn't # We can't find the category in the constants dict. This shouldn't
# happen, but just in case handle it by returning an empty string. # happen, but just in case handle it by returning an empty string.
value = '' value = ''
return six.text_type(value) return str(value)
def __str__(self): def __str__(self):
return six.text_type(self.name) return str(self.name)
def get_url_path(self): def get_url_path(self):
try: try:
@ -2024,7 +2016,6 @@ class AppSupport(ModelBase):
unique_together = ('addon', 'app') unique_together = ('addon', 'app')
@python_2_unicode_compatible
class DeniedSlug(ModelBase): class DeniedSlug(ModelBase):
name = models.CharField(max_length=255, unique=True, default='') name = models.CharField(max_length=255, unique=True, default='')
@ -2039,7 +2030,6 @@ class DeniedSlug(ModelBase):
return slug.isdigit() or cls.objects.filter(name=slug).exists() return slug.isdigit() or cls.objects.filter(name=slug).exists()
@python_2_unicode_compatible
class FrozenAddon(models.Model): class FrozenAddon(models.Model):
"""Add-ons in this table never get a hotness score.""" """Add-ons in this table never get a hotness score."""
id = PositiveAutoField(primary_key=True) id = PositiveAutoField(primary_key=True)
@ -2059,7 +2049,6 @@ def freezer(sender, instance, **kw):
Addon.objects.get(id=instance.addon_id).update(hotness=0) Addon.objects.get(id=instance.addon_id).update(hotness=0)
@python_2_unicode_compatible
class CompatOverride(ModelBase): class CompatOverride(ModelBase):
"""Helps manage compat info for add-ons not hosted on AMO.""" """Helps manage compat info for add-ons not hosted on AMO."""
id = PositiveAutoField(primary_key=True) id = PositiveAutoField(primary_key=True)
@ -2082,7 +2071,7 @@ class CompatOverride(ModelBase):
def __str__(self): def __str__(self):
if self.addon: if self.addon:
return six.text_type(self.addon) return str(self.addon)
elif self.name: elif self.name:
return '%s (%s)' % (self.name, self.guid) return '%s (%s)' % (self.name, self.guid)
else: else:
@ -2160,7 +2149,6 @@ class CompatOverrideRange(ModelBase):
return {0: 'compatible', 1: 'incompatible'}[self.type] return {0: 'compatible', 1: 'incompatible'}[self.type]
@python_2_unicode_compatible
class IncompatibleVersions(ModelBase): class IncompatibleVersions(ModelBase):
""" """
Denormalized table to join against for fast compat override filtering. Denormalized table to join against for fast compat override filtering.

Просмотреть файл

@ -2,8 +2,6 @@ import re
from django.conf import settings from django.conf import settings
import six
from rest_framework import exceptions, serializers from rest_framework import exceptions, serializers
from olympia import amo from olympia import amo
@ -125,11 +123,11 @@ class LicenseSerializer(serializers.ModelSerializer):
request = self.context.get('request', None) request = self.context.get('request', None)
if request and request.method == 'GET' and 'lang' in request.GET: if request and request.method == 'GET' and 'lang' in request.GET:
# A single lang requested so return a flat string # A single lang requested so return a flat string
return six.text_type(license_constant.name) return str(license_constant.name)
else: else:
# Otherwise mock the dict with the default lang. # Otherwise mock the dict with the default lang.
lang = getattr(request, 'LANG', None) or settings.LANGUAGE_CODE lang = getattr(request, 'LANG', None) or settings.LANGUAGE_CODE
return {lang: six.text_type(license_constant.name)} return {lang: str(license_constant.name)}
def to_representation(self, instance): def to_representation(self, instance):
data = super(LicenseSerializer, self).to_representation(instance) data = super(LicenseSerializer, self).to_representation(instance)
@ -234,7 +232,7 @@ class CurrentVersionSerializer(SimpleVersionSerializer):
application = value[0] application = value[0]
appversions = dict(zip(('min', 'max'), value[1:])) appversions = dict(zip(('min', 'max'), value[1:]))
except ValueError as exc: except ValueError as exc:
raise exceptions.ParseError(six.text_type(exc)) raise exceptions.ParseError(str(exc))
version_qs = Version.objects.latest_public_compatible_with( version_qs = Version.objects.latest_public_compatible_with(
application, appversions).filter(addon=addon) application, appversions).filter(addon=addon)
@ -375,7 +373,7 @@ class AddonSerializer(serializers.ModelSerializer):
def outgoingify(self, data): def outgoingify(self, data):
if data: if data:
if isinstance(data, six.string_types): if isinstance(data, str):
return get_outgoing_url(data) return get_outgoing_url(data)
elif isinstance(data, dict): elif isinstance(data, dict):
return {key: get_outgoing_url(value) if value else None return {key: get_outgoing_url(value) if value else None
@ -726,7 +724,7 @@ class ReplacementAddonSerializer(serializers.ModelSerializer):
def _get_collection_guids(self, user_id, collection_slug): def _get_collection_guids(self, user_id, collection_slug):
try: try:
get_args = {'slug': collection_slug, 'listed': True} get_args = {'slug': collection_slug, 'listed': True}
if isinstance(user_id, six.string_types) and not user_id.isdigit(): if isinstance(user_id, str) and not user_id.isdigit():
get_args.update(**{'author__username': user_id}) get_args.update(**{'author__username': user_id})
else: else:
get_args.update(**{'author': user_id}) get_args.update(**{'author': user_id})

Просмотреть файл

@ -1,8 +1,7 @@
from django import http from django import http
from unittest import mock from unittest import mock
from urllib.parse import quote
from six.moves.urllib_parse import quote
from olympia.addons import decorators as dec from olympia.addons import decorators as dec
from olympia.addons.models import Addon from olympia.addons.models import Addon

Просмотреть файл

@ -4,6 +4,7 @@ import os
import time import time
from datetime import datetime, timedelta from datetime import datetime, timedelta
from unittest.mock import Mock, patch
from django import forms from django import forms
from django.conf import settings from django.conf import settings
@ -11,9 +12,6 @@ from django.core import mail
from django.utils import translation from django.utils import translation
import pytest import pytest
import six
from unittest.mock import Mock, patch
from olympia import amo, core from olympia import amo, core
from olympia.activity.models import ActivityLog, AddonLog from olympia.activity.models import ActivityLog, AddonLog
@ -2112,12 +2110,12 @@ class TestPersonaModel(TestCase):
id_ = str(self.persona.addon.id) id_ = str(self.persona.addon.id)
assert data['id'] == id_ assert data['id'] == id_
assert data['name'] == six.text_type(self.persona.addon.name) assert data['name'] == str(self.persona.addon.name)
assert data['accentcolor'] == '#8d8d97' assert data['accentcolor'] == '#8d8d97'
assert data['textcolor'] == '#ffffff' assert data['textcolor'] == '#ffffff'
assert data['category'] == 'Abstract' assert data['category'] == 'Abstract'
assert data['author'] == 'persona_author ®' assert data['author'] == 'persona_author ®'
assert data['description'] == six.text_type(self.addon.description) assert data['description'] == str(self.addon.description)
assert data['headerURL'].startswith( assert data['headerURL'].startswith(
'%s%s/header.png?' % (user_media_url('addons'), id_)) '%s%s/header.png?' % (user_media_url('addons'), id_))
@ -2151,12 +2149,12 @@ class TestPersonaModel(TestCase):
id_ = str(self.persona.addon.id) id_ = str(self.persona.addon.id)
assert data['id'] == id_ assert data['id'] == id_
assert data['name'] == six.text_type(self.persona.addon.name) assert data['name'] == str(self.persona.addon.name)
assert data['accentcolor'] == '#8d8d97' assert data['accentcolor'] == '#8d8d97'
assert data['textcolor'] == '#ffffff' assert data['textcolor'] == '#ffffff'
assert data['category'] == 'Abstract' assert data['category'] == 'Abstract'
assert data['author'] == 'persona_author ®' assert data['author'] == 'persona_author ®'
assert data['description'] == six.text_type(self.addon.description) assert data['description'] == str(self.addon.description)
assert data['headerURL'].startswith( assert data['headerURL'].startswith(
'%s%s/header.png?' % (user_media_url('addons'), id_)) '%s%s/header.png?' % (user_media_url('addons'), id_))

Просмотреть файл

@ -2,8 +2,6 @@
from django.test.utils import override_settings from django.test.utils import override_settings
from django.utils.translation import override from django.utils.translation import override
import six
from rest_framework.test import APIRequestFactory from rest_framework.test import APIRequestFactory
from olympia import amo from olympia import amo
@ -221,9 +219,7 @@ class AddonSerializerOutputTestMixin(object):
assert result['guid'] == self.addon.guid assert result['guid'] == self.addon.guid
assert result['has_eula'] is False assert result['has_eula'] is False
assert result['has_privacy_policy'] is False assert result['has_privacy_policy'] is False
assert result['homepage'] == { assert result['homepage'] == {'en-US': str(self.addon.homepage)}
'en-US': six.text_type(self.addon.homepage),
}
assert result['icon_url'] == absolutify(self.addon.get_icon_url(64)) assert result['icon_url'] == absolutify(self.addon.get_icon_url(64))
assert result['icons'] == { assert result['icons'] == {
'32': absolutify(self.addon.get_icon_url(32)), '32': absolutify(self.addon.get_icon_url(32)),
@ -283,9 +279,7 @@ class AddonSerializerOutputTestMixin(object):
assert result['status'] == 'public' assert result['status'] == 'public'
assert result['summary'] == {'en-US': self.addon.summary} assert result['summary'] == {'en-US': self.addon.summary}
assert result['support_email'] == {'en-US': self.addon.support_email} assert result['support_email'] == {'en-US': self.addon.support_email}
assert result['support_url'] == { assert result['support_url'] == {'en-US': str(self.addon.support_url)}
'en-US': six.text_type(self.addon.support_url),
}
assert set(result['tags']) == {'some_tag', 'some_other_tag'} assert set(result['tags']) == {'some_tag', 'some_other_tag'}
assert result['type'] == 'extension' assert result['type'] == 'extension'
assert result['url'] == self.addon.get_absolute_url() assert result['url'] == self.addon.get_absolute_url()
@ -301,12 +295,12 @@ class AddonSerializerOutputTestMixin(object):
self.request = APIRequestFactory().get('/', {'wrap_outgoing_links': 1}) self.request = APIRequestFactory().get('/', {'wrap_outgoing_links': 1})
result = self.serialize() result = self.serialize()
assert result['contributions_url'] == ( assert result['contributions_url'] == (
get_outgoing_url(six.text_type(self.addon.contributions))) get_outgoing_url(str(self.addon.contributions)))
assert result['homepage'] == { assert result['homepage'] == {
'en-US': get_outgoing_url(six.text_type(self.addon.homepage)), 'en-US': get_outgoing_url(str(self.addon.homepage)),
} }
assert result['support_url'] == { assert result['support_url'] == {
'en-US': get_outgoing_url(six.text_type(self.addon.support_url)), 'en-US': get_outgoing_url(str(self.addon.support_url)),
} }
# Try a single translation. # Try a single translation.
@ -314,24 +308,24 @@ class AddonSerializerOutputTestMixin(object):
'lang': 'en-US', 'wrap_outgoing_links': 1}) 'lang': 'en-US', 'wrap_outgoing_links': 1})
result = self.serialize() result = self.serialize()
assert result['contributions_url'] == ( assert result['contributions_url'] == (
get_outgoing_url(six.text_type(self.addon.contributions))) get_outgoing_url(str(self.addon.contributions)))
assert result['homepage'] == { assert result['homepage'] == {
'en-US': get_outgoing_url(six.text_type(self.addon.homepage)), 'en-US': get_outgoing_url(str(self.addon.homepage)),
} }
assert result['support_url'] == { assert result['support_url'] == {
'en-US': get_outgoing_url(six.text_type(self.addon.support_url)), 'en-US': get_outgoing_url(str(self.addon.support_url)),
} }
# And again, but with v3 style flat strings # And again, but with v3 style flat strings
gates = {None: ('l10n_flat_input_output',)} gates = {None: ('l10n_flat_input_output',)}
with override_settings(DRF_API_GATES=gates): with override_settings(DRF_API_GATES=gates):
result = self.serialize() result = self.serialize()
assert result['contributions_url'] == ( assert result['contributions_url'] == (
get_outgoing_url(six.text_type(self.addon.contributions))) get_outgoing_url(str(self.addon.contributions)))
assert result['homepage'] == ( assert result['homepage'] == (
get_outgoing_url(six.text_type(self.addon.homepage)) get_outgoing_url(str(self.addon.homepage))
) )
assert result['support_url'] == ( assert result['support_url'] == (
get_outgoing_url(six.text_type(self.addon.support_url)) get_outgoing_url(str(self.addon.support_url))
) )
# Try with empty strings/None. Annoyingly, contribution model field # Try with empty strings/None. Annoyingly, contribution model field
@ -1016,7 +1010,7 @@ class TestVersionSerializerOutput(TestCase):
# A request with no ?lang gets you the site default l10n in a dict to # A request with no ?lang gets you the site default l10n in a dict to
# match how non-constant values are returned. # match how non-constant values are returned.
assert result['name'] == { assert result['name'] == {
'en-US': six.text_type(LICENSES_BY_BUILTIN[18].name)} 'en-US': str(LICENSES_BY_BUILTIN[18].name)}
accept_request = APIRequestFactory().get('/') accept_request = APIRequestFactory().get('/')
accept_request.LANG = 'de' accept_request.LANG = 'de'
@ -1024,13 +1018,13 @@ class TestVersionSerializerOutput(TestCase):
context={'request': accept_request}).to_representation(license) context={'request': accept_request}).to_representation(license)
# An Accept-Language should result in a different default though. # An Accept-Language should result in a different default though.
assert result['name'] == { assert result['name'] == {
'de': six.text_type(LICENSES_BY_BUILTIN[18].name)} 'de': str(LICENSES_BY_BUILTIN[18].name)}
# But a requested lang returns a flat string # But a requested lang returns a flat string
lang_request = APIRequestFactory().get('/?lang=fr') lang_request = APIRequestFactory().get('/?lang=fr')
result = LicenseSerializer( result = LicenseSerializer(
context={'request': lang_request}).to_representation(license) context={'request': lang_request}).to_representation(license)
assert result['name'] == six.text_type(LICENSES_BY_BUILTIN[18].name) assert result['name'] == str(LICENSES_BY_BUILTIN[18].name)
def test_file_webext_permissions(self): def test_file_webext_permissions(self):
self.version = addon_factory().current_version self.version = addon_factory().current_version
@ -1200,7 +1194,7 @@ class TestESAddonAutoCompleteSerializer(ESTestCase):
{'id', 'name', 'icon_url', 'is_recommended', 'type', 'url'} {'id', 'name', 'icon_url', 'is_recommended', 'type', 'url'}
) )
assert result['id'] == self.addon.pk assert result['id'] == self.addon.pk
assert result['name'] == {'en-US': six.text_type(self.addon.name)} assert result['name'] == {'en-US': str(self.addon.name)}
assert result['icon_url'] == absolutify(self.addon.get_icon_url(64)) assert result['icon_url'] == absolutify(self.addon.get_icon_url(64))
assert result['is_recommended'] == self.addon.is_recommended is False assert result['is_recommended'] == self.addon.is_recommended is False
assert result['type'] == 'extension' assert result['type'] == 'extension'

Просмотреть файл

@ -1,15 +1,14 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import json import json
import io
from unittest import mock
from urllib.parse import urlencode
from django.conf import settings from django.conf import settings
from django.db import connection from django.db import connection
from django.test.utils import override_settings from django.test.utils import override_settings
from unittest import mock
import six
from six import StringIO
from six.moves.urllib_parse import urlencode
from services import theme_update from services import theme_update
from olympia import amo from olympia import amo
@ -23,7 +22,7 @@ class TestWSGIApplication(TestCase):
def setUp(self): def setUp(self):
super(TestWSGIApplication, self).setUp() super(TestWSGIApplication, self).setUp()
self.environ = {'wsgi.input': StringIO()} self.environ = {'wsgi.input': io.StringIO()}
self.start_response = mock.Mock() self.start_response = mock.Mock()
self.urls = { self.urls = {
'/themes/update-check/5': ['en-US', 5, None], '/themes/update-check/5': ['en-US', 5, None],
@ -38,7 +37,7 @@ class TestWSGIApplication(TestCase):
MigratedUpdate_mock.return_value.is_migrated = False MigratedUpdate_mock.return_value.is_migrated = False
LWThemeUpdate_mock.return_value.get_json.return_value = u'{"fo": ""}' LWThemeUpdate_mock.return_value.get_json.return_value = u'{"fo": ""}'
# From AMO we consume the ID as the `addon_id`. # From AMO we consume the ID as the `addon_id`.
for path_info, call_args in six.iteritems(self.urls): for path_info, call_args in self.urls.items():
environ = dict(self.environ, PATH_INFO=path_info) environ = dict(self.environ, PATH_INFO=path_info)
response = theme_update.application(environ, self.start_response) response = theme_update.application(environ, self.start_response)
# wsgi expects a bytestring, rather than unicode response. # wsgi expects a bytestring, rather than unicode response.
@ -49,7 +48,7 @@ class TestWSGIApplication(TestCase):
# From getpersonas.com we append `?src=gp` so we know to consume # From getpersonas.com we append `?src=gp` so we know to consume
# the ID as the `persona_id`. # the ID as the `persona_id`.
self.environ['QUERY_STRING'] = 'src=gp' self.environ['QUERY_STRING'] = 'src=gp'
for path_info, call_args in six.iteritems(self.urls): for path_info, call_args in self.urls.items():
environ = dict(self.environ, PATH_INFO=path_info) environ = dict(self.environ, PATH_INFO=path_info)
theme_update.application(environ, self.start_response) theme_update.application(environ, self.start_response)
call_args[2] = 'src=gp' call_args[2] = 'src=gp'
@ -66,7 +65,7 @@ class TestWSGIApplication(TestCase):
MigratedUpdate_mock.return_value.get_json.return_value = ( MigratedUpdate_mock.return_value.get_json.return_value = (
u'{"foó": "ba"}') u'{"foó": "ba"}')
# From AMO we consume the ID as the `addon_id`. # From AMO we consume the ID as the `addon_id`.
for path_info, call_args in six.iteritems(self.urls): for path_info, call_args in self.urls.items():
environ = dict(self.environ, PATH_INFO=path_info) environ = dict(self.environ, PATH_INFO=path_info)
response = theme_update.application(environ, self.start_response) response = theme_update.application(environ, self.start_response)
# wsgi expects a bytestring, rather than unicode response. # wsgi expects a bytestring, rather than unicode response.
@ -78,7 +77,7 @@ class TestWSGIApplication(TestCase):
# From getpersonas.com we append `?src=gp` so we know to consume # From getpersonas.com we append `?src=gp` so we know to consume
# the ID as the `persona_id`. # the ID as the `persona_id`.
self.environ['QUERY_STRING'] = 'src=gp' self.environ['QUERY_STRING'] = 'src=gp'
for path_info, call_args in six.iteritems(self.urls): for path_info, call_args in self.urls.items():
environ = dict(self.environ, PATH_INFO=path_info) environ = dict(self.environ, PATH_INFO=path_info)
theme_update.application(environ, self.start_response) theme_update.application(environ, self.start_response)
call_args[2] = 'src=gp' call_args[2] = 'src=gp'
@ -110,7 +109,7 @@ class TestWSGIApplication(TestCase):
def test_404_for_migrated_but_updates_disabled( def test_404_for_migrated_but_updates_disabled(
self, LWThemeUpdate_mock, MigratedUpdate_mock): self, LWThemeUpdate_mock, MigratedUpdate_mock):
MigratedUpdate_mock.return_value.is_migrated = True MigratedUpdate_mock.return_value.is_migrated = True
for path_info, call_args in six.iteritems(self.urls): for path_info, call_args in self.urls.items():
environ = dict(self.environ, PATH_INFO=path_info) environ = dict(self.environ, PATH_INFO=path_info)
theme_update.application(environ, self.start_response) theme_update.application(environ, self.start_response)
assert not LWThemeUpdate_mock.called assert not LWThemeUpdate_mock.called
@ -142,7 +141,7 @@ class TestThemeUpdate(TestCase):
} }
def check_good(self, data): def check_good(self, data):
for k, v in six.iteritems(self.good): for k, v in self.good.items():
got = data[k] got = data[k]
if k.endswith('URL'): if k.endswith('URL'):
if k in ('detailURL', 'updateURL'): if k in ('detailURL', 'updateURL'):

Просмотреть файл

@ -1,13 +1,13 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import json import json
from unittest import mock
from django.test.utils import override_settings from django.test.utils import override_settings
from django.utils.encoding import force_bytes, force_text from django.utils.encoding import force_bytes, force_text
from django.utils.http import urlsafe_base64_encode, urlunquote from django.utils.http import urlsafe_base64_encode, urlunquote
from unittest import mock
import pytest import pytest
import six
from elasticsearch import Elasticsearch from elasticsearch import Elasticsearch
from unittest.mock import patch from unittest.mock import patch
@ -1782,7 +1782,7 @@ class TestAddonSearchView(ESTestCase):
# Exclude addon1 and addon2 by pk. # Exclude addon1 and addon2 by pk.
data = self.perform_search( data = self.perform_search(
self.url, {'exclude_addons': u','.join( self.url, {'exclude_addons': u','.join(
map(six.text_type, (addon2.pk, addon1.pk)))}) map(str, (addon2.pk, addon1.pk)))})
assert len(data['results']) == 1 assert len(data['results']) == 1
assert data['count'] == 1 assert data['count'] == 1
@ -1791,7 +1791,7 @@ class TestAddonSearchView(ESTestCase):
# Exclude addon1 by pk and addon3 by slug. # Exclude addon1 by pk and addon3 by slug.
data = self.perform_search( data = self.perform_search(
self.url, {'exclude_addons': u','.join( self.url, {'exclude_addons': u','.join(
(six.text_type(addon1.pk), addon3.slug))}) (str(addon1.pk), addon3.slug))})
assert len(data['results']) == 1 assert len(data['results']) == 1
assert data['count'] == 1 assert data['count'] == 1

Просмотреть файл

@ -12,7 +12,6 @@ from django.db.models import Q
from django.forms import ValidationError from django.forms import ValidationError
from django.utils.translation import ugettext from django.utils.translation import ugettext
import six
import waffle import waffle
from django_statsd.clients import statsd from django_statsd.clients import statsd
@ -201,11 +200,10 @@ def build_static_theme_xpi_from_lwt(lwt, upload_zip):
else amo.THEME_FRAME_COLOR_DEFAULT) else amo.THEME_FRAME_COLOR_DEFAULT)
textcolor = '#%s' % (lwt.persona.textcolor or '000') textcolor = '#%s' % (lwt.persona.textcolor or '000')
lwt_header = MULTIPLE_STOPS_REGEX.sub( lwt_header = MULTIPLE_STOPS_REGEX.sub(u'.', str(lwt.persona.header))
u'.', six.text_type(lwt.persona.header))
manifest = { manifest = {
"manifest_version": 2, "manifest_version": 2,
"name": six.text_type(lwt.name) or six.text_type(lwt.slug), "name": str(lwt.name) or str(lwt.slug),
"version": '1.0', "version": '1.0',
"theme": { "theme": {
"images": { "images": {
@ -218,7 +216,7 @@ def build_static_theme_xpi_from_lwt(lwt, upload_zip):
} }
} }
if lwt.description: if lwt.description:
manifest['description'] = six.text_type(lwt.description) manifest['description'] = str(lwt.description)
# build zip with manifest and background file # build zip with manifest and background file
with zipfile.ZipFile(upload_zip, 'w', zipfile.ZIP_DEFLATED) as dest: with zipfile.ZipFile(upload_zip, 'w', zipfile.ZIP_DEFLATED) as dest:
@ -292,7 +290,7 @@ def build_webext_dictionary_from_legacy(addon, destination):
manifest = { manifest = {
'manifest_version': 2, 'manifest_version': 2,
'name': six.text_type(addon.name), 'name': str(addon.name),
'browser_specific_settings': { 'browser_specific_settings': {
'gecko': { 'gecko': {
'id': addon.guid, 'id': addon.guid,

Просмотреть файл

@ -4,8 +4,6 @@ from django.contrib.syndication.views import Feed
from django.db.transaction import non_atomic_requests from django.db.transaction import non_atomic_requests
from django.utils.decorators import method_decorator from django.utils.decorators import method_decorator
import six
class BaseFeed(Feed): class BaseFeed(Feed):
""" """
@ -43,5 +41,5 @@ class BaseFeed(Feed):
'title' 'title'
) )
if data and attname in problematic_keys: if data and attname in problematic_keys:
data = re.sub(self.CONTROL_CHARS_REGEXP, '', six.text_type(data)) data = re.sub(self.CONTROL_CHARS_REGEXP, '', str(data))
return data return data

Просмотреть файл

@ -1,7 +1,5 @@
from django.conf import settings from django.conf import settings
import six
import olympia.core.logger import olympia.core.logger
from olympia.constants.search import SEARCH_ANALYZER_MAP from olympia.constants.search import SEARCH_ANALYZER_MAP
@ -141,7 +139,7 @@ class BaseSearchIndexer(object):
extend_with_me = { extend_with_me = {
'%s_translations' % field: [ '%s_translations' % field: [
{'lang': to_language(lang), 'string': six.text_type(string)} {'lang': to_language(lang), 'string': str(string)}
for lang, string in obj.translations[getattr(obj, db_field)] for lang, string in obj.translations[getattr(obj, db_field)]
if string if string
] ]
@ -162,9 +160,7 @@ class BaseSearchIndexer(object):
default_locale = default_locale.lower() if default_locale else None default_locale = default_locale.lower() if default_locale else None
value = translations.get(default_locale, getattr(obj, field)) value = translations.get(default_locale, getattr(obj, field))
return { return {field: str(value) if value else ''}
field: six.text_type(value) if value else ''
}
@classmethod @classmethod
def extract_field_analyzed_translations(cls, obj, field, db_field=None): def extract_field_analyzed_translations(cls, obj, field, db_field=None):
@ -179,9 +175,9 @@ class BaseSearchIndexer(object):
# Indices for each language. languages is a list of locales we want to # Indices for each language. languages is a list of locales we want to
# index with analyzer if the string's locale matches. # index with analyzer if the string's locale matches.
for analyzer, languages in six.iteritems(SEARCH_ANALYZER_MAP): for analyzer, languages in SEARCH_ANALYZER_MAP.items():
extend_with_me['%s_l10n_%s' % (field, analyzer)] = list( extend_with_me['%s_l10n_%s' % (field, analyzer)] = list(
set(six.text_type(string) for locale, string set(str(string) for locale, string
in obj.translations[getattr(obj, db_field)] in obj.translations[getattr(obj, db_field)]
if locale.lower() in languages and string)) if locale.lower() in languages and string))

Просмотреть файл

@ -10,8 +10,6 @@ from django.core.management.base import BaseCommand, CommandError
from django.contrib.staticfiles.finders import find as find_static_path from django.contrib.staticfiles.finders import find as find_static_path
from django.utils.encoding import force_bytes from django.utils.encoding import force_bytes
import six
from olympia.lib.jingo_minify_helpers import ensure_path_exists from olympia.lib.jingo_minify_helpers import ensure_path_exists
@ -73,8 +71,8 @@ class Command(BaseCommand):
# - Concat all files into one # - Concat all files into one
# - Cache bust all images in CSS files # - Cache bust all images in CSS files
# - Minify the concatted files # - Minify the concatted files
for ftype, bundle in six.iteritems(settings.MINIFY_BUNDLES): for ftype, bundle in settings.MINIFY_BUNDLES.items():
for name, files in six.iteritems(bundle): for name, files in bundle.items():
# Set the paths to the files. # Set the paths to the files.
concatted_file = os.path.join( concatted_file = os.path.join(
settings.ROOT, 'static', settings.ROOT, 'static',

Просмотреть файл

@ -5,7 +5,6 @@ from django.template import loader
from django.utils import safestring from django.utils import safestring
import jinja2 import jinja2
import six
from rest_framework.request import Request from rest_framework.request import Request
@ -53,10 +52,10 @@ def _is_dupe(msg, request):
return False return False
try: try:
smsg = six.text_type(msg) smsg = str(msg)
is_dupe = False is_dupe = False
for message in storage: for message in storage:
if six.text_type(message) == smsg: if str(message) == smsg:
# We can't return from here because we need to tell Django not # We can't return from here because we need to tell Django not
# to consume the messages. # to consume the messages.
is_dupe = True is_dupe = True

Просмотреть файл

@ -3,6 +3,8 @@ import re
import socket import socket
import uuid import uuid
from urllib.parse import quote
from django.conf import settings from django.conf import settings
from django.contrib.auth.middleware import AuthenticationMiddleware from django.contrib.auth.middleware import AuthenticationMiddleware
from django.contrib.auth.models import AnonymousUser from django.contrib.auth.models import AnonymousUser
@ -19,7 +21,6 @@ from django.utils.encoding import force_text, iri_to_uri
from django.utils.translation import activate, ugettext_lazy as _ from django.utils.translation import activate, ugettext_lazy as _
from rest_framework import permissions from rest_framework import permissions
from six.moves.urllib.parse import quote
import MySQLdb as mysql import MySQLdb as mysql

Просмотреть файл

@ -1,11 +1,11 @@
import os import os
import io
import socket import socket
import traceback import traceback
from django.conf import settings from django.conf import settings
import requests import requests
import six
from kombu import Connection from kombu import Connection
from PIL import Image from PIL import Image
@ -64,7 +64,7 @@ def libraries():
libraries_results = [] libraries_results = []
status = '' status = ''
try: try:
Image.new('RGB', (16, 16)).save(six.BytesIO(), 'JPEG') Image.new('RGB', (16, 16)).save(io.BytesIO(), 'JPEG')
libraries_results.append(('PIL+JPEG', True, 'Got it!')) libraries_results.append(('PIL+JPEG', True, 'Got it!'))
except Exception as e: except Exception as e:
msg = "Failed to create a jpeg image: %s" % e msg = "Failed to create a jpeg image: %s" % e

Просмотреть файл

@ -2,6 +2,8 @@ import json as jsonlib
import os import os
import random import random
from urllib.parse import urljoin
from django.conf import settings from django.conf import settings
from django.core.exceptions import ObjectDoesNotExist from django.core.exceptions import ObjectDoesNotExist
from django.forms import CheckboxInput from django.forms import CheckboxInput
@ -14,14 +16,12 @@ from django.utils.translation import (
get_language, to_locale, trim_whitespace, ugettext) get_language, to_locale, trim_whitespace, ugettext)
import jinja2 import jinja2
import six
import waffle import waffle
from babel.support import Format from babel.support import Format
from django_jinja import library from django_jinja import library
from rest_framework.reverse import reverse as drf_reverse from rest_framework.reverse import reverse as drf_reverse
from rest_framework.settings import api_settings from rest_framework.settings import api_settings
from six.moves.urllib_parse import urljoin
from olympia.amo import urlresolvers, utils from olympia.amo import urlresolvers, utils
from olympia.constants.licenses import PERSONA_LICENSES_IDS from olympia.constants.licenses import PERSONA_LICENSES_IDS
@ -38,7 +38,7 @@ library.global_function(utils.randslice)
# Mark a lazy marked instance as safe but keep # Mark a lazy marked instance as safe but keep
# it lazy # it lazy
mark_safe_lazy = lazy(mark_safe, six.text_type) mark_safe_lazy = lazy(mark_safe, str)
@library.global_function @library.global_function
@ -205,14 +205,14 @@ def strip_controls(s):
""" """
# Translation table of control characters. # Translation table of control characters.
control_trans = dict((n, None) for n in range(32) if n not in [10, 13]) control_trans = dict((n, None) for n in range(32) if n not in [10, 13])
rv = six.text_type(s).translate(control_trans) rv = str(s).translate(control_trans)
return jinja2.Markup(rv) if isinstance(s, jinja2.Markup) else rv return jinja2.Markup(rv) if isinstance(s, jinja2.Markup) else rv
@library.filter @library.filter
def external_url(url): def external_url(url):
"""Bounce a URL off outgoing.prod.mozaws.net.""" """Bounce a URL off outgoing.prod.mozaws.net."""
return urlresolvers.get_outgoing_url(six.text_type(url)) return urlresolvers.get_outgoing_url(str(url))
@library.filter @library.filter
@ -227,7 +227,7 @@ def license_link(license):
"""Link to a code license, including icon where applicable.""" """Link to a code license, including icon where applicable."""
# If passed in an integer, try to look up the License. # If passed in an integer, try to look up the License.
from olympia.versions.models import License from olympia.versions.models import License
if isinstance(license, six.integer_types): if isinstance(license, int):
if license in PERSONA_LICENSES_IDS: if license in PERSONA_LICENSES_IDS:
# Grab built-in license. # Grab built-in license.
license = PERSONA_LICENSES_IDS[license] license = PERSONA_LICENSES_IDS[license]

Просмотреть файл

@ -2,7 +2,6 @@
import os import os
import random import random
import shutil import shutil
import six
import socket import socket
import struct import struct
import time import time
@ -11,7 +10,7 @@ from contextlib import contextmanager
from datetime import datetime, timedelta from datetime import datetime, timedelta
from functools import partial from functools import partial
from importlib import import_module from importlib import import_module
from six.moves.urllib_parse import parse_qs, urlparse from urllib.parse import parse_qs, urlparse
from tempfile import NamedTemporaryFile from tempfile import NamedTemporaryFile
from django import forms, test from django import forms, test
@ -191,7 +190,7 @@ def check_links(expected, elements, selected=None, verify=True):
if isinstance(item, tuple): if isinstance(item, tuple):
text, link = item text, link = item
# Or list item could be `link`. # Or list item could be `link`.
elif isinstance(item, six.string_types): elif isinstance(item, str):
text, link = None, item text, link = None, item
e = elements.eq(idx) e = elements.eq(idx)
@ -211,8 +210,8 @@ def check_links(expected, elements, selected=None, verify=True):
def assert_url_equal(url, expected, compare_host=False): def assert_url_equal(url, expected, compare_host=False):
"""Compare url paths and query strings.""" """Compare url paths and query strings."""
parsed = urlparse(six.text_type(url)) parsed = urlparse(str(url))
parsed_expected = urlparse(six.text_type(expected)) parsed_expected = urlparse(str(expected))
compare_url_part(parsed.path, parsed_expected.path) compare_url_part(parsed.path, parsed_expected.path)
compare_url_part(parse_qs(parsed.query), parse_qs(parsed_expected.query)) compare_url_part(parse_qs(parsed.query), parse_qs(parsed_expected.query))
if compare_host: if compare_host:
@ -464,7 +463,7 @@ class TestCase(PatchMixin, InitializeSessionMixin, test.TestCase):
# There are multiple contexts so iter all of them. # There are multiple contexts so iter all of them.
tpl = response.context tpl = response.context
for ctx in tpl: for ctx in tpl:
for k, v in six.iteritems(ctx): for k, v in ctx.items():
if isinstance(v, (forms.BaseForm, forms.formsets.BaseFormSet)): if isinstance(v, (forms.BaseForm, forms.formsets.BaseFormSet)):
if isinstance(v, forms.formsets.BaseFormSet): if isinstance(v, forms.formsets.BaseFormSet):
# Concatenate errors from each form in the formset. # Concatenate errors from each form in the formset.
@ -495,7 +494,7 @@ class TestCase(PatchMixin, InitializeSessionMixin, test.TestCase):
""" """
# Try parsing the string if it's not a datetime. # Try parsing the string if it's not a datetime.
if isinstance(dt, six.string_types): if isinstance(dt, str):
try: try:
dt = dateutil_parser(dt) dt = dateutil_parser(dt)
except ValueError as e: except ValueError as e:
@ -670,8 +669,7 @@ def addon_factory(
default_locale = kw.get('default_locale', settings.LANGUAGE_CODE) default_locale = kw.get('default_locale', settings.LANGUAGE_CODE)
# Keep as much unique data as possible in the uuid: '-' aren't important. # Keep as much unique data as possible in the uuid: '-' aren't important.
name = kw.pop('name', u'Addôn %s' % name = kw.pop('name', u'Addôn %s' % str(uuid.uuid4()).replace('-', ''))
six.text_type(uuid.uuid4()).replace('-', ''))
slug = kw.pop('slug', None) slug = kw.pop('slug', None)
if slug is None: if slug is None:
slug = name.replace(' ', '-').lower()[:30] slug = name.replace(' ', '-').lower()[:30]
@ -696,7 +694,7 @@ def addon_factory(
kwargs['summary'] = u'Summary for %s' % name kwargs['summary'] = u'Summary for %s' % name
if type_ not in [amo.ADDON_PERSONA, amo.ADDON_SEARCH]: if type_ not in [amo.ADDON_PERSONA, amo.ADDON_SEARCH]:
# Personas and search engines don't need guids # Personas and search engines don't need guids
kwargs['guid'] = kw.pop('guid', '{%s}' % six.text_type(uuid.uuid4())) kwargs['guid'] = kw.pop('guid', '{%s}' % str(uuid.uuid4()))
kwargs.update(kw) kwargs.update(kw)
# Save 1. # Save 1.

Просмотреть файл

@ -1,5 +1,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import os import os
import io
from importlib import import_module from importlib import import_module
from django.conf import settings from django.conf import settings
@ -9,7 +11,6 @@ from django.test.utils import override_settings
from unittest import mock from unittest import mock
import pytest import pytest
import six
def sample_cron_job(*args): def sample_cron_job(*args):
@ -42,7 +43,7 @@ def test_cron_command_invalid_job():
def test_cron_jobs_setting(): def test_cron_jobs_setting():
for name, path in six.iteritems(settings.CRON_JOBS): for name, path in settings.CRON_JOBS.items():
module = import_module(path) module = import_module(path)
getattr(module, name) getattr(module, name)
@ -54,7 +55,7 @@ def test_compress_assets_command_without_git():
# Capture output to avoid it being logged and allow us to validate it # Capture output to avoid it being logged and allow us to validate it
# later if needed # later if needed
out = six.StringIO() out = io.StringIO()
call_command('compress_assets', stdout=out) call_command('compress_assets', stdout=out)
build_id_file = os.path.realpath(os.path.join(settings.ROOT, 'build.py')) build_id_file = os.path.realpath(os.path.join(settings.ROOT, 'build.py'))
@ -86,7 +87,7 @@ def test_compress_assets_correctly_fetches_static_images(settings, tmpdir):
# Capture output to avoid it being logged and allow us to validate it # Capture output to avoid it being logged and allow us to validate it
# later if needed # later if needed
out = six.StringIO() out = io.StringIO()
# Now run compress and collectstatic # Now run compress and collectstatic
call_command('compress_assets', force=True, stdout=out) call_command('compress_assets', force=True, stdout=out)

Просмотреть файл

@ -3,7 +3,8 @@ import mimetypes
import os import os
from datetime import datetime, timedelta from datetime import datetime, timedelta
from six.moves.urllib_parse import urljoin from urllib.parse import urljoin
from unittest.mock import Mock, patch
from django.conf import settings from django.conf import settings
from django.core.files.uploadedfile import SimpleUploadedFile from django.core.files.uploadedfile import SimpleUploadedFile
@ -14,7 +15,6 @@ from django.utils.encoding import force_bytes
import pytest import pytest
from unittest.mock import Mock, patch
from pyquery import PyQuery from pyquery import PyQuery
import olympia import olympia

Просмотреть файл

@ -3,7 +3,6 @@ from django import test
from django.test.client import RequestFactory from django.test.client import RequestFactory
import pytest import pytest
import six
from unittest.mock import patch from unittest.mock import patch
from pyquery import PyQuery as pq from pyquery import PyQuery as pq
@ -77,28 +76,14 @@ def test_source_with_wrong_unicode_get():
response = test.Client().get('/firefox/collections/mozmj/autumn/' response = test.Client().get('/firefox/collections/mozmj/autumn/'
'?source=firefoxsocialmedia\x14\x85') '?source=firefoxsocialmedia\x14\x85')
assert response.status_code == 302 assert response.status_code == 302
# Django's behaviour for URLs containing unicode characters is different assert response['Location'].endswith(
# under Python 2 and 3. This is fine though, as browsers should send URLs '?source=firefoxsocialmedia%14%C3%82%C2%85')
# urlencoded, and that's tested above in test_redirect_with_unicode_get().
# We just need to make sure we're not crashing on such URLs.
if six.PY2:
assert response['Location'].endswith('?source=firefoxsocialmedia%14')
else:
assert response['Location'].endswith(
'?source=firefoxsocialmedia%14%C3%82%C2%85')
def test_trailing_slash_middleware(): def test_trailing_slash_middleware():
response = test.Client().get(u'/en-US/about/?xxx=\xc3') response = test.Client().get(u'/en-US/about/?xxx=\xc3')
assert response.status_code == 301 assert response.status_code == 301
# Django's behaviour for URLs containing unicode characters is different assert response['Location'].endswith('/en-US/about?xxx=%C3%83%C2%83')
# under Python 2 and 3. This is fine though, as browsers should send URLs
# urlencoded, and that's tested above in test_redirect_with_unicode_get().
# We just need to make sure we're not crashing on such URLs.
if six.PY2:
assert response['Location'].endswith('/en-US/about?xxx=%C3%83')
else:
assert response['Location'].endswith('/en-US/about?xxx=%C3%83%C2%83')
class AdminMessageTest(TestCase): class AdminMessageTest(TestCase):
@ -140,7 +125,7 @@ def test_request_id_middleware(client):
"""Test that we add a request id to every response""" """Test that we add a request id to every response"""
response = client.get(reverse('devhub.index')) response = client.get(reverse('devhub.index'))
assert response.status_code == 200 assert response.status_code == 200
assert isinstance(response['X-AMO-Request-ID'], six.string_types) assert isinstance(response['X-AMO-Request-ID'], str)
# Test that we set `request.request_id` too # Test that we set `request.request_id` too

Просмотреть файл

@ -2,7 +2,6 @@ from django.core.paginator import (
EmptyPage, InvalidPage, PageNotAnInteger, Paginator) EmptyPage, InvalidPage, PageNotAnInteger, Paginator)
import pytest import pytest
import six
from unittest.mock import MagicMock, Mock from unittest.mock import MagicMock, Mock
@ -107,7 +106,7 @@ class TestSearchPaginator(TestCase):
# unfortunately since `pytest.raises` won't check the exact # unfortunately since `pytest.raises` won't check the exact
# instance but also accepts parent exceptions inherited. # instance but also accepts parent exceptions inherited.
assert ( assert (
six.text_type(exc.value) == str(exc.value) ==
'That page number is too high for the current page size') 'That page number is too high for the current page size')
assert isinstance(exc.value, InvalidPage) assert isinstance(exc.value, InvalidPage)

Просмотреть файл

@ -8,7 +8,6 @@ from django.core.mail import EmailMessage
from django.utils import translation from django.utils import translation
from unittest import mock from unittest import mock
import six
from celery.exceptions import Retry from celery.exceptions import Retry
@ -213,7 +212,7 @@ class TestSendMail(TestCase):
assert '<a href' not in message1, 'text-only email contained HTML!' assert '<a href' not in message1, 'text-only email contained HTML!'
assert '<a href' in message2, 'HTML email did not contain HTML!' assert '<a href' in message2, 'HTML email did not contain HTML!'
unsubscribe_msg = six.text_type(notifications.individual_contact.label) unsubscribe_msg = str(notifications.individual_contact.label)
assert unsubscribe_msg in message1 assert unsubscribe_msg in message1
assert unsubscribe_msg in message2 assert unsubscribe_msg in message2

Просмотреть файл

@ -3,7 +3,6 @@ import os
import json import json
import pytest import pytest
import six
from django.conf import settings from django.conf import settings
@ -29,7 +28,7 @@ def test_base_paths_bytestring(key):
See https://github.com/mozilla/addons-server/issues/3579 for context. See https://github.com/mozilla/addons-server/issues/3579 for context.
""" """
assert isinstance(getattr(settings, key), six.string_types) assert isinstance(getattr(settings, key), str)
def test_raven_release_config(): def test_raven_release_config():

Просмотреть файл

@ -9,7 +9,6 @@ from django.utils.functional import cached_property
import freezegun import freezegun
from unittest import mock from unittest import mock
import pytest import pytest
import six
from babel import Locale from babel import Locale
@ -44,7 +43,7 @@ class TestAttachTransDict(TestCase):
# it for __str__. We depend on this behaviour later in the test. # it for __str__. We depend on this behaviour later in the test.
assert '<script>' in addon.description.localized_string assert '<script>' in addon.description.localized_string
assert '<script>' not in addon.description.localized_string_clean assert '<script>' not in addon.description.localized_string_clean
assert '<script>' not in six.text_type(addon.description) assert '<script>' not in str(addon.description)
# Attach trans dict. # Attach trans dict.
attach_trans_dict(Addon, [addon]) attach_trans_dict(Addon, [addon])
@ -60,18 +59,15 @@ class TestAttachTransDict(TestCase):
# Build expected translations dict. # Build expected translations dict.
expected_translations = { expected_translations = {
addon.eula_id: [('en-us', six.text_type(addon.eula))], addon.eula_id: [('en-us', str(addon.eula))],
addon.description_id: [ addon.description_id: [('en-us', str(addon.description))],
('en-us', six.text_type(addon.description))],
addon.developer_comments_id: addon.developer_comments_id:
[('en-us', six.text_type(addon.developer_comments))], [('en-us', str(addon.developer_comments))],
addon.summary_id: [('en-us', six.text_type(addon.summary))], addon.summary_id: [('en-us', str(addon.summary))],
addon.homepage_id: [('en-us', six.text_type(addon.homepage))], addon.homepage_id: [('en-us', str(addon.homepage))],
addon.name_id: [('en-us', six.text_type(addon.name))], addon.name_id: [('en-us', str(addon.name))],
addon.support_email_id: [ addon.support_email_id: [('en-us', str(addon.support_email))],
('en-us', six.text_type(addon.support_email))], addon.support_url_id: [('en-us', str(addon.support_url))]
addon.support_url_id: [
('en-us', six.text_type(addon.support_url))]
} }
assert translations == expected_translations assert translations == expected_translations

Просмотреть файл

@ -4,6 +4,8 @@ import re
import sys import sys
from datetime import datetime, timedelta from datetime import datetime, timedelta
from unittest import mock
from urllib.parse import urlparse
import django import django
from django import test from django import test
@ -11,13 +13,11 @@ from django.conf import settings
from django.test.utils import override_settings from django.test.utils import override_settings
from django.utils.encoding import force_text from django.utils.encoding import force_text
from unittest import mock
import pytest import pytest
from lxml import etree from lxml import etree
from unittest.mock import patch from unittest.mock import patch
from pyquery import PyQuery as pq from pyquery import PyQuery as pq
from six.moves.urllib_parse import urlparse
from olympia import amo, core from olympia import amo, core
from olympia.access import acl from olympia.access import acl

Просмотреть файл

@ -4,6 +4,7 @@ import hmac
import re import re
from threading import local from threading import local
from urllib.parse import quote
from django import urls from django import urls
from django.conf import settings from django.conf import settings
@ -13,9 +14,7 @@ from django.utils.translation.trans_real import parse_accept_lang_header
import bleach import bleach
import jinja2 import jinja2
import six
from six.moves.urllib_parse import quote
from olympia import amo from olympia import amo
@ -241,13 +240,13 @@ def linkify_escape(text):
# Parameters are already escaped. # Parameters are already escaped.
return u'<a href="{0}">{0}</a>'.format(match.group(0)) return u'<a href="{0}">{0}</a>'.format(match.group(0))
return URL_RE.sub(linkify, six.text_type(jinja2.escape(text))) return URL_RE.sub(linkify, str(jinja2.escape(text)))
def linkify_with_outgoing(text): def linkify_with_outgoing(text):
"""Wrapper around bleach.linkify: uses get_outgoing_url.""" """Wrapper around bleach.linkify: uses get_outgoing_url."""
callbacks = [linkify_bounce_url_callback, bleach.callbacks.nofollow] callbacks = [linkify_bounce_url_callback, bleach.callbacks.nofollow]
return bleach.linkify(six.text_type(text), callbacks=callbacks) return bleach.linkify(str(text), callbacks=callbacks)
def lang_from_accept_header(header): def lang_from_accept_header(header):

Просмотреть файл

@ -11,13 +11,13 @@ import random
import re import re
import scandir import scandir
import shutil import shutil
import six
import string import string
import subprocess import subprocess
import time import time
import unicodedata import unicodedata
from six.moves.urllib_parse import parse_qsl, ParseResult, unquote_to_bytes from urllib.parse import (
parse_qsl, ParseResult, unquote_to_bytes, urlencode as urllib_urlencode)
import django.core.mail import django.core.mail
@ -221,12 +221,12 @@ def send_mail(subject, message, from_email=None, recipient_list=None,
if not recipient_list: if not recipient_list:
return True return True
if isinstance(recipient_list, six.string_types): if isinstance(recipient_list, str):
raise ValueError('recipient_list should be a list, not a string.') raise ValueError('recipient_list should be a list, not a string.')
# Check against user notification settings # Check against user notification settings
if perm_setting: if perm_setting:
if isinstance(perm_setting, six.string_types): if isinstance(perm_setting, str):
perm_setting = notifications.NOTIFICATIONS_BY_SHORT[perm_setting] perm_setting = notifications.NOTIFICATIONS_BY_SHORT[perm_setting]
perms = dict(UserNotification.objects perms = dict(UserNotification.objects
.filter(user__email__in=recipient_list, .filter(user__email__in=recipient_list,
@ -252,8 +252,8 @@ def send_mail(subject, message, from_email=None, recipient_list=None,
from_email = settings.DEFAULT_FROM_EMAIL from_email = settings.DEFAULT_FROM_EMAIL
if cc: if cc:
# If not six.string_types, assume it is already a list. # If not str, assume it is already a list.
if isinstance(cc, six.string_types): if isinstance(cc, str):
cc = [cc] cc = [cc]
if not headers: if not headers:
@ -444,10 +444,9 @@ def chunked(seq, n):
def urlencode(items): def urlencode(items):
"""A Unicode-safe URLencoder.""" """A Unicode-safe URLencoder."""
try: try:
return six.moves.urllib_parse.urlencode(items) return urllib_urlencode(items)
except UnicodeEncodeError: except UnicodeEncodeError:
return six.moves.urllib_parse.urlencode( return urllib_urlencode([(k, force_bytes(v)) for k, v in items])
[(k, force_bytes(v)) for k, v in items])
def randslice(qs, limit, exclude=None): def randslice(qs, limit, exclude=None):
@ -750,7 +749,7 @@ class HttpResponseSendFile(HttpResponse):
super(HttpResponseSendFile, self).__init__('', status=status, super(HttpResponseSendFile, self).__init__('', status=status,
content_type=content_type) content_type=content_type)
header_path = self.path header_path = self.path
if isinstance(header_path, six.text_type): if isinstance(header_path, str):
header_path = header_path.encode('utf8') header_path = header_path.encode('utf8')
if settings.XSENDFILE: if settings.XSENDFILE:
self[settings.XSENDFILE_HEADER] = header_path self[settings.XSENDFILE_HEADER] = header_path
@ -821,7 +820,7 @@ def escape_all(value):
Only linkify full urls, including a scheme, if "linkify_only_full" is True. Only linkify full urls, including a scheme, if "linkify_only_full" is True.
""" """
if isinstance(value, six.string_types): if isinstance(value, str):
value = jinja2.escape(force_text(value)) value = jinja2.escape(force_text(value))
value = linkify_with_outgoing(value) value = linkify_with_outgoing(value)
return value return value
@ -829,7 +828,7 @@ def escape_all(value):
for i, lv in enumerate(value): for i, lv in enumerate(value):
value[i] = escape_all(lv) value[i] = escape_all(lv)
elif isinstance(value, dict): elif isinstance(value, dict):
for k, lv in six.iteritems(value): for k, lv in value.items():
value[k] = escape_all(lv) value[k] = escape_all(lv)
elif isinstance(value, Translation): elif isinstance(value, Translation):
value = jinja2.escape(force_text(value)) value = jinja2.escape(force_text(value))
@ -903,7 +902,7 @@ def attach_trans_dict(model, objs):
converted_translation = new_class() converted_translation = new_class()
converted_translation.__dict__ = translation.__dict__ converted_translation.__dict__ = translation.__dict__
return (converted_translation.locale.lower(), return (converted_translation.locale.lower(),
six.text_type(converted_translation)) str(converted_translation))
# Build and attach translations for each field on each object. # Build and attach translations for each field on each object.
for obj in objs: for obj in objs:

Просмотреть файл

@ -10,8 +10,6 @@ from django.db.transaction import non_atomic_requests
from django.http import HttpResponse, JsonResponse from django.http import HttpResponse, JsonResponse
from django.views.decorators.cache import never_cache from django.views.decorators.cache import never_cache
import six
from django_statsd.clients import statsd from django_statsd.clients import statsd
from rest_framework.exceptions import NotFound from rest_framework.exceptions import NotFound
@ -78,7 +76,7 @@ def handler404(request, exception=None, **kwargs):
if request.is_api: if request.is_api:
# It's a v3+ api request # It's a v3+ api request
return JsonResponse( return JsonResponse(
{'detail': six.text_type(NotFound.default_detail)}, status=404) {'detail': str(NotFound.default_detail)}, status=404)
# X_IS_MOBILE_AGENTS is set by nginx as an env variable when it detects # X_IS_MOBILE_AGENTS is set by nginx as an env variable when it detects
# a mobile User Agent or when the mamo cookie is present. # a mobile User Agent or when the mamo cookie is present.
if request.META.get('X_IS_MOBILE_AGENTS') == '1': if request.META.get('X_IS_MOBILE_AGENTS') == '1':

Просмотреть файл

@ -3,8 +3,6 @@ from django.core.exceptions import ObjectDoesNotExist, ValidationError
from django.utils.encoding import smart_text from django.utils.encoding import smart_text
from django.utils.translation import get_language, ugettext_lazy as _ from django.utils.translation import get_language, ugettext_lazy as _
import six
from rest_framework import fields, serializers from rest_framework import fields, serializers
from olympia.amo.utils import to_language from olympia.amo.utils import to_language
@ -96,13 +94,11 @@ class TranslationSerializerField(fields.Field):
def fetch_all_translations(self, obj, source, field): def fetch_all_translations(self, obj, source, field):
translations = field.__class__.objects.filter( translations = field.__class__.objects.filter(
id=field.id, localized_string__isnull=False) id=field.id, localized_string__isnull=False)
return {to_language(trans.locale): six.text_type(trans) return {to_language(trans.locale): str(trans)
for trans in translations} if translations else None for trans in translations} if translations else None
def fetch_single_translation(self, obj, source, field, requested_language): def fetch_single_translation(self, obj, source, field, requested_language):
return ( return {to_language(field.locale): str(field)} if field else None
{to_language(field.locale): six.text_type(field)} if field
else None)
def get_attribute(self, obj): def get_attribute(self, obj):
source = self.source or self.field_name source = self.source or self.field_name
@ -128,7 +124,7 @@ class TranslationSerializerField(fields.Field):
return val return val
def to_internal_value(self, data): def to_internal_value(self, data):
if isinstance(data, six.string_types): if isinstance(data, str):
self.validate(data) self.validate(data)
return data.strip() return data.strip()
elif isinstance(data, dict): elif isinstance(data, dict):
@ -136,7 +132,7 @@ class TranslationSerializerField(fields.Field):
for key, value in data.items(): for key, value in data.items():
data[key] = value and value.strip() data[key] = value and value.strip()
return data return data
return six.text_type(data) return str(data)
def validate(self, value): def validate(self, value):
if not self.flat and not isinstance(value, dict): if not self.flat and not isinstance(value, dict):
@ -146,7 +142,7 @@ class TranslationSerializerField(fields.Field):
value_too_short = True value_too_short = True
if isinstance(value, six.string_types): if isinstance(value, str):
if self.min_length and len(value.strip()) >= self.min_length: if self.min_length and len(value.strip()) >= self.min_length:
value_too_short = False value_too_short = False
else: else:

Просмотреть файл

@ -1,5 +1,4 @@
import csv import csv
import six
from django.core.management.base import BaseCommand from django.core.management.base import BaseCommand
from django.db import transaction from django.db import transaction
@ -11,7 +10,7 @@ class Command(BaseCommand):
help = 'Revoke the API (secret, key) tuples from specified csv file.' help = 'Revoke the API (secret, key) tuples from specified csv file.'
def add_arguments(self, parser): def add_arguments(self, parser):
parser.add_argument('csv_file', type=six.text_type) parser.add_argument('csv_file', type=str)
def handle(self, *args, **options): def handle(self, *args, **options):
revoked_count = 0 revoked_count = 0

Просмотреть файл

@ -3,7 +3,7 @@ import os
import random import random
from django.db import models from django.db import models
from django.utils.encoding import force_text, python_2_unicode_compatible from django.utils.encoding import force_text
from aesfield.field import AESField from aesfield.field import AESField
@ -21,7 +21,6 @@ API_KEY_TYPES = [
] ]
@python_2_unicode_compatible
class APIKey(ModelBase): class APIKey(ModelBase):
""" """
A developer's key/secret pair to access the API. A developer's key/secret pair to access the API.

Просмотреть файл

@ -3,6 +3,7 @@ import time
from calendar import timegm from calendar import timegm
from datetime import datetime, timedelta from datetime import datetime, timedelta
from unittest import mock
from django.conf import settings from django.conf import settings
from django.core import signing from django.core import signing
@ -11,8 +12,6 @@ from django.urls import reverse
from django.utils.encoding import force_bytes from django.utils.encoding import force_bytes
import jwt import jwt
from unittest import mock
import six
from freezegun import freeze_time from freezegun import freeze_time
from rest_framework.exceptions import AuthenticationFailed from rest_framework.exceptions import AuthenticationFailed
@ -77,8 +76,8 @@ class TestJWTKeyAuthentication(JWTAuthKeyTester, TestCase):
issued_at = int(time.mktime(datetime.utcnow().timetuple())) issued_at = int(time.mktime(datetime.utcnow().timetuple()))
payload = { payload = {
'iss': api_key.key, 'iss': api_key.key,
'iat': six.text_type(issued_at), 'iat': str(issued_at),
'exp': six.text_type( 'exp': str(
issued_at + settings.MAX_APIKEY_JWT_AUTH_TOKEN_LIFETIME), issued_at + settings.MAX_APIKEY_JWT_AUTH_TOKEN_LIFETIME),
} }
token = self.encode_token_payload(payload, api_key.secret) token = self.encode_token_payload(payload, api_key.secret)

Просмотреть файл

@ -1,10 +1,9 @@
import os.path import os.path
import io
from django.conf import settings from django.conf import settings
from django.core.management import call_command from django.core.management import call_command
from six import StringIO
from olympia.amo.tests import TestCase, user_factory from olympia.amo.tests import TestCase, user_factory
from olympia.api.models import APIKey from olympia.api.models import APIKey
@ -20,7 +19,7 @@ class TestRevokeAPIKeys(TestCase):
# The test csv does not contain an entry for this user. # The test csv does not contain an entry for this user.
apikey = APIKey.new_jwt_credentials(user=user) apikey = APIKey.new_jwt_credentials(user=user)
old_secret = apikey.secret old_secret = apikey.secret
stdout = StringIO() stdout = io.StringIO()
call_command('revoke_api_keys', self.csv_path, stdout=stdout) call_command('revoke_api_keys', self.csv_path, stdout=stdout)
stdout.seek(0) stdout.seek(0)
output = stdout.readlines() output = stdout.readlines()
@ -44,7 +43,7 @@ class TestRevokeAPIKeys(TestCase):
apikey = APIKey.objects.create( apikey = APIKey.objects.create(
key='user:{}:{}'.format(user.pk, '333'), secret=right_secret, key='user:{}:{}'.format(user.pk, '333'), secret=right_secret,
user=user, is_active=None) # inactive APIKey. user=user, is_active=None) # inactive APIKey.
stdout = StringIO() stdout = io.StringIO()
call_command('revoke_api_keys', self.csv_path, stdout=stdout) call_command('revoke_api_keys', self.csv_path, stdout=stdout)
stdout.seek(0) stdout.seek(0)
output = stdout.readlines() output = stdout.readlines()
@ -68,7 +67,7 @@ class TestRevokeAPIKeys(TestCase):
apikey = APIKey.objects.create( apikey = APIKey.objects.create(
key='user:{}:{}'.format(user.pk, '666'), secret=right_secret, key='user:{}:{}'.format(user.pk, '666'), secret=right_secret,
user=user, is_active=True) user=user, is_active=True)
stdout = StringIO() stdout = io.StringIO()
call_command('revoke_api_keys', self.csv_path, stdout=stdout) call_command('revoke_api_keys', self.csv_path, stdout=stdout)
stdout.seek(0) stdout.seek(0)
output = stdout.readlines() output = stdout.readlines()
@ -92,7 +91,7 @@ class TestRevokeAPIKeys(TestCase):
apikey = APIKey.objects.create( apikey = APIKey.objects.create(
key='user:{}:{}'.format(user.pk, '333'), secret=right_secret, key='user:{}:{}'.format(user.pk, '333'), secret=right_secret,
user=user, is_active=True) user=user, is_active=True)
stdout = StringIO() stdout = io.StringIO()
call_command('revoke_api_keys', self.csv_path, stdout=stdout) call_command('revoke_api_keys', self.csv_path, stdout=stdout)
stdout.seek(0) stdout.seek(0)
output = stdout.readlines() output = stdout.readlines()

Просмотреть файл

@ -2,8 +2,6 @@
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.test.utils import override_settings from django.test.utils import override_settings
import six
from unittest.mock import Mock from unittest.mock import Mock
from rest_framework import serializers from rest_framework import serializers
from rest_framework.request import Request from rest_framework.request import Request
@ -62,12 +60,10 @@ class TestTranslationSerializerField(TestCase):
field.bind('name', serializer) field.bind('name', serializer)
result = field.to_representation(field.get_attribute(self.addon)) result = field.to_representation(field.get_attribute(self.addon))
expected = { expected = {
'en-US': six.text_type( 'en-US': str(Translation.objects.get(
Translation.objects.get(id=self.addon.name.id, id=self.addon.name.id, locale='en-US')),
locale='en-US')), 'es': str(Translation.objects.get(
'es': six.text_type( id=self.addon.name.id, locale='es')),
Translation.objects.get(id=self.addon.name.id,
locale='es')),
} }
assert result == expected assert result == expected
@ -84,7 +80,7 @@ class TestTranslationSerializerField(TestCase):
field.bind('name', serializer) field.bind('name', serializer)
result = field.to_representation(field.get_attribute(self.addon)) result = field.to_representation(field.get_attribute(self.addon))
expected = { expected = {
'en-US': six.text_type(self.addon.name), 'en-US': str(self.addon.name),
} }
assert result == expected assert result == expected
@ -92,7 +88,7 @@ class TestTranslationSerializerField(TestCase):
field.bind('description', serializer) field.bind('description', serializer)
result = field.to_representation(field.get_attribute(self.addon)) result = field.to_representation(field.get_attribute(self.addon))
expected = { expected = {
'en-US': six.text_type(self.addon.description), 'en-US': str(self.addon.description),
} }
assert result == expected assert result == expected
@ -171,12 +167,10 @@ class TestTranslationSerializerField(TestCase):
field = self.field_class(source='mymock.mymocked_field') field = self.field_class(source='mymock.mymocked_field')
result = field.to_internal_value(field.get_attribute(self.addon)) result = field.to_internal_value(field.get_attribute(self.addon))
expected = { expected = {
'en-US': six.text_type( 'en-US': str(Translation.objects.get(
Translation.objects.get(id=self.addon.name.id, id=self.addon.name.id, locale='en-US')),
locale='en-US')), 'es': str(Translation.objects.get(
'es': six.text_type( id=self.addon.name.id, locale='es')),
Translation.objects.get(id=self.addon.name.id,
locale='es')),
} }
assert result == expected assert result == expected
@ -247,13 +241,13 @@ class TestTranslationSerializerFieldFlat(TestTranslationSerializerField):
def _test_expected_single_locale(self, field, serializer=None): def _test_expected_single_locale(self, field, serializer=None):
field.bind('name', serializer) field.bind('name', serializer)
result = field.to_representation(field.get_attribute(self.addon)) result = field.to_representation(field.get_attribute(self.addon))
expected = six.text_type(self.addon.name) expected = str(self.addon.name)
assert result == expected assert result == expected
field.source = None field.source = None
field.bind('description', serializer) field.bind('description', serializer)
result = field.to_representation(field.get_attribute(self.addon)) result = field.to_representation(field.get_attribute(self.addon))
expected = six.text_type(self.addon.description) expected = str(self.addon.description)
assert result == expected assert result == expected
def test_to_internal_value(self): def test_to_internal_value(self):
@ -344,7 +338,7 @@ class TestESTranslationSerializerField(TestTranslationSerializerField):
field.bind('name', serializer) field.bind('name', serializer)
result = field.to_representation(field.get_attribute(self.addon)) result = field.to_representation(field.get_attribute(self.addon))
expected = { expected = {
'en-US': six.text_type(self.addon.name_translations['en-US']) 'en-US': str(self.addon.name_translations['en-US'])
} }
assert result == expected assert result == expected
@ -352,8 +346,7 @@ class TestESTranslationSerializerField(TestTranslationSerializerField):
field.bind('description', serializer) field.bind('description', serializer)
result = field.to_representation(field.get_attribute(self.addon)) result = field.to_representation(field.get_attribute(self.addon))
expected = { expected = {
'en-US': six.text_type( 'en-US': str(self.addon.description_translations['en-US'])
self.addon.description_translations['en-US'])
} }
assert result == expected assert result == expected
@ -397,13 +390,13 @@ class TestESTranslationSerializerFieldFlat(TestTranslationSerializerFieldFlat,
def _test_expected_single_locale(self, field, serializer=None): def _test_expected_single_locale(self, field, serializer=None):
field.bind('name', serializer) field.bind('name', serializer)
result = field.to_representation(field.get_attribute(self.addon)) result = field.to_representation(field.get_attribute(self.addon))
expected = six.text_type(self.addon.name_translations['en-US']) expected = str(self.addon.name_translations['en-US'])
assert result == expected assert result == expected
field.source = None field.source = None
field.bind('description', serializer) field.bind('description', serializer)
result = field.to_representation(field.get_attribute(self.addon)) result = field.to_representation(field.get_attribute(self.addon))
expected = six.text_type(self.addon.description_translations['en-US']) expected = str(self.addon.description_translations['en-US'])
assert result == expected assert result == expected

Просмотреть файл

@ -1,10 +1,10 @@
import io
from gzip import GzipFile from gzip import GzipFile
from unittest import mock
from django.conf import settings from django.conf import settings
from unittest import mock
from six import BytesIO
from olympia.amo.tests import TestCase, addon_factory, reverse_ns from olympia.amo.tests import TestCase, addon_factory, reverse_ns
from olympia.api.middleware import ( from olympia.api.middleware import (
GZipMiddlewareForAPIOnly, IdentifyAPIRequestMiddleware) GZipMiddlewareForAPIOnly, IdentifyAPIRequestMiddleware)
@ -77,5 +77,5 @@ class TestGzipMiddleware(TestCase):
assert len(response_gzipped.content) < len(response.content) assert len(response_gzipped.content) < len(response.content)
ungzipped_content = GzipFile( ungzipped_content = GzipFile(
'', 'r', 0, BytesIO(response_gzipped.content)).read() '', 'r', 0, io.BytesIO(response_gzipped.content)).read()
assert ungzipped_content == response.content assert ungzipped_content == response.content

Просмотреть файл

@ -2,8 +2,6 @@ from unittest import mock
from django.db import IntegrityError from django.db import IntegrityError
from six import text_type
from olympia.amo.tests import TestCase from olympia.amo.tests import TestCase
from olympia.users.models import UserProfile from olympia.users.models import UserProfile
@ -27,10 +25,10 @@ class TestAPIKey(TestCase):
def test_string_representation(self): def test_string_representation(self):
credentials = APIKey.new_jwt_credentials(self.user) credentials = APIKey.new_jwt_credentials(self.user)
str_creds = text_type(credentials) str_creds = str(credentials)
assert credentials.key in str_creds assert credentials.key in str_creds
assert credentials.secret not in str_creds assert credentials.secret not in str_creds
assert text_type(credentials.user) in str_creds assert str(credentials.user) in str_creds
def test_cant_have_two_active_keys_for_same_user(self): def test_cant_have_two_active_keys_for_same_user(self):
APIKey.new_jwt_credentials(self.user) APIKey.new_jwt_credentials(self.user)

Просмотреть файл

@ -1,7 +1,6 @@
from datetime import datetime from datetime import datetime
from rest_framework.test import APIClient from rest_framework.test import APIClient
from six import text_type
from olympia.amo.tests import TestCase from olympia.amo.tests import TestCase
from olympia.api.authentication import JWTKeyAuthentication from olympia.api.authentication import JWTKeyAuthentication
@ -19,7 +18,7 @@ class APIKeyAuthTestMixin(TestCase, JWTAuthKeyTester):
read_dev_agreement=datetime.today(), read_dev_agreement=datetime.today(),
) )
self.api_key = self.create_api_key( self.api_key = self.create_api_key(
self.user, text_type(self.user.pk) + ':f') self.user, str(self.user.pk) + ':f')
def authorization(self): def authorization(self):
""" """

Просмотреть файл

@ -1,5 +1,4 @@
from django.db import models from django.db import models
from django.utils.encoding import python_2_unicode_compatible
from olympia.amo.fields import PositiveAutoField from olympia.amo.fields import PositiveAutoField
from olympia.amo.models import ModelBase from olympia.amo.models import ModelBase
@ -7,7 +6,6 @@ from olympia.constants.applications import APPS_CHOICES
from olympia.versions import compare from olympia.versions import compare
@python_2_unicode_compatible
class AppVersion(ModelBase): class AppVersion(ModelBase):
id = PositiveAutoField(primary_key=True) id = PositiveAutoField(primary_key=True)
application = models.PositiveIntegerField(choices=APPS_CHOICES, application = models.PositiveIntegerField(choices=APPS_CHOICES,

Просмотреть файл

@ -1,7 +1,6 @@
import uuid import uuid
from django.db import models from django.db import models
from django.utils.encoding import python_2_unicode_compatible
from olympia import activity, amo from olympia import activity, amo
from olympia.access import acl from olympia.access import acl
@ -61,7 +60,6 @@ class CollectionManager(ManagerBase):
return self.filter(author=user.pk) return self.filter(author=user.pk)
@python_2_unicode_compatible
class Collection(ModelBase): class Collection(ModelBase):
id = PositiveAutoField(primary_key=True) id = PositiveAutoField(primary_key=True)
TYPE_CHOICES = amo.COLLECTION_CHOICES.items() TYPE_CHOICES = amo.COLLECTION_CHOICES.items()
@ -279,7 +277,6 @@ models.signals.post_delete.connect(CollectionAddon.post_delete,
dispatch_uid='coll.post_delete') dispatch_uid='coll.post_delete')
@python_2_unicode_compatible
class FeaturedCollection(ModelBase): class FeaturedCollection(ModelBase):
id = PositiveAutoField(primary_key=True) id = PositiveAutoField(primary_key=True)
application = models.PositiveIntegerField(choices=amo.APPS_CHOICES, application = models.PositiveIntegerField(choices=amo.APPS_CHOICES,

Просмотреть файл

@ -1,7 +1,6 @@
from django.core.serializers import serialize as object_serialize from django.core.serializers import serialize as object_serialize
from django.utils.translation import ugettext, ugettext_lazy as _ from django.utils.translation import ugettext, ugettext_lazy as _
import six
import waffle import waffle
from rest_framework import serializers from rest_framework import serializers
@ -88,7 +87,7 @@ class CollectionSerializer(serializers.ModelSerializer):
# if we have a localised dict of values validate them all. # if we have a localised dict of values validate them all.
if isinstance(value, dict): if isinstance(value, dict):
return {locale: self.validate_name(sub_value) return {locale: self.validate_name(sub_value)
for locale, sub_value in six.iteritems(value)} for locale, sub_value in value.items()}
if value.strip() == u'': if value.strip() == u'':
raise serializers.ValidationError( raise serializers.ValidationError(
ugettext(u'Name cannot be empty.')) ugettext(u'Name cannot be empty.'))
@ -98,7 +97,7 @@ class CollectionSerializer(serializers.ModelSerializer):
return value return value
def validate_description(self, value): def validate_description(self, value):
if has_links(clean_nl(six.text_type(value))): if has_links(clean_nl(str(value))):
# There's some links, we don't want them. # There's some links, we don't want them.
raise serializers.ValidationError( raise serializers.ValidationError(
ugettext(u'No links are allowed.')) ugettext(u'No links are allowed.'))

Просмотреть файл

@ -1,7 +1,5 @@
from django.conf import settings from django.conf import settings
import six
from pyquery import PyQuery as pq from pyquery import PyQuery as pq
from olympia import amo from olympia import amo
@ -94,7 +92,7 @@ class TestCollectionAdmin(TestCase):
assert response.status_code == 200 assert response.status_code == 200
content = response.content.decode('utf-8') content = response.content.decode('utf-8')
assert collection.slug in content assert collection.slug in content
assert six.text_type(addon.name) in content assert str(addon.name) in content
post_data = { post_data = {
# Django wants the whole form to be submitted, unfortunately. # Django wants the whole form to be submitted, unfortunately.
@ -199,7 +197,7 @@ class TestCollectionAdmin(TestCase):
assert response.status_code == 200 assert response.status_code == 200
content = response.content.decode('utf-8') content = response.content.decode('utf-8')
assert collection.slug in content assert collection.slug in content
assert six.text_type(addon.name) in content assert str(addon.name) in content
post_data = { post_data = {
# Django wants the whole form to be submitted, unfortunately. # Django wants the whole form to be submitted, unfortunately.
@ -230,7 +228,7 @@ class TestCollectionAdmin(TestCase):
assert response.status_code == 200 assert response.status_code == 200
content = response.content.decode('utf-8') content = response.content.decode('utf-8')
assert collection.slug in content assert collection.slug in content
assert six.text_type(addon2.name) in content assert str(addon2.name) in content
assert CollectionAddon.objects.filter( assert CollectionAddon.objects.filter(
collection=collection).count() == 1 collection=collection).count() == 1

Просмотреть файл

@ -1,7 +1,6 @@
import uuid import uuid
from unittest import mock from unittest import mock
import six
from olympia import amo, core from olympia import amo, core
from olympia.activity.models import ActivityLog from olympia.activity.models import ActivityLog
@ -38,13 +37,12 @@ class TestCollections(TestCase):
description='<a href="http://example.com">example.com</a> ' description='<a href="http://example.com">example.com</a> '
'http://example.com <b>foo</b> some text') 'http://example.com <b>foo</b> some text')
# All markup escaped, links are stripped. # All markup escaped, links are stripped.
assert six.text_type( assert str(c.description) == '&lt;b&gt;foo&lt;/b&gt; some text'
c.description) == '&lt;b&gt;foo&lt;/b&gt; some text'
def test_translation_default(self): def test_translation_default(self):
"""Make sure we're getting strings from the default locale.""" """Make sure we're getting strings from the default locale."""
c = Collection.objects.get(pk=512) c = Collection.objects.get(pk=512)
assert six.text_type(c.name) == 'yay' assert str(c.name) == 'yay'
def test_listed(self): def test_listed(self):
"""Make sure the manager's listed() filter works.""" """Make sure the manager's listed() filter works."""

Просмотреть файл

@ -6,8 +6,6 @@ import django.test
from django.conf import settings from django.conf import settings
from django.test.utils import override_settings from django.test.utils import override_settings
import six
from unittest.mock import patch from unittest.mock import patch
from rest_framework.fields import empty from rest_framework.fields import empty
from waffle.testutils import override_switch from waffle.testutils import override_switch
@ -239,7 +237,7 @@ class TestCollectionViewSetDetail(TestCase):
addon_data = response.data['addons'][0]['addon'] addon_data = response.data['addons'][0]['addon']
assert addon_data['id'] == addon.id assert addon_data['id'] == addon.id
assert isinstance(addon_data['name'], dict) assert isinstance(addon_data['name'], dict)
assert addon_data['name'] == {'en-US': six.text_type(addon.name)} assert addon_data['name'] == {'en-US': str(addon.name)}
# Now test the limit of addons returned # Now test the limit of addons returned
self.collection.add_addon(addon_factory()) self.collection.add_addon(addon_factory())
@ -264,14 +262,14 @@ class TestCollectionViewSetDetail(TestCase):
assert response.data['id'] == self.collection.id assert response.data['id'] == self.collection.id
addon_data = response.data['addons'][0]['addon'] addon_data = response.data['addons'][0]['addon']
assert addon_data['id'] == addon.id assert addon_data['id'] == addon.id
assert isinstance(addon_data['name']['en-US'], six.string_types) assert isinstance(addon_data['name']['en-US'], str)
assert addon_data['name'] == {'en-US': six.text_type(addon.name)} assert addon_data['name'] == {'en-US': str(addon.name)}
assert isinstance(addon_data['homepage']['en-US'], six.string_types) assert isinstance(addon_data['homepage']['en-US'], str)
assert addon_data['homepage'] == { assert addon_data['homepage'] == {
'en-US': get_outgoing_url(six.text_type(addon.homepage))} 'en-US': get_outgoing_url(str(addon.homepage))}
assert isinstance(addon_data['support_url']['en-US'], six.string_types) assert isinstance(addon_data['support_url']['en-US'], str)
assert addon_data['support_url'] == { assert addon_data['support_url'] == {
'en-US': get_outgoing_url(six.text_type(addon.support_url))} 'en-US': get_outgoing_url(str(addon.support_url))}
overridden_api_gates = { overridden_api_gates = {
'v5': ('l10n_flat_input_output',)} 'v5': ('l10n_flat_input_output',)}
@ -282,14 +280,14 @@ class TestCollectionViewSetDetail(TestCase):
assert response.data['id'] == self.collection.id assert response.data['id'] == self.collection.id
addon_data = response.data['addons'][0]['addon'] addon_data = response.data['addons'][0]['addon']
assert addon_data['id'] == addon.id assert addon_data['id'] == addon.id
assert isinstance(addon_data['name'], six.string_types) assert isinstance(addon_data['name'], str)
assert addon_data['name'] == six.text_type(addon.name) assert addon_data['name'] == str(addon.name)
assert isinstance(addon_data['homepage'], six.string_types) assert isinstance(addon_data['homepage'], str)
assert addon_data['homepage'] == get_outgoing_url( assert addon_data['homepage'] == get_outgoing_url(
six.text_type(addon.homepage)) str(addon.homepage))
assert isinstance(addon_data['support_url'], six.string_types) assert isinstance(addon_data['support_url'], str)
assert addon_data['support_url'] == get_outgoing_url( assert addon_data['support_url'] == get_outgoing_url(
six.text_type(addon.support_url)) str(addon.support_url))
class CollectionViewSetDataMixin(object): class CollectionViewSetDataMixin(object):
@ -319,7 +317,7 @@ class CollectionViewSetDataMixin(object):
return self._user return self._user
def check_data(self, collection, data, json): def check_data(self, collection, data, json):
for prop, value in six.iteritems(data): for prop, value in data.items():
assert json[prop] == value assert json[prop] == value
with self.activate('fr'): with self.activate('fr'):

Просмотреть файл

@ -1,5 +1,4 @@
import waffle import waffle
from six import text_type
from olympia.lib.akismet.models import AkismetReport from olympia.lib.akismet.models import AkismetReport
from olympia.translations.models import Translation from olympia.translations.models import Translation
@ -18,7 +17,7 @@ def get_collection_akismet_reports(collection, user, user_agent, referrer,
translation_ids = [id_ for id_ in translation_ids_gen if id_] translation_ids = [id_ for id_ in translation_ids_gen if id_]
# Just get all the values together to make it simplier # Just get all the values together to make it simplier
existing_data = { existing_data = {
text_type(value) str(value)
for value in Translation.objects.filter(id__in=translation_ids)} for value in Translation.objects.filter(id__in=translation_ids)}
reports = [] reports = []
for prop in properties: for prop in properties:

Просмотреть файл

@ -1,7 +1,5 @@
from django.conf import settings from django.conf import settings
import six
from rest_framework import serializers from rest_framework import serializers
from rest_framework.viewsets import ModelViewSet from rest_framework.viewsets import ModelViewSet
@ -129,7 +127,7 @@ class CollectionAddonViewSet(ModelViewSet):
self.lookup_url_kwarg = self.lookup_url_kwarg or self.lookup_field self.lookup_url_kwarg = self.lookup_url_kwarg or self.lookup_field
lookup_value = self.kwargs.get(self.lookup_url_kwarg) lookup_value = self.kwargs.get(self.lookup_url_kwarg)
# if the lookup is not a number, its probably the slug instead. # if the lookup is not a number, its probably the slug instead.
if lookup_value and not six.text_type(lookup_value).isdigit(): if lookup_value and not str(lookup_value).isdigit():
self.lookup_field = '%s__slug' % self.lookup_field self.lookup_field = '%s__slug' % self.lookup_field
return super(CollectionAddonViewSet, self).get_object() return super(CollectionAddonViewSet, self).get_object()

Просмотреть файл

@ -4,11 +4,9 @@ import copy
from functools import total_ordering from functools import total_ordering
from django.urls import reverse from django.urls import reverse
from django.utils.encoding import force_bytes, python_2_unicode_compatible from django.utils.encoding import force_bytes
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
import six
from olympia.constants.applications import ANDROID, FIREFOX from olympia.constants.applications import ANDROID, FIREFOX
from olympia.constants.base import ( from olympia.constants.base import (
ADDON_DICT, ADDON_EXTENSION, ADDON_LPAPP, ADDON_PERSONA, ADDON_SEARCH, ADDON_DICT, ADDON_EXTENSION, ADDON_LPAPP, ADDON_PERSONA, ADDON_SEARCH,
@ -16,7 +14,6 @@ from olympia.constants.base import (
@total_ordering @total_ordering
@python_2_unicode_compatible
class StaticCategory(object): class StaticCategory(object):
"""Helper to populate `CATEGORIES` and provide some helpers. """Helper to populate `CATEGORIES` and provide some helpers.
@ -33,7 +30,7 @@ class StaticCategory(object):
object.__setattr__(self, 'description', description) object.__setattr__(self, 'description', description)
def __str__(self): def __str__(self):
return six.text_type(self.name) return str(self.name)
def __repr__(self): def __repr__(self):
return '<%s: %s (%s)>' % ( return '<%s: %s (%s)>' % (

Просмотреть файл

@ -3,6 +3,8 @@ import os
import tarfile import tarfile
import zipfile import zipfile
from urllib.parse import urlsplit
from django import forms from django import forms
from django.conf import settings from django.conf import settings
from django.core.files.storage import default_storage as storage from django.core.files.storage import default_storage as storage
@ -15,11 +17,9 @@ from django.utils.encoding import force_text
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
from django.utils.translation import ugettext, ugettext_lazy as _, ungettext from django.utils.translation import ugettext, ugettext_lazy as _, ungettext
import six
import waffle import waffle
from rest_framework.exceptions import Throttled from rest_framework.exceptions import Throttled
from six.moves.urllib_parse import urlsplit
from olympia import amo from olympia import amo
from olympia.access import acl from olympia.access import acl
@ -525,11 +525,10 @@ class LicenseRadioSelect(forms.RadioSelect):
if hasattr(license, 'url') and license.url: if hasattr(license, 'url') and license.url:
details = link % (license.url, ugettext('Details')) details = link % (license.url, ugettext('Details'))
context['label'] = mark_safe( context['label'] = mark_safe(str(context['label']) + ' ' + details)
six.text_type(context['label']) + ' ' + details)
if hasattr(license, 'icons'): if hasattr(license, 'icons'):
context['attrs']['data-cc'] = license.icons context['attrs']['data-cc'] = license.icons
context['attrs']['data-name'] = six.text_type(license) context['attrs']['data-name'] = str(license)
return context return context
@ -874,7 +873,7 @@ class BaseCompatFormSet(BaseModelFormSet):
# hidden delete fields in the data attribute, cause that's used to # hidden delete fields in the data attribute, cause that's used to
# populate initial data for all forms, and would therefore make # populate initial data for all forms, and would therefore make
# those delete fields active again. # those delete fields active again.
self.data = {k: v for k, v in six.iteritems(self.data) self.data = {k: v for k, v in self.data.items()
if not k.endswith('-DELETE')} if not k.endswith('-DELETE')}
for form in self.forms: for form in self.forms:
form.data = self.data form.data = self.data

Просмотреть файл

@ -1,13 +1,12 @@
from collections import defaultdict from collections import defaultdict
from urllib.parse import unquote_to_bytes
from django.utils.encoding import force_bytes from django.utils.encoding import force_bytes
from django.utils.translation import ugettext, ungettext from django.utils.translation import ugettext, ungettext
import jinja2 import jinja2
import six
from django_jinja import library from django_jinja import library
from six.moves.urllib.parse import unquote_to_bytes
from olympia import amo from olympia import amo
from olympia.access import acl from olympia.access import acl
@ -71,7 +70,7 @@ def dev_files_status(files):
for file in files: for file in files:
status_count[file.status] += 1 status_count[file.status] += 1
return [(count, six.text_type(choices[status])) for return [(count, str(choices[status])) for
(status, count) in status_count.items()] (status, count) in status_count.items()]

Просмотреть файл

@ -1,9 +1,8 @@
import uuid import uuid
from django.utils.encoding import force_text from urllib.parse import urlencode
import six from django.utils.encoding import force_text
from six.moves.urllib_parse import urlencode
from pyquery import PyQuery as pq from pyquery import PyQuery as pq
@ -231,8 +230,8 @@ class TestActivity(HubTest):
self.log_creates(1) self.log_creates(1)
doc = self.get_pq() doc = self.get_pq()
assert len(doc('.item')) == 1 assert len(doc('.item')) == 1
assert '<script>' not in six.text_type(doc), 'XSS FTL' assert '<script>' not in str(doc), 'XSS FTL'
assert '&lt;script&gt;' in six.text_type(doc), 'XSS FTL' assert '&lt;script&gt;' in str(doc), 'XSS FTL'
def test_xss_unlisted_addon(self): def test_xss_unlisted_addon(self):
self.addon.name = ("<script>alert('Buy more Diet Mountain Dew.')" self.addon.name = ("<script>alert('Buy more Diet Mountain Dew.')"
@ -242,53 +241,53 @@ class TestActivity(HubTest):
self.log_creates(1) self.log_creates(1)
doc = self.get_pq() doc = self.get_pq()
assert len(doc('.item')) == 2 assert len(doc('.item')) == 2
assert '<script>' not in six.text_type(doc), 'XSS FTL' assert '<script>' not in str(doc), 'XSS FTL'
assert '&lt;script&gt;' in six.text_type(doc), 'XSS FTL' assert '&lt;script&gt;' in str(doc), 'XSS FTL'
def test_xss_collections(self): def test_xss_collections(self):
self.log_collection(1, "<script>alert('v1@gra for u')</script>") self.log_collection(1, "<script>alert('v1@gra for u')</script>")
doc = self.get_pq() doc = self.get_pq()
assert len(doc('.item')) == 1 assert len(doc('.item')) == 1
assert '<script>' not in six.text_type(doc), 'XSS FTL' assert '<script>' not in str(doc), 'XSS FTL'
assert '&lt;script&gt;' in six.text_type(doc), 'XSS FTL' assert '&lt;script&gt;' in str(doc), 'XSS FTL'
def test_xss_collections_unlisted_addon(self): def test_xss_collections_unlisted_addon(self):
self.make_addon_unlisted(self.addon) self.make_addon_unlisted(self.addon)
self.log_collection(1, "<script>alert('v1@gra for u')</script>") self.log_collection(1, "<script>alert('v1@gra for u')</script>")
doc = self.get_pq() doc = self.get_pq()
assert len(doc('.item')) == 2 assert len(doc('.item')) == 2
assert '<script>' not in six.text_type(doc), 'XSS FTL' assert '<script>' not in str(doc), 'XSS FTL'
assert '&lt;script&gt;' in six.text_type(doc), 'XSS FTL' assert '&lt;script&gt;' in str(doc), 'XSS FTL'
def test_xss_tags(self): def test_xss_tags(self):
self.log_tag(1, "<script src='x.js'>") self.log_tag(1, "<script src='x.js'>")
doc = self.get_pq() doc = self.get_pq()
assert len(doc('.item')) == 1 assert len(doc('.item')) == 1
assert '<script' not in six.text_type(doc('.item')), 'XSS FTL' assert '<script' not in str(doc('.item')), 'XSS FTL'
assert '&lt;script' in six.text_type(doc('.item')), 'XSS FTL' assert '&lt;script' in str(doc('.item')), 'XSS FTL'
def test_xss_tags_unlisted_addon(self): def test_xss_tags_unlisted_addon(self):
self.make_addon_unlisted(self.addon) self.make_addon_unlisted(self.addon)
self.log_tag(1, "<script src='x.js'>") self.log_tag(1, "<script src='x.js'>")
doc = self.get_pq() doc = self.get_pq()
assert len(doc('.item')) == 2 assert len(doc('.item')) == 2
assert '<script' not in six.text_type(doc('.item')), 'XSS FTL' assert '<script' not in str(doc('.item')), 'XSS FTL'
assert '&lt;script' in six.text_type(doc('.item')), 'XSS FTL' assert '&lt;script' in str(doc('.item')), 'XSS FTL'
def test_xss_versions(self): def test_xss_versions(self):
self.log_updates(1, "<script src='x.js'>") self.log_updates(1, "<script src='x.js'>")
doc = self.get_pq() doc = self.get_pq()
assert len(doc('.item')) == 1 assert len(doc('.item')) == 1
assert '<script' not in six.text_type(doc('.item')), 'XSS FTL' assert '<script' not in str(doc('.item')), 'XSS FTL'
assert '&lt;script' in six.text_type(doc('.item')), 'XSS FTL' assert '&lt;script' in str(doc('.item')), 'XSS FTL'
def test_xss_versions_unlisted_addon(self): def test_xss_versions_unlisted_addon(self):
self.make_addon_unlisted(self.addon) self.make_addon_unlisted(self.addon)
self.log_updates(1, "<script src='x.js'>") self.log_updates(1, "<script src='x.js'>")
doc = self.get_pq() doc = self.get_pq()
assert len(doc('.item')) == 2 assert len(doc('.item')) == 2
assert '<script' not in six.text_type(doc('.item')), 'XSS FTL' assert '<script' not in str(doc('.item')), 'XSS FTL'
assert '&lt;script' in six.text_type(doc('.item')), 'XSS FTL' assert '&lt;script' in str(doc('.item')), 'XSS FTL'
def test_hidden(self): def test_hidden(self):
version = Version.objects.create(addon=self.addon) version = Version.objects.create(addon=self.addon)

Просмотреть файл

@ -3,15 +3,14 @@ import os
import shutil import shutil
import tempfile import tempfile
from datetime import timedelta from datetime import timedelta
from unittest import mock
from django.conf import settings from django.conf import settings
from django.core.files.storage import default_storage as storage from django.core.files.storage import default_storage as storage
from django.utils import translation from django.utils import translation
import pytest import pytest
import six
from freezegun import freeze_time from freezegun import freeze_time
from unittest import mock
from waffle.testutils import override_switch from waffle.testutils import override_switch
@ -330,7 +329,7 @@ class TestDistributionChoiceForm(TestCase):
label = form.fields['channel'].choices[0][1] label = form.fields['channel'].choices[0][1]
expected = 'On this site.' expected = 'On this site.'
label = six.text_type(label) label = str(label)
assert label.startswith(expected) assert label.startswith(expected)
with translation.override('de'): with translation.override('de'):
@ -338,7 +337,7 @@ class TestDistributionChoiceForm(TestCase):
label = form.fields['channel'].choices[0][1] label = form.fields['channel'].choices[0][1]
expected = 'Auf dieser Website.' expected = 'Auf dieser Website.'
label = six.text_type(label) label = str(label)
assert label.startswith(expected) assert label.startswith(expected)

Просмотреть файл

@ -1,12 +1,12 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from urllib.parse import quote
from django.utils import translation from django.utils import translation
from django.utils.encoding import force_bytes, force_text from django.utils.encoding import force_bytes, force_text
import pytest import pytest
import six
from unittest.mock import Mock from unittest.mock import Mock
from six.moves.urllib.parse import quote
from olympia import amo from olympia import amo
from olympia.activity.models import ActivityLog from olympia.activity.models import ActivityLog
@ -60,7 +60,7 @@ def test_summarize_validation():
def test_log_action_class(): def test_log_action_class():
v = Mock() v = Mock()
for k, v in six.iteritems(amo.LOG_BY_ID): for k, v in amo.LOG_BY_ID.items():
if v.action_class is not None: if v.action_class is not None:
cls = 'action-' + v.action_class cls = 'action-' + v.action_class
else: else:
@ -99,7 +99,7 @@ class TestDevFilesStatus(TestCase):
def expect(self, expected): def expect(self, expected):
cnt, msg = jinja_helpers.dev_files_status([self.file])[0] cnt, msg = jinja_helpers.dev_files_status([self.file])[0]
assert cnt == 1 assert cnt == 1
assert msg == six.text_type(expected) assert msg == str(expected)
def test_unreviewed_public(self): def test_unreviewed_public(self):
self.addon.status = amo.STATUS_APPROVED self.addon.status = amo.STATUS_APPROVED

Просмотреть файл

@ -11,7 +11,6 @@ import pytest
from waffle.testutils import override_switch from waffle.testutils import override_switch
from celery.result import AsyncResult from celery.result import AsyncResult
from six import text_type
from olympia import amo from olympia import amo
from olympia.amo.storage_utils import copy_stored_file from olympia.amo.storage_utils import copy_stored_file
@ -334,7 +333,7 @@ class TestGetAddonAkismetReports(UploadTest, TestCase):
existing_data = utils.fetch_existing_translations_from_addon( existing_data = utils.fetch_existing_translations_from_addon(
addon, ('summary', 'name', 'description')) addon, ('summary', 'name', 'description'))
# check fetch_existing_translations_from_addon worked okay # check fetch_existing_translations_from_addon worked okay
assert existing_data == {text_type(addon.name), u'¡Ochó!'} assert existing_data == {str(addon.name), u'¡Ochó!'}
self.parse_addon_mock.return_value = { self.parse_addon_mock.return_value = {
'description': { 'description': {
'en-US': u'fóó', 'en-US': u'fóó',
@ -373,7 +372,7 @@ class TestGetAddonAkismetReports(UploadTest, TestCase):
existing_data = utils.fetch_existing_translations_from_addon( existing_data = utils.fetch_existing_translations_from_addon(
addon, ('summary', 'name', 'description')) addon, ('summary', 'name', 'description'))
# check fetch_existing_translations_from_addon worked okay # check fetch_existing_translations_from_addon worked okay
assert existing_data == {text_type(addon.name), u'¡Ochó!'} assert existing_data == {str(addon.name), u'¡Ochó!'}
cleaned_data = { cleaned_data = {
'description': { 'description': {
'en-US': u'fóó', 'en-US': u'fóó',

Просмотреть файл

@ -3,6 +3,7 @@ import json
import os import os
from datetime import datetime, timedelta from datetime import datetime, timedelta
from urllib.parse import urlencode
from django.conf import settings from django.conf import settings
from django.core import mail from django.core import mail
@ -17,7 +18,6 @@ import pytest
import responses import responses
from pyquery import PyQuery as pq from pyquery import PyQuery as pq
from six.moves.urllib_parse import urlencode
from waffle.testutils import override_switch from waffle.testutils import override_switch
from olympia import amo, core from olympia import amo, core

Просмотреть файл

@ -7,7 +7,6 @@ from django.core.files.storage import default_storage as storage
from django.utils.encoding import force_text from django.utils.encoding import force_text
from unittest import mock from unittest import mock
import six
from pyquery import PyQuery as pq from pyquery import PyQuery as pq
from waffle.testutils import override_switch from waffle.testutils import override_switch
@ -116,15 +115,15 @@ class BaseTestEditDescribe(BaseTestEdit):
assert response.status_code == 200 assert response.status_code == 200
addon = self.get_addon() addon = self.get_addon()
assert six.text_type(addon.name) == data['name'] assert str(addon.name) == data['name']
assert addon.name.id == old_name.id assert addon.name.id == old_name.id
assert six.text_type(addon.summary) == data['summary'] assert str(addon.summary) == data['summary']
assert six.text_type(addon.slug) == data['slug'] assert str(addon.slug) == data['slug']
if self.listed: if self.listed:
assert ( assert (
[six.text_type(t) for t in addon.tags.all()] == [str(t) for t in addon.tags.all()] ==
sorted(self.tags)) sorted(self.tags))
def test_edit_slug_invalid(self): def test_edit_slug_invalid(self):
@ -175,13 +174,13 @@ class BaseTestEditDescribe(BaseTestEdit):
assert response.status_code == 200 assert response.status_code == 200
addon = self.get_addon() addon = self.get_addon()
assert six.text_type(addon.name) == data['name'] assert str(addon.name) == data['name']
assert six.text_type(addon.summary) == data['summary'] assert str(addon.summary) == data['summary']
assert six.text_type(addon.slug) == data['slug'] assert str(addon.slug) == data['slug']
if self.listed: if self.listed:
assert ( assert (
[six.text_type(t) for t in addon.tags.all()] == [str(t) for t in addon.tags.all()] ==
sorted(self.tags)) sorted(self.tags))
def test_edit_name_required(self): def test_edit_name_required(self):
@ -297,7 +296,7 @@ class BaseTestEditDescribe(BaseTestEdit):
response = self.client.get(self.url) response = self.client.get(self.url)
doc_links = [ doc_links = [
six.text_type(a.attrib['href']) str(a.attrib['href'])
for a in pq(response.content)('#edit-addon-nav').find('li a')] for a in pq(response.content)('#edit-addon-nav').find('li a')]
assert links == doc_links assert links == doc_links
@ -348,9 +347,9 @@ class BaseTestEditDescribe(BaseTestEdit):
# And metadata was updated # And metadata was updated
addon = self.get_addon() addon = self.get_addon()
assert six.text_type(addon.name) == data['name'] assert str(addon.name) == data['name']
assert six.text_type(addon.summary) == data['summary'] assert str(addon.summary) == data['summary']
assert six.text_type(addon.description) == data['description'] assert str(addon.description) == data['description']
@override_switch('akismet-spam-check', active=True) @override_switch('akismet-spam-check', active=True)
@override_switch('akismet-addon-action', active=False) @override_switch('akismet-addon-action', active=False)
@ -380,9 +379,9 @@ class BaseTestEditDescribe(BaseTestEdit):
# And metadata was updated # And metadata was updated
addon = self.get_addon() addon = self.get_addon()
assert six.text_type(addon.name) == data['name'] assert str(addon.name) == data['name']
assert six.text_type(addon.summary) == data['summary'] assert str(addon.summary) == data['summary']
assert six.text_type(addon.description) == data['description'] assert str(addon.description) == data['description']
@override_switch('akismet-spam-check', active=True) @override_switch('akismet-spam-check', active=True)
@override_switch('akismet-addon-action', active=True) @override_switch('akismet-addon-action', active=True)
@ -422,10 +421,9 @@ class BaseTestEditDescribe(BaseTestEdit):
# And metadata was NOT updated # And metadata was NOT updated
addon = self.get_addon() addon = self.get_addon()
assert six.text_type(addon.name) == six.text_type(old_name) assert str(addon.name) == str(old_name)
assert six.text_type(addon.summary) == six.text_type(old_summary) assert str(addon.summary) == str(old_summary)
assert six.text_type( assert str(addon.description) == str(old_description)
addon.description) == six.text_type(old_description)
def test_edit_xss(self): def test_edit_xss(self):
""" """
@ -602,7 +600,7 @@ class TestEditDescribeListed(BaseTestEditDescribe, L10nTestsMixin):
self.cat_initial['categories'] = [22, 1] self.cat_initial['categories'] = [22, 1]
data = self.get_dict() data = self.get_dict()
self.client.post(self.describe_edit_url, data) self.client.post(self.describe_edit_url, data)
assert six.text_type(self.get_addon().name) == data['name'] assert str(self.get_addon().name) == data['name']
def test_edit_categories_no_disclaimer(self): def test_edit_categories_no_disclaimer(self):
"""Ensure that there is a not disclaimer for non-creatured add-ons.""" """Ensure that there is a not disclaimer for non-creatured add-ons."""
@ -745,7 +743,7 @@ class TestEditDescribeListed(BaseTestEditDescribe, L10nTestsMixin):
addon = self.get_addon() addon = self.get_addon()
for k in data: for k in data:
assert six.text_type(getattr(addon, k)) == data[k] assert str(getattr(addon, k)) == data[k]
def test_edit_support_optional_url(self): def test_edit_support_optional_url(self):
data = { data = {
@ -757,7 +755,7 @@ class TestEditDescribeListed(BaseTestEditDescribe, L10nTestsMixin):
addon = self.get_addon() addon = self.get_addon()
for k in data: for k in data:
assert six.text_type(getattr(addon, k)) == data[k] assert str(getattr(addon, k)) == data[k]
def test_edit_support_optional_email(self): def test_edit_support_optional_email(self):
data = { data = {
@ -769,7 +767,7 @@ class TestEditDescribeListed(BaseTestEditDescribe, L10nTestsMixin):
addon = self.get_addon() addon = self.get_addon()
for k in data: for k in data:
assert six.text_type(getattr(addon, k)) == data[k] assert str(getattr(addon, k)) == data[k]
@override_switch('content-optimization', active=True) @override_switch('content-optimization', active=True)
def test_description_not_optional(self): def test_description_not_optional(self):
@ -875,7 +873,7 @@ class TestEditMedia(BaseTestEdit):
assert addon.get_icon_url(64).endswith('icons/default-64.png') assert addon.get_icon_url(64).endswith('icons/default-64.png')
for k in data: for k in data:
assert six.text_type(getattr(addon, k)) == data[k] assert str(getattr(addon, k)) == data[k]
def test_edit_media_shows_proper_labels(self): def test_edit_media_shows_proper_labels(self):
"""Regression test for """Regression test for
@ -920,7 +918,7 @@ class TestEditMedia(BaseTestEdit):
assert addon.get_icon_url(64).endswith('icons/appearance-64.png') assert addon.get_icon_url(64).endswith('icons/appearance-64.png')
for k in data: for k in data:
assert six.text_type(getattr(addon, k)) == data[k] assert str(getattr(addon, k)) == data[k]
def test_edit_media_uploadedicon(self): def test_edit_media_uploadedicon(self):
img = get_image_path('mozilla.png') img = get_image_path('mozilla.png')
@ -1449,7 +1447,7 @@ class BaseTestEditAdditionalDetails(BaseTestEdit):
addon = self.get_addon() addon = self.get_addon()
for k in data: for k in data:
assert six.text_type(getattr(addon, k)) == data[k] assert str(getattr(addon, k)) == data[k]
def test_edit_homepage_optional(self): def test_edit_homepage_optional(self):
data = { data = {
@ -1463,7 +1461,7 @@ class BaseTestEditAdditionalDetails(BaseTestEdit):
addon = self.get_addon() addon = self.get_addon()
for k in data: for k in data:
assert six.text_type(getattr(addon, k)) == data[k] assert str(getattr(addon, k)) == data[k]
class TestEditAdditionalDetailsListed(BaseTestEditAdditionalDetails, class TestEditAdditionalDetailsListed(BaseTestEditAdditionalDetails,
@ -1477,7 +1475,7 @@ class TestEditAdditionalDetailsListed(BaseTestEditAdditionalDetails,
'You are missing ') 'You are missing ')
data = { data = {
'homepage': six.text_type(self.addon.homepage), 'homepage': str(self.addon.homepage),
'default_locale': 'fr' 'default_locale': 'fr'
} }
response = self.client.post(self.details_edit_url, data) response = self.client.post(self.details_edit_url, data)
@ -1568,11 +1566,9 @@ class TestEditTechnical(BaseTestEdit):
addon = self.get_addon() addon = self.get_addon()
for k in data: for k in data:
if k == 'developer_comments': if k == 'developer_comments':
assert six.text_type( assert str(getattr(addon, k)) == str(data[k])
getattr(addon, k)) == six.text_type(data[k])
elif k == 'whiteboard-public': elif k == 'whiteboard-public':
assert six.text_type( assert str(addon.whiteboard.public) == str(data[k])
addon.whiteboard.public) == six.text_type(data[k])
else: else:
assert getattr(addon, k) == (data[k] == 'on') assert getattr(addon, k) == (data[k] == 'on')
@ -1594,8 +1590,7 @@ class TestEditTechnical(BaseTestEdit):
addon = self.get_addon() addon = self.get_addon()
for k in data: for k in data:
if k == 'developer_comments': if k == 'developer_comments':
assert six.text_type( assert str(getattr(addon, k)) == str(data[k])
getattr(addon, k)) == six.text_type(data[k])
else: else:
assert getattr(addon, k) == (data[k] == 'on') assert getattr(addon, k) == (data[k] == 'on')
@ -1726,7 +1721,7 @@ class TestEditDescribeStaticThemeListed(StaticMixin, BaseTestEditDescribe,
self._feature_addon() self._feature_addon()
data = self.get_dict() data = self.get_dict()
self.client.post(self.describe_edit_url, data) self.client.post(self.describe_edit_url, data)
assert six.text_type(self.get_addon().name) == data['name'] assert str(self.get_addon().name) == data['name']
def test_theme_preview_shown(self): def test_theme_preview_shown(self):
response = self.client.get(self.url) response = self.client.get(self.url)

Просмотреть файл

@ -1,8 +1,6 @@
"""Tests related to the ``devhub.addons.owner`` view.""" """Tests related to the ``devhub.addons.owner`` view."""
from django.core import mail from django.core import mail
import six
from pyquery import PyQuery as pq from pyquery import PyQuery as pq
from olympia import amo from olympia import amo
@ -49,7 +47,7 @@ class TestEditPolicy(TestOwnership):
response = self.client.post(self.url, data) response = self.client.post(self.url, data)
assert response.status_code == 302 assert response.status_code == 302
addon = self.get_addon() addon = self.get_addon()
assert six.text_type(addon.eula) == 'new eula' assert str(addon.eula) == 'new eula'
assert addon.eula.id == old_eula.id assert addon.eula.id == old_eula.id
def test_delete_eula(self): def test_delete_eula(self):
@ -128,8 +126,8 @@ class TestEditLicense(TestOwnership):
response = self.client.post(self.url, data) response = self.client.post(self.url, data)
assert response.status_code == 302 assert response.status_code == 302
license = self.get_version().license license = self.get_version().license
assert six.text_type(license.text) == 'text' assert str(license.text) == 'text'
assert six.text_type(license.name) == 'name' assert str(license.name) == 'name'
assert license.builtin == License.OTHER assert license.builtin == License.OTHER
def test_success_edit_custom(self): def test_success_edit_custom(self):
@ -141,8 +139,8 @@ class TestEditLicense(TestOwnership):
response = self.client.post(self.url, data) response = self.client.post(self.url, data)
assert response.status_code == 302 assert response.status_code == 302
license_two = self.get_version().license license_two = self.get_version().license
assert six.text_type(license_two.text) == 'woo' assert str(license_two.text) == 'woo'
assert six.text_type(license_two.name) == 'name' assert str(license_two.name) == 'name'
assert license_two.builtin == License.OTHER assert license_two.builtin == License.OTHER
assert license_two.id == license_one.id assert license_two.id == license_one.id
@ -155,14 +153,14 @@ class TestEditLicense(TestOwnership):
response = self.client.post(self.url, data) response = self.client.post(self.url, data)
assert response.status_code == 302 assert response.status_code == 302
license_two = self.get_version().license license_two = self.get_version().license
assert six.text_type(license_two.text) == 'text' assert str(license_two.text) == 'text'
assert six.text_type(license_two.name) == 'name' assert str(license_two.name) == 'name'
assert license_two.builtin == License.OTHER assert license_two.builtin == License.OTHER
assert license_one != license_two assert license_one != license_two
# Make sure the old license wasn't edited. # Make sure the old license wasn't edited.
license = License.objects.get(builtin=1) license = License.objects.get(builtin=1)
assert six.text_type(license.name) == 'bsd' assert str(license.name) == 'bsd'
data = self.formset(builtin=1) data = self.formset(builtin=1)
response = self.client.post(self.url, data) response = self.client.post(self.url, data)
@ -182,8 +180,8 @@ class TestEditLicense(TestOwnership):
response = self.client.post(self.url, data) response = self.client.post(self.url, data)
assert response.status_code == 302 assert response.status_code == 302
license = self.get_version().license license = self.get_version().license
assert six.text_type(license.text) == 'text' assert str(license.text) == 'text'
assert six.text_type(license.name) == 'Custom License' assert str(license.name) == 'Custom License'
assert license.builtin == License.OTHER assert license.builtin == License.OTHER
def test_no_version(self): def test_no_version(self):
@ -196,11 +194,11 @@ class TestEditLicense(TestOwnership):
def test_license_details_links(self): def test_license_details_links(self):
# Check that builtin licenses get details links. # Check that builtin licenses get details links.
doc = pq(six.text_type(LicenseForm(version=self.version))) doc = pq(str(LicenseForm(version=self.version)))
for license in License.objects.builtins(): for license in License.objects.builtins():
radio = 'input.license[value="%s"]' % license.builtin radio = 'input.license[value="%s"]' % license.builtin
assert doc(radio).parent().text() == ( assert doc(radio).parent().text() == (
six.text_type(license.name) + ' Details') str(license.name) + ' Details')
assert doc(radio + '+ a').attr('href') == license.url assert doc(radio + '+ a').attr('href') == license.url
assert doc('input[name=builtin]:last-child').parent().text() == 'Other' assert doc('input[name=builtin]:last-child').parent().text() == 'Other'

Просмотреть файл

@ -1,11 +1,13 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import json import json
import os import os
import io
import stat import stat
import tarfile import tarfile
import zipfile import zipfile
from datetime import datetime, timedelta from datetime import datetime, timedelta
from urllib.parse import urlencode
from django.conf import settings from django.conf import settings
from django.core.files import temp from django.core.files import temp
@ -14,11 +16,8 @@ from django.test.utils import override_settings
from unittest import mock from unittest import mock
import responses import responses
import six
from pyquery import PyQuery as pq from pyquery import PyQuery as pq
from six import text_type
from six.moves.urllib_parse import urlencode
from waffle.testutils import override_switch from waffle.testutils import override_switch
from olympia import amo from olympia import amo
@ -86,7 +85,7 @@ class TestSubmitBase(TestCase):
with tarfile.open(fileobj=source, mode=mode) as tar_file: with tarfile.open(fileobj=source, mode=mode) as tar_file:
tar_info = tarfile.TarInfo('foo') tar_info = tarfile.TarInfo('foo')
tar_info.size = len(data) tar_info.size = len(data)
tar_file.addfile(tar_info, six.BytesIO(data)) tar_file.addfile(tar_info, io.BytesIO(data))
source.seek(0) source.seek(0)
return source return source
@ -1141,7 +1140,7 @@ class DetailsPageMixin(object):
report = AkismetReport.objects.get() report = AkismetReport.objects.get()
assert report.comment_type == 'product-name' assert report.comment_type == 'product-name'
assert report.comment == u'spám' assert report.comment == u'spám'
assert text_type(self.addon.name) != u'spám' assert str(self.addon.name) != u'spám'
comment_check_mock.assert_called_once() comment_check_mock.assert_called_once()
@ -1159,7 +1158,7 @@ class DetailsPageMixin(object):
report = AkismetReport.objects.get() report = AkismetReport.objects.get()
assert report.comment_type == 'product-name' assert report.comment_type == 'product-name'
assert report.comment == u'spám' assert report.comment == u'spám'
assert text_type(self.addon.name) == u'spám' assert str(self.addon.name) == u'spám'
assert b'spam' not in response.content assert b'spam' not in response.content
comment_check_mock.assert_called_once() comment_check_mock.assert_called_once()
@ -1675,7 +1674,7 @@ class TestAddonSubmitFinish(TestSubmitBase):
self.client.get(self.url) self.client.get(self.url)
context = { context = {
'addon_name': 'Delicious Bookmarks', 'addon_name': 'Delicious Bookmarks',
'app': six.text_type(amo.FIREFOX.pretty), 'app': str(amo.FIREFOX.pretty),
'detail_url': 'http://b.ro/en-US/firefox/addon/a3615/', 'detail_url': 'http://b.ro/en-US/firefox/addon/a3615/',
'version_url': 'http://b.ro/en-US/developers/addon/a3615/versions', 'version_url': 'http://b.ro/en-US/developers/addon/a3615/versions',
'edit_url': 'http://b.ro/en-US/developers/addon/a3615/edit', 'edit_url': 'http://b.ro/en-US/developers/addon/a3615/edit',
@ -1692,7 +1691,7 @@ class TestAddonSubmitFinish(TestSubmitBase):
self.client.get(self.url) self.client.get(self.url)
context = { context = {
'addon_name': 'Delicious Bookmarks', 'addon_name': 'Delicious Bookmarks',
'app': six.text_type(amo.FIREFOX.pretty), 'app': str(amo.FIREFOX.pretty),
'detail_url': 'http://b.ro/en-US/firefox/addon/a3615/', 'detail_url': 'http://b.ro/en-US/firefox/addon/a3615/',
'version_url': 'http://b.ro/en-US/developers/addon/a3615/versions', 'version_url': 'http://b.ro/en-US/developers/addon/a3615/versions',
'edit_url': 'http://b.ro/en-US/developers/addon/a3615/edit', 'edit_url': 'http://b.ro/en-US/developers/addon/a3615/edit',
@ -1712,7 +1711,7 @@ class TestAddonSubmitFinish(TestSubmitBase):
self.client.get(self.url) self.client.get(self.url)
context = { context = {
'addon_name': 'Delicious Bookmarks', 'addon_name': 'Delicious Bookmarks',
'app': six.text_type(amo.FIREFOX.pretty), 'app': str(amo.FIREFOX.pretty),
'detail_url': 'http://b.ro/en-US/firefox/addon/a3615/', 'detail_url': 'http://b.ro/en-US/firefox/addon/a3615/',
'version_url': 'http://b.ro/en-US/developers/addon/a3615/versions', 'version_url': 'http://b.ro/en-US/developers/addon/a3615/versions',
'edit_url': 'http://b.ro/en-US/developers/addon/a3615/edit', 'edit_url': 'http://b.ro/en-US/developers/addon/a3615/edit',
@ -2091,7 +2090,7 @@ class VersionSubmitUploadMixin(object):
assert doc('#theme-wizard').attr('data-version') == '3.0' assert doc('#theme-wizard').attr('data-version') == '3.0'
assert doc('input#theme-name').attr('type') == 'hidden' assert doc('input#theme-name').attr('type') == 'hidden'
assert doc('input#theme-name').attr('value') == ( assert doc('input#theme-name').attr('value') == (
six.text_type(self.addon.name)) str(self.addon.name))
# Existing colors should be the default values for the fields # Existing colors should be the default values for the fields
assert doc('#frame').attr('value') == '#123456' assert doc('#frame').attr('value') == '#123456'
assert doc('#tab_background_text').attr('value') == 'rgba(1,2,3,0.4)' assert doc('#tab_background_text').attr('value') == 'rgba(1,2,3,0.4)'
@ -2152,7 +2151,7 @@ class VersionSubmitUploadMixin(object):
assert doc('#theme-wizard').attr('data-version') == '3.0' assert doc('#theme-wizard').attr('data-version') == '3.0'
assert doc('input#theme-name').attr('type') == 'hidden' assert doc('input#theme-name').attr('type') == 'hidden'
assert doc('input#theme-name').attr('value') == ( assert doc('input#theme-name').attr('value') == (
six.text_type(self.addon.name)) str(self.addon.name))
# Existing colors should be the default values for the fields # Existing colors should be the default values for the fields
assert doc('#frame').attr('value') == '#123456' assert doc('#frame').attr('value') == '#123456'
assert doc('#tab_background_text').attr('value') == 'rgba(1,2,3,0.4)' assert doc('#tab_background_text').attr('value') == 'rgba(1,2,3,0.4)'
@ -2514,9 +2513,9 @@ class TestVersionSubmitDetails(TestSubmitBase):
# metadata is missing, name, slug, summary and category are required to # metadata is missing, name, slug, summary and category are required to
# be present. # be present.
data = { data = {
'name': six.text_type(self.addon.name), 'name': str(self.addon.name),
'slug': self.addon.slug, 'slug': self.addon.slug,
'summary': six.text_type(self.addon.summary), 'summary': str(self.addon.summary),
'form-0-categories': [22, 1], 'form-0-categories': [22, 1],
'form-0-application': 1, 'form-0-application': 1,
@ -2581,7 +2580,7 @@ class TestVersionSubmitDetailsFirstListed(TestAddonSubmitDetails):
report = AkismetReport.objects.first() report = AkismetReport.objects.first()
assert report.comment_type == 'product-name' assert report.comment_type == 'product-name'
assert report.comment == u'spám' assert report.comment == u'spám'
assert text_type(self.addon.name) != u'spám' assert str(self.addon.name) != u'spám'
report = AkismetReport.objects.last() report = AkismetReport.objects.last()
assert report.comment_type == 'product-summary' assert report.comment_type == 'product-summary'
assert report.comment == u'Delicious Bookmarks is the official' assert report.comment == u'Delicious Bookmarks is the official'
@ -2605,7 +2604,7 @@ class TestVersionSubmitDetailsFirstListed(TestAddonSubmitDetails):
report = AkismetReport.objects.first() report = AkismetReport.objects.first()
assert report.comment_type == 'product-name' assert report.comment_type == 'product-name'
assert report.comment == u'spám' assert report.comment == u'spám'
assert text_type(self.addon.name) == u'spám' # It changed assert str(self.addon.name) == u'spám' # It changed
report = AkismetReport.objects.last() report = AkismetReport.objects.last()
assert report.comment_type == 'product-summary' assert report.comment_type == 'product-summary'
assert report.comment == u'Delicious Bookmarks is the official' assert report.comment == u'Delicious Bookmarks is the official'
@ -2629,7 +2628,7 @@ class TestVersionSubmitDetailsFirstListed(TestAddonSubmitDetails):
report = AkismetReport.objects.first() report = AkismetReport.objects.first()
assert report.comment_type == 'product-name' assert report.comment_type == 'product-name'
assert report.comment == u'spám' assert report.comment == u'spám'
assert text_type(self.addon.name) == u'spám' # It changed assert str(self.addon.name) == u'spám' # It changed
report = AkismetReport.objects.last() report = AkismetReport.objects.last()
assert report.comment_type == 'product-summary' assert report.comment_type == 'product-summary'
assert report.comment == u'Delicious Bookmarks is the official' assert report.comment == u'Delicious Bookmarks is the official'

Просмотреть файл

@ -8,7 +8,6 @@ from django.core.files import temp
from django.core.files.base import File as DjangoFile from django.core.files.base import File as DjangoFile
from unittest import mock from unittest import mock
import six
from pyquery import PyQuery as pq from pyquery import PyQuery as pq
from waffle.testutils import override_switch from waffle.testutils import override_switch
@ -312,7 +311,7 @@ class TestVersion(TestCase):
entry = ActivityLog.objects.get() entry = ActivityLog.objects.get()
assert entry.action == amo.LOG.USER_DISABLE.id assert entry.action == amo.LOG.USER_DISABLE.id
msg = entry.to_string() msg = entry.to_string()
assert six.text_type(self.addon.name) in msg, ("Unexpected: %r" % msg) assert str(self.addon.name) in msg, ("Unexpected: %r" % msg)
@mock.patch('olympia.files.models.File.hide_disabled_file') @mock.patch('olympia.files.models.File.hide_disabled_file')
def test_user_can_disable_addon_pending_version(self, hide_mock): def test_user_can_disable_addon_pending_version(self, hide_mock):
@ -339,7 +338,7 @@ class TestVersion(TestCase):
entry = ActivityLog.objects.get() entry = ActivityLog.objects.get()
assert entry.action == amo.LOG.USER_DISABLE.id assert entry.action == amo.LOG.USER_DISABLE.id
msg = entry.to_string() msg = entry.to_string()
assert six.text_type(self.addon.name) in msg, ("Unexpected: %r" % msg) assert str(self.addon.name) in msg, ("Unexpected: %r" % msg)
@mock.patch('olympia.files.models.File.hide_disabled_file') @mock.patch('olympia.files.models.File.hide_disabled_file')
def test_disabling_addon_awaiting_review_disables_version(self, hide_mock): def test_disabling_addon_awaiting_review_disables_version(self, hide_mock):
@ -372,7 +371,7 @@ class TestVersion(TestCase):
entry = ActivityLog.objects.get() entry = ActivityLog.objects.get()
assert entry.action == amo.LOG.USER_ENABLE.id assert entry.action == amo.LOG.USER_ENABLE.id
msg = entry.to_string() msg = entry.to_string()
assert six.text_type(self.addon.name) in msg, ("Unexpected: %r" % msg) assert str(self.addon.name) in msg, ("Unexpected: %r" % msg)
def test_unprivileged_user_cant_disable_addon(self): def test_unprivileged_user_cant_disable_addon(self):
self.addon.update(disabled_by_user=False) self.addon.update(disabled_by_user=False)
@ -693,8 +692,8 @@ class TestVersionEditDetails(TestVersionEditBase):
response = self.client.post(self.url, data) response = self.client.post(self.url, data)
assert response.status_code == 302 assert response.status_code == 302
version = self.get_version() version = self.get_version()
assert six.text_type(version.release_notes) == 'xx' assert str(version.release_notes) == 'xx'
assert six.text_type(version.approval_notes) == 'yy' assert str(version.approval_notes) == 'yy'
def test_version_number_redirect(self): def test_version_number_redirect(self):
url = self.url.replace(str(self.version.id), self.version.version) url = self.url.replace(str(self.version.id), self.version.version)
@ -904,8 +903,8 @@ class TestVersionEditSearchEngine(TestVersionEditMixin, TestCase):
response = self.client.post(self.url, dd) response = self.client.post(self.url, dd)
assert response.status_code == 302 assert response.status_code == 302
version = Addon.objects.get(id=4594).current_version version = Addon.objects.get(id=4594).current_version
assert six.text_type(version.release_notes) == 'xx' assert str(version.release_notes) == 'xx'
assert six.text_type(version.approval_notes) == 'yy' assert str(version.approval_notes) == 'yy'
def test_no_compat(self): def test_no_compat(self):
response = self.client.get(self.url) response = self.client.get(self.url)

Просмотреть файл

@ -7,7 +7,6 @@ from django.forms import ValidationError
from django.utils.translation import ugettext from django.utils.translation import ugettext
import waffle import waffle
from six import text_type
import olympia.core.logger import olympia.core.logger
@ -329,7 +328,7 @@ def fetch_existing_translations_from_addon(addon, properties):
translation_ids = [id_ for id_ in translation_ids_gen if id_] translation_ids = [id_ for id_ in translation_ids_gen if id_]
# Just get all the values together to make it simplier # Just get all the values together to make it simplier
return { return {
text_type(value) str(value)
for value in Translation.objects.filter(id__in=translation_ids)} for value in Translation.objects.filter(id__in=translation_ids)}

Просмотреть файл

@ -18,7 +18,6 @@ from django.utils.translation import ugettext, ugettext_lazy as _
from django.views.decorators.cache import never_cache from django.views.decorators.cache import never_cache
from django.views.decorators.csrf import csrf_exempt from django.views.decorators.csrf import csrf_exempt
import six
import waffle import waffle
from django_statsd.clients import statsd from django_statsd.clients import statsd
@ -463,19 +462,19 @@ def ownership(request, addon_id, addon):
if action: if action:
ActivityLog.create( ActivityLog.create(
action, author.user, action, author.user,
six.text_type(author.get_role_display()), addon) str(author.get_role_display()), addon)
if (author._original_user_id and if (author._original_user_id and
author.user_id != author._original_user_id): author.user_id != author._original_user_id):
ActivityLog.create( ActivityLog.create(
amo.LOG.REMOVE_USER_WITH_ROLE, amo.LOG.REMOVE_USER_WITH_ROLE,
(UserProfile, author._original_user_id), (UserProfile, author._original_user_id),
six.text_type(author.get_role_display()), addon) str(author.get_role_display()), addon)
for author in user_form.deleted_objects: for author in user_form.deleted_objects:
author.delete() author.delete()
ActivityLog.create( ActivityLog.create(
amo.LOG.REMOVE_USER_WITH_ROLE, author.user, amo.LOG.REMOVE_USER_WITH_ROLE, author.user,
six.text_type(author.get_role_display()), addon) str(author.get_role_display()), addon)
authors_emails.add(author.user.email) authors_emails.add(author.user.email)
mail_user_changes( mail_user_changes(
author=author, author=author,
@ -1556,8 +1555,8 @@ def _submit_finish(request, addon, version):
# We can use locale-prefixed URLs because the submitter probably # We can use locale-prefixed URLs because the submitter probably
# speaks the same language by the time he/she reads the email. # speaks the same language by the time he/she reads the email.
context = { context = {
'addon_name': six.text_type(addon.name), 'addon_name': str(addon.name),
'app': six.text_type(request.APP.pretty), 'app': str(request.APP.pretty),
'detail_url': absolutify(addon.get_url_path()), 'detail_url': absolutify(addon.get_url_path()),
'version_url': absolutify(addon.get_dev_url('versions')), 'version_url': absolutify(addon.get_dev_url('versions')),
'edit_url': absolutify(addon.get_dev_url('edit')), 'edit_url': absolutify(addon.get_dev_url('edit')),

Просмотреть файл

@ -5,8 +5,6 @@ from django.utils import translation
from django.utils.html import format_html from django.utils.html import format_html
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
import six
from olympia.addons.models import Addon from olympia.addons.models import Addon
from olympia.discovery.models import DiscoveryItem from olympia.discovery.models import DiscoveryItem
@ -20,8 +18,7 @@ class SlugOrPkChoiceField(forms.ModelChoiceField):
"""A ModelChoiceField that supports entering slugs instead of PKs for """A ModelChoiceField that supports entering slugs instead of PKs for
convenience.""" convenience."""
def clean(self, value): def clean(self, value):
if (value and isinstance(value, six.string_types) and if (value and isinstance(value, str) and not value.isdigit()):
not value.isdigit()):
try: try:
value = self.queryset.values_list( value = self.queryset.values_list(
'pk', flat=True).get(slug=value) 'pk', flat=True).get(slug=value)

Просмотреть файл

@ -1,19 +1,15 @@
from django.conf import settings from django.conf import settings
from django.db import models from django.db import models
from django.http import QueryDict from django.http import QueryDict
from django.utils.encoding import python_2_unicode_compatible
from django.utils.html import conditional_escape, format_html from django.utils.html import conditional_escape, format_html
from django.utils.translation import ugettext from django.utils.translation import ugettext
import six
from olympia import amo from olympia import amo
from olympia.addons.models import Addon, update_search_index from olympia.addons.models import Addon, update_search_index
from olympia.amo.models import ModelBase, OnChangeMixin from olympia.amo.models import ModelBase, OnChangeMixin
from olympia.amo.templatetags.jinja_helpers import absolutify from olympia.amo.templatetags.jinja_helpers import absolutify
@python_2_unicode_compatible
class DiscoveryItem(OnChangeMixin, ModelBase): class DiscoveryItem(OnChangeMixin, ModelBase):
RECOMMENDED = 'Recommended' RECOMMENDED = 'Recommended'
PENDING_RECOMMENDATION = 'Pending Recommendation' PENDING_RECOMMENDATION = 'Pending Recommendation'
@ -63,7 +59,7 @@ class DiscoveryItem(OnChangeMixin, ModelBase):
'new versions will be reviewed for recommended status.') 'new versions will be reviewed for recommended status.')
def __str__(self): def __str__(self):
return six.text_type(self.addon) return str(self.addon)
def build_querystring(self): def build_querystring(self):
qs = QueryDict(mutable=True) qs = QueryDict(mutable=True)
@ -76,7 +72,7 @@ class DiscoveryItem(OnChangeMixin, ModelBase):
return qs.urlencode() return qs.urlencode()
def _build_heading(self, html=False): def _build_heading(self, html=False):
addon_name = six.text_type(self.custom_addon_name or self.addon.name) addon_name = str(self.custom_addon_name or self.addon.name)
custom_heading = ugettext( custom_heading = ugettext(
self.custom_heading) if self.custom_heading else None self.custom_heading) if self.custom_heading else None

Просмотреть файл

@ -1,6 +1,4 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import six
from olympia import amo from olympia import amo
from olympia.amo.tests import TestCase, addon_factory, user_factory from olympia.amo.tests import TestCase, addon_factory, user_factory
from olympia.amo.urlresolvers import django_reverse, reverse from olympia.amo.urlresolvers import django_reverse, reverse
@ -111,7 +109,7 @@ class TestDiscoveryAdmin(TestCase):
response = self.client.post( response = self.client.post(
self.detail_url, { self.detail_url, {
'addon': six.text_type(addon.pk), 'addon': str(addon.pk),
'custom_addon_name': u'Xäxâxàxaxaxa !', 'custom_addon_name': u'Xäxâxàxaxaxa !',
'custom_heading': u'This heading is totally custom.', 'custom_heading': u'This heading is totally custom.',
'custom_description': u'This description is as well!', 'custom_description': u'This description is as well!',
@ -144,7 +142,7 @@ class TestDiscoveryAdmin(TestCase):
# Change add-on using the slug. # Change add-on using the slug.
response = self.client.post( response = self.client.post(
self.detail_url, self.detail_url,
{'addon': six.text_type(addon2.slug)}, follow=True) {'addon': str(addon2.slug)}, follow=True)
assert response.status_code == 200 assert response.status_code == 200
item.reload() item.reload()
assert DiscoveryItem.objects.count() == 1 assert DiscoveryItem.objects.count() == 1
@ -152,7 +150,7 @@ class TestDiscoveryAdmin(TestCase):
# Change add-on using the id. # Change add-on using the id.
response = self.client.post( response = self.client.post(
self.detail_url, {'addon': six.text_type(addon.pk)}, follow=True) self.detail_url, {'addon': str(addon.pk)}, follow=True)
assert response.status_code == 200 assert response.status_code == 200
item.reload() item.reload()
assert DiscoveryItem.objects.count() == 1 assert DiscoveryItem.objects.count() == 1
@ -182,7 +180,7 @@ class TestDiscoveryAdmin(TestCase):
# Try changing using an unknown id. # Try changing using an unknown id.
response = self.client.post( response = self.client.post(
self.detail_url, self.detail_url,
{'addon': six.text_type(addon2.pk + 666)}, follow=True) {'addon': str(addon2.pk + 666)}, follow=True)
assert response.status_code == 200 assert response.status_code == 200
assert not response.context_data['adminform'].form.is_valid() assert not response.context_data['adminform'].form.is_valid()
assert 'addon' in response.context_data['adminform'].form.errors assert 'addon' in response.context_data['adminform'].form.errors
@ -192,7 +190,7 @@ class TestDiscoveryAdmin(TestCase):
# Try changing using a non-public add-on id. # Try changing using a non-public add-on id.
addon3 = addon_factory(status=amo.STATUS_DISABLED) addon3 = addon_factory(status=amo.STATUS_DISABLED)
response = self.client.post( response = self.client.post(
self.detail_url, {'addon': six.text_type(addon3.pk)}, follow=True) self.detail_url, {'addon': str(addon3.pk)}, follow=True)
assert response.status_code == 200 assert response.status_code == 200
assert not response.context_data['adminform'].form.is_valid() assert not response.context_data['adminform'].form.is_valid()
assert 'addon' in response.context_data['adminform'].form.errors assert 'addon' in response.context_data['adminform'].form.errors
@ -202,7 +200,7 @@ class TestDiscoveryAdmin(TestCase):
# Try changing to an add-on that is already used by another item. # Try changing to an add-on that is already used by another item.
item2 = DiscoveryItem.objects.create(addon=addon2) item2 = DiscoveryItem.objects.create(addon=addon2)
response = self.client.post( response = self.client.post(
self.detail_url, {'addon': six.text_type(addon2.pk)}, follow=True) self.detail_url, {'addon': str(addon2.pk)}, follow=True)
assert response.status_code == 200 assert response.status_code == 200
assert not response.context_data['adminform'].form.is_valid() assert not response.context_data['adminform'].form.is_valid()
assert 'addon' in response.context_data['adminform'].form.errors assert 'addon' in response.context_data['adminform'].form.errors
@ -243,7 +241,7 @@ class TestDiscoveryAdmin(TestCase):
assert DiscoveryItem.objects.count() == 0 assert DiscoveryItem.objects.count() == 0
response = self.client.post( response = self.client.post(
self.add_url, { self.add_url, {
'addon': six.text_type(addon.pk), 'addon': str(addon.pk),
'custom_addon_name': u'Xäxâxàxaxaxa !', 'custom_addon_name': u'Xäxâxàxaxaxa !',
'custom_heading': u'This heading is totally custom.', 'custom_heading': u'This heading is totally custom.',
'custom_description': u'This description is as well!', 'custom_description': u'This description is as well!',
@ -265,9 +263,9 @@ class TestDiscoveryAdmin(TestCase):
response = self.client.get(self.add_url, follow=True) response = self.client.get(self.add_url, follow=True)
assert response.status_code == 403 assert response.status_code == 403
response = self.client.post( response = self.client.post(
self.add_url, { self.add_url,
'addon': six.text_type(addon.pk), {'addon': str(addon.pk)},
}, follow=True) follow=True)
assert response.status_code == 403 assert response.status_code == 403
assert DiscoveryItem.objects.count() == 0 assert DiscoveryItem.objects.count() == 0
@ -285,7 +283,7 @@ class TestDiscoveryAdmin(TestCase):
response = self.client.post( response = self.client.post(
self.detail_url, { self.detail_url, {
'addon': six.text_type(addon.pk), 'addon': str(addon.pk),
'custom_addon_name': u'Noooooô !', 'custom_addon_name': u'Noooooô !',
'custom_heading': u'I should not be able to do this.', 'custom_heading': u'I should not be able to do this.',
'custom_description': u'This is wrong.', 'custom_description': u'This is wrong.',

Просмотреть файл

@ -2,7 +2,6 @@
from django.test.utils import override_settings from django.test.utils import override_settings
from unittest import mock from unittest import mock
import six
from waffle import switch_is_active from waffle import switch_is_active
from waffle.testutils import override_switch from waffle.testutils import override_switch
@ -49,10 +48,9 @@ class DiscoveryTestMixin(object):
addon = item.addon addon = item.addon
assert result['addon']['id'] == item.addon_id == addon.pk assert result['addon']['id'] == item.addon_id == addon.pk
if flat_name: if flat_name:
assert result['addon']['name'] == six.text_type(addon.name) assert result['addon']['name'] == str(addon.name)
else: else:
assert result['addon']['name'] == { assert result['addon']['name'] == {'en-US': str(addon.name)}
'en-US': six.text_type(addon.name)}
assert result['addon']['slug'] == addon.slug assert result['addon']['slug'] == addon.slug
assert result['addon']['icon_url'] == absolutify( assert result['addon']['icon_url'] == absolutify(
addon.get_icon_url(64)) addon.get_icon_url(64))

Просмотреть файл

@ -1,6 +1,6 @@
import json import json
from collections import OrderedDict from collections import OrderedDict
from six.moves.urllib_parse import urljoin from urllib.parse import urljoin
from django.conf import settings from django.conf import settings
from django.utils.http import urlencode from django.utils.http import urlencode

Просмотреть файл

@ -12,12 +12,9 @@ from django.core.files.storage import default_storage as storage
from django.db import models from django.db import models
from django.dispatch import receiver from django.dispatch import receiver
from django.template.defaultfilters import slugify from django.template.defaultfilters import slugify
from django.utils.encoding import ( from django.utils.encoding import force_bytes, force_text
force_bytes, force_text, python_2_unicode_compatible)
from django.utils.functional import cached_property from django.utils.functional import cached_property
import six
from django_extensions.db.fields.json import JSONField from django_extensions.db.fields.json import JSONField
from django_statsd.clients import statsd from django_statsd.clients import statsd
@ -39,7 +36,6 @@ from olympia.lib.cache import memoize
log = olympia.core.logger.getLogger('z.files') log = olympia.core.logger.getLogger('z.files')
@python_2_unicode_compatible
class File(OnChangeMixin, ModelBase): class File(OnChangeMixin, ModelBase):
id = PositiveAutoField(primary_key=True) id = PositiveAutoField(primary_key=True)
STATUS_CHOICES = amo.STATUS_CHOICES_FILE STATUS_CHOICES = amo.STATUS_CHOICES_FILE
@ -92,7 +88,7 @@ class File(OnChangeMixin, ModelBase):
db_table = 'files' db_table = 'files'
def __str__(self): def __str__(self):
return six.text_type(self.id) return str(self.id)
def get_platform_display(self): def get_platform_display(self):
return force_text(amo.PLATFORMS[self.platform].name) return force_text(amo.PLATFORMS[self.platform].name)
@ -372,7 +368,7 @@ class File(OnChangeMixin, ModelBase):
# Remove any duplicate permissions. # Remove any duplicate permissions.
permissions = set() permissions = set()
permissions = [p for p in self._webext_permissions.permissions permissions = [p for p in self._webext_permissions.permissions
if isinstance(p, six.string_types) and not if isinstance(p, str) and not
(p in permissions or permissions.add(p))] (p in permissions or permissions.add(p))]
return permissions return permissions
@ -490,7 +486,6 @@ def track_file_status_change(file_):
statsd.incr('file_status_change.all.status_{}'.format(file_.status)) statsd.incr('file_status_change.all.status_{}'.format(file_.status))
@python_2_unicode_compatible
class FileUpload(ModelBase): class FileUpload(ModelBase):
"""Created when a file is uploaded for validation/submission.""" """Created when a file is uploaded for validation/submission."""
uuid = models.UUIDField(default=uuid.uuid4, editable=False) uuid = models.UUIDField(default=uuid.uuid4, editable=False)
@ -520,7 +515,7 @@ class FileUpload(ModelBase):
db_table = 'file_uploads' db_table = 'file_uploads'
def __str__(self): def __str__(self):
return six.text_type(self.uuid.hex) return str(self.uuid.hex)
def save(self, *args, **kw): def save(self, *args, **kw):
if self.validation: if self.validation:
@ -638,7 +633,7 @@ class FileValidation(ModelBase):
@classmethod @classmethod
def from_json(cls, file, validation): def from_json(cls, file, validation):
if isinstance(validation, six.string_types): if isinstance(validation, str):
validation = json.loads(validation) validation = json.loads(validation)
if 'metadata' in validation: if 'metadata' in validation:
@ -686,6 +681,6 @@ class WebextPermission(ModelBase):
def nfd_str(u): def nfd_str(u):
"""Uses NFD to normalize unicode strings.""" """Uses NFD to normalize unicode strings."""
if isinstance(u, six.text_type): if isinstance(u, str):
return unicodedata.normalize('NFD', u).encode('utf-8') return unicodedata.normalize('NFD', u).encode('utf-8')
return u return u

Просмотреть файл

@ -11,7 +11,6 @@ from django.core.files.storage import default_storage as storage
import flufl.lock import flufl.lock
import pytest import pytest
import six
from freezegun import freeze_time from freezegun import freeze_time
from unittest.mock import Mock, patch from unittest.mock import Mock, patch
@ -486,17 +485,6 @@ class TestSafeZipFile(TestCase, amo.tests.AMOPaths):
assert zip_file.is_valid assert zip_file.is_valid
assert b'locale browser de' in zip_file.read('chrome.manifest') assert b'locale browser de' in zip_file.read('chrome.manifest')
@pytest.mark.skipif(
six.PY3,
reason='Python 3 seems to handle filenames in that zip just fine.')
def test_invalid_zip_encoding(self):
with pytest.raises(forms.ValidationError) as exc:
SafeZip(self.xpi_path('invalid-cp437-encoding.xpi'))
assert isinstance(exc.value, forms.ValidationError)
assert exc.value.message.endswith(
'Please make sure all filenames are utf-8 or latin1 encoded.')
def test_not_secure(self): def test_not_secure(self):
zip_file = SafeZip(self.xpi_path('extension')) zip_file = SafeZip(self.xpi_path('extension'))
assert not zip_file.is_signed() assert not zip_file.is_signed()

Просмотреть файл

@ -7,6 +7,7 @@ import time
import zipfile import zipfile
from datetime import timedelta from datetime import timedelta
from unittest import mock
from django import forms from django import forms
from django.conf import settings from django.conf import settings
@ -14,9 +15,7 @@ from django.forms import ValidationError
import flufl.lock import flufl.lock
import lxml import lxml
from unittest import mock
import pytest import pytest
import six
from defusedxml.common import EntitiesForbidden, NotSupportedError from defusedxml.common import EntitiesForbidden, NotSupportedError
from waffle.testutils import override_switch from waffle.testutils import override_switch
@ -989,7 +988,7 @@ def test_parse_search_empty_shortname():
utils.parse_search(fname) utils.parse_search(fname)
assert ( assert (
six.text_type(excinfo.value.message) == str(excinfo.value.message) ==
'Could not parse uploaded file, missing or empty <ShortName> element') 'Could not parse uploaded file, missing or empty <ShortName> element')

Просмотреть файл

@ -3,17 +3,16 @@ import json
import os import os
import shutil import shutil
from urllib.parse import urlparse
from django.conf import settings from django.conf import settings
from django.core.cache import cache from django.core.cache import cache
from django.test.utils import override_settings from django.test.utils import override_settings
from django.utils.encoding import force_text from django.utils.encoding import force_text
from django.utils.http import http_date, quote_etag from django.utils.http import http_date, quote_etag
import six
from unittest.mock import patch from unittest.mock import patch
from pyquery import PyQuery as pq from pyquery import PyQuery as pq
from six.moves.urllib_parse import urlparse
from olympia import amo from olympia import amo
from olympia.addons.models import Addon from olympia.addons.models import Addon
@ -459,7 +458,7 @@ class TestFileViewer(FilesBase, TestCase):
assert res.status_code == 200 assert res.status_code == 200
def test_unicode_unicode_tmp_path(self): def test_unicode_unicode_tmp_path(self):
with override_settings(TMP_PATH=six.text_type(settings.TMP_PATH)): with override_settings(TMP_PATH=str(settings.TMP_PATH)):
self.test_unicode() self.test_unicode()
def test_serve_no_token(self): def test_serve_no_token(self):

Просмотреть файл

@ -14,7 +14,6 @@ import tempfile
import zipfile import zipfile
from datetime import datetime, timedelta from datetime import datetime, timedelta
from six import text_type
from django import forms from django import forms
from django.conf import settings from django.conf import settings
@ -27,7 +26,6 @@ from django.utils.translation import ugettext
import flufl.lock import flufl.lock
import rdflib import rdflib
import six
from xml.parsers.expat import ExpatError from xml.parsers.expat import ExpatError
@ -86,7 +84,7 @@ def get_filepath(fileorpath):
This supports various input formats, a path, a django `File` object, This supports various input formats, a path, a django `File` object,
`olympia.files.File`, a `FileUpload` or just a regular file-like object. `olympia.files.File`, a `FileUpload` or just a regular file-like object.
""" """
if isinstance(fileorpath, six.string_types): if isinstance(fileorpath, str):
return fileorpath return fileorpath
elif isinstance(fileorpath, DjangoFile): elif isinstance(fileorpath, DjangoFile):
return fileorpath return fileorpath
@ -106,7 +104,7 @@ def id_to_path(pk):
12 => 2/12/12 12 => 2/12/12
123456 => 6/56/123456 123456 => 6/56/123456
""" """
pk = six.text_type(pk) pk = str(pk)
path = [pk[-1]] path = [pk[-1]]
if len(pk) >= 2: if len(pk) >= 2:
path.append(pk[-2:]) path.append(pk[-2:])
@ -126,7 +124,7 @@ def get_file(fileorpath):
def make_xpi(files): def make_xpi(files):
file_obj = six.BytesIO() file_obj = io.BytesIO()
zip_file = zipfile.ZipFile(file_obj, 'w') zip_file = zipfile.ZipFile(file_obj, 'w')
for path, data in files.items(): for path, data in files.items():
zip_file.writestr(path, data) zip_file.writestr(path, data)
@ -326,7 +324,7 @@ class RDFExtractor(object):
match = list(self.rdf.objects(ctx, predicate=self.uri(name))) match = list(self.rdf.objects(ctx, predicate=self.uri(name)))
# These come back as rdflib.Literal, which subclasses unicode. # These come back as rdflib.Literal, which subclasses unicode.
if match: if match:
return six.text_type(match[0]) return str(match[0])
def apps(self): def apps(self):
rv = [] rv = []
@ -802,7 +800,7 @@ class SafeZip(object):
if type == 'jar': if type == 'jar':
parts = path.split('!') parts = path.split('!')
for part in parts[:-1]: for part in parts[:-1]:
jar = self.__class__(six.BytesIO(jar.zip_file.read(part))) jar = self.__class__(io.BytesIO(jar.zip_file.read(part)))
path = parts[-1] path = parts[-1]
return jar.read(path[1:] if path.startswith('/') else path) return jar.read(path[1:] if path.startswith('/') else path)
@ -1269,7 +1267,7 @@ def resolve_i18n_message(message, messages, locale, default_locale=None):
:param messages: A dictionary of messages, e.g the return value :param messages: A dictionary of messages, e.g the return value
of `extract_translations`. of `extract_translations`.
""" """
if not message or not isinstance(message, six.string_types): if not message or not isinstance(message, str):
# Don't even attempt to extract invalid data. # Don't even attempt to extract invalid data.
# See https://github.com/mozilla/addons-server/issues/3067 # See https://github.com/mozilla/addons-server/issues/3067
# for more details # for more details
@ -1326,7 +1324,7 @@ def get_background_images(file_obj, theme_data, header_only=False):
try: try:
with zipfile.ZipFile(xpi, 'r') as source: with zipfile.ZipFile(xpi, 'r') as source:
for url in image_urls: for url in image_urls:
_, file_ext = os.path.splitext(text_type(url).lower()) _, file_ext = os.path.splitext(str(url).lower())
if file_ext not in amo.THEME_BACKGROUND_EXTS: if file_ext not in amo.THEME_BACKGROUND_EXTS:
# Just extract image files. # Just extract image files.
continue continue

Просмотреть файл

@ -1,5 +1,4 @@
import requests import requests
import six
import uuid import uuid
from django.conf import settings from django.conf import settings
@ -35,7 +34,7 @@ class Command(BaseCommand):
help='only consider this specific add-on type' help='only consider this specific add-on type'
) )
parser.add_argument( parser.add_argument(
'--query', metavar='type', type=six.text_type, '--query', metavar='type', type=str,
help='only consider add-ons matching this query' help='only consider add-ons matching this query'
) )

Просмотреть файл

@ -1,6 +1,4 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import six
from olympia.addons.models import Category from olympia.addons.models import Category
from olympia.amo.tests import TestCase from olympia.amo.tests import TestCase
from olympia.constants.applications import APPS from olympia.constants.applications import APPS
@ -23,7 +21,7 @@ class CategoriesTests(TestCase):
category = Category.objects.get( category = Category.objects.get(
id=CATEGORIES[APPS['android'].id][ADDON_EXTENSION]['shopping'].id) id=CATEGORIES[APPS['android'].id][ADDON_EXTENSION]['shopping'].id)
assert six.text_type(category.name) == u'Shopping' assert str(category.name) == u'Shopping'
# Re-generating should not create any more. # Re-generating should not create any more.
data = generate_categories(APPS['android'], ADDON_EXTENSION) data = generate_categories(APPS['android'], ADDON_EXTENSION)
@ -33,4 +31,4 @@ class CategoriesTests(TestCase):
# Name should still be the same. # Name should still be the same.
category = Category.objects.get( category = Category.objects.get(
id=CATEGORIES[APPS['android'].id][ADDON_EXTENSION]['shopping'].id) id=CATEGORIES[APPS['android'].id][ADDON_EXTENSION]['shopping'].id)
assert six.text_type(category.name) == u'Shopping' assert str(category.name) == u'Shopping'

Просмотреть файл

@ -1,6 +1,4 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import six
from olympia import amo from olympia import amo
from olympia.addons.models import Addon from olympia.addons.models import Addon
from olympia.amo.tests import TestCase from olympia.amo.tests import TestCase
@ -25,7 +23,7 @@ class CollectionsTests(TestCase):
def test_collections_themes_translations(self): def test_collections_themes_translations(self):
generate_collection(self.addon) generate_collection(self.addon)
with self.activate(locale='es'): with self.activate(locale='es'):
collection_name = six.text_type(Collection.objects.last().name) collection_name = str(Collection.objects.last().name)
assert collection_name.startswith(u'(español) ') assert collection_name.startswith(u'(español) ')
def test_collections_addons_generation(self): def test_collections_addons_generation(self):
@ -38,5 +36,5 @@ class CollectionsTests(TestCase):
def test_collections_addons_translations(self): def test_collections_addons_translations(self):
generate_collection(self.addon, APPS['android']) generate_collection(self.addon, APPS['android'])
with self.activate(locale='es'): with self.activate(locale='es'):
collection_name = six.text_type(Collection.objects.last().name) collection_name = str(Collection.objects.last().name)
assert collection_name.startswith(u'(español) ') assert collection_name.startswith(u'(español) ')

Просмотреть файл

@ -1,6 +1,4 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import six
from olympia import amo from olympia import amo
from olympia.addons.models import Addon from olympia.addons.models import Addon
from olympia.amo.tests import TestCase from olympia.amo.tests import TestCase
@ -21,5 +19,5 @@ class RatingsTests(TestCase):
assert UserProfile.objects.count() == 3 assert UserProfile.objects.count() == 3
for n, review in enumerate(Rating.objects.all().order_by('pk')): for n, review in enumerate(Rating.objects.all().order_by('pk')):
assert review.addon == self.addon assert review.addon == self.addon
assert six.text_type(review.body) == u'Test Review %d' % (n + 1) assert str(review.body) == u'Test Review %d' % (n + 1)
assert review.user.email.endswith('@example.com') assert review.user.email.endswith('@example.com')

Просмотреть файл

@ -1,12 +1,11 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import six
def generate_translations(item): def generate_translations(item):
"""Generate French and Spanish translations for the given `item`.""" """Generate French and Spanish translations for the given `item`."""
fr_prefix = u'(français) ' fr_prefix = u'(français) '
es_prefix = u'(español) ' es_prefix = u'(español) '
oldname = six.text_type(item.name) oldname = str(item.name)
item.name = {'en': oldname, item.name = {'en': oldname,
'fr': fr_prefix + oldname, 'fr': fr_prefix + oldname,
'es': es_prefix + oldname} 'es': es_prefix + oldname}

Просмотреть файл

@ -1,5 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from datetime import datetime from datetime import datetime
from unittest import mock
import django.contrib.messages as django_messages import django.contrib.messages as django_messages
@ -8,10 +9,8 @@ from django.contrib import admin
from django.test import RequestFactory from django.test import RequestFactory
from django.test.utils import override_settings from django.test.utils import override_settings
from unittest import mock
import pytest import pytest
import responses import responses
import six
from freezegun import freeze_time from freezegun import freeze_time
from pyquery import PyQuery as pq from pyquery import PyQuery as pq
@ -225,7 +224,7 @@ class TestAkismetReportsAddon(BaseAkismetReportsModelTest, TestCase):
'comment_author': user.name, 'comment_author': user.name,
'comment_author_email': user.email, 'comment_author_email': user.email,
'comment_author_url': user.homepage, 'comment_author_url': user.homepage,
'comment_content': six.text_type(addon.name), 'comment_content': str(addon.name),
'comment_date_gmt': time_now, 'comment_date_gmt': time_now,
'blog_charset': 'utf-8', 'blog_charset': 'utf-8',
'is_test': not settings.AKISMET_REAL_SUBMIT, 'is_test': not settings.AKISMET_REAL_SUBMIT,
@ -331,7 +330,7 @@ class TestAkismetAdmin(TestCase):
[ham_report_not_already_submitted.pk], True) [ham_report_not_already_submitted.pk], True)
assert len(django_messages.get_messages(request)) == 1 assert len(django_messages.get_messages(request)) == 1
for message in django_messages.get_messages(request): for message in django_messages.get_messages(request):
assert six.text_type(message) == ( assert str(message) == (
'1 Ham reports submitted as Spam; 5 reports ignored') '1 Ham reports submitted as Spam; 5 reports ignored')
@mock.patch('olympia.lib.akismet.admin.submit_to_akismet.delay') @mock.patch('olympia.lib.akismet.admin.submit_to_akismet.delay')
@ -351,7 +350,7 @@ class TestAkismetAdmin(TestCase):
[r.id for r in spam_reports_not_already_submitted], False) [r.id for r in spam_reports_not_already_submitted], False)
assert len(django_messages.get_messages(request)) == 1 assert len(django_messages.get_messages(request)) == 1
for message in django_messages.get_messages(request): for message in django_messages.get_messages(request):
assert six.text_type(message) == ( assert str(message) == (
'2 Spam reports submitted as Ham; 4 reports ignored') '2 Spam reports submitted as Ham; 4 reports ignored')
def test_submit_spam_button_on_ham_page(self): def test_submit_spam_button_on_ham_page(self):

Просмотреть файл

@ -11,7 +11,6 @@ from django.core.exceptions import ObjectDoesNotExist
from django.utils.encoding import force_bytes, force_text from django.utils.encoding import force_bytes, force_text
import requests import requests
import six
import waffle import waffle
from django_statsd.clients import statsd from django_statsd.clients import statsd
@ -175,7 +174,7 @@ def sign_file(file_obj):
.format(file_obj.version.pk)) .format(file_obj.version.pk))
# Sign the file. If there's any exception, we skip the rest. # Sign the file. If there's any exception, we skip the rest.
cert_serial_num = six.text_type(call_signing(file_obj)) cert_serial_num = str(call_signing(file_obj))
size = storage.size(file_obj.current_file_path) size = storage.size(file_obj.current_file_path)

Просмотреть файл

@ -1,12 +1,11 @@
import threading import threading
import time import time
import io
from django.core import management from django.core import management
from django.db import connection from django.db import connection
from django.test.testcases import TransactionTestCase from django.test.testcases import TransactionTestCase
import six
from olympia.amo.tests import ( from olympia.amo.tests import (
addon_factory, create_switch, ESTestCase, reverse_ns) addon_factory, create_switch, ESTestCase, reverse_ns)
from olympia.amo.utils import urlparams from olympia.amo.utils import urlparams
@ -86,7 +85,7 @@ class TestIndexCommand(ESTestCase):
# This is to start a reindexation in the background. # This is to start a reindexation in the background.
class ReindexThread(threading.Thread): class ReindexThread(threading.Thread):
def __init__(self): def __init__(self):
self.stdout = six.StringIO() self.stdout = io.StringIO()
super(ReindexThread, self).__init__() super(ReindexThread, self).__init__()
def run(self): def run(self):

Просмотреть файл

@ -1,5 +1,4 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from collections import namedtuple
import uuid import uuid
import os import os
import io import io
@ -8,7 +7,8 @@ import tempfile
import sys import sys
import mimetypes import mimetypes
import six from collections import namedtuple
import pygit2 import pygit2
import magic import magic
@ -466,7 +466,7 @@ class AddonGitRepository(object):
""" """
# When `commit` is a commit hash, e.g passed to us through the API # When `commit` is a commit hash, e.g passed to us through the API
# serializers we have to fetch the actual commit object to proceed. # serializers we have to fetch the actual commit object to proceed.
if isinstance(commit, six.string_types): if isinstance(commit, str):
commit = self.git_repository.revparse_single(commit) commit = self.git_repository.revparse_single(commit)
return self.git_repository[commit.tree[EXTRACTED_PREFIX].oid] return self.git_repository[commit.tree[EXTRACTED_PREFIX].oid]

Просмотреть файл

@ -4,7 +4,6 @@ from django.conf import settings
from django.test.utils import override_settings from django.test.utils import override_settings
from unittest import mock from unittest import mock
import six
from olympia.amo.utils import from_string from olympia.amo.utils import from_string
@ -227,7 +226,7 @@ def test_css(getmtime, time):
'css': {'compiled': ['css/impala/buttons.less']}}) 'css': {'compiled': ['css/impala/buttons.less']}})
@mock.patch('olympia.lib.jingo_minify_helpers.os.path.getmtime') @mock.patch('olympia.lib.jingo_minify_helpers.os.path.getmtime')
@mock.patch('olympia.lib.jingo_minify_helpers.subprocess') @mock.patch('olympia.lib.jingo_minify_helpers.subprocess')
@mock.patch('%s.open' % ('__builtin__' if six.PY2 else 'builtins'), spec=True) @mock.patch('builtins.open', spec=True)
def test_compiled_css(open_mock, subprocess_mock, getmtime_mock): def test_compiled_css(open_mock, subprocess_mock, getmtime_mock):
getmtime_mock.side_effect = [ getmtime_mock.side_effect = [
# The first call is for the source # The first call is for the source

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше