refactor: pyupgrade on ace_common, api_admin, auth_exchange (#26782)

This commit is contained in:
M. Zulqarnain
2021-03-12 14:15:03 +05:00
committed by GitHub
parent 2c44315ce0
commit 6286de8bd1
32 changed files with 118 additions and 144 deletions

View File

@@ -20,14 +20,14 @@ class AceCommonConfig(AppConfig):
plugin_app = {
PluginSettings.CONFIG: {
ProjectType.LMS: {
SettingsType.PRODUCTION: {PluginSettings.RELATIVE_PATH: u'settings.production'},
SettingsType.COMMON: {PluginSettings.RELATIVE_PATH: u'settings.common'},
SettingsType.DEVSTACK: {PluginSettings.RELATIVE_PATH: u'settings.devstack'},
SettingsType.PRODUCTION: {PluginSettings.RELATIVE_PATH: 'settings.production'},
SettingsType.COMMON: {PluginSettings.RELATIVE_PATH: 'settings.common'},
SettingsType.DEVSTACK: {PluginSettings.RELATIVE_PATH: 'settings.devstack'},
},
ProjectType.CMS: {
SettingsType.PRODUCTION: {PluginSettings.RELATIVE_PATH: u'settings.production'},
SettingsType.COMMON: {PluginSettings.RELATIVE_PATH: u'settings.common'},
SettingsType.DEVSTACK: {PluginSettings.RELATIVE_PATH: u'settings.devstack'},
SettingsType.PRODUCTION: {PluginSettings.RELATIVE_PATH: 'settings.production'},
SettingsType.COMMON: {PluginSettings.RELATIVE_PATH: 'settings.common'},
SettingsType.DEVSTACK: {PluginSettings.RELATIVE_PATH: 'settings.devstack'},
}
}
}

View File

@@ -10,7 +10,7 @@ from openedx.core.djangoapps.site_configuration import helpers as configuration_
class BaseMessageType(MessageType): # lint-amnesty, pylint: disable=missing-class-docstring
def __init__(self, *args, **kwargs):
super(BaseMessageType, self).__init__(*args, **kwargs) # lint-amnesty, pylint: disable=super-with-arguments
super().__init__(*args, **kwargs)
from_address = configuration_helpers.get_value('email_from_address')
if from_address:
self.options.update({'from_address': from_address}) # pylint: disable=no-member

View File

@@ -1,10 +1,9 @@
# pylint: disable=missing-docstring
from urllib.parse import urlparse
from crum import get_current_request
from django import template
from django.utils.safestring import mark_safe
from six.moves.urllib.parse import urlparse # pylint: disable=import-error
from openedx.core.djangoapps.ace_common.tracking import CampaignTrackingInfo, GoogleAnalyticsTrackingPixel
from openedx.core.djangolib.markup import HTML
@@ -57,14 +56,14 @@ def _get_variables_from_context(context, tag_name):
if request is None:
raise template.VariableDoesNotExist(
u'The {0} template tag requires a "request" to be present in the template context. Consider using '
u'"emulate_http_request" if you are rendering the template in a celery task.'.format(tag_name)
'The {} template tag requires a "request" to be present in the template context. Consider using '
'"emulate_http_request" if you are rendering the template in a celery task.'.format(tag_name)
)
message = context.get('message')
if message is None:
raise template.VariableDoesNotExist(
u'The {0} template tag requires a "message" to be present in the template context.'.format(tag_name)
f'The {tag_name} template tag requires a "message" to be present in the template context.'
)
return request.site, request.user, message
@@ -88,7 +87,7 @@ def google_analytics_tracking_pixel(context):
image_url = _get_google_analytics_tracking_url(context)
if image_url is not None:
return mark_safe(
HTML(u'<img src="{0}" alt="" role="presentation" aria-hidden="true" />').format(HTML(image_url))
HTML('<img src="{0}" alt="" role="presentation" aria-hidden="true" />').format(HTML(image_url))
)
else:
return ''
@@ -103,7 +102,7 @@ def _get_google_analytics_tracking_url(context):
campaign_source=message.app_label,
campaign_name=message.name,
campaign_content=message.uuid,
document_path='/email/{0}/{1}/{2}/{3}'.format(
document_path='/email/{}/{}/{}/{}'.format(
message.app_label,
message.name,
message.send_uuid,
@@ -151,5 +150,5 @@ def ensure_url_is_absolute(site, relative_path):
else:
root = site.domain.rstrip('/')
relative_path = relative_path.lstrip('/')
url = u'https://{root}/{path}'.format(root=root, path=relative_path)
url = f'https://{root}/{relative_path}'
return url

View File

@@ -2,17 +2,17 @@
import uuid
from unittest.mock import patch
from urllib.parse import parse_qs, urlparse
from django.http import HttpRequest
from edx_ace import Message, Recipient
from mock import patch
from six.moves.urllib.parse import parse_qs, urlparse # pylint: disable=import-error
from openedx.core.djangoapps.site_configuration.tests.factories import SiteFactory
from common.djangoapps.student.tests.factories import UserFactory
class QueryStringAssertionMixin(object):
class QueryStringAssertionMixin:
def assert_query_string_equal(self, expected_qs, actual_qs):
"""
@@ -64,10 +64,10 @@ class QueryStringAssertionMixin(object):
assert parsed_qs[expected_key] == [str(expected_value)]
class EmailTemplateTagMixin(object):
class EmailTemplateTagMixin:
def setUp(self):
super(EmailTemplateTagMixin, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
patcher = patch('openedx.core.djangoapps.ace_common.templatetags.ace.get_current_request')
self.mock_get_current_request = patcher.start()

View File

@@ -1,11 +1,10 @@
"""
Tests for ace message module
"""
from unittest.mock import patch
import ddt
from django.test import TestCase
from mock import patch
from openedx.core.djangoapps.ace_common.message import BaseMessageType

View File

@@ -21,7 +21,7 @@ class TestAbsoluteUrl(CacheIsolationTestCase):
def setUp(self):
self.site = SiteFactory.create()
self.site.domain = 'example.com'
super(TestAbsoluteUrl, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
def test_absolute_url(self):
absolute = ensure_url_is_absolute(self.site, '/foo/bar')

View File

@@ -1,10 +1,9 @@
# pylint: disable=missing-docstring
from urllib.parse import parse_qs
import attr
import six
from django.utils.http import urlencode
from six.moves.urllib.parse import parse_qs # pylint: disable=import-error, ungrouped-imports
from openedx.core.djangoapps.theming.helpers import get_config_value_from_site_or_settings
@@ -13,7 +12,7 @@ DEFAULT_CAMPAIGN_MEDIUM = 'email'
@attr.s
class CampaignTrackingInfo(object):
class CampaignTrackingInfo:
"""
A struct for storing the set of UTM parameters that are recognized by tracking tools when included in URLs.
"""
@@ -40,14 +39,14 @@ class CampaignTrackingInfo(object):
if existing_query_string is not None:
parameters = parse_qs(existing_query_string)
for attribute, value in six.iteritems(attr.asdict(self)):
for attribute, value in attr.asdict(self).items():
if value is not None:
parameters['utm_' + attribute] = [value]
return urlencode(parameters, doseq=True)
@attr.s
class GoogleAnalyticsTrackingPixel(object):
class GoogleAnalyticsTrackingPixel:
"""
Implementation of the Google Analytics measurement protocol for email tracking.
@@ -101,14 +100,14 @@ class GoogleAnalyticsTrackingPixel(object):
site=self.site,
)
if user_id_dimension is not None and self.user_id is not None:
parameter_name = 'cd{0}'.format(user_id_dimension)
parameter_name = f'cd{user_id_dimension}'
parameters[parameter_name] = self.user_id
if self.course_id is not None and self.event_label is None:
param_name = fields.event_label.metadata['param_name']
parameters[param_name] = six.text_type(self.course_id)
parameters[param_name] = str(self.course_id)
return u"https://www.google-analytics.com/collect?{params}".format(params=urlencode(parameters))
return "https://www.google-analytics.com/collect?{params}".format(params=urlencode(parameters))
def _get_tracking_id(self):
tracking_id = get_config_value_from_site_or_settings("GOOGLE_ANALYTICS_ACCOUNT", site=self.site)

View File

@@ -33,9 +33,9 @@ class ApiAccessRequestAdmin(admin.ModelAdmin):
},),
('Status', {
'description': Text(_(
u'Once you have approved this request, go to {catalog_admin_url} to set up a catalog for this user.'
'Once you have approved this request, go to {catalog_admin_url} to set up a catalog for this user.'
)).format(
catalog_admin_url=HTML(u'<a href="{0}">{0}</a>').format(reverse('api_admin:catalog-search'))
catalog_admin_url=HTML('<a href="{0}">{0}</a>').format(reverse('api_admin:catalog-search'))
),
'fields': ('status',),
}),

View File

@@ -11,7 +11,7 @@ class ApiAccessRequestSerializer(serializers.ModelSerializer):
"""
ApiAccessRequest serializer.
"""
class Meta(object):
class Meta:
model = ApiAccessRequest
fields = (
'id', 'created', 'modified', 'user', 'status', 'website',

View File

@@ -83,7 +83,7 @@ class ApiAccessRequestViewTests(TestCase):
"""
self.update_user_and_re_login(is_staff=True)
response = self.client.get(self.url + '?user__username={}'.format(self.user.username))
response = self.client.get(self.url + f'?user__username={self.user.username}')
self._assert_api_access_request_response(api_response=response, expected_results_count=1)
def test_filtering_for_non_existing_user(self):

View File

@@ -13,7 +13,7 @@ class ApiAccessRequestForm(forms.ModelForm):
"""Form to request API access."""
terms_of_service = forms.BooleanField(widget=TermsOfServiceCheckboxInput(), label='')
class Meta(object):
class Meta:
model = ApiAccessRequest
fields = ('company_name', 'website', 'company_address', 'reason', 'terms_of_service')
labels = {
@@ -34,7 +34,7 @@ class ApiAccessRequestForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
# Get rid of the colons at the end of the field labels.
kwargs.setdefault('label_suffix', '')
super(ApiAccessRequestForm, self).__init__(*args, **kwargs) # lint-amnesty, pylint: disable=super-with-arguments
super().__init__(*args, **kwargs)
class ViewersWidget(forms.widgets.TextInput):
@@ -61,7 +61,7 @@ class ViewersField(forms.Field):
return [username.strip() for username in value.split(',')]
def validate(self, value):
super(ViewersField, self).validate(value) # lint-amnesty, pylint: disable=super-with-arguments
super().validate(value)
nonexistent_users = []
for username in value:
try:
@@ -70,7 +70,7 @@ class ViewersField(forms.Field):
nonexistent_users.append(username)
if nonexistent_users:
raise forms.ValidationError(
_(u'The following users do not exist: {usernames}.').format(usernames=nonexistent_users)
_('The following users do not exist: {usernames}.').format(usernames=nonexistent_users)
)
@@ -79,7 +79,7 @@ class CatalogForm(forms.ModelForm):
viewers = ViewersField()
class Meta(object):
class Meta:
model = Catalog
fields = ('name', 'query', 'viewers')
help_texts = {

View File

@@ -8,7 +8,6 @@ from django.contrib.auth.models import User # lint-amnesty, pylint: disable=imp
from django.contrib.sites.models import Site
from django.core.management.base import BaseCommand, CommandError
from django.db.models.signals import post_save, pre_save
from six import text_type
from openedx.core.djangoapps.api_admin.models import (
ApiAccessConfig,
@@ -106,7 +105,7 @@ class Command(BaseCommand):
try:
return User.objects.get(username=username)
except User.DoesNotExist:
raise CommandError('User {} not found'.format(username)) # lint-amnesty, pylint: disable=raise-missing-from
raise CommandError(f'User {username} not found') # lint-amnesty, pylint: disable=raise-missing-from
def create_api_access_request(self, user, status, reason, website):
"""
@@ -123,9 +122,9 @@ class Command(BaseCommand):
except OSError as e:
# Ignore a specific error that occurs in the downstream `send_request_email` receiver.
# see https://openedx.atlassian.net/browse/EDUCATOR-4478
error_msg = text_type(e)
error_msg = str(e)
if 'Permission denied' in error_msg and 'mako_lms' in error_msg:
logger.warning('Error sending email about access request: {}'.format(error_msg))
logger.warning(f'Error sending email about access request: {error_msg}')
else:
raise CommandError(error_msg) # lint-amnesty, pylint: disable=raise-missing-from
except Exception as e:
@@ -136,7 +135,7 @@ class Command(BaseCommand):
)
raise CommandError(msg) # lint-amnesty, pylint: disable=raise-missing-from
logger.info('Created ApiAccessRequest for user {}'.format(user.username))
logger.info(f'Created ApiAccessRequest for user {user.username}')
def create_api_access_config(self):
"""

View File

@@ -1,4 +1,5 @@
import unittest
from unittest.mock import patch
import ddt
from django.conf import settings
@@ -6,7 +7,6 @@ from django.contrib.sites.models import Site
from django.core.management import call_command
from django.core.management.base import CommandError
from django.test import TestCase
from mock import patch
from openedx.core.djangoapps.api_admin.management.commands import create_api_access_request
from openedx.core.djangoapps.api_admin.models import ApiAccessConfig, ApiAccessRequest
@@ -20,7 +20,7 @@ class TestCreateApiAccessRequest(TestCase):
@classmethod
def setUpClass(cls):
super(TestCreateApiAccessRequest, cls).setUpClass()
super().setUpClass()
cls.command = 'create_api_access_request'
cls.user = UserFactory()

View File

@@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
import django.db.models.deletion
import django.utils.timezone
import model_utils.fields
@@ -21,7 +18,7 @@ class Migration(migrations.Migration):
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('created', model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, verbose_name='created', editable=False)),
('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, verbose_name='modified', editable=False)),
('status', models.CharField(default=u'pending', help_text='Status of this API access request', max_length=255, db_index=True, choices=[(u'pending', 'Pending'), (u'denied', 'Denied'), (u'approved', 'Approved')])),
('status', models.CharField(default='pending', help_text='Status of this API access request', max_length=255, db_index=True, choices=[('pending', 'Pending'), ('denied', 'Denied'), ('approved', 'Approved')])),
('website', models.URLField(help_text='The URL of the website associated with this API user.')),
('reason', models.TextField(help_text='The reason this user wants to access the API.')),
('user', models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)),
@@ -38,7 +35,7 @@ class Migration(migrations.Migration):
('id', models.IntegerField(verbose_name='ID', db_index=True, auto_created=True, blank=True)),
('created', model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, verbose_name='created', editable=False)),
('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, verbose_name='modified', editable=False)),
('status', models.CharField(default=u'pending', help_text='Status of this API access request', max_length=255, db_index=True, choices=[(u'pending', 'Pending'), (u'denied', 'Denied'), (u'approved', 'Approved')])),
('status', models.CharField(default='pending', help_text='Status of this API access request', max_length=255, db_index=True, choices=[('pending', 'Pending'), ('denied', 'Denied'), ('approved', 'Approved')])),
('website', models.URLField(help_text='The URL of the website associated with this API user.')),
('reason', models.TextField(help_text='The reason this user wants to access the API.')),
('history_id', models.AutoField(serialize=False, primary_key=True)),

View File

@@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from django.db import migrations, models
API_GROUP_NAME = 'API Access Request Approvers'

View File

@@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
@@ -30,22 +27,22 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='apiaccessrequest',
name='company_address',
field=models.CharField(default=u'', max_length=255),
field=models.CharField(default='', max_length=255),
),
migrations.AddField(
model_name='apiaccessrequest',
name='company_name',
field=models.CharField(default=u'', max_length=255),
field=models.CharField(default='', max_length=255),
),
migrations.AddField(
model_name='historicalapiaccessrequest',
name='company_address',
field=models.CharField(default=u'', max_length=255),
field=models.CharField(default='', max_length=255),
),
migrations.AddField(
model_name='historicalapiaccessrequest',
name='company_name',
field=models.CharField(default=u'', max_length=255),
field=models.CharField(default='', max_length=255),
),
migrations.AlterField(
model_name='apiaccessrequest',

View File

@@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
import django.db.models.deletion
from django.db import migrations, models

View File

@@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from django.conf import settings
from django.db import migrations, models

View File

@@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from django.db import migrations, models

View File

@@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from django.db import migrations, models

View File

@@ -3,6 +3,7 @@
import logging
from smtplib import SMTPException
from urllib.parse import urlunsplit
from config_models.models import ConfigurationModel
from django.conf import settings
@@ -18,7 +19,6 @@ from django.utils.translation import ugettext_lazy as _
from django.utils.encoding import python_2_unicode_compatible
from model_utils.models import TimeStampedModel
from six.moves.urllib.parse import urlunsplit # pylint: disable=import-error
from common.djangoapps.edxmako.shortcuts import render_to_string
from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers
@@ -36,9 +36,9 @@ class ApiAccessRequest(TimeStampedModel):
.. pii_retirement: local_api
"""
PENDING = u'pending'
DENIED = u'denied'
APPROVED = u'approved'
PENDING = 'pending'
DENIED = 'denied'
APPROVED = 'approved'
STATUS_CHOICES = (
(PENDING, _('Pending')),
(DENIED, _('Denied')),
@@ -54,8 +54,8 @@ class ApiAccessRequest(TimeStampedModel):
)
website = models.URLField(help_text=_('The URL of the website associated with this API user.'))
reason = models.TextField(help_text=_('The reason this user wants to access the API.'))
company_name = models.CharField(max_length=255, default=u'')
company_address = models.CharField(max_length=255, default=u'')
company_name = models.CharField(max_length=255, default='')
company_address = models.CharField(max_length=255, default='')
site = models.ForeignKey(Site, on_delete=models.CASCADE)
contacted = models.BooleanField(default=False)
@@ -118,18 +118,18 @@ class ApiAccessRequest(TimeStampedModel):
def approve(self):
"""Approve this request."""
log.info(u'Approving API request from user [%s].', self.user.id)
log.info('Approving API request from user [%s].', self.user.id)
self.status = self.APPROVED
self.save()
def deny(self):
"""Deny this request."""
log.info(u'Denying API request from user [%s].', self.user.id)
log.info('Denying API request from user [%s].', self.user.id)
self.status = self.DENIED
self.save()
def __str__(self):
return u'ApiAccessRequest {website} [{status}]'.format(website=self.website, status=self.status)
return f'ApiAccessRequest {self.website} [{self.status}]'
@python_2_unicode_compatible
@@ -141,7 +141,7 @@ class ApiAccessConfig(ConfigurationModel):
"""
def __str__(self):
return 'ApiAccessConfig [enabled={}]'.format(self.enabled)
return f'ApiAccessConfig [enabled={self.enabled}]'
@receiver(post_save, sender=ApiAccessRequest, dispatch_uid="api_access_request_post_save_email")
@@ -178,14 +178,14 @@ def _send_new_pending_email(instance):
message = render_to_string('api_admin/api_access_request_email_new_request.txt', context)
try:
send_mail(
_u(u'API access request from {company}').format(company=instance.company_name),
_u('API access request from {company}').format(company=instance.company_name),
message,
settings.API_ACCESS_FROM_EMAIL,
[settings.API_ACCESS_MANAGER_EMAIL],
fail_silently=False
)
except SMTPException:
log.exception(u'Error sending API user notification email for request [%s].', instance.id)
log.exception('Error sending API user notification email for request [%s].', instance.id)
def _send_decision_email(instance):
@@ -208,7 +208,7 @@ def _send_decision_email(instance):
}
message = render_to_string(
'api_admin/api_access_request_email_{status}.txt'.format(status=instance.status),
f'api_admin/api_access_request_email_{instance.status}.txt',
context
)
try:
@@ -221,7 +221,7 @@ def _send_decision_email(instance):
)
instance.contacted = True
except SMTPException:
log.exception(u'Error sending API user notification email for request [%s].', instance.id)
log.exception('Error sending API user notification email for request [%s].', instance.id)
@python_2_unicode_compatible
@@ -237,7 +237,7 @@ class Catalog(models.Model):
query = models.TextField(null=False, blank=False)
viewers = models.TextField()
class Meta(object):
class Meta:
# Catalogs live in course discovery, so we do not create any
# tables in LMS. Instead we override the save method to not
# touch the database, and use our API client to communicate
@@ -252,7 +252,7 @@ class Catalog(models.Model):
self.query = attributes['query']
self.viewers = attributes['viewers']
else:
super(Catalog, self).__init__(*args, **kwargs) # lint-amnesty, pylint: disable=super-with-arguments
super().__init__(*args, **kwargs)
def save(self, **kwargs): # lint-amnesty, pylint: disable=arguments-differ, unused-argument
return None
@@ -268,4 +268,4 @@ class Catalog(models.Model):
}
def __str__(self):
return u'Catalog {name} [{query}]'.format(name=self.name, query=self.query)
return f'Catalog {self.name} [{self.query}]'

View File

@@ -15,7 +15,7 @@ Application = get_application_model() # pylint: disable=invalid-name
class ApiAccessRequestFactory(DjangoModelFactory):
"""Factory for ApiAccessRequest objects."""
class Meta(object):
class Meta:
model = ApiAccessRequest
user = factory.SubFactory(UserFactory)
@@ -24,7 +24,7 @@ class ApiAccessRequestFactory(DjangoModelFactory):
class ApplicationFactory(DjangoModelFactory):
"""Factory for OAuth Application objects."""
class Meta(object):
class Meta:
model = Application
authorization_grant_type = Application.GRANT_CLIENT_CREDENTIALS
@@ -34,7 +34,7 @@ class ApplicationFactory(DjangoModelFactory):
class CatalogFactory(DjangoModelFactory):
"""Factory for Catalog objects."""
class Meta(object):
class Meta:
model = Catalog
id = FuzzyInteger(0, 999) # pylint: disable=invalid-name

View File

@@ -2,11 +2,10 @@
from smtplib import SMTPException
from unittest import mock
import pytest
import ddt
import mock
import six
from django.db import IntegrityError
from django.test import TestCase
@@ -23,7 +22,7 @@ from common.djangoapps.student.tests.factories import UserFactory
class ApiAccessRequestTests(TestCase):
def setUp(self):
super(ApiAccessRequestTests, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
self.user = UserFactory()
self.request = ApiAccessRequestFactory(user=self.user)
@@ -64,7 +63,7 @@ class ApiAccessRequestTests(TestCase):
assert ApiAccessRequest.api_access_status(self.user) is None
def test_unicode(self):
request_unicode = six.text_type(self.request)
request_unicode = str(self.request)
assert self.request.website in request_unicode
assert self.request.status in request_unicode
@@ -85,14 +84,14 @@ class ApiAccessRequestTests(TestCase):
class ApiAccessConfigTests(TestCase):
def test_unicode(self):
assert six.text_type(ApiAccessConfig(enabled=True)) == u'ApiAccessConfig [enabled=True]'
assert six.text_type(ApiAccessConfig(enabled=False)) == u'ApiAccessConfig [enabled=False]'
assert str(ApiAccessConfig(enabled=True)) == 'ApiAccessConfig [enabled=True]'
assert str(ApiAccessConfig(enabled=False)) == 'ApiAccessConfig [enabled=False]'
@skip_unless_lms
class ApiAccessRequestSignalTests(TestCase):
def setUp(self):
super(ApiAccessRequestSignalTests, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
self.user = UserFactory()
self.api_access_request = ApiAccessRequest(user=self.user, site=SiteFactory())
self.send_new_pending_email_function = 'openedx.core.djangoapps.api_admin.models._send_new_pending_email'
@@ -141,7 +140,7 @@ class ApiAccessRequestSignalTests(TestCase):
# Verify that initial save logs email errors properly
mock_model_log_exception.assert_called_once_with(
u'Error sending API user notification email for request [%s].', self.api_access_request.id
'Error sending API user notification email for request [%s].', self.api_access_request.id
)
# Verify object saved
assert self.api_access_request.id is not None
@@ -151,7 +150,7 @@ class ApiAccessRequestSignalTests(TestCase):
self.api_access_request.approve()
# Verify that updating request status logs email errors properly
mock_model_log_exception.assert_called_once_with(
u'Error sending API user notification email for request [%s].', self.api_access_request.id
'Error sending API user notification email for request [%s].', self.api_access_request.id
)
# Verify object saved
assert self.api_access_request.status == ApiAccessRequest.APPROVED

View File

@@ -29,7 +29,7 @@ class ApiAdminTest(TestCase):
Base class to allow API admin access to tests.
"""
def setUp(self):
super(ApiAdminTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
ApiAccessConfig(enabled=True).save()
@@ -39,7 +39,7 @@ class ApiRequestViewTest(ApiAdminTest):
Test the API Request View.
"""
def setUp(self):
super(ApiRequestViewTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
self.url = reverse('api_admin:api-request')
password = 'abc123'
self.user = UserFactory(password=password)
@@ -110,7 +110,7 @@ class ApiRequestStatusViewTest(ApiAdminTest):
Tests of the API Status endpoint.
"""
def setUp(self):
super(ApiRequestStatusViewTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
password = 'abc123'
self.user = UserFactory(password=password)
self.client.login(username=self.user.username, password=password)
@@ -226,7 +226,7 @@ class CatalogTest(ApiAdminTest):
Test the catalog API.
"""
def setUp(self):
super(CatalogTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
password = 'abc123'
self.user = UserFactory(password=password, is_staff=True)
self.client.login(username=self.user.username, password=password)
@@ -237,7 +237,7 @@ class CatalogTest(ApiAdminTest):
url = '{root}/catalogs/'.format(root=settings.COURSE_CATALOG_API_URL.rstrip('/'))
if catalog_id:
url += '{id}/'.format(id=catalog_id)
url += f'{catalog_id}/'
httpretty.register_uri(
method,
@@ -254,7 +254,7 @@ class CatalogSearchViewTest(CatalogTest):
Test the catalog search endpoint.
"""
def setUp(self):
super(CatalogSearchViewTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
self.url = reverse('api_admin:catalog-search')
def test_get(self):
@@ -279,7 +279,7 @@ class CatalogListViewTest(CatalogTest):
Test the catalog list endpoint.
"""
def setUp(self):
super(CatalogListViewTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
self.catalog_user = UserFactory()
self.url = reverse('api_admin:catalog-list', kwargs={'username': self.catalog_user.username})
@@ -331,7 +331,7 @@ class CatalogEditViewTest(CatalogTest):
Test edits to the catalog endpoint.
"""
def setUp(self):
super(CatalogEditViewTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
self.catalog_user = UserFactory()
self.catalog = CatalogFactory(viewers=[self.catalog_user.username])
self.url = reverse('api_admin:catalog-edit', kwargs={'catalog_id': self.catalog.id})
@@ -353,7 +353,7 @@ class CatalogEditViewTest(CatalogTest):
self.assertRedirects(response, reverse('api_admin:catalog-search'))
assert httpretty.last_request().method == 'DELETE' # lint-amnesty, pylint: disable=no-member
assert httpretty.last_request().path == \
'/api/v1/catalogs/{}/'.format(self.catalog.id) # lint-amnesty, pylint: disable=no-member
f'/api/v1/catalogs/{self.catalog.id}/' # lint-amnesty, pylint: disable=no-member
assert len(httpretty.httpretty.latest_requests) == 1
@httpretty.activate
@@ -380,7 +380,7 @@ class CatalogPreviewViewTest(CatalogTest):
Test the catalog preview endpoint.
"""
def setUp(self):
super(CatalogPreviewViewTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
self.url = reverse('api_admin:catalog-preview')
@httpretty.activate

View File

@@ -40,12 +40,12 @@ class ApiRequestView(CreateView):
"""
if ApiAccessRequest.api_access_status(request.user) is not None:
return redirect(reverse('api_admin:api-status'))
return super(ApiRequestView, self).get(request) # lint-amnesty, pylint: disable=super-with-arguments
return super().get(request)
def form_valid(self, form):
form.instance.user = self.request.user
form.instance.site = get_current_site(self.request)
return super(ApiRequestView, self).form_valid(form) # lint-amnesty, pylint: disable=super-with-arguments
return super().form_valid(form)
class ApiRequestStatusView(ApplicationRegistration):
@@ -87,7 +87,7 @@ class ApiRequestStatusView(ApplicationRegistration):
})
def get_form(self, form_class=None):
form = super(ApiRequestStatusView, self).get_form(form_class) # lint-amnesty, pylint: disable=super-with-arguments
form = super().get_form(form_class)
# Copy the data, since it's an immutable QueryDict.
copied_data = form.data.copy()
# Now set the fields that were removed earlier. We give them
@@ -105,14 +105,14 @@ class ApiRequestStatusView(ApplicationRegistration):
def form_valid(self, form):
# Delete any existing applications if the user has decided to regenerate their credentials
Application.objects.filter(user=self.request.user).delete()
return super(ApiRequestStatusView, self).form_valid(form) # lint-amnesty, pylint: disable=super-with-arguments
return super().form_valid(form)
def form_invalid(self, form):
return self.get(self.request, form)
@require_api_access
def post(self, request): # lint-amnesty, pylint: disable=arguments-differ
return super(ApiRequestStatusView, self).post(request) # lint-amnesty, pylint: disable=super-with-arguments
return super().post(request)
class ApiTosView(TemplateView):
@@ -121,7 +121,7 @@ class ApiTosView(TemplateView):
template_name = 'api_admin/terms_of_service.html'
class CatalogApiMixin(object):
class CatalogApiMixin:
def get_catalog_api_client(self, user):
return create_catalog_api_client(user)

View File

@@ -30,16 +30,16 @@ class TermsOfServiceCheckboxInput(CheckboxInput):
# Translators: link_start and link_end are HTML tags for a link to the terms of service.
# platform_name is the name of this Open edX installation.
label = Text(_(
u'I, and my organization, accept the {link_start}{platform_name} API Terms of Service{link_end}.'
'I, and my organization, accept the {link_start}{platform_name} API Terms of Service{link_end}.'
)).format(
platform_name=configuration_helpers.get_value('PLATFORM_NAME', settings.PLATFORM_NAME),
link_start=HTML(u'<a href="{url}" rel="noopener" target="_blank">').format(
link_start=HTML('<a href="{url}" rel="noopener" target="_blank">').format(
url=reverse('api_admin:api-tos')
),
link_end=HTML('</a>'),
)
html = HTML(u'<input{{}} /> <label class="tos-checkbox-label" for="{id}">{label}</label>').format(
html = HTML('<input{{}} /> <label class="tos-checkbox-label" for="{id}">{label}</label>').format(
id=final_attrs['id'],
label=label
)

View File

@@ -55,7 +55,7 @@ class ScopeChoiceField(forms.ChoiceField):
value = value.split(' ')
# Split values into list
return u' '.join([smart_text(val) for val in value]).split(u' ')
return ' '.join([smart_text(val) for val in value]).split(' ')
def validate(self, value):
"""
@@ -86,7 +86,7 @@ class AccessTokenExchangeForm(forms.Form):
client_id = CharField(required=False)
def __init__(self, request, oauth2_adapter, *args, **kwargs):
super(AccessTokenExchangeForm, self).__init__(*args, **kwargs) # lint-amnesty, pylint: disable=super-with-arguments
super().__init__(*args, **kwargs)
self.request = request
self.oauth2_adapter = oauth2_adapter
@@ -96,7 +96,7 @@ class AccessTokenExchangeForm(forms.Form):
instead of validating each field.
"""
try:
super(AccessTokenExchangeForm, self)._clean_fields() # lint-amnesty, pylint: disable=super-with-arguments
super()._clean_fields()
except OAuthValidationError as e:
self._errors.update(e.args[0])
@@ -105,7 +105,7 @@ class AccessTokenExchangeForm(forms.Form):
Overriding the default cleaning behaviour for a shallow error dict.
"""
try:
super(AccessTokenExchangeForm, self)._clean_form() # lint-amnesty, pylint: disable=super-with-arguments
super()._clean_form()
except OAuthValidationError as e:
self._errors.update(e.args[0])
@@ -118,7 +118,7 @@ class AccessTokenExchangeForm(forms.Form):
raise OAuthValidationError(
{
"error": "invalid_request",
"error_description": u"{} is required".format(field_name),
"error_description": f"{field_name} is required",
}
)
return field_val
@@ -154,7 +154,7 @@ class AccessTokenExchangeForm(forms.Form):
raise OAuthValidationError(
{
"error": "invalid_request",
"error_description": u"{} is not a supported provider".format(backend.name),
"error_description": f"{backend.name} is not a supported provider",
}
)
@@ -167,7 +167,7 @@ class AccessTokenExchangeForm(forms.Form):
raise OAuthValidationError( # lint-amnesty, pylint: disable=raise-missing-from
{
"error": "invalid_client",
"error_description": u"{} is not a valid client_id".format(client_id),
"error_description": f"{client_id} is not a valid client_id",
}
)
if client.client_type != Application.CLIENT_PUBLIC:
@@ -176,7 +176,7 @@ class AccessTokenExchangeForm(forms.Form):
# invalid_client isn't really the right code, but this mirrors
# https://github.com/edx/django-oauth2-provider/blob/edx/provider/oauth2/forms.py#L331
"error": "invalid_client",
"error_description": u"{} is not a public client".format(client_id),
"error_description": f"{client_id} is not a public client",
}
)
self.cleaned_data["client"] = client

View File

@@ -6,7 +6,7 @@ from openedx.core.djangoapps.oauth_dispatch import adapters
from openedx.core.djangoapps.oauth_dispatch.tests.constants import DUMMY_REDIRECT_URL
class DOTAdapterMixin(object):
class DOTAdapterMixin:
"""
Mixin to rewire existing tests to use django-oauth-toolkit (DOT) backend

View File

@@ -25,7 +25,7 @@ class AccessTokenExchangeFormTest(AccessTokenExchangeTestMixin):
Mixin that defines test cases for AccessTokenExchangeForm
"""
def setUp(self):
super(AccessTokenExchangeFormTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
self.request = RequestFactory().post("dummy_url")
redirect_uri = 'dummy_redirect_url'
SessionMiddleware().process_request(self.request)
@@ -34,7 +34,7 @@ class AccessTokenExchangeFormTest(AccessTokenExchangeTestMixin):
self.request.backend = social_utils.load_backend(self.request.social_strategy, self.BACKEND, redirect_uri)
def tearDown(self):
super(AccessTokenExchangeFormTest, self).tearDown() # lint-amnesty, pylint: disable=super-with-arguments
super().tearDown()
Partial.objects.all().delete()
def _assert_error(self, data, expected_error, expected_error_description): # lint-amnesty, pylint: disable=arguments-differ

View File

@@ -40,19 +40,19 @@ class AccessTokenExchangeViewTest(AccessTokenExchangeTestMixin):
in the future.
"""
def setUp(self):
super(AccessTokenExchangeViewTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
self.url = reverse("exchange_access_token", kwargs={"backend": self.BACKEND})
self.csrf_client = APIClient(enforce_csrf_checks=True)
def tearDown(self):
super(AccessTokenExchangeViewTest, self).tearDown() # lint-amnesty, pylint: disable=super-with-arguments
super().tearDown()
Partial.objects.all().delete()
def _assert_error(self, data, expected_error, expected_error_description, error_code=None):
response = self.csrf_client.post(self.url, data)
assert response.status_code == (error_code if error_code else 400)
assert response['Content-Type'] == 'application/json'
expected_data = {u"error": expected_error, u"error_description": expected_error_description}
expected_data = {"error": expected_error, "error_description": expected_error_description}
if error_code:
expected_data['error_code'] = error_code
assert json.loads(response.content.decode('utf-8')) == expected_data
@@ -146,7 +146,7 @@ class TestLoginWithAccessTokenView(TestCase):
Tests for LoginWithAccessTokenView
"""
def setUp(self):
super(TestLoginWithAccessTokenView, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
self.user = UserFactory()
self.oauth2_client = Application.objects.create(client_type=Application.CLIENT_CONFIDENTIAL)
@@ -155,7 +155,7 @@ class TestLoginWithAccessTokenView(TestCase):
Calls the login_with_access_token endpoint and verifies the response given the expected values.
"""
url = reverse("login_with_access_token")
response = self.client.post(url, HTTP_AUTHORIZATION=u"Bearer {0}".format(access_token).encode('utf-8'))
response = self.client.post(url, HTTP_AUTHORIZATION=f"Bearer {access_token}".encode('utf-8'))
assert response.status_code == expected_status_code
if expected_cookie_name:
assert expected_cookie_name in response.cookies

View File

@@ -20,7 +20,7 @@ class AccessTokenExchangeTestMixin(ThirdPartyOAuthTestMixin):
* _assert_success(data, expected_scopes)
"""
def setUp(self):
super(AccessTokenExchangeTestMixin, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
# Initialize to minimal data
self.data = {
@@ -61,7 +61,7 @@ class AccessTokenExchangeTestMixin(ThirdPartyOAuthTestMixin):
for field in ["access_token", "client_id"]:
data = dict(self.data)
del data[field]
self._assert_error(data, "invalid_request", u"{} is required".format(field)) # lint-amnesty, pylint: disable=no-value-for-parameter
self._assert_error(data, "invalid_request", f"{field} is required") # lint-amnesty, pylint: disable=no-value-for-parameter
def test_invalid_client(self):
self.data["client_id"] = "nonexistent_client"
@@ -77,7 +77,7 @@ class AccessTokenExchangeTestMixin(ThirdPartyOAuthTestMixin):
self._assert_error( # lint-amnesty, pylint: disable=no-value-for-parameter
self.data,
"invalid_client",
"{}_confidential is not a public client".format(self.client_id),
f"{self.client_id}_confidential is not a public client",
)
def test_inactive_user(self):

View File

@@ -41,7 +41,7 @@ class AccessTokenExchangeBase(APIView):
@method_decorator(social_utils.psa("social:complete"))
def dispatch(self, *args, **kwargs): # pylint: disable=arguments-differ
return super(AccessTokenExchangeBase, self).dispatch(*args, **kwargs) # lint-amnesty, pylint: disable=super-with-arguments
return super().dispatch(*args, **kwargs)
def post(self, request, _backend):
"""
@@ -146,8 +146,8 @@ class LoginWithAccessTokenView(APIView):
if not self._is_grant_password(request.auth):
raise AuthenticationFailed({
u'error_code': u'non_supported_token',
u'developer_message': u'Only support DOT type access token with grant type password. '
'error_code': 'non_supported_token',
'developer_message': 'Only support DOT type access token with grant type password. '
})
login(request, request.user) # login generates and stores the user's cookies in the session