From 3a5be3b074dc1ae08c096282026eb88d7b670898 Mon Sep 17 00:00:00 2001 From: "M. Zulqarnain" Date: Tue, 2 Mar 2021 16:45:20 +0500 Subject: [PATCH] pyupgrade on course_creators, maintenance and models apps under CMS (#26709) --- cms/djangoapps/course_creators/admin.py | 4 +-- .../migrations/0001_initial.py | 7 ++-- cms/djangoapps/course_creators/models.py | 20 +++++------ .../course_creators/tests/test_admin.py | 8 ++--- .../course_creators/tests/test_views.py | 5 +-- cms/djangoapps/maintenance/tests.py | 25 +++++++------- cms/djangoapps/maintenance/views.py | 34 +++++++++---------- .../models/settings/course_grading.py | 27 +++++++-------- .../models/settings/course_metadata.py | 24 ++++++------- 9 files changed, 73 insertions(+), 81 deletions(-) diff --git a/cms/djangoapps/course_creators/admin.py b/cms/djangoapps/course_creators/admin.py index 3c41cd5370..90683660a6 100644 --- a/cms/djangoapps/course_creators/admin.py +++ b/cms/djangoapps/course_creators/admin.py @@ -114,7 +114,7 @@ def send_user_notification_callback(sender, **kwargs): # lint-amnesty, pylint: try: user.email_user(subject, message, studio_request_email) except: # lint-amnesty, pylint: disable=bare-except - log.warning(u"Unable to send course creator status e-mail to %s", user.email) + log.warning("Unable to send course creator status e-mail to %s", user.email) @receiver(send_admin_notification, sender=CourseCreator) @@ -140,4 +140,4 @@ def send_admin_notification_callback(sender, **kwargs): # lint-amnesty, pylint: fail_silently=False ) except SMTPException: - log.warning(u"Failure sending 'pending state' e-mail for %s to %s", user.email, studio_request_email) + log.warning("Failure sending 'pending state' e-mail for %s to %s", user.email, studio_request_email) diff --git a/cms/djangoapps/course_creators/migrations/0001_initial.py b/cms/djangoapps/course_creators/migrations/0001_initial.py index d2a13be28b..845ccd2149 100644 --- a/cms/djangoapps/course_creators/migrations/0001_initial.py +++ b/cms/djangoapps/course_creators/migrations/0001_initial.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- - - from django.conf import settings from django.db import migrations, models @@ -16,8 +13,8 @@ class Migration(migrations.Migration): name='CourseCreator', fields=[ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('state_changed', models.DateTimeField(help_text='The date when state was last updated', verbose_name=u'state last updated', auto_now_add=True)), - ('state', models.CharField(default=u'unrequested', help_text='Current course creator state', max_length=24, choices=[(u'unrequested', 'unrequested'), (u'pending', 'pending'), (u'granted', 'granted'), (u'denied', 'denied')])), + ('state_changed', models.DateTimeField(help_text='The date when state was last updated', verbose_name='state last updated', auto_now_add=True)), + ('state', models.CharField(default='unrequested', help_text='Current course creator state', max_length=24, choices=[('unrequested', 'unrequested'), ('pending', 'pending'), ('granted', 'granted'), ('denied', 'denied')])), ('note', models.CharField(help_text='Optional notes about this user (for example, why course creation access was denied)', max_length=512, blank=True)), ('user', models.OneToOneField(to=settings.AUTH_USER_MODEL, help_text='Studio user', on_delete=models.CASCADE)), ], diff --git a/cms/djangoapps/course_creators/models.py b/cms/djangoapps/course_creators/models.py index 2b2c8a0129..40f20db016 100644 --- a/cms/djangoapps/course_creators/models.py +++ b/cms/djangoapps/course_creators/models.py @@ -28,21 +28,21 @@ class CourseCreator(models.Model): .. no_pii: """ - UNREQUESTED = u'unrequested' - PENDING = u'pending' - GRANTED = u'granted' - DENIED = u'denied' + UNREQUESTED = 'unrequested' + PENDING = 'pending' + GRANTED = 'granted' + DENIED = 'denied' # Second value is the "human-readable" version. STATES = ( - (UNREQUESTED, _(u'unrequested')), - (PENDING, _(u'pending')), - (GRANTED, _(u'granted')), - (DENIED, _(u'denied')), + (UNREQUESTED, _('unrequested')), + (PENDING, _('pending')), + (GRANTED, _('granted')), + (DENIED, _('denied')), ) user = models.OneToOneField(User, help_text=_("Studio user"), on_delete=models.CASCADE) - state_changed = models.DateTimeField(u'state last updated', auto_now_add=True, + state_changed = models.DateTimeField('state last updated', auto_now_add=True, help_text=_("The date when state was last updated")) state = models.CharField(max_length=24, blank=False, choices=STATES, default=UNREQUESTED, help_text=_("Current course creator state")) @@ -50,7 +50,7 @@ class CourseCreator(models.Model): "why course creation access was denied)")) def __str__(self): - return u"{0} | {1} [{2}]".format(self.user, self.state, self.state_changed) + return f"{self.user} | {self.state} [{self.state_changed}]" @receiver(post_init, sender=CourseCreator) diff --git a/cms/djangoapps/course_creators/tests/test_admin.py b/cms/djangoapps/course_creators/tests/test_admin.py index 75c329306b..eeddde9e61 100644 --- a/cms/djangoapps/course_creators/tests/test_admin.py +++ b/cms/djangoapps/course_creators/tests/test_admin.py @@ -3,13 +3,13 @@ Tests course_creators.admin.py. """ -import mock +from unittest import mock + from django.contrib.admin.sites import AdminSite from django.contrib.auth.models import User # lint-amnesty, pylint: disable=imported-auth-user from django.core import mail from django.http import HttpRequest from django.test import TestCase -from six.moves import range from cms.djangoapps.course_creators.admin import CourseCreatorAdmin from cms.djangoapps.course_creators.models import CourseCreator @@ -29,7 +29,7 @@ class CourseCreatorAdminTest(TestCase): def setUp(self): """ Test case setup """ - super(CourseCreatorAdminTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments + super().setUp() self.user = User.objects.create_user('test_user', 'test_user+courses@edx.org', 'foo') self.table_entry = CourseCreator(user=self.user) self.table_entry.save() @@ -113,7 +113,7 @@ class CourseCreatorAdminTest(TestCase): # message sent. Admin message will follow. base_num_emails = 1 if expect_sent_to_user else 0 if expect_sent_to_admin: - context = {'user_name': u'test_user', 'user_email': u'test_user+courses@edx.org'} + context = {'user_name': 'test_user', 'user_email': 'test_user+courses@edx.org'} self.assertEqual(base_num_emails + 1, len(mail.outbox), 'Expected admin message to be sent') sent_mail = mail.outbox[base_num_emails] diff --git a/cms/djangoapps/course_creators/tests/test_views.py b/cms/djangoapps/course_creators/tests/test_views.py index 7618c207ee..5d3846ca28 100644 --- a/cms/djangoapps/course_creators/tests/test_views.py +++ b/cms/djangoapps/course_creators/tests/test_views.py @@ -3,7 +3,8 @@ Tests course_creators.views.py. """ -import mock +from unittest import mock + from django.contrib.auth.models import User # lint-amnesty, pylint: disable=imported-auth-user from django.core.exceptions import PermissionDenied from django.test import TestCase @@ -27,7 +28,7 @@ class CourseCreatorView(TestCase): def setUp(self): """ Test case setup """ - super(CourseCreatorView, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments + super().setUp() self.user = User.objects.create_user('test_user', 'test_user+courses@edx.org', 'foo') self.admin = User.objects.create_user('Mark', 'admin+courses@edx.org', 'foo') self.admin.is_staff = True diff --git a/cms/djangoapps/maintenance/tests.py b/cms/djangoapps/maintenance/tests.py index c324be9b1d..b06fd4b351 100644 --- a/cms/djangoapps/maintenance/tests.py +++ b/cms/djangoapps/maintenance/tests.py @@ -6,13 +6,12 @@ Tests for the maintenance app views. import json import ddt -import six from django.conf import settings from django.urls import reverse from cms.djangoapps.contentstore.management.commands.utils import get_course_versions -from openedx.features.announcements.models import Announcement from common.djangoapps.student.tests.factories import AdminFactory, UserFactory +from openedx.features.announcements.models import Announcement from xmodule.modulestore import ModuleStoreEnum from xmodule.modulestore.django import modulestore from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase @@ -30,7 +29,7 @@ class TestMaintenanceIndex(ModuleStoreTestCase): """ def setUp(self): - super(TestMaintenanceIndex, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments + super().setUp() self.user = AdminFactory() login_success = self.client.login(username=self.user.username, password='test') self.assertTrue(login_success) @@ -56,7 +55,7 @@ class MaintenanceViewTestCase(ModuleStoreTestCase): view_url = '' def setUp(self): - super(MaintenanceViewTestCase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments + super().setUp() self.user = AdminFactory() login_success = self.client.login(username=self.user.username, password='test') self.assertTrue(login_success) @@ -73,7 +72,7 @@ class MaintenanceViewTestCase(ModuleStoreTestCase): Reverse the setup. """ self.client.logout() - super(MaintenanceViewTestCase, self).tearDown() # lint-amnesty, pylint: disable=super-with-arguments + super().tearDown() @ddt.ddt @@ -119,7 +118,7 @@ class MaintenanceViewAccessTests(MaintenanceViewTestCase): response = self.client.get(url) self.assertContains( response, - u'Must be {platform_name} staff to perform this action.'.format(platform_name=settings.PLATFORM_NAME), + f'Must be {settings.PLATFORM_NAME} staff to perform this action.', status_code=403 ) @@ -131,7 +130,7 @@ class TestForcePublish(MaintenanceViewTestCase): """ def setUp(self): - super(TestForcePublish, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments + super().setUp() self.view_url = reverse('maintenance:force_publish_course') def setup_test_course(self): @@ -177,7 +176,7 @@ class TestForcePublish(MaintenanceViewTestCase): # validate non split error message course = CourseFactory.create(default_store=ModuleStoreEnum.Type.mongo) self.verify_error_message( - data={'course-id': six.text_type(course.id)}, + data={'course-id': str(course.id)}, error_message='Force publishing course is not supported with old mongo courses.' ) @@ -189,7 +188,7 @@ class TestForcePublish(MaintenanceViewTestCase): # validate non split error message course = CourseFactory.create(org='e', number='d', run='X', default_store=ModuleStoreEnum.Type.mongo) self.verify_error_message( - data={'course-id': six.text_type(course.id)}, + data={'course-id': str(course.id)}, error_message='Force publishing course is not supported with old mongo courses.' ) # Now search for the course key in split version. @@ -210,7 +209,7 @@ class TestForcePublish(MaintenanceViewTestCase): # now course is published, we should get `already published course` error. self.verify_error_message( - data={'course-id': six.text_type(course.id)}, + data={'course-id': str(course.id)}, error_message='Course is already in published state.' ) @@ -222,7 +221,7 @@ class TestForcePublish(MaintenanceViewTestCase): course (object): a course object. """ # get draft and publish branch versions - versions = get_course_versions(six.text_type(course.id)) + versions = get_course_versions(str(course.id)) # verify that draft and publish point to different versions self.assertNotEqual(versions['draft-branch'], versions['published-branch']) @@ -242,7 +241,7 @@ class TestForcePublish(MaintenanceViewTestCase): # force publish course view data = { - 'course-id': six.text_type(course.id) + 'course-id': str(course.id) } response = self.client.post(self.view_url, data=data, HTTP_X_REQUESTED_WITH='XMLHttpRequest') response_data = json.loads(response.content.decode('utf-8')) @@ -271,7 +270,7 @@ class TestAnnouncementsViews(MaintenanceViewTestCase): """ def setUp(self): - super(TestAnnouncementsViews, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments + super().setUp() self.admin = AdminFactory.create( email='staff@edx.org', username='admin', diff --git a/cms/djangoapps/maintenance/views.py b/cms/djangoapps/maintenance/views.py index ba80d6500c..da60ec5e5e 100644 --- a/cms/djangoapps/maintenance/views.py +++ b/cms/djangoapps/maintenance/views.py @@ -5,7 +5,6 @@ Views for the maintenance app. import logging -import six from django.core.validators import ValidationError from django.db import transaction from django.urls import reverse, reverse_lazy @@ -16,14 +15,13 @@ from django.views.generic.edit import CreateView, DeleteView, UpdateView from django.views.generic.list import ListView from opaque_keys import InvalidKeyError from opaque_keys.edx.keys import CourseKey -from six import text_type from cms.djangoapps.contentstore.management.commands.utils import get_course_versions from common.djangoapps.edxmako.shortcuts import render_to_response -from openedx.features.announcements.forms import AnnouncementForm -from openedx.features.announcements.models import Announcement from common.djangoapps.util.json_request import JsonResponse from common.djangoapps.util.views import require_global_staff +from openedx.features.announcements.forms import AnnouncementForm +from openedx.features.announcements.models import Announcement from xmodule.modulestore import ModuleStoreEnum from xmodule.modulestore.django import modulestore from xmodule.modulestore.exceptions import ItemNotFoundError @@ -84,7 +82,7 @@ class MaintenanceBaseView(View): template = 'maintenance/container.html' def __init__(self, view=None): - super(MaintenanceBaseView, self).__init__() # lint-amnesty, pylint: disable=super-with-arguments + super().__init__() self.context = { 'view': view if view else '', 'form_data': {}, @@ -142,7 +140,7 @@ class ForcePublishCourseView(MaintenanceBaseView): """ def __init__(self): - super(ForcePublishCourseView, self).__init__(MAINTENANCE_VIEWS['force_publish_course']) # lint-amnesty, pylint: disable=super-with-arguments + super().__init__(MAINTENANCE_VIEWS['force_publish_course']) self.context.update({ 'current_versions': [], 'updated_versions': [], @@ -157,8 +155,8 @@ class ForcePublishCourseView(MaintenanceBaseView): Returns a dict containing unicoded values of draft and published draft versions. """ return { - 'draft-branch': six.text_type(versions['draft-branch']), - 'published-branch': six.text_type(versions['published-branch']) + 'draft-branch': str(versions['draft-branch']), + 'published-branch': str(versions['published-branch']) } @transaction.atomic @@ -188,10 +186,10 @@ class ForcePublishCourseView(MaintenanceBaseView): self.context['msg'] = COURSE_KEY_ERROR_MESSAGES['invalid_course_key'] except ItemNotFoundError as exc: self.context['error'] = True - self.context['msg'] = text_type(exc) + self.context['msg'] = str(exc) except ValidationError as exc: self.context['error'] = True - self.context['msg'] = text_type(exc) + self.context['msg'] = str(exc) if self.context['error']: return self.render_response() @@ -200,7 +198,7 @@ class ForcePublishCourseView(MaintenanceBaseView): if not hasattr(source_store, 'force_publish_course'): self.context['msg'] = _('Force publishing course is not supported with old mongo courses.') log.warning( - u'Force publishing course is not supported with old mongo courses. \ + 'Force publishing course is not supported with old mongo courses. \ %s attempted to force publish the course %s.', request.user, course_id, @@ -214,7 +212,7 @@ class ForcePublishCourseView(MaintenanceBaseView): if current_versions['published-branch'] == current_versions['draft-branch']: self.context['msg'] = _('Course is already in published state.') log.warning( - u'Course is already in published state. %s attempted to force publish the course %s.', + 'Course is already in published state. %s attempted to force publish the course %s.', request.user, course_id, exc_info=True @@ -223,7 +221,7 @@ class ForcePublishCourseView(MaintenanceBaseView): self.context['current_versions'] = current_versions log.info( - u'%s dry ran force publish the course %s.', + '%s dry ran force publish the course %s.', request.user, course_id, exc_info=True @@ -238,7 +236,7 @@ class AnnouncementBaseView(View): @method_decorator(require_global_staff) def dispatch(self, request, *args, **kwargs): - return super(AnnouncementBaseView, self).dispatch(request, *args, **kwargs) # lint-amnesty, pylint: disable=super-with-arguments + return super().dispatch(request, *args, **kwargs) class AnnouncementIndexView(ListView, MaintenanceBaseView): @@ -251,10 +249,10 @@ class AnnouncementIndexView(ListView, MaintenanceBaseView): paginate_by = 8 def __init__(self): - super(AnnouncementIndexView, self).__init__(MAINTENANCE_VIEWS['announcement_index']) # lint-amnesty, pylint: disable=super-with-arguments + super().__init__(MAINTENANCE_VIEWS['announcement_index']) def get_context_data(self, **kwargs): - context = super(AnnouncementIndexView, self).get_context_data(**kwargs) # lint-amnesty, pylint: disable=super-with-arguments + context = super().get_context_data(**kwargs) context['view'] = MAINTENANCE_VIEWS['announcement_index'] return context @@ -274,7 +272,7 @@ class AnnouncementEditView(UpdateView, AnnouncementBaseView): template_name = '/maintenance/_announcement_edit.html' def get_context_data(self, **kwargs): - context = super(AnnouncementEditView, self).get_context_data(**kwargs) # lint-amnesty, pylint: disable=super-with-arguments + context = super().get_context_data(**kwargs) context['action_url'] = reverse('maintenance:announcement_edit', kwargs={'pk': context['announcement'].pk}) return context @@ -289,7 +287,7 @@ class AnnouncementCreateView(CreateView, AnnouncementBaseView): template_name = '/maintenance/_announcement_edit.html' def get_context_data(self, **kwargs): - context = super(AnnouncementCreateView, self).get_context_data(**kwargs) # lint-amnesty, pylint: disable=super-with-arguments + context = super().get_context_data(**kwargs) context['action_url'] = reverse('maintenance:announcement_create') return context diff --git a/cms/djangoapps/models/settings/course_grading.py b/cms/djangoapps/models/settings/course_grading.py index 738b31f2fe..642a91ba03 100644 --- a/cms/djangoapps/models/settings/course_grading.py +++ b/cms/djangoapps/models/settings/course_grading.py @@ -7,7 +7,6 @@ from base64 import b64encode from datetime import timedelta from hashlib import sha1 -import six from eventtracking import tracker from cms.djangoapps.contentstore.signals.signals import GRADING_POLICY_CHANGED @@ -20,7 +19,7 @@ log = logging.getLogger(__name__) GRADING_POLICY_CHANGED_EVENT_TYPE = 'edx.grades.grading_policy_changed' -class CourseGradingModel(object): +class CourseGradingModel: """ Basically a DAO and Model combo for CRUD operations pertaining to grading policy. """ @@ -71,7 +70,7 @@ class CourseGradingModel(object): Probably not the usual path for updates as it's too coarse grained. """ descriptor = modulestore().get_course(course_key) - previous_grading_policy_hash = six.text_type(hash_grading_policy(descriptor.grading_policy)) + previous_grading_policy_hash = str(hash_grading_policy(descriptor.grading_policy)) graders_parsed = [CourseGradingModel.parse_grader(jsonele) for jsonele in jsondict['graders']] fire_signal = CourseGradingModel.must_fire_grading_event_and_signal( @@ -90,10 +89,10 @@ class CourseGradingModel(object): CourseGradingModel.update_minimum_grade_credit_from_json(course_key, jsondict['minimum_grade_credit'], user) descriptor = modulestore().get_course(course_key) - new_grading_policy_hash = six.text_type(hash_grading_policy(descriptor.grading_policy)) + new_grading_policy_hash = str(hash_grading_policy(descriptor.grading_policy)) log.info( "Updated course grading policy for course %s from %s to %s. fire_signal = %s", - six.text_type(course_key), + str(course_key), previous_grading_policy_hash, new_grading_policy_hash, fire_signal @@ -155,7 +154,7 @@ class CourseGradingModel(object): grader which is a full model on the client but not on the server (just a dict) """ descriptor = modulestore().get_course(course_key) - previous_grading_policy_hash = six.text_type(hash_grading_policy(descriptor.grading_policy)) + previous_grading_policy_hash = str(hash_grading_policy(descriptor.grading_policy)) # parse removes the id; so, grab it before parse index = int(grader.get('id', len(descriptor.raw_grader))) @@ -175,10 +174,10 @@ class CourseGradingModel(object): modulestore().update_item(descriptor, user.id) descriptor = modulestore().get_course(course_key) - new_grading_policy_hash = six.text_type(hash_grading_policy(descriptor.grading_policy)) + new_grading_policy_hash = str(hash_grading_policy(descriptor.grading_policy)) log.info( "Updated grader for course %s. Grading policy has changed from %s to %s. fire_signal = %s", - six.text_type(course_key), + str(course_key), previous_grading_policy_hash, new_grading_policy_hash, fire_signal @@ -272,12 +271,12 @@ class CourseGradingModel(object): descriptor = modulestore().get_item(location) return { "graderType": descriptor.format if descriptor.format is not None else 'notgraded', - "location": six.text_type(location), + "location": str(location), } @staticmethod def update_section_grader_type(descriptor, grader_type, user): # lint-amnesty, pylint: disable=missing-function-docstring - if grader_type is not None and grader_type != u'notgraded': + if grader_type is not None and grader_type != 'notgraded': descriptor.format = grader_type descriptor.graded = True else: @@ -345,12 +344,12 @@ class CourseGradingModel(object): def _grading_event_and_signal(course_key, user_id): # lint-amnesty, pylint: disable=missing-function-docstring name = GRADING_POLICY_CHANGED_EVENT_TYPE course = modulestore().get_course(course_key) - grading_policy_hash = six.text_type(hash_grading_policy(course.grading_policy)) + grading_policy_hash = str(hash_grading_policy(course.grading_policy)) data = { - "course_id": six.text_type(course_key), - "user_id": six.text_type(user_id), + "course_id": str(course_key), + "user_id": str(user_id), "grading_policy_hash": grading_policy_hash, - "event_transaction_id": six.text_type(create_new_event_transaction_id()), + "event_transaction_id": str(create_new_event_transaction_id()), "event_transaction_type": GRADING_POLICY_CHANGED_EVENT_TYPE, } tracker.emit(name, data) diff --git a/cms/djangoapps/models/settings/course_metadata.py b/cms/djangoapps/models/settings/course_metadata.py index 61e37e5998..2c9a28ca04 100644 --- a/cms/djangoapps/models/settings/course_metadata.py +++ b/cms/djangoapps/models/settings/course_metadata.py @@ -6,23 +6,21 @@ Django module for Course Metadata class -- manages advanced settings and related from datetime import datetime import pytz -import six from crum import get_current_user from django.conf import settings from django.core.exceptions import ValidationError from django.utils.translation import ugettext as _ -from six import text_type from xblock.fields import Scope from cms.djangoapps.contentstore import toggles -from openedx.core.lib.teams_config import TeamsetType -from openedx.features.course_experience import COURSE_ENABLE_UNENROLLED_ACCESS_FLAG from common.djangoapps.student.roles import GlobalStaff from common.djangoapps.xblock_django.models import XBlockStudioConfigurationFlag +from openedx.core.lib.teams_config import TeamsetType +from openedx.features.course_experience import COURSE_ENABLE_UNENROLLED_ACCESS_FLAG from xmodule.modulestore.django import modulestore -class CourseMetadata(object): +class CourseMetadata: ''' For CRUD operations on metadata fields which do not have specific editors on the other pages including any user generated ones. @@ -158,7 +156,7 @@ class CourseMetadata(object): metadata = cls.fetch_all(descriptor) exclude_list_of_fields = cls.get_exclude_list_of_fields(descriptor.id) - for key, value in six.iteritems(metadata): + for key, value in metadata.items(): if key in exclude_list_of_fields: continue result[key] = value @@ -203,7 +201,7 @@ class CourseMetadata(object): # Validate the values before actually setting them. key_values = {} - for key, model in six.iteritems(jsondict): + for key, model in jsondict.items(): # should it be an error if one of the filtered list items is in the payload? if key in exclude_list_of_fields: continue @@ -212,8 +210,8 @@ class CourseMetadata(object): if hasattr(descriptor, key) and getattr(descriptor, key) != val: key_values[key] = descriptor.fields[key].from_json(val) except (TypeError, ValueError) as err: - raise ValueError(_(u"Incorrect format for field '{name}'. {detailed_message}").format( # lint-amnesty, pylint: disable=raise-missing-from - name=model['display_name'], detailed_message=text_type(err))) + raise ValueError(_("Incorrect format for field '{name}'. {detailed_message}").format( # lint-amnesty, pylint: disable=raise-missing-from + name=model['display_name'], detailed_message=str(err))) return cls.update_from_dict(key_values, descriptor, user) @@ -236,20 +234,20 @@ class CourseMetadata(object): if not filter_tabs: exclude_list_of_fields.remove("tabs") - filtered_dict = dict((k, v) for k, v in six.iteritems(jsondict) if k not in exclude_list_of_fields) + filtered_dict = {k: v for k, v in jsondict.items() if k not in exclude_list_of_fields} did_validate = True errors = [] key_values = {} updated_data = None - for key, model in six.iteritems(filtered_dict): + for key, model in filtered_dict.items(): try: val = model['value'] if hasattr(descriptor, key) and getattr(descriptor, key) != val: key_values[key] = descriptor.fields[key].from_json(val) except (TypeError, ValueError, ValidationError) as err: did_validate = False - errors.append({'key': key, 'message': text_type(err), 'model': model}) + errors.append({'key': key, 'message': str(err), 'model': model}) team_setting_errors = cls.validate_team_settings(filtered_dict) if team_setting_errors: @@ -272,7 +270,7 @@ class CourseMetadata(object): """ Update metadata descriptor from key_values. Saves to modulestore if save is true. """ - for key, value in six.iteritems(key_values): + for key, value in key_values.items(): setattr(descriptor, key, value) if save and key_values: