refactor: Ran pyupgrade on openedx/core/djangoapps

Ran pyupgrade on openedx/core/djangoapps/{util, verified_track_content}
This commit is contained in:
Usama Sadiq
2021-03-11 18:38:56 +05:00
parent d540688f8e
commit ac8c3b6a03
26 changed files with 114 additions and 141 deletions

View File

@@ -26,7 +26,7 @@ class MultiValueField(Field):
"""
Convert the form input to a list of strings
"""
values = super(MultiValueField, self).to_python(list_of_string_values) or set() # lint-amnesty, pylint: disable=super-with-arguments
values = super().to_python(list_of_string_values) or set()
if values:
# combine all values if there were multiple specified individually

View File

@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
"""
print_setting
=============

View File

@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
"""
reset_db
========
@@ -16,10 +15,10 @@ originally from http://www.djangosnippets.org/snippets/828/ by dnordberg
import logging
import configparser
import django
from django.conf import settings
from django.core.management.base import BaseCommand, CommandError
from six.moves import configparser
class Command(BaseCommand): # lint-amnesty, pylint: disable=missing-class-docstring
@@ -40,7 +39,7 @@ class Command(BaseCommand): # lint-amnesty, pylint: disable=missing-class-docst
router = options.get('router')
dbinfo = settings.DATABASES.get(router)
if dbinfo is None:
raise CommandError(u"Unknown database router %s" % router)
raise CommandError("Unknown database router %s" % router)
engine = dbinfo.get('ENGINE').split('.')[-1]
@@ -64,7 +63,7 @@ class Command(BaseCommand): # lint-amnesty, pylint: disable=missing-class-docst
if engine in ('sqlite3', 'spatialite'):
import os
try:
logging.info(u"Unlinking %s database", engine)
logging.info("Unlinking %s database", engine)
os.unlink(database_name)
except OSError:
pass
@@ -84,9 +83,9 @@ class Command(BaseCommand): # lint-amnesty, pylint: disable=missing-class-docst
kwargs['port'] = int(database_port)
connection = Database.connect(**kwargs)
drop_query = u'DROP DATABASE IF EXISTS `%s`' % database_name
drop_query = 'DROP DATABASE IF EXISTS `%s`' % database_name
utf8_support = 'CHARACTER SET utf8'
create_query = u'CREATE DATABASE `%s` %s' % (database_name, utf8_support)
create_query = f'CREATE DATABASE `{database_name}` {utf8_support}'
logging.info('Executing... "' + drop_query + '"') # lint-amnesty, pylint: disable=logging-not-lazy
connection.query(drop_query)
logging.info('Executing... "' + create_query + '"') # lint-amnesty, pylint: disable=logging-not-lazy
@@ -112,35 +111,35 @@ class Command(BaseCommand): # lint-amnesty, pylint: disable=missing-class-docst
connection.set_isolation_level(0) # autocommit false
cursor = connection.cursor()
drop_query = u"DROP DATABASE \"%s\";" % database_name
drop_query = "DROP DATABASE \"%s\";" % database_name
logging.info('Executing... "' + drop_query + '"') # lint-amnesty, pylint: disable=logging-not-lazy
try:
cursor.execute(drop_query)
except Database.ProgrammingError as e:
logging.exception(u"Error: %s", e)
logging.exception("Error: %s", e)
create_query = u"CREATE DATABASE \"%s\"" % database_name
create_query = "CREATE DATABASE \"%s\"" % database_name
if owner:
create_query += u" WITH OWNER = \"%s\" " % owner
create_query += u" ENCODING = 'UTF8'"
create_query += " WITH OWNER = \"%s\" " % owner
create_query += " ENCODING = 'UTF8'"
if engine == 'postgis' and django.VERSION < (1, 9):
# For PostGIS 1.5, fetch template name if it exists
from django.contrib.gis.db.backends.postgis.base import DatabaseWrapper
postgis_template = DatabaseWrapper(dbinfo).template_postgis # lint-amnesty, pylint: disable=no-member
if postgis_template is not None:
create_query += u' TEMPLATE = %s' % postgis_template
create_query += ' TEMPLATE = %s' % postgis_template
if settings.DEFAULT_TABLESPACE:
create_query += u' TABLESPACE = %s;' % settings.DEFAULT_TABLESPACE
create_query += ' TABLESPACE = %s;' % settings.DEFAULT_TABLESPACE
else:
create_query += u';'
create_query += ';'
logging.info('Executing... "' + create_query + '"') # lint-amnesty, pylint: disable=logging-not-lazy
cursor.execute(create_query)
else:
raise CommandError(u"Unknown database engine %s" % engine)
raise CommandError("Unknown database engine %s" % engine)
if verbosity >= 2:
print("Reset successful.")

View File

@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
"""
Django management command to update the loaded test fixtures as necessary for
the current test environment. Currently just sets an appropriate domain for
@@ -25,7 +24,7 @@ class Command(BaseCommand):
host = os.environ['BOK_CHOY_HOSTNAME']
cms_port = os.environ['BOK_CHOY_CMS_PORT']
lms_port = os.environ['BOK_CHOY_LMS_PORT']
cms_domain = '{}:{}'.format(host, cms_port)
cms_domain = f'{host}:{cms_port}'
Site.objects.filter(name='cms').update(domain=cms_domain)
lms_domain = '{}:{}'.format(host, lms_port)
lms_domain = f'{host}:{lms_port}'
Site.objects.filter(name='lms').update(domain=lms_domain)

View File

@@ -1,5 +1,5 @@
# lint-amnesty, pylint: disable=missing-module-docstring
class Creator(object):
class Creator:
"""
A placeholder class that provides a way to set the attribute on the model.
"""
@@ -15,13 +15,13 @@ class Creator(object):
obj.__dict__[self.field.name] = self.field.to_python(value)
class CreatorMixin(object):
class CreatorMixin:
"""
Mixin class to provide SubfieldBase functionality to django fields.
See: https://docs.djangoproject.com/en/1.11/releases/1.8/#subfieldbase
"""
def contribute_to_class(self, cls, name, *args, **kwargs):
super(CreatorMixin, self).contribute_to_class(cls, name, *args, **kwargs) # lint-amnesty, pylint: disable=super-with-arguments
super().contribute_to_class(cls, name, *args, **kwargs)
setattr(cls, name, Creator(self))
def from_db_value(self, value, expression, connection): # lint-amnesty, pylint: disable=unused-argument

View File

@@ -55,22 +55,22 @@ def delete_rows(model_mgr,
sleep_between (float): Number of seconds to sleep between transactions.
"""
if chunk_size <= 0:
raise CommandError(u'Only positive chunk size is allowed ({}).'.format(chunk_size))
raise CommandError(f'Only positive chunk size is allowed ({chunk_size}).')
if sleep_between < 0:
raise CommandError(u'Only non-negative sleep between seconds is allowed ({}).'.format(sleep_between))
raise CommandError(f'Only non-negative sleep between seconds is allowed ({sleep_between}).')
# The "as id" below fools Django raw query into thinking the primary key is being queried.
# It's necessary because Django will throw an exception if the raw SQL does not query the primary key.
min_max_ids = model_mgr.raw(
u'SELECT MIN({}) as id, MAX({}) as max_id FROM {}'.format(primary_id_name, primary_id_name, table_name) # lint-amnesty, pylint: disable=duplicate-string-formatting-argument
f'SELECT MIN({primary_id_name}) as id, MAX({primary_id_name}) as max_id FROM {table_name}' # lint-amnesty, pylint: disable=duplicate-string-formatting-argument
)[0]
min_id = min_max_ids.id
max_id = min_max_ids.max_id
if not min_id or not max_id:
log.info(u"No data exists in table %s - skipping.", table_name)
log.info("No data exists in table %s - skipping.", table_name)
return
log.info(
u"STARTED: Deleting around %s rows with chunk size of %s and %s seconds between chunks.",
"STARTED: Deleting around %s rows with chunk size of %s and %s seconds between chunks.",
max_id - min_id + 1, chunk_size, sleep_between
)
@@ -78,10 +78,10 @@ def delete_rows(model_mgr,
while lower_id <= max_id:
deletions_now = min(chunk_size, max_id - lower_id + 1)
upper_id = lower_id + deletions_now
log.info(u"Deleting around %s rows between ids %s and %s...", deletions_now, lower_id, upper_id)
log.info("Deleting around %s rows between ids %s and %s...", deletions_now, lower_id, upper_id)
with transaction.atomic():
# xss-lint: disable=python-wrap-html
delete_sql = u'DELETE FROM {} WHERE {} >= {} AND {} < {}'.format( # lint-amnesty, pylint: disable=duplicate-string-formatting-argument
delete_sql = 'DELETE FROM {} WHERE {} >= {} AND {} < {}'.format( # lint-amnesty, pylint: disable=duplicate-string-formatting-argument
table_name, primary_id_name, lower_id, primary_id_name, upper_id
)
log.info(delete_sql)
@@ -93,9 +93,9 @@ def delete_rows(model_mgr,
# But - it will cause a "TypeError: 'NoneType' object is not iterable" to be ignored.
pass
lower_id += deletions_now
log.info(u"Sleeping %s seconds...", sleep_between)
log.info("Sleeping %s seconds...", sleep_between)
time.sleep(sleep_between)
log.info(u"FINISHED: Deleted at most %s rows total.", max_id - min_id + 1)
log.info("FINISHED: Deleted at most %s rows total.", max_id - min_id + 1)
class BaseDeletionCommand(BaseCommand):

View File

@@ -19,7 +19,7 @@ def record_request_exception(sender, **kwargs):
Logs the stack trace whenever an exception
occurs in processing a request.
"""
logging.exception(u"Uncaught exception from {sender}".format(
logging.exception("Uncaught exception from {sender}".format(
sender=sender
))

View File

@@ -3,7 +3,7 @@ Mixins for testing forms.
"""
class FormTestMixin(object):
class FormTestMixin:
"""A mixin for testing forms"""
def get_form(self, expected_valid):
"""

View File

@@ -25,7 +25,7 @@ class ContentGroupTestCase(ModuleStoreTestCase):
and a non-cohorted user with no special access.
"""
def setUp(self):
super(ContentGroupTestCase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
self.course = CourseFactory.create(
org='org', number='number', run='run',
@@ -144,7 +144,7 @@ class TestConditionalContent(ModuleStoreTestCase):
-> vertical (Group B)
-> problem
"""
super(TestConditionalContent, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
# Create user partitions
self.user_partition_group_a = 0
@@ -190,13 +190,13 @@ class TestConditionalContent(ModuleStoreTestCase):
UserCourseTagFactory(
user=self.student_a,
course_id=self.course.id,
key='xblock.partition_service.partition_{0}'.format(self.partition.id),
key=f'xblock.partition_service.partition_{self.partition.id}',
value=str(self.user_partition_group_a)
)
UserCourseTagFactory(
user=self.student_b,
course_id=self.course.id,
key='xblock.partition_service.partition_{0}'.format(self.partition.id),
key=f'xblock.partition_service.partition_{self.partition.id}',
value=str(self.user_partition_group_b)
)

View File

@@ -1,6 +1,3 @@
# -*- coding: utf-8 -*- # lint-amnesty, pylint: disable=missing-module-docstring
import pytest
from django.core.management import CommandError, call_command

View File

@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
"""
Tests of the update_fixtures management command for bok-choy test database
initialization.

View File

@@ -22,7 +22,7 @@ class UserMessagesTestCase(TestCase):
Unit tests for page level user messages.
"""
def setUp(self):
super(UserMessagesTestCase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
self.student = UserFactory.create()
self.request = RequestFactory().request()
self.request.session = {}

View File

@@ -3,7 +3,6 @@
import unittest
import six
from django.contrib.auth.models import AnonymousUser
from ..user_utils import SystemUser
@@ -12,7 +11,7 @@ from ..user_utils import SystemUser
class SystemUserTestCase(unittest.TestCase):
""" Tests for response-related utility functions """
def setUp(self):
super(SystemUserTestCase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
self.sysuser = SystemUser()
def test_system_user_is_anonymous(self):
@@ -21,7 +20,7 @@ class SystemUserTestCase(unittest.TestCase):
assert self.sysuser.id is None
def test_system_user_has_custom_unicode_representation(self):
assert six.text_type(self.sysuser) != six.text_type(AnonymousUser())
assert str(self.sysuser) != str(AnonymousUser())
def test_system_user_is_not_staff(self):
assert not self.sysuser.is_staff

View File

@@ -18,7 +18,6 @@ There are two common use cases:
from abc import abstractmethod
from enum import Enum
import six
from django.contrib import messages
from django.utils.translation import ugettext as _
@@ -167,7 +166,7 @@ class UserMessageCollection():
for __, type in UserMessageType.__members__.items(): # lint-amnesty, pylint: disable=redefined-builtin, no-member
if type.value is level:
return type
raise Exception(u'Unable to find UserMessageType for level {level}'.format(level=level))
raise Exception(f'Unable to find UserMessageType for level {level}')
def _create_user_message(message):
"""
@@ -175,7 +174,7 @@ class UserMessageCollection():
"""
return UserMessage(
type=_get_message_type_for_level(message.level),
message_html=six.text_type(message.message),
message_html=str(message.message),
)
django_messages = messages.get_messages(request)
@@ -194,7 +193,7 @@ class PageLevelMessages(UserMessageCollection):
Returns the entire HTML snippet for the message.
"""
if title:
title_area = Text(_(u'{header_open}{title}{header_close}')).format(
title_area = Text(_('{header_open}{title}{header_close}')).format(
header_open=HTML('<div class="message-header">'),
title=title,
header_close=HTML('</div>')
@@ -203,11 +202,11 @@ class PageLevelMessages(UserMessageCollection):
title_area = ''
if dismissable:
dismiss_button = HTML(
u'<div class="message-actions">'
u'<button class="btn-link action-dismiss">'
u'<span class="sr">{dismiss_text}</span>'
u'<span class="icon fa fa-times" aria-hidden="true"></span></button>'
u'</div>'
'<div class="message-actions">'
'<button class="btn-link action-dismiss">'
'<span class="sr">{dismiss_text}</span>'
'<span class="icon fa fa-times" aria-hidden="true"></span></button>'
'</div>'
).format(
dismiss_text=Text(_("Dismiss"))
)
@@ -215,7 +214,7 @@ class PageLevelMessages(UserMessageCollection):
dismiss_button = ''
return Text('{title_area}{body_area}{dismiss_button}').format(
title_area=title_area,
body_area=HTML(u'<div class="message-content">{body_html}</div>').format(
body_area=HTML('<div class="message-content">{body_html}</div>').format(
body_html=body_html,
),
dismiss_button=dismiss_button,

View File

@@ -23,7 +23,7 @@ class VerifiedTrackCourseForm(forms.ModelForm):
error message instead.
"""
class Meta(object):
class Meta:
model = VerifiedTrackCohortedCourse
fields = '__all__'

View File

@@ -48,18 +48,18 @@ class Command(BaseCommand):
# Verify that the MigrateVerifiedTrackCohortsSetting has all required fields
if not old_course_key:
raise CommandError(u"No old_course_key set for MigrateVerifiedTrackCohortsSetting with ID: '%s'"
raise CommandError("No old_course_key set for MigrateVerifiedTrackCohortsSetting with ID: '%s'"
% verified_track_cohorts_setting.id)
if not rerun_course_key:
raise CommandError(u"No rerun_course_key set for MigrateVerifiedTrackCohortsSetting with ID: '%s'"
raise CommandError("No rerun_course_key set for MigrateVerifiedTrackCohortsSetting with ID: '%s'"
% verified_track_cohorts_setting.id)
if not audit_cohort_names:
raise CommandError(u"No audit_cohort_names set for MigrateVerifiedTrackCohortsSetting with ID: '%s'"
raise CommandError("No audit_cohort_names set for MigrateVerifiedTrackCohortsSetting with ID: '%s'"
% verified_track_cohorts_setting.id)
print(u"Running for MigrateVerifiedTrackCohortsSetting with old_course_key='%s' and rerun_course_key='%s'" %
print("Running for MigrateVerifiedTrackCohortsSetting with old_course_key='%s' and rerun_course_key='%s'" %
(verified_track_cohorts_setting.old_course_key, verified_track_cohorts_setting.rerun_course_key))
# Get the CourseUserGroup IDs for the audit course names from the old course
@@ -71,7 +71,7 @@ class Command(BaseCommand):
if not audit_course_user_group_ids:
raise CommandError(
u"No Audit CourseUserGroup found for course_id='%s' with group_type='%s' for names='%s'"
"No Audit CourseUserGroup found for course_id='%s' with group_type='%s' for names='%s'"
% (old_course_key, CourseUserGroup.COHORT, audit_cohort_names)
)
@@ -83,7 +83,7 @@ class Command(BaseCommand):
if not random_audit_course_user_group_ids:
raise CommandError(
u"No Audit CourseCohorts found for course_user_group_ids='%s' with assignment_type='%s"
"No Audit CourseCohorts found for course_user_group_ids='%s' with assignment_type='%s"
% (audit_course_user_group_ids, CourseCohort.RANDOM)
)
@@ -95,7 +95,7 @@ class Command(BaseCommand):
if not random_audit_course_user_group_partition_groups:
raise CommandError(
u"No Audit CourseUserGroupPartitionGroup found for course_user_group_ids='%s'"
"No Audit CourseUserGroupPartitionGroup found for course_user_group_ids='%s'"
% random_audit_course_user_group_ids
)
@@ -103,10 +103,10 @@ class Command(BaseCommand):
try:
verified_track_cohorted_course = VerifiedTrackCohortedCourse.objects.get(course_key=old_course_key)
except VerifiedTrackCohortedCourse.DoesNotExist:
raise CommandError(u"No VerifiedTrackCohortedCourse found for course: '%s'" % old_course_key) # lint-amnesty, pylint: disable=raise-missing-from
raise CommandError("No VerifiedTrackCohortedCourse found for course: '%s'" % old_course_key) # lint-amnesty, pylint: disable=raise-missing-from
if not verified_track_cohorted_course.enabled:
raise CommandError(u"VerifiedTrackCohortedCourse not enabled for course: '%s'" % old_course_key)
raise CommandError("VerifiedTrackCohortedCourse not enabled for course: '%s'" % old_course_key)
# Get the single CourseUserGroupPartitionGroup for the verified_track
# based on the verified_track name for the old course
@@ -118,7 +118,7 @@ class Command(BaseCommand):
)
except CourseUserGroup.DoesNotExist:
raise CommandError( # lint-amnesty, pylint: disable=raise-missing-from
u"No Verified CourseUserGroup found for course_id='%s' with group_type='%s' for names='%s'"
"No Verified CourseUserGroup found for course_id='%s' with group_type='%s' for names='%s'"
% (old_course_key, CourseUserGroup.COHORT, verified_track_cohorted_course.verified_cohort_name)
)
@@ -128,7 +128,7 @@ class Command(BaseCommand):
)
except CourseUserGroupPartitionGroup.DoesNotExist:
raise CommandError( # lint-amnesty, pylint: disable=raise-missing-from
u"No Verified CourseUserGroupPartitionGroup found for course_user_group_ids='%s'"
"No Verified CourseUserGroupPartitionGroup found for course_user_group_ids='%s'"
% random_audit_course_user_group_ids
)
@@ -139,7 +139,7 @@ class Command(BaseCommand):
mode_slug=CourseMode.AUDIT
)
except CourseMode.DoesNotExist:
raise CommandError(u"Audit CourseMode is not defined for course: '%s'" % rerun_course_key) # lint-amnesty, pylint: disable=raise-missing-from
raise CommandError("Audit CourseMode is not defined for course: '%s'" % rerun_course_key) # lint-amnesty, pylint: disable=raise-missing-from
try:
CourseMode.objects.get(
@@ -147,11 +147,11 @@ class Command(BaseCommand):
mode_slug=CourseMode.VERIFIED
)
except CourseMode.DoesNotExist:
raise CommandError(u"Verified CourseMode is not defined for course: '%s'" % rerun_course_key) # lint-amnesty, pylint: disable=raise-missing-from
raise CommandError("Verified CourseMode is not defined for course: '%s'" % rerun_course_key) # lint-amnesty, pylint: disable=raise-missing-from
items = module_store.get_items(rerun_course_key)
if not items:
raise CommandError(u"Items for Course with key '%s' not found." % rerun_course_key)
raise CommandError("Items for Course with key '%s' not found." % rerun_course_key)
items_to_update = []
@@ -175,7 +175,7 @@ class Command(BaseCommand):
)
if (audit_partition_group_access
and audit_course_user_group_partition_group.group_id in audit_partition_group_access):
print(u"Queueing XBlock at location: '%s' for Audit Content Group update " % item.location)
print("Queueing XBlock at location: '%s' for Audit Content Group update " % item.location)
set_audit_enrollment_track = True
# Check the partition and group IDs for the verified course group, if it exists in
@@ -192,11 +192,11 @@ class Command(BaseCommand):
# This only needs to be checked for this partition_group once
if non_verified_track_access_groups:
errors.append(
u"Non audit/verified cohorted content group set for xblock, location '%s' with IDs '%s'"
"Non audit/verified cohorted content group set for xblock, location '%s' with IDs '%s'"
% (item.location, non_verified_track_access_groups)
)
if verified_course_user_group_partition_group.group_id in verified_partition_group_access:
print(u"Queueing XBlock at location: '%s' for Verified Content Group update " % item.location)
print("Queueing XBlock at location: '%s' for Verified Content Group update " % item.location)
set_verified_enrollment_track = True
# Add the enrollment track ids to a group access array
@@ -217,7 +217,7 @@ class Command(BaseCommand):
item.group_access = {ENROLLMENT_TRACK_PARTITION_ID: enrollment_track_group_access}
items_to_update.append(item)
else:
errors.append(u"XBlock '%s' with location '%s' needs access changes, but is a draft"
errors.append("XBlock '%s' with location '%s' needs access changes, but is a draft"
% (item.display_name, item.location))
partitions_to_delete = random_audit_course_user_group_partition_groups
@@ -228,7 +228,7 @@ class Command(BaseCommand):
for item in items_to_update:
module_store.update_item(item, ModuleStoreEnum.UserID.mgmt_command)
module_store.publish(item.location, ModuleStoreEnum.UserID.mgmt_command)
print(u"Updated and published XBlock at location: '%s'" % item.location)
print("Updated and published XBlock at location: '%s'" % item.location)
# Check if we should delete any partition groups if there are no errors.
# If there are errors, none of the xblock items will have been updated,
@@ -249,7 +249,7 @@ class Command(BaseCommand):
usages = GroupConfiguration.get_partitions_usage_info(module_store, course)
used = group_id in usages[partition.id]
if used:
errors.append(u"Content group '%s' is in use and cannot be deleted."
errors.append("Content group '%s' is in use and cannot be deleted."
% partition_to_delete.group_id)
# If there are not errors, proceed to update the course and user_partitions
@@ -270,11 +270,11 @@ class Command(BaseCommand):
# If there are any errors, join them together and raise the CommandError
if errors:
raise CommandError(
(u"Error for MigrateVerifiedTrackCohortsSetting with ID='%s'\n" % verified_track_cohorts_setting.id) +
("Error for MigrateVerifiedTrackCohortsSetting with ID='%s'\n" % verified_track_cohorts_setting.id) +
"\t\n".join(errors)
)
print(u"Finished for MigrateVerifiedTrackCohortsSetting with ID='%s" % verified_track_cohorts_setting.id)
print("Finished for MigrateVerifiedTrackCohortsSetting with ID='%s" % verified_track_cohorts_setting.id)
def _latest_settings(self):
"""

View File

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

View File

@@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from django.db import migrations, models
@@ -14,6 +11,6 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='verifiedtrackcohortedcourse',
name='verified_cohort_name',
field=models.CharField(default=u'Verified Learners', max_length=100),
field=models.CharField(default='Verified Learners', max_length=100),
),
]

View File

@@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from django.db import migrations, models
import django.db.models.deletion
from django.conf import settings
@@ -21,9 +18,9 @@ class Migration(migrations.Migration):
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('change_date', models.DateTimeField(auto_now_add=True, verbose_name='Change date')),
('enabled', models.BooleanField(default=False, verbose_name='Enabled')),
('old_course_key', CourseKeyField(help_text=u'Course key for which to migrate verified track cohorts from', max_length=255)),
('rerun_course_key', CourseKeyField(help_text=u'Course key for which to migrate verified track cohorts to enrollment tracks to', max_length=255)),
('audit_cohort_names', models.TextField(help_text=u'Comma-separated list of audit cohort names')),
('old_course_key', CourseKeyField(help_text='Course key for which to migrate verified track cohorts from', max_length=255)),
('rerun_course_key', CourseKeyField(help_text='Course key for which to migrate verified track cohorts to enrollment tracks to', max_length=255)),
('audit_cohort_names', models.TextField(help_text='Comma-separated list of audit cohort names')),
('changed_by', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, editable=False, to=settings.AUTH_USER_MODEL, null=True, verbose_name='Changed by')),
],
),

View File

@@ -4,7 +4,6 @@ Models for verified track selections.
import logging
import six
from config_models.models import ConfigurationModel
from django.db import models
@@ -28,7 +27,7 @@ from common.djangoapps.student.models import CourseEnrollment
log = logging.getLogger(__name__)
DEFAULT_VERIFIED_COHORT_NAME = u"Verified Learners"
DEFAULT_VERIFIED_COHORT_NAME = "Verified Learners"
@receiver(post_save, sender=CourseEnrollment)
@@ -43,7 +42,7 @@ def move_to_verified_cohort(sender, instance, **kwargs): # pylint: disable=unus
if verified_cohort_enabled and (instance.mode != instance._old_mode): # pylint: disable=protected-access
if not is_course_cohorted(course_key):
log.error(u"Automatic verified cohorting enabled for course '%s', but course is not cohorted.", course_key)
log.error("Automatic verified cohorting enabled for course '%s', but course is not cohorted.", course_key)
else:
course = get_course_by_id(course_key)
existing_manual_cohorts = get_course_cohorts(course, assignment_type=CourseCohort.MANUAL)
@@ -53,14 +52,14 @@ def move_to_verified_cohort(sender, instance, **kwargs): # pylint: disable=unus
# cohort yet exist.
random_cohort = get_random_cohort(course_key)
args = {
'course_id': six.text_type(course_key),
'course_id': str(course_key),
'user_id': instance.user.id,
'verified_cohort_name': verified_cohort_name,
'default_cohort_name': random_cohort.name
}
log.info(
u"Queuing automatic cohorting for user '%s' in course '%s' "
u"due to change in enrollment mode from '%s' to '%s'.",
"Queuing automatic cohorting for user '%s' in course '%s' "
"due to change in enrollment mode from '%s' to '%s'.",
instance.user.id, course_key, instance._old_mode, instance.mode # pylint: disable=protected-access
)
@@ -74,8 +73,8 @@ def move_to_verified_cohort(sender, instance, **kwargs): # pylint: disable=unus
sync_cohort_with_mode.apply_async(kwargs=args, countdown=300)
else:
log.error(
u"Automatic verified cohorting enabled for course '%s', "
u"but verified cohort named '%s' does not exist.",
"Automatic verified cohorting enabled for course '%s', "
"but verified cohort named '%s' does not exist.",
course_key,
verified_cohort_name,
)
@@ -102,17 +101,17 @@ class VerifiedTrackCohortedCourse(models.Model):
"""
course_key = CourseKeyField(
max_length=255, db_index=True, unique=True,
help_text=ugettext_lazy(u"The course key for the course we would like to be auto-cohorted.")
help_text=ugettext_lazy("The course key for the course we would like to be auto-cohorted.")
)
verified_cohort_name = models.CharField(max_length=100, default=DEFAULT_VERIFIED_COHORT_NAME)
enabled = models.BooleanField()
CACHE_NAMESPACE = u"verified_track_content.VerifiedTrackCohortedCourse.cache."
CACHE_NAMESPACE = "verified_track_content.VerifiedTrackCohortedCourse.cache."
def __str__(self):
return u"Course: {}, enabled: {}".format(six.text_type(self.course_key), self.enabled)
return "Course: {}, enabled: {}".format(str(self.course_key), self.enabled)
@classmethod
def verified_cohort_name_for_course(cls, course_key):
@@ -164,21 +163,21 @@ class MigrateVerifiedTrackCohortsSetting(ConfigurationModel):
.. no_pii:
"""
class Meta(object):
class Meta:
app_label = "verified_track_content"
old_course_key = CourseKeyField(
max_length=255,
blank=False,
help_text=u"Course key for which to migrate verified track cohorts from"
help_text="Course key for which to migrate verified track cohorts from"
)
rerun_course_key = CourseKeyField(
max_length=255,
blank=False,
help_text=u"Course key for which to migrate verified track cohorts to enrollment tracks to"
help_text="Course key for which to migrate verified track cohorts to enrollment tracks to"
)
audit_cohort_names = models.TextField(
help_text=u"Comma-separated list of audit cohort names"
help_text="Comma-separated list of audit cohort names"
)
@classmethod

View File

@@ -5,7 +5,6 @@ UserPartitionScheme for enrollment tracks.
import logging
import six
from django.conf import settings
from opaque_keys.edx.keys import CourseKey
@@ -49,12 +48,12 @@ class EnrollmentTrackUserPartition(UserPartition):
return []
return [
Group(ENROLLMENT_GROUP_IDS[mode.slug]["id"], six.text_type(mode.name))
Group(ENROLLMENT_GROUP_IDS[mode.slug]["id"], str(mode.name))
for mode in CourseMode.modes_for_course(course_key, include_expired=True)
]
class EnrollmentTrackPartitionScheme(object):
class EnrollmentTrackPartitionScheme:
"""
This scheme uses learner enrollment tracks to map learners into partition groups.
"""
@@ -96,7 +95,7 @@ class EnrollmentTrackPartitionScheme(object):
course_mode = CourseMode.verified_mode_for_course(course_key, include_expired=True)
if not course_mode:
course_mode = CourseMode.DEFAULT_MODE
return Group(ENROLLMENT_GROUP_IDS[course_mode.slug]["id"], six.text_type(course_mode.name))
return Group(ENROLLMENT_GROUP_IDS[course_mode.slug]["id"], str(course_mode.name))
else:
return None
@@ -118,8 +117,8 @@ class EnrollmentTrackPartitionScheme(object):
"""
return EnrollmentTrackUserPartition(
id,
six.text_type(name),
six.text_type(description),
str(name),
str(description),
[],
cls,
parameters,

View File

@@ -3,8 +3,6 @@ Celery task for Automatic Verifed Track Cohorting MVP feature.
"""
import six
from celery import shared_task
from celery.utils.log import get_task_logger
from django.contrib.auth.models import User # lint-amnesty, pylint: disable=imported-auth-user
@@ -40,26 +38,26 @@ def sync_cohort_with_mode(self, course_id, user_id, verified_cohort_name, defaul
acceptable_modes = {CourseMode.VERIFIED, CourseMode.CREDIT_MODE}
if enrollment.mode in acceptable_modes and (current_cohort.id != verified_cohort.id):
LOGGER.info(
u"MOVING_TO_VERIFIED: Moving user '%s' to the verified cohort '%s' for course '%s'",
"MOVING_TO_VERIFIED: Moving user '%s' to the verified cohort '%s' for course '%s'",
user.id, verified_cohort.name, course_id
)
add_user_to_cohort(verified_cohort, user.username)
elif enrollment.mode not in acceptable_modes and current_cohort.id == verified_cohort.id:
default_cohort = get_cohort_by_name(course_key, default_cohort_name)
LOGGER.info(
u"MOVING_TO_DEFAULT: Moving user '%s' to the default cohort '%s' for course '%s'",
"MOVING_TO_DEFAULT: Moving user '%s' to the default cohort '%s' for course '%s'",
user.id, default_cohort.name, course_id
)
add_user_to_cohort(default_cohort, user.username)
else:
LOGGER.info(
u"NO_ACTION_NECESSARY: No action necessary for user '%s' in course '%s' and enrollment mode '%s'. "
u"The user is already in cohort '%s'.",
"NO_ACTION_NECESSARY: No action necessary for user '%s' in course '%s' and enrollment mode '%s'. "
"The user is already in cohort '%s'.",
user.id, course_id, enrollment.mode, current_cohort.name
)
except Exception as exc:
LOGGER.warning(
u"SYNC_COHORT_WITH_MODE_RETRY: Exception encountered for course '%s' and user '%s': %s",
course_id, user.id, six.text_type(exc)
"SYNC_COHORT_WITH_MODE_RETRY: Exception encountered for course '%s' and user '%s': %s",
course_id, user.id, str(exc)
)
raise self.retry(exc=exc)

View File

@@ -2,8 +2,6 @@
Test for forms helpers.
"""
import six
from openedx.core.djangoapps.verified_track_content.forms import VerifiedTrackCourseForm
from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory
@@ -19,12 +17,12 @@ class TestVerifiedTrackCourseForm(SharedModuleStoreTestCase):
@classmethod
def setUpClass(cls):
super(TestVerifiedTrackCourseForm, cls).setUpClass()
super().setUpClass()
cls.course = CourseFactory.create()
def test_form_validation_success(self):
form_data = {
'course_key': six.text_type(self.course.id), 'verified_cohort_name': 'Verified Learners', 'enabled': True
'course_key': str(self.course.id), 'verified_cohort_name': 'Verified Learners', 'enabled': True
}
form = VerifiedTrackCourseForm(data=form_data)
assert form.is_valid()

View File

@@ -4,9 +4,8 @@ Tests for Verified Track Cohorting models
# pylint: disable=attribute-defined-outside-init
from unittest import mock
import ddt
import mock
import six
from django.test import TestCase
from opaque_keys.edx.keys import CourseKey
@@ -53,7 +52,7 @@ class TestVerifiedTrackCohortedCourse(TestCase):
# Enable for a course
config = VerifiedTrackCohortedCourse.objects.create(course_key=course_key, enabled=True)
config.save()
assert six.text_type(config) == u'Course: {}, enabled: True'.format(self.SAMPLE_COURSE)
assert str(config) == f'Course: {self.SAMPLE_COURSE}, enabled: True'
def test_verified_cohort_name(self):
cohort_name = 'verified cohort'
@@ -77,11 +76,11 @@ class TestMoveToVerified(SharedModuleStoreTestCase):
@classmethod
def setUpClass(cls):
super(TestMoveToVerified, cls).setUpClass()
super().setUpClass()
cls.course = CourseFactory.create()
def setUp(self):
super(TestMoveToVerified, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
self.user = UserFactory()
# Spy on number of calls to celery task.
celery_task_patcher = mock.patch.object(
@@ -180,7 +179,7 @@ class TestMoveToVerified(SharedModuleStoreTestCase):
assert VerifiedTrackCohortedCourse.is_verified_track_cohort_enabled(self.course.id)
self._verify_no_automatic_cohorting()
assert error_logger.called
error_message = u"cohort named '%s' does not exist"
error_message = "cohort named '%s' does not exist"
assert error_message in error_logger.call_args[0][0]
@ddt.data(CourseMode.VERIFIED, CourseMode.CREDIT_MODE)

View File

@@ -6,7 +6,6 @@ Tests for verified_track_content/partition_scheme.py.
from datetime import datetime, timedelta
import pytz
import six
import pytest
from common.djangoapps.course_modes.models import CourseMode
from common.djangoapps.student.models import CourseEnrollment
@@ -26,7 +25,7 @@ class EnrollmentTrackUserPartitionTest(SharedModuleStoreTestCase):
@classmethod
def setUpClass(cls):
super(EnrollmentTrackUserPartitionTest, cls).setUpClass()
super().setUpClass()
cls.course = CourseFactory.create()
def test_only_default_mode(self):
@@ -95,7 +94,7 @@ class EnrollmentTrackPartitionSchemeTest(SharedModuleStoreTestCase):
@classmethod
def setUpClass(cls):
super(EnrollmentTrackPartitionSchemeTest, cls).setUpClass()
super().setUpClass()
cls.course = CourseFactory.create()
cls.student = UserFactory()
@@ -107,7 +106,7 @@ class EnrollmentTrackPartitionSchemeTest(SharedModuleStoreTestCase):
def test_create_user_partition(self):
user_partition = UserPartition.get_scheme('enrollment_track').create_user_partition(
301, "partition", "test partition", parameters={"course_id": six.text_type(self.course.id)}
301, "partition", "test partition", parameters={"course_id": str(self.course.id)}
)
assert isinstance(user_partition, EnrollmentTrackUserPartition)
assert user_partition.name == 'partition'
@@ -186,7 +185,7 @@ def create_enrollment_track_partition(course):
id=1,
name="Test Enrollment Track Partition",
description="Test partition for segmenting users by enrollment track",
parameters={"course_id": six.text_type(course.id)}
parameters={"course_id": str(course.id)}
)
return partition

View File

@@ -4,7 +4,6 @@ Tests for verified track content views.
import json
import six
import pytest
from django.http import Http404
from django.test.client import RequestFactory
@@ -26,7 +25,7 @@ class CohortingSettingsTestCase(SharedModuleStoreTestCase):
@classmethod
def setUpClass(cls):
super(CohortingSettingsTestCase, cls).setUpClass()
super().setUpClass()
cls.course = CourseFactory.create()
def test_non_staff(self):
@@ -36,14 +35,14 @@ class CohortingSettingsTestCase(SharedModuleStoreTestCase):
request = RequestFactory().get("dummy_url")
request.user = UserFactory()
with pytest.raises(Http404):
cohorting_settings(request, six.text_type(self.course.id))
cohorting_settings(request, str(self.course.id))
def test_cohorting_settings_enabled(self):
"""
Verify that cohorting_settings is working for HTTP GET when verified track cohorting is enabled.
"""
config = VerifiedTrackCohortedCourse.objects.create(
course_key=six.text_type(self.course.id), enabled=True, verified_cohort_name="Verified Learners"
course_key=str(self.course.id), enabled=True, verified_cohort_name="Verified Learners"
)
config.save()
@@ -66,6 +65,6 @@ class CohortingSettingsTestCase(SharedModuleStoreTestCase):
""" Verify that the response was successful and matches the expected JSON payload. """
request = RequestFactory().get("dummy_url")
request.user = AdminFactory()
response = cohorting_settings(request, six.text_type(self.course.id))
response = cohorting_settings(request, str(self.course.id))
assert 200 == response.status_code
assert expected_response == json.loads(response.content.decode('utf-8'))