diff --git a/openedx/testing/coverage_context_listener/pytest_plugin.py b/openedx/testing/coverage_context_listener/pytest_plugin.py index aa25ab0ca0..cdafa7df81 100644 --- a/openedx/testing/coverage_context_listener/pytest_plugin.py +++ b/openedx/testing/coverage_context_listener/pytest_plugin.py @@ -8,7 +8,7 @@ import requests from pavelib.utils.envs import Env -class RemoteContextPlugin(object): +class RemoteContextPlugin: """ Pytest plugin for reporting pytests contexts to coverage running in another process """ @@ -31,7 +31,7 @@ class RemoteContextPlugin(object): result = requests.post( 'http://{host}:{port}/coverage_context/update_context'.format(**cfg), { - 'context': "{}|{}".format(item.nodeid, when), + 'context': f"{item.nodeid}|{when}", } ) assert result.status_code == 204 diff --git a/openedx/tests/completion_integration/test_handlers.py b/openedx/tests/completion_integration/test_handlers.py index ef4016b269..677a751462 100644 --- a/openedx/tests/completion_integration/test_handlers.py +++ b/openedx/tests/completion_integration/test_handlers.py @@ -3,15 +3,14 @@ Test signal handlers for completion. """ from datetime import datetime +from unittest.mock import patch import ddt import pytest -import six from completion import handlers from completion.models import BlockCompletion from completion.test_utils import CompletionSetUpMixin from django.test import TestCase -from mock import patch from pytz import utc from xblock.completable import XBlockCompletionMode from xblock.core import XBlock @@ -47,7 +46,7 @@ class ScorableCompletionHandlerTestCase(CompletionSetUpMixin, TestCase): COMPLETION_SWITCH_ENABLED = True def setUp(self): - super(ScorableCompletionHandlerTestCase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments + super().setUp() self.block_key = self.context_key.make_usage_key(block_type='problem', block_id='red') def call_scorable_block_completion_handler(self, block_key, score_deleted=None): @@ -63,8 +62,8 @@ class ScorableCompletionHandlerTestCase(CompletionSetUpMixin, TestCase): handlers.scorable_block_completion( sender=self, user_id=self.user.id, - course_id=six.text_type(self.context_key), - usage_id=six.text_type(block_key), + course_id=str(self.context_key), + usage_id=str(block_key), weighted_earned=0.0, weighted_possible=3.0, modified=datetime.utcnow().replace(tzinfo=utc), @@ -124,8 +123,8 @@ class ScorableCompletionHandlerTestCase(CompletionSetUpMixin, TestCase): grades_signals.PROBLEM_WEIGHTED_SCORE_CHANGED.send_robust( sender=self, user_id=self.user.id, - course_id=six.text_type(self.context_key), - usage_id=six.text_type(self.block_key), + course_id=str(self.context_key), + usage_id=str(self.block_key), weighted_earned=0.0, weighted_possible=3.0, modified=datetime.utcnow().replace(tzinfo=utc), @@ -143,15 +142,15 @@ class DisabledCompletionHandlerTestCase(CompletionSetUpMixin, TestCase): COMPLETION_SWITCH_ENABLED = False def setUp(self): - super(DisabledCompletionHandlerTestCase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments + super().setUp() self.block_key = self.context_key.make_usage_key(block_type='problem', block_id='red') def test_disabled_handler_does_not_submit_completion(self): handlers.scorable_block_completion( sender=self, user_id=self.user.id, - course_id=six.text_type(self.context_key), - usage_id=six.text_type(self.block_key), + course_id=str(self.context_key), + usage_id=str(self.block_key), weighted_earned=0.0, weighted_possible=3.0, modified=datetime.utcnow().replace(tzinfo=utc), diff --git a/openedx/tests/completion_integration/test_models.py b/openedx/tests/completion_integration/test_models.py index a0486d38db..8871272b3c 100644 --- a/openedx/tests/completion_integration/test_models.py +++ b/openedx/tests/completion_integration/test_models.py @@ -3,7 +3,6 @@ Test models, managers, and validators. """ import pytest -import six from completion import models from completion.test_utils import CompletionWaffleTestMixin, submit_completions_for_testing from completion.waffle import ENABLE_COMPLETION_TRACKING_SWITCH @@ -11,7 +10,6 @@ from django.core.exceptions import ValidationError from django.test import TestCase from edx_toggles.toggles.testutils import override_waffle_switch from opaque_keys.edx.keys import CourseKey, UsageKey -from six.moves import range, zip from common.djangoapps.student.tests.factories import CourseEnrollmentFactory, UserFactory from openedx.core.djangolib.testing.utils import skip_unless_lms @@ -42,7 +40,7 @@ class CompletionSetUpMixin(CompletionWaffleTestMixin): """ def set_up_completion(self): self.user = UserFactory() - self.block_key = UsageKey.from_string(u'block-v1:edx+test+run+type@video+block@doggos') + self.block_key = UsageKey.from_string('block-v1:edx+test+run+type@video+block@doggos') self.completion = models.BlockCompletion.objects.create( user=self.user, context_key=self.block_key.context_key, @@ -59,7 +57,7 @@ class SubmitCompletionTestCase(CompletionSetUpMixin, TestCase): semantics. """ def setUp(self): - super(SubmitCompletionTestCase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments + super().setUp() self.override_waffle_switch(True) self.set_up_completion() @@ -100,7 +98,7 @@ class SubmitCompletionTestCase(CompletionSetUpMixin, TestCase): assert models.BlockCompletion.objects.count() == 2 def test_new_block(self): - newblock = UsageKey.from_string(u'block-v1:edx+test+run+type@video+block@puppers') + newblock = UsageKey.from_string('block-v1:edx+test+run+type@video+block@puppers') with self.assertNumQueries(SELECT + UPDATE + 4 * SAVEPOINT): _, isnew = models.BlockCompletion.objects.submit_completion( user=self.user, @@ -128,7 +126,7 @@ class CompletionDisabledTestCase(CompletionSetUpMixin, TestCase): Tests that completion API is not called when the feature is disabled. """ def setUp(self): - super(CompletionDisabledTestCase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments + super().setUp() # insert one completion record... self.set_up_completion() # ...then disable the feature. @@ -152,13 +150,13 @@ class SubmitBatchCompletionTestCase(CompletionWaffleTestMixin, TestCase): semantics. """ def setUp(self): - super(SubmitBatchCompletionTestCase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments + super().setUp() self.override_waffle_switch(True) self.block_key = UsageKey.from_string('block-v1:edx+test+run+type@video+block@doggos') self.course_key_obj = CourseKey.from_string('course-v1:edx+test+run') self.user = UserFactory() - CourseEnrollmentFactory.create(user=self.user, course_id=six.text_type(self.course_key_obj)) + CourseEnrollmentFactory.create(user=self.user, course_id=str(self.course_key_obj)) def test_submit_batch_completion(self): blocks = [(self.block_key, 1.0)] @@ -194,14 +192,14 @@ class BatchCompletionMethodTests(CompletionWaffleTestMixin, TestCase): Tests for the classmethods that retrieve course/block completion data. """ def setUp(self): - super(BatchCompletionMethodTests, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments + super().setUp() self.override_waffle_switch(True) self.user = UserFactory.create() self.other_user = UserFactory.create() self.course_key = CourseKey.from_string("edX/MOOC101/2049_T2") self.other_course_key = CourseKey.from_string("course-v1:ReedX+Hum110+1904") - self.block_keys = [UsageKey.from_string("i4x://edX/MOOC101/video/{}".format(number)) for number in range(5)] + self.block_keys = [UsageKey.from_string(f"i4x://edX/MOOC101/video/{number}") for number in range(5)] self.block_keys_with_runs = [key.replace(course_key=self.course_key) for key in self.block_keys] self.other_course_block_keys = [self.other_course_key.make_usage_key('html', '1')] diff --git a/openedx/tests/completion_integration/test_services.py b/openedx/tests/completion_integration/test_services.py index bc382b4af7..fd23895d5a 100644 --- a/openedx/tests/completion_integration/test_services.py +++ b/openedx/tests/completion_integration/test_services.py @@ -8,7 +8,6 @@ from completion.models import BlockCompletion from completion.services import CompletionService from completion.test_utils import CompletionWaffleTestMixin from opaque_keys.edx.keys import CourseKey -from six.moves import range from openedx.core.djangolib.testing.utils import skip_unless_lms from common.djangoapps.student.tests.factories import UserFactory @@ -28,7 +27,7 @@ class CompletionServiceTestCase(CompletionWaffleTestMixin, SharedModuleStoreTest @classmethod def setUpClass(cls): - super(CompletionServiceTestCase, cls).setUpClass() + super().setUpClass() cls.course = CourseFactory.create() with cls.store.bulk_operations(cls.course.id): cls.chapter = ItemFactory.create( @@ -80,7 +79,7 @@ class CompletionServiceTestCase(CompletionWaffleTestMixin, SharedModuleStoreTest cls.problems = [cls.problem, cls.problem2, cls.problem3, cls.problem4, cls.problem5] def setUp(self): - super(CompletionServiceTestCase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments + super().setUp() self.override_waffle_switch(True) self.user = UserFactory.create() self.other_user = UserFactory.create() diff --git a/openedx/tests/completion_integration/test_views.py b/openedx/tests/completion_integration/test_views.py index 971a502ecf..9fe8300070 100644 --- a/openedx/tests/completion_integration/test_views.py +++ b/openedx/tests/completion_integration/test_views.py @@ -1,11 +1,9 @@ -# -*- coding: utf-8 -*- """ Test models, managers, and validators. """ import ddt -import six from completion.test_utils import CompletionWaffleTestMixin from completion.waffle import ENABLE_COMPLETION_TRACKING_SWITCH from django.urls import reverse @@ -38,7 +36,7 @@ class CompletionBatchTestCase(CompletionWaffleTestMixin, ModuleStoreTestCase): """ Create the test data. """ - super(CompletionBatchTestCase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments + super().setUp() self.url = reverse('completion:v1:completion-batch') # Enable the waffle flag for all tests @@ -49,21 +47,21 @@ class CompletionBatchTestCase(CompletionWaffleTestMixin, ModuleStoreTestCase): org='TestX', number='101', display_name='Test', default_store=ModuleStoreEnum.Type.split, ) - assert six.text_type(self.course.id) == self.COURSE_KEY + assert str(self.course.id) == self.COURSE_KEY self.problem = ItemFactory.create( parent=self.course, category="problem", display_name="Test Problem", publish_item=False, ) - assert six.text_type(self.problem.location) == self.BLOCK_KEY + assert str(self.problem.location) == self.BLOCK_KEY # And an old mongo course: self.course_deprecated = CourseFactory.create( org='TestX', number='201', display_name='Test', default_store=ModuleStoreEnum.Type.mongo, ) - assert six.text_type(self.course_deprecated.id) == self.COURSE_KEY_DEPRECATED + assert str(self.course_deprecated.id) == self.COURSE_KEY_DEPRECATED self.problem_deprecated = ItemFactory.create( parent=self.course_deprecated, category="problem", display_name="Test Problem", ) - assert six.text_type(self.problem_deprecated.location) == self.BLOCK_KEY_DEPRECATED + assert str(self.problem_deprecated.location) == self.BLOCK_KEY_DEPRECATED # Create users self.staff_user = UserFactory(is_staff=True) @@ -152,8 +150,8 @@ class CompletionBatchTestCase(CompletionWaffleTestMixin, ModuleStoreTestCase): 400, { "detail": ( - u"Block with key: 'block-v1:TestX+101+OtherCourse+type@problem+block@other' " - u"is not in context {}".format(COURSE_KEY) + "Block with key: 'block-v1:TestX+101+OtherCourse+type@problem+block@other' " + "is not in context {}".format(COURSE_KEY) ) } ), diff --git a/openedx/tests/xblock_integration/test_crowdsource_hinter.py b/openedx/tests/xblock_integration/test_crowdsource_hinter.py index b2c5c69685..3223a1da24 100644 --- a/openedx/tests/xblock_integration/test_crowdsource_hinter.py +++ b/openedx/tests/xblock_integration/test_crowdsource_hinter.py @@ -8,8 +8,6 @@ import unittest import simplejson as json from django.conf import settings from django.urls import reverse -from six import text_type -from six.moves import range from lms.djangoapps.courseware.tests.factories import GlobalStaffFactory from lms.djangoapps.courseware.tests.helpers import LoginEnrollmentTestCase @@ -36,7 +34,7 @@ class TestCrowdsourceHinter(SharedModuleStoreTestCase, LoginEnrollmentTestCase): if settings.ROOT_URLCONF != 'lms.urls': raise unittest.SkipTest('Test only valid in lms') - super(TestCrowdsourceHinter, cls).setUpClass() + super().setUpClass() cls.course = CourseFactory.create( display_name='CrowdsourceHinter_Test_Course' ) @@ -59,16 +57,16 @@ class TestCrowdsourceHinter(SharedModuleStoreTestCase, LoginEnrollmentTestCase): cls.course_url = reverse( 'courseware_section', kwargs={ - 'course_id': text_type(cls.course.id), + 'course_id': str(cls.course.id), 'chapter': 'Overview', 'section': 'Welcome', } ) def setUp(self): - super(TestCrowdsourceHinter, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments + super().setUp() for idx, student in enumerate(self.STUDENTS): - username = "u{}".format(idx) + username = f"u{idx}" self.create_account(username, student['email'], student['password']) self.activate_user(student['email']) @@ -81,8 +79,8 @@ class TestCrowdsourceHinter(SharedModuleStoreTestCase, LoginEnrollmentTestCase): if xblock_name is None: xblock_name = TestCrowdsourceHinter.XBLOCK_NAMES[0] return reverse('xblock_handler', kwargs={ - 'course_id': text_type(self.course.id), - 'usage_id': quote_slashes(text_type(self.course.id.make_usage_key('crowdsourcehinter', xblock_name))), + 'course_id': str(self.course.id), + 'usage_id': quote_slashes(str(self.course.id.make_usage_key('crowdsourcehinter', xblock_name))), 'handler': handler, 'suffix': '' }) diff --git a/openedx/tests/xblock_integration/test_recommender.py b/openedx/tests/xblock_integration/test_recommender.py index 9fe8c3b88b..cc1d9e6446 100644 --- a/openedx/tests/xblock_integration/test_recommender.py +++ b/openedx/tests/xblock_integration/test_recommender.py @@ -11,12 +11,9 @@ from copy import deepcopy from io import BytesIO import simplejson as json -import six from ddt import data, ddt from django.conf import settings from django.urls import reverse -from six import text_type -from six.moves import range from lms.djangoapps.courseware.tests.factories import GlobalStaffFactory from lms.djangoapps.courseware.tests.helpers import LoginEnrollmentTestCase @@ -43,7 +40,7 @@ class TestRecommender(SharedModuleStoreTestCase, LoginEnrollmentTestCase): if settings.ROOT_URLCONF != 'lms.urls': raise unittest.SkipTest('Test only valid in lms') - super(TestRecommender, cls).setUpClass() + super().setUpClass() cls.course = CourseFactory.create( display_name='Recommender_Test_Course' ) @@ -71,7 +68,7 @@ class TestRecommender(SharedModuleStoreTestCase, LoginEnrollmentTestCase): cls.course_url = reverse( 'courseware_section', kwargs={ - 'course_id': text_type(cls.course.id), + 'course_id': str(cls.course.id), 'chapter': 'Overview', 'section': 'Welcome', } @@ -117,9 +114,9 @@ class TestRecommender(SharedModuleStoreTestCase, LoginEnrollmentTestCase): } def setUp(self): - super(TestRecommender, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments + super().setUp() for idx, student in enumerate(self.STUDENTS): - username = "u{}".format(idx) + username = f"u{idx}" self.create_account(username, student['email'], student['password']) self.activate_user(student['email']) self.logout() @@ -133,8 +130,8 @@ class TestRecommender(SharedModuleStoreTestCase, LoginEnrollmentTestCase): if xblock_name is None: xblock_name = TestRecommender.XBLOCK_NAMES[0] return reverse('xblock_handler', kwargs={ - 'course_id': text_type(self.course.id), - 'usage_id': quote_slashes(text_type(self.course.id.make_usage_key('recommender', xblock_name))), + 'course_id': str(self.course.id), + 'usage_id': quote_slashes(str(self.course.id.make_usage_key('recommender', xblock_name))), 'handler': handler, 'suffix': '' }) @@ -209,7 +206,7 @@ class TestRecommenderCreateFromEmpty(TestRecommender): """ self.enroll_student(self.STUDENTS[0]['email'], self.STUDENTS[0]['password']) # Check whether adding new resource is successful - for resource_id, resource in six.iteritems(self.test_recommendations): + for resource_id, resource in self.test_recommendations.items(): for xblock_name in self.XBLOCK_NAMES: result = self.call_event('add_resource', resource, xblock_name) @@ -228,7 +225,7 @@ class TestRecommenderCreateFromEmpty(TestRecommender): class TestRecommenderResourceBase(TestRecommender): """Base helper class for tests with resources.""" def setUp(self): - super(TestRecommenderResourceBase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments + super().setUp() self.resource_id = self.resource_urls[0] self.resource_id_second = self.resource_urls[1] self.non_existing_resource_id = 'An non-existing id' @@ -251,7 +248,7 @@ class TestRecommenderResourceBase(TestRecommender): """ resource = {"id": resource_id} edited_recommendations = { - key: value + "edited" for key, value in six.iteritems(self.test_recommendations[self.resource_id]) + key: value + "edited" for key, value in self.test_recommendations[self.resource_id].items() } resource.update(edited_recommendations) return resource @@ -634,7 +631,7 @@ class TestRecommenderFileUploading(TestRecommender): Check whether we can handle file uploading correctly """ def setUp(self): - super(TestRecommenderFileUploading, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments + super().setUp() self.initial_configuration = { 'flagged_accum_resources': {}, 'endorsed_recommendation_reasons': [], @@ -653,7 +650,7 @@ class TestRecommenderFileUploading(TestRecommender): f_handler = BytesIO(codecs.decode(test_case['magic_number'], 'hex_codec')) elif content is not None: f_handler = BytesIO( - json.dumps(content, sort_keys=True) if six.PY2 else json.dumps(content, sort_keys=True).encode('utf-8')) + json.dumps(content, sort_keys=True).encode('utf-8')) else: f_handler = BytesIO(b'') diff --git a/openedx/tests/xblock_integration/xblock_testcase.py b/openedx/tests/xblock_integration/xblock_testcase.py index 3f6503b712..d9e6d3cac8 100644 --- a/openedx/tests/xblock_integration/xblock_testcase.py +++ b/openedx/tests/xblock_integration/xblock_testcase.py @@ -43,13 +43,11 @@ import unittest from datetime import datetime, timedelta import html -import mock +from unittest import mock import pytz -import six from bs4 import BeautifulSoup from django.conf import settings from django.urls import reverse -from six.moves import range from xblock.plugin import Plugin import lms.djangoapps.lms_xblock.runtime @@ -58,7 +56,7 @@ from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory -class XBlockEventTestMixin(object): +class XBlockEventTestMixin: """Mixin for easily verifying that events were published during a test. @@ -101,7 +99,7 @@ class XBlockEventTestMixin(object): passed into it. """ - super(XBlockEventTestMixin, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments + super().setUp() saved_init = lms.djangoapps.lms_xblock.runtime.LmsModuleSystem.__init__ def patched_init(runtime_self, **kwargs): @@ -166,7 +164,7 @@ class XBlockEventTestMixin(object): self.events = [] -class GradePublishTestMixin(object): +class GradePublishTestMixin: ''' This checks whether a grading event was correctly published. This puts basic plumbing in place, but we would like to: @@ -188,7 +186,7 @@ class GradePublishTestMixin(object): ''' Hot-patch the grading emission system to capture grading events. ''' - super(GradePublishTestMixin, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments + super().setUp() def capture_score(user_id, usage_key, score, max_score): ''' @@ -218,7 +216,7 @@ class GradePublishTestMixin(object): assert grade == self.scores[(- 1)]['score'] -class XBlockScenarioTestCaseMixin(object): +class XBlockScenarioTestCaseMixin: ''' This allows us to have test cases defined in JSON today, and in OLX someday. @@ -232,7 +230,7 @@ class XBlockScenarioTestCaseMixin(object): Create a set of pages with XBlocks on them. For now, we restrict ourselves to one block per learning sequence. """ - super(XBlockScenarioTestCaseMixin, cls).setUpClass() + super().setUpClass() cls.course = CourseFactory.create( display_name='XBlock_Test_Course' @@ -273,10 +271,10 @@ class XBlockScenarioTestCaseMixin(object): ) cls.xblocks[xblock_config['urlname']] = xblock - scenario_url = six.text_type(reverse( + scenario_url = str(reverse( 'courseware_section', kwargs={ - 'course_id': six.text_type(cls.course.id), + 'course_id': str(cls.course.id), 'chapter': "ch_" + chapter_config['urlname'], 'section': "sec_" + chapter_config['urlname'] } @@ -285,7 +283,7 @@ class XBlockScenarioTestCaseMixin(object): cls.scenario_urls[chapter_config['urlname']] = scenario_url -class XBlockStudentTestCaseMixin(object): +class XBlockStudentTestCaseMixin: ''' Creates a default set of students for XBlock tests ''' @@ -303,9 +301,9 @@ class XBlockStudentTestCaseMixin(object): users, so we exercise more corner cases, but we could standardize if this is more hassle than it's worth. """ - super(XBlockStudentTestCaseMixin, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments + super().setUp() for idx, student in enumerate(self.student_list): - username = "u{}".format(idx) + username = f"u{idx}" self._enroll_user(username, student['email'], student['password']) self.select_student(0) @@ -324,8 +322,8 @@ class XBlockStudentTestCaseMixin(object): """ # If we don't have enough users, add a few more... for newuser_id in range(len(self.student_list), user_id): - username = "user_{i}".format(i=newuser_id) - email = "user_{i}@example.edx.org".format(i=newuser_id) + username = f"user_{newuser_id}" + email = f"user_{newuser_id}@example.edx.org" password = "12345" self._enroll_user(username, email, password) self.student_list.append({'email': email, 'password': password}) @@ -365,15 +363,15 @@ class XBlockTestCase(XBlockStudentTestCaseMixin, # So, skip the test class here if we are not in the LMS. if settings.ROOT_URLCONF != 'lms.urls': raise unittest.SkipTest('Test only valid in lms') - super(XBlockTestCase, cls).setUpClass() + super().setUpClass() def get_handler_url(self, handler, xblock_name=None): """ Get url for the specified xblock handler """ return reverse('xblock_handler', kwargs={ - 'course_id': six.text_type(self.course.id), - 'usage_id': six.text_type( + 'course_id': str(self.course.id), + 'usage_id': str( self.course.id.make_usage_key('done', xblock_name) ), 'handler': handler, @@ -413,9 +411,9 @@ class XBlockTestCase(XBlockStudentTestCaseMixin, if block["urlname"] == xblock_name: xblock_type = block["blocktype"] - key = six.text_type(self.course.id.make_usage_key(xblock_type, xblock_name)) + key = str(self.course.id.make_usage_key(xblock_type, xblock_name)) return reverse('xblock_handler', kwargs={ - 'course_id': six.text_type(self.course.id), + 'course_id': str(self.course.id), 'usage_id': key, 'handler': handler, 'suffix': '' @@ -449,7 +447,7 @@ class XBlockTestCase(XBlockStudentTestCaseMixin, usage_id = self.xblocks[urlname].scope_ids.usage_id # First, we get out our