diff --git a/cms/djangoapps/api/__init__.py b/cms/djangoapps/api/__init__.py index 2046a6c208..fd876356d9 100644 --- a/cms/djangoapps/api/__init__.py +++ b/cms/djangoapps/api/__init__.py @@ -1,2 +1,2 @@ -# pylint: disable=missing-module-docstring +# lint-amnesty, pylint: disable=django-not-configured, missing-module-docstring default_app_config = 'cms.djangoapps.api.apps.ApiConfig' diff --git a/cms/djangoapps/api/v1/serializers/course_runs.py b/cms/djangoapps/api/v1/serializers/course_runs.py index 2579a6cdee..8bd97eac4f 100644 --- a/cms/djangoapps/api/v1/serializers/course_runs.py +++ b/cms/djangoapps/api/v1/serializers/course_runs.py @@ -26,7 +26,7 @@ User = get_user_model() log = logging.getLogger(__name__) -class CourseAccessRoleSerializer(serializers.ModelSerializer): +class CourseAccessRoleSerializer(serializers.ModelSerializer): # lint-amnesty, pylint: disable=missing-class-docstring user = serializers.SlugRelatedField(slug_field='username', queryset=User.objects.all()) class Meta: @@ -34,21 +34,21 @@ class CourseAccessRoleSerializer(serializers.ModelSerializer): fields = ('user', 'role',) -class CourseRunScheduleSerializer(serializers.Serializer): +class CourseRunScheduleSerializer(serializers.Serializer): # lint-amnesty, pylint: disable=abstract-method start = serializers.DateTimeField() end = serializers.DateTimeField() enrollment_start = serializers.DateTimeField(allow_null=True, required=False) enrollment_end = serializers.DateTimeField(allow_null=True, required=False) -class CourseRunTeamSerializer(serializers.Serializer): +class CourseRunTeamSerializer(serializers.Serializer): # lint-amnesty, pylint: disable=abstract-method, missing-class-docstring def to_internal_value(self, data): """Overriding this to support deserialization, for write operations.""" for member in data: try: User.objects.get(username=member['user']) except User.DoesNotExist: - raise serializers.ValidationError( + raise serializers.ValidationError( # lint-amnesty, pylint: disable=raise-missing-from _('Course team user does not exist') ) @@ -64,10 +64,10 @@ class CourseRunTeamSerializer(serializers.Serializer): return instance -class CourseRunTeamSerializerMixin(serializers.Serializer): +class CourseRunTeamSerializerMixin(serializers.Serializer): # lint-amnesty, pylint: disable=abstract-method, missing-class-docstring team = CourseRunTeamSerializer(required=False) - def update_team(self, instance, team): + def update_team(self, instance, team): # lint-amnesty, pylint: disable=missing-function-docstring # Existing data should remain intact when performing a partial update. if not self.partial: CourseAccessRole.objects.filter(course_id=instance.id).delete() @@ -91,7 +91,7 @@ def image_is_jpeg_or_png(value): u'Only JPEG and PNG image types are supported. {} is not valid'.format(content_type)) -class CourseRunImageField(serializers.ImageField): +class CourseRunImageField(serializers.ImageField): # lint-amnesty, pylint: disable=missing-class-docstring default_validators = [image_is_jpeg_or_png] def get_attribute(self, instance): @@ -103,7 +103,7 @@ class CourseRunImageField(serializers.ImageField): return request.build_absolute_uri(value) -class CourseRunPacingTypeField(serializers.ChoiceField): +class CourseRunPacingTypeField(serializers.ChoiceField): # lint-amnesty, pylint: disable=missing-class-docstring def to_representation(self, value): return 'self_paced' if value else 'instructor_paced' @@ -111,7 +111,7 @@ class CourseRunPacingTypeField(serializers.ChoiceField): return data == 'self_paced' -class CourseRunImageSerializer(serializers.Serializer): +class CourseRunImageSerializer(serializers.Serializer): # lint-amnesty, pylint: disable=abstract-method, missing-class-docstring # We set an empty default to prevent the parent serializer from attempting # to save this value to the Course object. card_image = CourseRunImageField(source='course_image', default=empty) @@ -126,13 +126,13 @@ class CourseRunImageSerializer(serializers.Serializer): return instance -class CourseRunSerializerCommonFieldsMixin(serializers.Serializer): +class CourseRunSerializerCommonFieldsMixin(serializers.Serializer): # lint-amnesty, pylint: disable=abstract-method schedule = CourseRunScheduleSerializer(source='*', required=False) pacing_type = CourseRunPacingTypeField(source='self_paced', required=False, choices=((False, 'instructor_paced'), (True, 'self_paced'),)) -class CourseRunSerializer(CourseRunSerializerCommonFieldsMixin, CourseRunTeamSerializerMixin, serializers.Serializer): +class CourseRunSerializer(CourseRunSerializerCommonFieldsMixin, CourseRunTeamSerializerMixin, serializers.Serializer): # lint-amnesty, pylint: disable=abstract-method, missing-class-docstring id = serializers.CharField(read_only=True) title = serializers.CharField(source='display_name') images = CourseRunImageSerializer(source='*', required=False) @@ -150,7 +150,7 @@ class CourseRunSerializer(CourseRunSerializerCommonFieldsMixin, CourseRunTeamSer return instance -class CourseRunCreateSerializer(CourseRunSerializer): +class CourseRunCreateSerializer(CourseRunSerializer): # lint-amnesty, pylint: disable=missing-class-docstring org = serializers.CharField(source='id.org') number = serializers.CharField(source='id.course') run = serializers.CharField(source='id.run') @@ -166,7 +166,7 @@ class CourseRunCreateSerializer(CourseRunSerializer): return instance -class CourseRunRerunSerializer(CourseRunSerializerCommonFieldsMixin, CourseRunTeamSerializerMixin, +class CourseRunRerunSerializer(CourseRunSerializerCommonFieldsMixin, CourseRunTeamSerializerMixin, # lint-amnesty, pylint: disable=abstract-method, missing-class-docstring serializers.Serializer): title = serializers.CharField(source='display_name', required=False) number = serializers.CharField(source='id.course', required=False) @@ -182,7 +182,7 @@ class CourseRunRerunSerializer(CourseRunSerializerCommonFieldsMixin, CourseRunTe with store.default_store('split'): new_course_run_key = store.make_course_key(course_run_key.org, number, run) except InvalidKeyError: - raise serializers.ValidationError( + raise serializers.ValidationError( # lint-amnesty, pylint: disable=raise-missing-from u'Invalid key supplied. Ensure there are no special characters in the Course Number.' ) if store.has_course(new_course_run_key, ignore_case=True): diff --git a/cms/djangoapps/api/v1/tests/test_serializers/test_course_runs.py b/cms/djangoapps/api/v1/tests/test_serializers/test_course_runs.py index b37c067939..3a6dbb1f6f 100644 --- a/cms/djangoapps/api/v1/tests/test_serializers/test_course_runs.py +++ b/cms/djangoapps/api/v1/tests/test_serializers/test_course_runs.py @@ -18,10 +18,10 @@ from ..utils import serialize_datetime @ddt.ddt -class CourseRunSerializerTests(ModuleStoreTestCase): +class CourseRunSerializerTests(ModuleStoreTestCase): # lint-amnesty, pylint: disable=missing-class-docstring def setUp(self): - super(CourseRunSerializerTests, self).setUp() + super(CourseRunSerializerTests, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.course_start = datetime.datetime.now(pytz.UTC) self.course_end = self.course_start + datetime.timedelta(days=30) diff --git a/cms/djangoapps/api/v1/tests/test_views/test_course_runs.py b/cms/djangoapps/api/v1/tests/test_views/test_course_runs.py index 7b2cc67242..5d98818c04 100644 --- a/cms/djangoapps/api/v1/tests/test_views/test_course_runs.py +++ b/cms/djangoapps/api/v1/tests/test_views/test_course_runs.py @@ -8,7 +8,7 @@ import pytz from django.core.files.uploadedfile import SimpleUploadedFile from django.test import RequestFactory, override_settings from django.urls import reverse -from mock import patch +from mock import patch # lint-amnesty, pylint: disable=unused-import from opaque_keys.edx.keys import CourseKey from organizations.api import add_organization, get_course_organizations from rest_framework.test import APIClient @@ -35,7 +35,7 @@ class CourseRunViewSetTests(ModuleStoreTestCase): list_url = reverse('api:v1:course_run-list') def setUp(self): - super(CourseRunViewSetTests, self).setUp() + super(CourseRunViewSetTests, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.client = APIClient() user = AdminFactory() self.client.login(username=user.username, password=TEST_PASSWORD) @@ -331,7 +331,7 @@ class CourseRunViewSetTests(ModuleStoreTestCase): original_course_run = ToyCourseFactory() add_organization({ 'name': 'Test Organization', - 'short_name': original_course_run.id.org, + 'short_name': original_course_run.id.org, # lint-amnesty, pylint: disable=no-member 'description': 'Testing Organization Description', }) start = datetime.datetime.now(pytz.UTC).replace(microsecond=0) @@ -339,7 +339,7 @@ class CourseRunViewSetTests(ModuleStoreTestCase): user = UserFactory() role = 'instructor' run = '3T2017' - url = reverse('api:v1:course_run-rerun', kwargs={'pk': str(original_course_run.id)}) + url = reverse('api:v1:course_run-rerun', kwargs={'pk': str(original_course_run.id)}) # lint-amnesty, pylint: disable=no-member data = { 'run': run, 'schedule': { @@ -369,16 +369,16 @@ class CourseRunViewSetTests(ModuleStoreTestCase): if number: assert course_run.id.course == number - assert course_run.id.course != original_course_run.id.course + assert course_run.id.course != original_course_run.id.course # lint-amnesty, pylint: disable=no-member else: - assert course_run.id.course == original_course_run.id.course + assert course_run.id.course == original_course_run.id.course # lint-amnesty, pylint: disable=no-member self.assert_course_run_schedule(course_run, start, end) self.assert_access_role(course_run, user, role) self.assert_course_access_role_count(course_run, 1) course_orgs = get_course_organizations(course_run_key) self.assertEqual(len(course_orgs), 1) - self.assertEqual(course_orgs[0]['short_name'], original_course_run.id.org) + self.assertEqual(course_orgs[0]['short_name'], original_course_run.id.org) # lint-amnesty, pylint: disable=no-member def test_rerun_duplicate_run(self): course_run = ToyCourseFactory() diff --git a/cms/djangoapps/api/v1/tests/utils.py b/cms/djangoapps/api/v1/tests/utils.py index 750c1a5a27..1684e018dd 100644 --- a/cms/djangoapps/api/v1/tests/utils.py +++ b/cms/djangoapps/api/v1/tests/utils.py @@ -1,2 +1,3 @@ +# lint-amnesty, pylint: disable=missing-module-docstring def serialize_datetime(d): return d.strftime('%Y-%m-%dT%H:%M:%S.%fZ') diff --git a/cms/djangoapps/api/v1/views/course_runs.py b/cms/djangoapps/api/v1/views/course_runs.py index 9718251382..ebe1b63777 100644 --- a/cms/djangoapps/api/v1/views/course_runs.py +++ b/cms/djangoapps/api/v1/views/course_runs.py @@ -20,7 +20,7 @@ from ..serializers.course_runs import ( ) -class CourseRunViewSet(viewsets.GenericViewSet): +class CourseRunViewSet(viewsets.GenericViewSet): # lint-amnesty, pylint: disable=missing-class-docstring authentication_classes = (JwtAuthentication, SessionAuthentication,) lookup_value_regex = settings.COURSE_KEY_REGEX permission_classes = (permissions.IsAdminUser,) @@ -43,18 +43,18 @@ class CourseRunViewSet(viewsets.GenericViewSet): raise Http404 - def list(self, request, *args, **kwargs): + def list(self, request, *args, **kwargs): # lint-amnesty, pylint: disable=unused-argument course_runs, __ = _accessible_courses_iter(request) page = self.paginate_queryset(list(course_runs)) serializer = self.get_serializer(page, many=True) return self.get_paginated_response(serializer.data) - def retrieve(self, request, *args, **kwargs): + def retrieve(self, request, *args, **kwargs): # lint-amnesty, pylint: disable=unused-argument course_run = self.get_object() serializer = self.get_serializer(course_run) return Response(serializer.data) - def update(self, request, *args, **kwargs): + def update(self, request, *args, **kwargs): # lint-amnesty, pylint: disable=missing-function-docstring, unused-argument course_run = self.get_object() partial = kwargs.pop('partial', False) @@ -67,7 +67,7 @@ class CourseRunViewSet(viewsets.GenericViewSet): kwargs['partial'] = True return self.update(request, *args, **kwargs) - def create(self, request, *args, **kwargs): + def create(self, request, *args, **kwargs): # lint-amnesty, pylint: disable=unused-argument serializer = CourseRunCreateSerializer(data=request.data, context=self.get_serializer_context()) serializer.is_valid(raise_exception=True) serializer.save() @@ -78,7 +78,7 @@ class CourseRunViewSet(viewsets.GenericViewSet): methods=['post', 'put'], parser_classes=(parsers.FormParser, parsers.MultiPartParser,), serializer_class=CourseRunImageSerializer) - def images(self, request, *args, **kwargs): + def images(self, request, *args, **kwargs): # lint-amnesty, pylint: disable=missing-function-docstring, unused-argument course_run = self.get_object() serializer = CourseRunImageSerializer(course_run, data=request.data, context=self.get_serializer_context()) serializer.is_valid(raise_exception=True) @@ -86,7 +86,7 @@ class CourseRunViewSet(viewsets.GenericViewSet): return Response(serializer.data) @action(detail=True, methods=['post']) - def rerun(self, request, *args, **kwargs): + def rerun(self, request, *args, **kwargs): # lint-amnesty, pylint: disable=missing-function-docstring, unused-argument course_run = self.get_object() serializer = CourseRunRerunSerializer(course_run, data=request.data, context=self.get_serializer_context()) serializer.is_valid(raise_exception=True) diff --git a/cms/djangoapps/cms_user_tasks/tests.py b/cms/djangoapps/cms_user_tasks/tests.py index 7eac8b1951..7015b7b4e2 100644 --- a/cms/djangoapps/cms_user_tasks/tests.py +++ b/cms/djangoapps/cms_user_tasks/tests.py @@ -9,7 +9,7 @@ from uuid import uuid4 import mock from boto.exception import NoAuthHandlerFound from django.conf import settings -from django.contrib.auth.models import User +from django.contrib.auth.models import User # lint-amnesty, pylint: disable=imported-auth-user from django.core import mail from django.test import override_settings from django.urls import reverse @@ -72,7 +72,7 @@ class TestUserTasks(APITestCase): """ @classmethod - def setUpTestData(cls): + def setUpTestData(cls): # lint-amnesty, pylint: disable=super-method-not-called cls.user = User.objects.create_user('test_user', 'test@example.com', 'password') cls.status = UserTaskStatus.objects.create( user=cls.user, task_id=str(uuid4()), task_class='test_rest_api.sample_task', name='SampleTask 2', @@ -80,7 +80,7 @@ class TestUserTasks(APITestCase): cls.artifact = UserTaskArtifact.objects.create(status=cls.status, text='Lorem ipsum') def setUp(self): - super(TestUserTasks, self).setUp() + super(TestUserTasks, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.status.refresh_from_db() self.client.force_authenticate(self.user) # pylint: disable=no-member @@ -145,14 +145,14 @@ class TestUserTaskStopped(APITestCase): """ @classmethod - def setUpTestData(cls): + def setUpTestData(cls): # lint-amnesty, pylint: disable=super-method-not-called cls.user = User.objects.create_user('test_user', 'test@example.com', 'password') cls.status = UserTaskStatus.objects.create( user=cls.user, task_id=str(uuid4()), task_class='test_rest_api.sample_task', name='SampleTask 2', total_steps=5) def setUp(self): - super(TestUserTaskStopped, self).setUp() + super(TestUserTaskStopped, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.status.refresh_from_db() self.client.force_authenticate(self.user) # pylint: disable=no-member diff --git a/cms/djangoapps/contentstore/api/views/course_import.py b/cms/djangoapps/contentstore/api/views/course_import.py index 2d94d951f7..9430aee2cd 100644 --- a/cms/djangoapps/contentstore/api/views/course_import.py +++ b/cms/djangoapps/contentstore/api/views/course_import.py @@ -35,7 +35,7 @@ class CourseImportExportViewMixin(DeveloperErrorViewMixin): """ Ensures that the user is authenticated (e.g. not an AnonymousUser) """ - super(CourseImportExportViewMixin, self).perform_authentication(request) + super(CourseImportExportViewMixin, self).perform_authentication(request) # lint-amnesty, pylint: disable=super-with-arguments if request.user.is_anonymous: raise AuthenticationFailed diff --git a/cms/djangoapps/contentstore/api/views/course_quality.py b/cms/djangoapps/contentstore/api/views/course_quality.py index 51ee50234b..998bc828c5 100644 --- a/cms/djangoapps/contentstore/api/views/course_quality.py +++ b/cms/djangoapps/contentstore/api/views/course_quality.py @@ -1,3 +1,4 @@ +# lint-amnesty, pylint: disable=missing-module-docstring import logging import time @@ -128,7 +129,7 @@ class CourseQualityView(DeveloperErrorViewMixin, GenericAPIView): return Response(response) - def _required_course_depth(self, request, all_requested): + def _required_course_depth(self, request, all_requested): # lint-amnesty, pylint: disable=missing-function-docstring if get_bool_param(request, 'units', all_requested): # The num_blocks metric for "units" requires retrieving all blocks in the graph. return None @@ -151,7 +152,7 @@ class CourseQualityView(DeveloperErrorViewMixin, GenericAPIView): highlights_enabled=highlights_setting.is_enabled(), ) - def _subsections_quality(self, course, request): + def _subsections_quality(self, course, request): # lint-amnesty, pylint: disable=missing-function-docstring subsection_unit_dict = self._get_subsections_and_units(course, request) num_block_types_per_subsection_dict = {} for subsection_key, unit_dict in six.iteritems(subsection_unit_dict): @@ -167,7 +168,7 @@ class CourseQualityView(DeveloperErrorViewMixin, GenericAPIView): num_block_types=self._stats_dict(list(six.itervalues(num_block_types_per_subsection_dict))), ) - def _units_quality(self, course, request): + def _units_quality(self, course, request): # lint-amnesty, pylint: disable=missing-function-docstring subsection_unit_dict = self._get_subsections_and_units(course, request) num_leaf_blocks_per_unit = [ unit_info['num_leaf_blocks'] @@ -179,7 +180,7 @@ class CourseQualityView(DeveloperErrorViewMixin, GenericAPIView): num_blocks=self._stats_dict(num_leaf_blocks_per_unit), ) - def _videos_quality(self, course): + def _videos_quality(self, course): # lint-amnesty, pylint: disable=missing-function-docstring video_blocks_in_course = modulestore().get_items(course.id, qualifiers={'category': 'video'}) videos, __ = get_videos_for_course(course.id) videos_in_val = list(videos) @@ -227,7 +228,7 @@ class CourseQualityView(DeveloperErrorViewMixin, GenericAPIView): return cls._get_all_children(course) @classmethod - def _get_all_children(cls, parent): + def _get_all_children(cls, parent): # lint-amnesty, pylint: disable=missing-function-docstring store = modulestore() children = [store.get_item(child_usage_key) for child_usage_key in cls._get_children(parent)] visible_children = [ @@ -242,14 +243,14 @@ class CourseQualityView(DeveloperErrorViewMixin, GenericAPIView): return visible_chidren @classmethod - def _get_children(cls, parent): + def _get_children(cls, parent): # lint-amnesty, pylint: disable=missing-function-docstring if not hasattr(parent, 'children'): return [] else: return parent.children @classmethod - def _get_leaf_blocks(cls, unit): + def _get_leaf_blocks(cls, unit): # lint-amnesty, pylint: disable=missing-function-docstring def leaf_filter(block): return ( block.location.block_type not in ('chapter', 'sequential', 'vertical') and @@ -257,11 +258,11 @@ class CourseQualityView(DeveloperErrorViewMixin, GenericAPIView): ) return [ - block for block in + block for block in # lint-amnesty, pylint: disable=unnecessary-comprehension traverse_pre_order(unit, cls._get_visible_children, leaf_filter) ] - def _stats_dict(self, data): + def _stats_dict(self, data): # lint-amnesty, pylint: disable=missing-function-docstring if not data: return dict( min=None, diff --git a/cms/djangoapps/contentstore/api/views/course_validation.py b/cms/djangoapps/contentstore/api/views/course_validation.py index 12d85e27f2..a04b022288 100644 --- a/cms/djangoapps/contentstore/api/views/course_validation.py +++ b/cms/djangoapps/contentstore/api/views/course_validation.py @@ -1,3 +1,4 @@ +# lint-amnesty, pylint: disable=missing-module-docstring import logging import dateutil @@ -110,7 +111,7 @@ class CourseValidationView(DeveloperErrorViewMixin, GenericAPIView): has_end_date=course.end is not None, ) - def _assignments_validation(self, course, request): + def _assignments_validation(self, course, request): # lint-amnesty, pylint: disable=missing-function-docstring assignments, visible_assignments = self._get_assignments(course) assignments_with_dates = [ a for a in visible_assignments if a.due @@ -218,7 +219,7 @@ class CourseValidationView(DeveloperErrorViewMixin, GenericAPIView): has_update=len(updates) > 0, ) - def _get_assignments(self, course): + def _get_assignments(self, course): # lint-amnesty, pylint: disable=missing-function-docstring store = modulestore() sections = [store.get_item(section_usage_key) for section_usage_key in course.children] assignments = [ @@ -245,7 +246,7 @@ class CourseValidationView(DeveloperErrorViewMixin, GenericAPIView): oras = modulestore().get_items(course.id, qualifiers={'category': 'openassessment'}) return oras if not graded_only else [ora for ora in oras if ora.graded] - def _has_date_before_start(self, ora, start): + def _has_date_before_start(self, ora, start): # lint-amnesty, pylint: disable=missing-function-docstring if ora.submission_start: if dateutil.parser.parse(ora.submission_start).replace(tzinfo=UTC) < start: return True @@ -262,7 +263,7 @@ class CourseValidationView(DeveloperErrorViewMixin, GenericAPIView): return False - def _has_date_after_end(self, ora, end): + def _has_date_after_end(self, ora, end): # lint-amnesty, pylint: disable=missing-function-docstring if ora.submission_start: if dateutil.parser.parse(ora.submission_start).replace(tzinfo=UTC) > end: return True @@ -281,7 +282,7 @@ class CourseValidationView(DeveloperErrorViewMixin, GenericAPIView): def _has_start_date(self, course): return not course.start_date_is_still_default - def _has_grading_policy(self, course): + def _has_grading_policy(self, course): # lint-amnesty, pylint: disable=missing-function-docstring grading_policy_formatted = {} default_grading_policy_formatted = {} diff --git a/cms/djangoapps/contentstore/course_group_config.py b/cms/djangoapps/contentstore/course_group_config.py index bea95bc619..a9ae47aecf 100644 --- a/cms/djangoapps/contentstore/course_group_config.py +++ b/cms/djangoapps/contentstore/course_group_config.py @@ -36,7 +36,7 @@ class GroupConfigurationsValidationError(Exception): """ An error thrown when a group configurations input is invalid. """ - pass + pass # lint-amnesty, pylint: disable=unnecessary-pass class GroupConfiguration(object): @@ -62,7 +62,7 @@ class GroupConfiguration(object): try: configuration = json.loads(json_string.decode("utf-8")) except ValueError: - raise GroupConfigurationsValidationError(_("invalid JSON")) + raise GroupConfigurationsValidationError(_("invalid JSON")) # lint-amnesty, pylint: disable=raise-missing-from configuration["version"] = UserPartition.VERSION return configuration @@ -102,7 +102,7 @@ class GroupConfiguration(object): """ Return a list of IDs that already in use. """ - return set([p.id for p in get_all_partitions_for_course(course)]) + return set([p.id for p in get_all_partitions_for_course(course)]) # lint-amnesty, pylint: disable=consider-using-set-comprehension def get_user_partition(self): """ @@ -111,7 +111,7 @@ class GroupConfiguration(object): try: return UserPartition.from_json(self.configuration) except ReadOnlyUserPartitionError: - raise GroupConfigurationsValidationError(_("unable to load this type of group configuration")) + raise GroupConfigurationsValidationError(_("unable to load this type of group configuration")) # lint-amnesty, pylint: disable=raise-missing-from @staticmethod def _get_usage_dict(course, unit, item, scheme_name=None): diff --git a/cms/djangoapps/contentstore/courseware_index.py b/cms/djangoapps/contentstore/courseware_index.py index ccb472fcea..e6b465797a 100644 --- a/cms/djangoapps/contentstore/courseware_index.py +++ b/cms/djangoapps/contentstore/courseware_index.py @@ -57,7 +57,7 @@ class SearchIndexingError(Exception): """ Indicates some error(s) occured during indexing """ def __init__(self, message, error_list): - super(SearchIndexingError, self).__init__(message) + super(SearchIndexingError, self).__init__(message) # lint-amnesty, pylint: disable=super-with-arguments self.error_list = error_list @@ -116,7 +116,7 @@ class SearchIndexerBase(object, metaclass=ABCMeta): searcher.remove(result_ids) @classmethod - def index(cls, modulestore, structure_key, triggered_at=None, reindex_age=REINDEX_AGE, timeout=INDEXING_REQUEST_TIMEOUT): + def index(cls, modulestore, structure_key, triggered_at=None, reindex_age=REINDEX_AGE, timeout=INDEXING_REQUEST_TIMEOUT): # lint-amnesty, pylint: disable=line-too-long, too-many-statements """ Process course for indexing @@ -187,7 +187,7 @@ class SearchIndexerBase(object, metaclass=ABCMeta): item_content_groups = None - if item.category == "split_test": + if item.category == "split_test": # lint-amnesty, pylint: disable=too-many-nested-blocks split_partition = item.get_selected_partition() for split_test_child in item.get_children(): if split_partition: @@ -327,7 +327,7 @@ class SearchIndexerBase(object, metaclass=ABCMeta): Returns: None """ - pass + pass # lint-amnesty, pylint: disable=unnecessary-pass @classmethod def supplemental_fields(cls, item): # pylint: disable=unused-argument @@ -667,7 +667,7 @@ class CourseAboutSearchIndexer(CoursewareSearchIndexer): return {"course": text_type(normalized_structure_key), "org": normalized_structure_key.org} @classmethod - def remove_deleted_items(cls, structure_key): + def remove_deleted_items(cls, structure_key): # lint-amnesty, pylint: disable=arguments-differ """ Remove item from Course About Search_index """ searcher = SearchEngine.get_search_engine(cls.INDEX_NAME) if not searcher: diff --git a/cms/djangoapps/contentstore/debug_file_uploader.py b/cms/djangoapps/contentstore/debug_file_uploader.py index 39d18cefe8..77cbc59b71 100644 --- a/cms/djangoapps/contentstore/debug_file_uploader.py +++ b/cms/djangoapps/contentstore/debug_file_uploader.py @@ -6,9 +6,9 @@ import time from django.core.files.uploadhandler import FileUploadHandler -class DebugFileUploader(FileUploadHandler): +class DebugFileUploader(FileUploadHandler): # lint-amnesty, pylint: disable=missing-class-docstring def __init__(self, request=None): - super(DebugFileUploader, self).__init__(request) + super(DebugFileUploader, self).__init__(request) # lint-amnesty, pylint: disable=super-with-arguments self.count = 0 def receive_data_chunk(self, raw_data, start): diff --git a/cms/djangoapps/contentstore/git_export_utils.py b/cms/djangoapps/contentstore/git_export_utils.py index 07c46322dd..470d3ac27c 100644 --- a/cms/djangoapps/contentstore/git_export_utils.py +++ b/cms/djangoapps/contentstore/git_export_utils.py @@ -10,7 +10,7 @@ import subprocess import six from django.conf import settings -from django.contrib.auth.models import User +from django.contrib.auth.models import User # lint-amnesty, pylint: disable=imported-auth-user from django.utils import timezone from django.utils.translation import ugettext_lazy as _ from six.moves.urllib.parse import urlparse @@ -34,7 +34,7 @@ class GitExportError(Exception): def __init__(self, message): # Force the lazy i18n values to turn into actual unicode objects - super(GitExportError, self).__init__(six.text_type(message)) + super(GitExportError, self).__init__(six.text_type(message)) # lint-amnesty, pylint: disable=super-with-arguments NO_EXPORT_DIR = _(u"GIT_REPO_EXPORT_DIR not set or path {0} doesn't exist, " "please create it, or configure a different path with " @@ -110,7 +110,7 @@ def export_to_git(course_id, repo, user='', rdir=None): branch = cmd_log(cmd, cwd).decode('utf-8').strip('\n') except subprocess.CalledProcessError as ex: log.exception(u'Failed to get branch: %r', ex.output) - raise GitExportError(GitExportError.DETACHED_HEAD) + raise GitExportError(GitExportError.DETACHED_HEAD) # lint-amnesty, pylint: disable=raise-missing-from cmds = [ ['git', 'remote', 'set-url', 'origin', repo], @@ -129,7 +129,7 @@ def export_to_git(course_id, repo, user='', rdir=None): cmd_log(cmd, cwd) except subprocess.CalledProcessError as ex: log.exception(u'Failed to pull git repository: %r', ex.output) - raise GitExportError(GitExportError.CANNOT_PULL) + raise GitExportError(GitExportError.CANNOT_PULL) # lint-amnesty, pylint: disable=raise-missing-from # export course as xml before commiting and pushing root_dir = os.path.dirname(rdirp) @@ -139,7 +139,7 @@ def export_to_git(course_id, repo, user='', rdir=None): root_dir, course_dir) except (EnvironmentError, AttributeError): log.exception('Failed export to xml') - raise GitExportError(GitExportError.XML_EXPORT_FAIL) + raise GitExportError(GitExportError.XML_EXPORT_FAIL) # lint-amnesty, pylint: disable=raise-missing-from # Get current branch if not already set if not branch: @@ -149,7 +149,7 @@ def export_to_git(course_id, repo, user='', rdir=None): except subprocess.CalledProcessError as ex: log.exception(u'Failed to get branch from freshly cloned repo: %r', ex.output) - raise GitExportError(GitExportError.MISSING_BRANCH) + raise GitExportError(GitExportError.MISSING_BRANCH) # lint-amnesty, pylint: disable=raise-missing-from # Now that we have fresh xml exported, set identity, add # everything to git, commit, and push to the right branch. @@ -171,15 +171,15 @@ def export_to_git(course_id, repo, user='', rdir=None): cmd_log(['git', 'config', 'user.name', ident['name']], cwd) except subprocess.CalledProcessError as ex: log.exception(u'Error running git configure commands: %r', ex.output) - raise GitExportError(GitExportError.CONFIG_ERROR) + raise GitExportError(GitExportError.CONFIG_ERROR) # lint-amnesty, pylint: disable=raise-missing-from try: cmd_log(['git', 'add', '.'], cwd) cmd_log(['git', 'commit', '-a', '-m', commit_msg], cwd) except subprocess.CalledProcessError as ex: log.exception(u'Unable to commit changes: %r', ex.output) - raise GitExportError(GitExportError.CANNOT_COMMIT) + raise GitExportError(GitExportError.CANNOT_COMMIT) # lint-amnesty, pylint: disable=raise-missing-from try: cmd_log(['git', 'push', '-q', 'origin', branch], cwd) except subprocess.CalledProcessError as ex: log.exception(u'Error running git push command: %r', ex.output) - raise GitExportError(GitExportError.CANNOT_PUSH) + raise GitExportError(GitExportError.CANNOT_PUSH) # lint-amnesty, pylint: disable=raise-missing-from diff --git a/cms/djangoapps/contentstore/management/commands/cleanup_assets.py b/cms/djangoapps/contentstore/management/commands/cleanup_assets.py index b6a41587da..4809b780a9 100644 --- a/cms/djangoapps/contentstore/management/commands/cleanup_assets.py +++ b/cms/djangoapps/contentstore/management/commands/cleanup_assets.py @@ -32,8 +32,8 @@ class Command(BaseCommand): # Remove all redundant Mac OS metadata files assets_deleted = content_store.remove_redundant_content_for_courses() success = True - except Exception as err: - log.info("=" * 30 + u"> failed to cleanup") + except Exception as err: # lint-amnesty, pylint: disable=broad-except + log.info("=" * 30 + u"> failed to cleanup") # lint-amnesty, pylint: disable=logging-not-lazy log.info("Error:") log.info(err) diff --git a/cms/djangoapps/contentstore/management/commands/create_course.py b/cms/djangoapps/contentstore/management/commands/create_course.py index d48b24e858..d582de49fd 100644 --- a/cms/djangoapps/contentstore/management/commands/create_course.py +++ b/cms/djangoapps/contentstore/management/commands/create_course.py @@ -5,7 +5,7 @@ Django management command to create a course in a specific modulestore from datetime import datetime, timedelta -from django.contrib.auth.models import User +from django.contrib.auth.models import User # lint-amnesty, pylint: disable=imported-auth-user from django.core.management.base import BaseCommand, CommandError from six import text_type @@ -53,7 +53,7 @@ class Command(BaseCommand): try: user_object = user_from_str(user) except User.DoesNotExist: - raise CommandError(u"No user {user} found.".format(user=user)) + raise CommandError(u"No user {user} found.".format(user=user)) # lint-amnesty, pylint: disable=raise-missing-from return user_object def handle(self, *args, **options): diff --git a/cms/djangoapps/contentstore/management/commands/delete_course.py b/cms/djangoapps/contentstore/management/commands/delete_course.py index fe8553b679..21b63c8ae9 100644 --- a/cms/djangoapps/contentstore/management/commands/delete_course.py +++ b/cms/djangoapps/contentstore/management/commands/delete_course.py @@ -68,7 +68,7 @@ class Command(BaseCommand): course_key = text_type(options['course_key']) course_key = CourseKey.from_string(course_key) except InvalidKeyError: - raise CommandError(u'Invalid course_key: {}'.format(options['course_key'])) + raise CommandError(u'Invalid course_key: {}'.format(options['course_key'])) # lint-amnesty, pylint: disable=raise-missing-from if not modulestore().get_course(course_key): raise CommandError(u'Course not found: {}'.format(options['course_key'])) @@ -81,6 +81,6 @@ class Command(BaseCommand): if options['remove_assets']: contentstore().delete_all_course_assets(course_key) - print(u'Deleted assets for course'.format(course_key)) + print(u'Deleted assets for course'.format(course_key)) # lint-amnesty, pylint: disable=too-many-format-args print(u'Deleted course {}'.format(course_key)) diff --git a/cms/djangoapps/contentstore/management/commands/delete_orphans.py b/cms/djangoapps/contentstore/management/commands/delete_orphans.py index d52f44a6c8..61550fa22b 100644 --- a/cms/djangoapps/contentstore/management/commands/delete_orphans.py +++ b/cms/djangoapps/contentstore/management/commands/delete_orphans.py @@ -25,7 +25,7 @@ class Command(BaseCommand): try: course_key = CourseKey.from_string(options['course_id']) except InvalidKeyError: - raise CommandError("Invalid course key.") + raise CommandError("Invalid course key.") # lint-amnesty, pylint: disable=raise-missing-from if options['commit']: print('Deleting orphans from the course:') diff --git a/cms/djangoapps/contentstore/management/commands/edit_course_tabs.py b/cms/djangoapps/contentstore/management/commands/edit_course_tabs.py index f4c6ed6c9b..32a817308a 100644 --- a/cms/djangoapps/contentstore/management/commands/edit_course_tabs.py +++ b/cms/djangoapps/contentstore/management/commands/edit_course_tabs.py @@ -1,3 +1,4 @@ +# lint-amnesty, pylint: disable=missing-module-docstring ### ### Script for editing the course's tabs ### @@ -37,7 +38,7 @@ def print_course(course): # {u'type': u'progress', u'name': u'Progress'}] -class Command(BaseCommand): +class Command(BaseCommand): # lint-amnesty, pylint: disable=missing-class-docstring help = """See and edit a course's tabs list. Only supports insertion and deletion. Move and rename etc. can be done with a delete followed by an insert. The tabs are numbered starting with 1. @@ -97,4 +98,4 @@ command again, adding --insert or --delete to edit the list. tabs.primitive_insert(course, num - 1, tab_type, name) # -1 as above except ValueError as e: # Cute: translate to CommandError so the CLI error prints nicely. - raise CommandError(e) + raise CommandError(e) # lint-amnesty, pylint: disable=raise-missing-from diff --git a/cms/djangoapps/contentstore/management/commands/export.py b/cms/djangoapps/contentstore/management/commands/export.py index 99fab8105f..43b22305d7 100644 --- a/cms/djangoapps/contentstore/management/commands/export.py +++ b/cms/djangoapps/contentstore/management/commands/export.py @@ -32,7 +32,7 @@ class Command(BaseCommand): try: course_key = CourseKey.from_string(options['course_id']) except InvalidKeyError: - raise CommandError(u"Invalid course_key: '%s'." % options['course_id']) + raise CommandError(u"Invalid course_key: '%s'." % options['course_id']) # lint-amnesty, pylint: disable=raise-missing-from if not modulestore().get_course(course_key): raise CommandError(u"Course with %s key not found." % options['course_id']) diff --git a/cms/djangoapps/contentstore/management/commands/export_content_library.py b/cms/djangoapps/contentstore/management/commands/export_content_library.py index 8a9e6b82cb..810821dae1 100644 --- a/cms/djangoapps/contentstore/management/commands/export_content_library.py +++ b/cms/djangoapps/contentstore/management/commands/export_content_library.py @@ -34,7 +34,7 @@ class Command(BaseCommand): try: library_key = CourseKey.from_string(options['library_id']) except InvalidKeyError: - raise CommandError(u'Invalid library ID: "{0}".'.format(options['library_id'])) + raise CommandError(u'Invalid library ID: "{0}".'.format(options['library_id'])) # lint-amnesty, pylint: disable=raise-missing-from if not isinstance(library_key, LibraryLocator): raise CommandError(u'Argument "{0}" is not a library key'.format(options['library_id'])) @@ -50,7 +50,7 @@ class Command(BaseCommand): # Generate archive using the handy tasks implementation tarball = tasks.create_export_tarball(library, library_key, {}, None) except Exception as e: - raise CommandError(u'Failed to export "{0}" with "{1}"'.format(library_key, e)) + raise CommandError(u'Failed to export "{0}" with "{1}"'.format(library_key, e)) # lint-amnesty, pylint: disable=raise-missing-from else: with tarball: # Save generated archive with keyed filename diff --git a/cms/djangoapps/contentstore/management/commands/export_olx.py b/cms/djangoapps/contentstore/management/commands/export_olx.py index 456727f8e1..52e0c051bb 100644 --- a/cms/djangoapps/contentstore/management/commands/export_olx.py +++ b/cms/djangoapps/contentstore/management/commands/export_olx.py @@ -47,9 +47,9 @@ class Command(BaseCommand): try: course_key = CourseKey.from_string(course_id) except InvalidKeyError: - raise CommandError("Unparsable course_id") + raise CommandError("Unparsable course_id") # lint-amnesty, pylint: disable=raise-missing-from except IndexError: - raise CommandError("Insufficient arguments") + raise CommandError("Insufficient arguments") # lint-amnesty, pylint: disable=raise-missing-from filename = options['output'] pipe_results = False diff --git a/cms/djangoapps/contentstore/management/commands/force_publish.py b/cms/djangoapps/contentstore/management/commands/force_publish.py index 88931cdf98..75d841a6f0 100644 --- a/cms/djangoapps/contentstore/management/commands/force_publish.py +++ b/cms/djangoapps/contentstore/management/commands/force_publish.py @@ -36,7 +36,7 @@ class Command(BaseCommand): try: course_key = CourseKey.from_string(options['course_key']) except InvalidKeyError: - raise CommandError("Invalid course key.") + raise CommandError("Invalid course key.") # lint-amnesty, pylint: disable=raise-missing-from if not modulestore().get_course(course_key): raise CommandError("Course not found.") diff --git a/cms/djangoapps/contentstore/management/commands/generate_courses.py b/cms/djangoapps/contentstore/management/commands/generate_courses.py index 6f9e56c748..4cab7fdc39 100644 --- a/cms/djangoapps/contentstore/management/commands/generate_courses.py +++ b/cms/djangoapps/contentstore/management/commands/generate_courses.py @@ -6,7 +6,7 @@ Django management command to generate a test course from a course config json import json import logging -from django.contrib.auth.models import User +from django.contrib.auth.models import User # lint-amnesty, pylint: disable=imported-auth-user from django.core.management.base import BaseCommand, CommandError from six import text_type @@ -34,9 +34,9 @@ class Command(BaseCommand): try: courses = json.loads(options["courses_json"])["courses"] except ValueError: - raise CommandError("Invalid JSON object") + raise CommandError("Invalid JSON object") # lint-amnesty, pylint: disable=raise-missing-from except KeyError: - raise CommandError("JSON object is missing courses list") + raise CommandError("JSON object is missing courses list") # lint-amnesty, pylint: disable=raise-missing-from for course_settings in courses: # Validate course @@ -52,7 +52,7 @@ class Command(BaseCommand): try: user = user_from_str(user_email) except User.DoesNotExist: - logger.warning(user_email + " user does not exist") + logger.warning(user_email + " user does not exist") # lint-amnesty, pylint: disable=logging-not-lazy logger.warning("Can't create course, proceeding to next course") continue fields = self._process_course_fields(course_settings["fields"]) @@ -102,7 +102,7 @@ class Command(BaseCommand): if field not in all_fields: # field does not exist as a CourseField del fields[field] - logger.info(field + "is not a valid CourseField") + logger.info(field + "is not a valid CourseField") # lint-amnesty, pylint: disable=logging-not-lazy elif fields[field] is None: # field is unset del fields[field] @@ -113,7 +113,7 @@ class Command(BaseCommand): fields[field] = Date().from_json(date_json) logger.info(field + " has been set to " + date_json) except Exception: # pylint: disable=broad-except - logger.info("The date string could not be parsed for " + field) + logger.info("The date string could not be parsed for " + field) # lint-amnesty, pylint: disable=logging-not-lazy del fields[field] elif field in course_tab_list_fields: # Generate CourseTabList object from the json value @@ -122,15 +122,15 @@ class Command(BaseCommand): fields[field] = CourseTabList().from_json(course_tab_list_json) logger.info(field + " has been set to " + course_tab_list_json) except Exception: # pylint: disable=broad-except - logger.info("The course tab list string could not be parsed for " + field) + logger.info("The course tab list string could not be parsed for " + field) # lint-amnesty, pylint: disable=logging-not-lazy del fields[field] else: # CourseField is valid and has been set - logger.info(field + " has been set to " + str(fields[field])) + logger.info(field + " has been set to " + str(fields[field])) # lint-amnesty, pylint: disable=logging-not-lazy for field in all_fields: if field not in fields: - logger.info(field + " has not been set") + logger.info(field + " has not been set") # lint-amnesty, pylint: disable=logging-not-lazy return fields def _course_is_valid(self, course): @@ -147,7 +147,7 @@ class Command(BaseCommand): ] for setting in required_course_settings: if setting not in course: - logger.warning("Course json is missing " + setting) + logger.warning("Course json is missing " + setting) # lint-amnesty, pylint: disable=logging-not-lazy is_valid = False # Check fields settings @@ -157,7 +157,7 @@ class Command(BaseCommand): if "fields" in course: for setting in required_field_settings: if setting not in course["fields"]: - logger.warning("Fields json is missing " + setting) + logger.warning("Fields json is missing " + setting) # lint-amnesty, pylint: disable=logging-not-lazy is_valid = False return is_valid diff --git a/cms/djangoapps/contentstore/management/commands/git_export.py b/cms/djangoapps/contentstore/management/commands/git_export.py index 6eaf3fb8f1..1edb40a107 100644 --- a/cms/djangoapps/contentstore/management/commands/git_export.py +++ b/cms/djangoapps/contentstore/management/commands/git_export.py @@ -51,7 +51,7 @@ class Command(BaseCommand): try: course_key = CourseKey.from_string(options['course_loc']) except InvalidKeyError: - raise CommandError(text_type(git_export_utils.GitExportError.BAD_COURSE)) + raise CommandError(text_type(git_export_utils.GitExportError.BAD_COURSE)) # lint-amnesty, pylint: disable=raise-missing-from try: git_export_utils.export_to_git( @@ -61,4 +61,4 @@ class Command(BaseCommand): options.get('rdir', None) ) except git_export_utils.GitExportError as ex: - raise CommandError(text_type(ex)) + raise CommandError(text_type(ex)) # lint-amnesty, pylint: disable=raise-missing-from diff --git a/cms/djangoapps/contentstore/management/commands/import_content_library.py b/cms/djangoapps/contentstore/management/commands/import_content_library.py index 6b22340916..8892d26f25 100644 --- a/cms/djangoapps/contentstore/management/commands/import_content_library.py +++ b/cms/djangoapps/contentstore/management/commands/import_content_library.py @@ -8,7 +8,7 @@ import os import tarfile from django.conf import settings -from django.contrib.auth.models import User +from django.contrib.auth.models import User # lint-amnesty, pylint: disable=imported-auth-user from django.core.exceptions import SuspiciousOperation from django.core.management.base import BaseCommand, CommandError from lxml import etree @@ -52,7 +52,7 @@ class Command(BaseCommand): try: safetar_extractall(tar_file, course_dir.encode('utf-8')) except SuspiciousOperation as exc: - raise CommandError(u'\n=== Course import {0}: Unsafe tar file - {1}\n'.format(archive_path, exc.args[0])) + raise CommandError(u'\n=== Course import {0}: Unsafe tar file - {1}\n'.format(archive_path, exc.args[0])) # lint-amnesty, pylint: disable=raise-missing-from finally: tar_file.close() diff --git a/cms/djangoapps/contentstore/management/commands/migrate_to_split.py b/cms/djangoapps/contentstore/management/commands/migrate_to_split.py index 955819f3cd..2e3abf97cd 100644 --- a/cms/djangoapps/contentstore/management/commands/migrate_to_split.py +++ b/cms/djangoapps/contentstore/management/commands/migrate_to_split.py @@ -4,7 +4,7 @@ to the new split-Mongo modulestore. """ -from django.contrib.auth.models import User +from django.contrib.auth.models import User # lint-amnesty, pylint: disable=imported-auth-user from django.core.management.base import BaseCommand, CommandError from opaque_keys import InvalidKeyError from opaque_keys.edx.keys import CourseKey @@ -37,12 +37,12 @@ class Command(BaseCommand): try: course_key = CourseKey.from_string(options['course_key']) except InvalidKeyError: - raise CommandError("Invalid location string") + raise CommandError("Invalid location string") # lint-amnesty, pylint: disable=raise-missing-from try: user = user_from_str(options['email']) except User.DoesNotExist: - raise CommandError(u"No user found identified by {}".format(options['email'])) + raise CommandError(u"No user found identified by {}".format(options['email'])) # lint-amnesty, pylint: disable=raise-missing-from return course_key, user.id, options['org'], options['course'], options['run'] @@ -51,7 +51,7 @@ class Command(BaseCommand): migrator = SplitMigrator( source_modulestore=modulestore(), - split_modulestore=modulestore()._get_modulestore_by_type(ModuleStoreEnum.Type.split), + split_modulestore=modulestore()._get_modulestore_by_type(ModuleStoreEnum.Type.split), # lint-amnesty, pylint: disable=protected-access ) migrator.migrate_mongo_course(course_key, user, org, course, run) diff --git a/cms/djangoapps/contentstore/management/commands/reindex_course.py b/cms/djangoapps/contentstore/management/commands/reindex_course.py index c84af51ade..aa9bd8bfd2 100644 --- a/cms/djangoapps/contentstore/management/commands/reindex_course.py +++ b/cms/djangoapps/contentstore/management/commands/reindex_course.py @@ -47,7 +47,7 @@ class Command(BaseCommand): try: result = CourseKey.from_string(raw_value) except InvalidKeyError: - raise CommandError(u"Invalid course_key: '%s'." % raw_value) + raise CommandError(u"Invalid course_key: '%s'." % raw_value) # lint-amnesty, pylint: disable=raise-missing-from if not isinstance(result, CourseLocator): raise CommandError(u"Argument {0} is not a course key".format(raw_value)) @@ -64,8 +64,7 @@ class Command(BaseCommand): setup_option = options['setup'] index_all_courses_option = all_option or setup_option - if (not len(course_ids) and not index_all_courses_option) or \ - (len(course_ids) and index_all_courses_option): + if (not len(course_ids) and not index_all_courses_option) or (len(course_ids) and index_all_courses_option): # lint-amnesty, pylint: disable=len-as-condition raise CommandError("reindex_course requires one or more s OR the --all or --setup flags.") store = modulestore() @@ -103,5 +102,5 @@ class Command(BaseCommand): for course_key in course_keys: try: CoursewareSearchIndexer.do_course_reindex(store, course_key) - except Exception as exc: + except Exception as exc: # lint-amnesty, pylint: disable=broad-except logging.exception('Error indexing course %s due to the error: %s', course_key, exc) diff --git a/cms/djangoapps/contentstore/management/commands/sync_courses.py b/cms/djangoapps/contentstore/management/commands/sync_courses.py index ea48234264..68fa50010b 100644 --- a/cms/djangoapps/contentstore/management/commands/sync_courses.py +++ b/cms/djangoapps/contentstore/management/commands/sync_courses.py @@ -5,7 +5,7 @@ integration environment. import logging from textwrap import dedent -from django.contrib.auth.models import User +from django.contrib.auth.models import User # lint-amnesty, pylint: disable=imported-auth-user from django.core.management.base import BaseCommand, CommandError from opaque_keys.edx.keys import CourseKey from six import text_type @@ -37,7 +37,7 @@ class Command(BaseCommand): try: user_object = user_from_str(user) except User.DoesNotExist: - raise CommandError(u"No user {user} found.".format(user=user)) + raise CommandError(u"No user {user} found.".format(user=user)) # lint-amnesty, pylint: disable=raise-missing-from return user_object def handle(self, *args, **options): diff --git a/cms/djangoapps/contentstore/management/commands/tests/test_cleanup_assets.py b/cms/djangoapps/contentstore/management/commands/tests/test_cleanup_assets.py index 0f4441fbcb..3086fa68fd 100644 --- a/cms/djangoapps/contentstore/management/commands/tests/test_cleanup_assets.py +++ b/cms/djangoapps/contentstore/management/commands/tests/test_cleanup_assets.py @@ -28,7 +28,7 @@ class ExportAllCourses(ModuleStoreTestCase): def setUp(self): """ Common setup. """ - super(ExportAllCourses, self).setUp() + super(ExportAllCourses, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.content_store = contentstore() # pylint: disable=protected-access self.module_store = modulestore()._get_modulestore_by_type(ModuleStoreEnum.Type.mongo) @@ -56,7 +56,7 @@ class ExportAllCourses(ModuleStoreTestCase): # check that there are two assets ['example.txt', '.example.txt'] in contentstore for imported course all_assets, count = self.content_store.get_all_content_for_course(course.id) self.assertEqual(count, 2) - self.assertEqual(set([asset['_id']['name'] for asset in all_assets]), set([u'.example.txt', u'example.txt'])) + self.assertEqual(set([asset['_id']['name'] for asset in all_assets]), set([u'.example.txt', u'example.txt'])) # lint-amnesty, pylint: disable=consider-using-set-comprehension # manually add redundant assets (file ".DS_Store" and filename starts with "._") course_filter = course.id.make_asset_key("asset", None) @@ -72,11 +72,11 @@ class ExportAllCourses(ModuleStoreTestCase): all_assets, count = self.content_store.get_all_content_for_course(course.id) self.assertEqual(count, 4) self.assertEqual( - set([asset['_id']['name'] for asset in all_assets]), + set([asset['_id']['name'] for asset in all_assets]), # lint-amnesty, pylint: disable=consider-using-set-comprehension set([u'.example.txt', u'example.txt', u'._example_test.txt', u'.DS_Store']) ) # now call asset_cleanup command and check that there is only two proper assets in contentstore for the course call_command('cleanup_assets') all_assets, count = self.content_store.get_all_content_for_course(course.id) self.assertEqual(count, 2) - self.assertEqual(set([asset['_id']['name'] for asset in all_assets]), set([u'.example.txt', u'example.txt'])) + self.assertEqual(set([asset['_id']['name'] for asset in all_assets]), set([u'.example.txt', u'example.txt'])) # lint-amnesty, pylint: disable=consider-using-set-comprehension diff --git a/cms/djangoapps/contentstore/management/commands/tests/test_create_course.py b/cms/djangoapps/contentstore/management/commands/tests/test_create_course.py index b0a6407575..7f57119a43 100644 --- a/cms/djangoapps/contentstore/management/commands/tests/test_create_course.py +++ b/cms/djangoapps/contentstore/management/commands/tests/test_create_course.py @@ -18,8 +18,8 @@ class TestArgParsing(TestCase): """ Tests for parsing arguments for the `create_course` management command """ - def setUp(self): - super(TestArgParsing, self).setUp() + def setUp(self): # lint-amnesty, pylint: disable=useless-super-delegation + super(TestArgParsing, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments def test_no_args(self): if six.PY2: diff --git a/cms/djangoapps/contentstore/management/commands/tests/test_export.py b/cms/djangoapps/contentstore/management/commands/tests/test_export.py index e5127f34e4..0967c71f8f 100644 --- a/cms/djangoapps/contentstore/management/commands/tests/test_export.py +++ b/cms/djangoapps/contentstore/management/commands/tests/test_export.py @@ -39,7 +39,7 @@ class TestCourseExport(ModuleStoreTestCase): Test exporting a course """ def setUp(self): - super(TestCourseExport, self).setUp() + super(TestCourseExport, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments # Temp directories (temp_dir_1: relative path, temp_dir_2: absolute path) self.temp_dir_1 = mkdtemp() diff --git a/cms/djangoapps/contentstore/management/commands/tests/test_export_all_courses.py b/cms/djangoapps/contentstore/management/commands/tests/test_export_all_courses.py index 60ec6f9b0d..29655df100 100644 --- a/cms/djangoapps/contentstore/management/commands/tests/test_export_all_courses.py +++ b/cms/djangoapps/contentstore/management/commands/tests/test_export_all_courses.py @@ -21,8 +21,8 @@ class ExportAllCourses(ModuleStoreTestCase): """ def setUp(self): """ Common setup. """ - super(ExportAllCourses, self).setUp() - self.store = modulestore()._get_modulestore_by_type(ModuleStoreEnum.Type.mongo) + super(ExportAllCourses, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments + self.store = modulestore()._get_modulestore_by_type(ModuleStoreEnum.Type.mongo) # lint-amnesty, pylint: disable=protected-access self.temp_dir = mkdtemp() self.addCleanup(shutil.rmtree, self.temp_dir) self.first_course = CourseFactory.create( diff --git a/cms/djangoapps/contentstore/management/commands/tests/test_force_publish.py b/cms/djangoapps/contentstore/management/commands/tests/test_force_publish.py index 8401d8bdca..423be9d53e 100644 --- a/cms/djangoapps/contentstore/management/commands/tests/test_force_publish.py +++ b/cms/djangoapps/contentstore/management/commands/tests/test_force_publish.py @@ -78,7 +78,7 @@ class TestForcePublishModifications(ModuleStoreTestCase): """ def setUp(self): - super(TestForcePublishModifications, self).setUp() + super(TestForcePublishModifications, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.course = CourseFactory.create(default_store=ModuleStoreEnum.Type.split) self.test_user_id = ModuleStoreEnum.UserID.test self.command = Command() diff --git a/cms/djangoapps/contentstore/management/commands/tests/test_git_export.py b/cms/djangoapps/contentstore/management/commands/tests/test_git_export.py index 79c74d3ee6..01564d5042 100644 --- a/cms/djangoapps/contentstore/management/commands/tests/test_git_export.py +++ b/cms/djangoapps/contentstore/management/commands/tests/test_git_export.py @@ -39,7 +39,7 @@ class TestGitExport(CourseTestCase): """ Create/reinitialize bare repo and folders needed """ - super(TestGitExport, self).setUp() + super(TestGitExport, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments if not os.path.isdir(git_export_utils.GIT_REPO_EXPORT_DIR): os.mkdir(git_export_utils.GIT_REPO_EXPORT_DIR) diff --git a/cms/djangoapps/contentstore/management/commands/tests/test_import.py b/cms/djangoapps/contentstore/management/commands/tests/test_import.py index 1d2263c3f4..65e73d537c 100644 --- a/cms/djangoapps/contentstore/management/commands/tests/test_import.py +++ b/cms/djangoapps/contentstore/management/commands/tests/test_import.py @@ -22,7 +22,7 @@ class TestImport(ModuleStoreTestCase): Unit tests for importing a course from command line """ - def create_course_xml(self, content_dir, course_id): + def create_course_xml(self, content_dir, course_id): # lint-amnesty, pylint: disable=missing-function-docstring directory = tempfile.mkdtemp(dir=content_dir) os.makedirs(os.path.join(directory, "course")) with open(os.path.join(directory, "course.xml"), "w+") as f: @@ -37,7 +37,7 @@ class TestImport(ModuleStoreTestCase): """ Build course XML for importing """ - super(TestImport, self).setUp() + super(TestImport, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.content_dir = path(tempfile.mkdtemp()) self.addCleanup(shutil.rmtree, self.content_dir) diff --git a/cms/djangoapps/contentstore/management/commands/tests/test_migrate_to_split.py b/cms/djangoapps/contentstore/management/commands/tests/test_migrate_to_split.py index 85bdc670f5..63f2b54cb6 100644 --- a/cms/djangoapps/contentstore/management/commands/tests/test_migrate_to_split.py +++ b/cms/djangoapps/contentstore/management/commands/tests/test_migrate_to_split.py @@ -18,8 +18,8 @@ class TestArgParsing(TestCase): """ Tests for parsing arguments for the `migrate_to_split` management command """ - def setUp(self): - super(TestArgParsing, self).setUp() + def setUp(self): # lint-amnesty, pylint: disable=useless-super-delegation + super(TestArgParsing, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments def test_no_args(self): """ @@ -64,7 +64,7 @@ class TestMigrateToSplit(ModuleStoreTestCase): """ def setUp(self): - super(TestMigrateToSplit, self).setUp() + super(TestMigrateToSplit, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.course = CourseFactory(default_store=ModuleStoreEnum.Type.mongo) def test_user_email(self): @@ -73,11 +73,11 @@ class TestMigrateToSplit(ModuleStoreTestCase): """ call_command( "migrate_to_split", - str(self.course.id), + str(self.course.id), # lint-amnesty, pylint: disable=no-member str(self.user.email), ) split_store = modulestore()._get_modulestore_by_type(ModuleStoreEnum.Type.split) - new_key = split_store.make_course_key(self.course.id.org, self.course.id.course, self.course.id.run) + new_key = split_store.make_course_key(self.course.id.org, self.course.id.course, self.course.id.run) # lint-amnesty, pylint: disable=no-member self.assertTrue( split_store.has_course(new_key), "Could not find course" @@ -90,7 +90,7 @@ class TestMigrateToSplit(ModuleStoreTestCase): # lack of error implies success call_command( "migrate_to_split", - str(self.course.id), + str(self.course.id), # lint-amnesty, pylint: disable=no-member str(self.user.id), ) @@ -100,7 +100,7 @@ class TestMigrateToSplit(ModuleStoreTestCase): """ call_command( "migrate_to_split", - str(self.course.id), + str(self.course.id), # lint-amnesty, pylint: disable=no-member str(self.user.id), org="org.dept", course="name", @@ -113,11 +113,11 @@ class TestMigrateToSplit(ModuleStoreTestCase): # Getting the original course with mongo course_id mongo_store = modulestore()._get_modulestore_by_type(ModuleStoreEnum.Type.mongo) - mongo_locator = mongo_store.make_course_key(self.course.id.org, self.course.id.course, self.course.id.run) + mongo_locator = mongo_store.make_course_key(self.course.id.org, self.course.id.course, self.course.id.run) # lint-amnesty, pylint: disable=no-member course_from_mongo = mongo_store.get_course(mongo_locator) self.assertIsNotNone(course_from_mongo) # Throws ItemNotFoundError when try to access original course with split course_id - split_locator = split_store.make_course_key(self.course.id.org, self.course.id.course, self.course.id.run) + split_locator = split_store.make_course_key(self.course.id.org, self.course.id.course, self.course.id.run) # lint-amnesty, pylint: disable=no-member with self.assertRaises(ItemNotFoundError): mongo_store.get_course(split_locator) diff --git a/cms/djangoapps/contentstore/management/commands/tests/test_reindex_courses.py b/cms/djangoapps/contentstore/management/commands/tests/test_reindex_courses.py index 7f8a7a860d..539b676960 100644 --- a/cms/djangoapps/contentstore/management/commands/tests/test_reindex_courses.py +++ b/cms/djangoapps/contentstore/management/commands/tests/test_reindex_courses.py @@ -7,7 +7,7 @@ import six from django.core.management import CommandError, call_command from six import text_type -from cms.djangoapps.contentstore.courseware_index import SearchIndexingError +from cms.djangoapps.contentstore.courseware_index import SearchIndexingError # lint-amnesty, pylint: disable=unused-import from cms.djangoapps.contentstore.management.commands.reindex_course import Command as ReindexCommand from xmodule.modulestore import ModuleStoreEnum from xmodule.modulestore.django import modulestore @@ -20,7 +20,7 @@ class TestReindexCourse(ModuleStoreTestCase): """ Tests for course reindex command """ def setUp(self): """ Setup method - create courses """ - super(TestReindexCourse, self).setUp() + super(TestReindexCourse, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.store = modulestore() self.first_lib = LibraryFactory.create( org="test", library="lib1", display_name="run1", default_store=ModuleStoreEnum.Type.split diff --git a/cms/djangoapps/contentstore/management/commands/tests/test_reindex_library.py b/cms/djangoapps/contentstore/management/commands/tests/test_reindex_library.py index 7397872ac5..3e540c8501 100644 --- a/cms/djangoapps/contentstore/management/commands/tests/test_reindex_library.py +++ b/cms/djangoapps/contentstore/management/commands/tests/test_reindex_library.py @@ -20,7 +20,7 @@ class TestReindexLibrary(ModuleStoreTestCase): """ Tests for library reindex command """ def setUp(self): """ Setup method - create libraries and courses """ - super(TestReindexLibrary, self).setUp() + super(TestReindexLibrary, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.store = modulestore() self.first_lib = LibraryFactory.create( org="test", library="lib1", display_name="run1", default_store=ModuleStoreEnum.Type.split diff --git a/cms/djangoapps/contentstore/management/commands/tests/test_sync_courses.py b/cms/djangoapps/contentstore/management/commands/tests/test_sync_courses.py index 276f858a53..e181fc17e2 100644 --- a/cms/djangoapps/contentstore/management/commands/tests/test_sync_courses.py +++ b/cms/djangoapps/contentstore/management/commands/tests/test_sync_courses.py @@ -22,7 +22,7 @@ class TestSyncCoursesCommand(ModuleStoreTestCase): """ Test sync_courses command """ def setUp(self): - super(TestSyncCoursesCommand, self).setUp() + super(TestSyncCoursesCommand, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.user = UserFactory(username='test', email='test@example.com') self.catalog_course_runs = [ @@ -32,9 +32,9 @@ class TestSyncCoursesCommand(ModuleStoreTestCase): def _validate_courses(self): for run in self.catalog_course_runs: - course_key = CourseKey.from_string(run.get('key')) + course_key = CourseKey.from_string(run.get('key')) # lint-amnesty, pylint: disable=no-member self.assertTrue(modulestore().has_course(course_key)) - CourseOverview.objects.get(id=run.get('key')) + CourseOverview.objects.get(id=run.get('key')) # lint-amnesty, pylint: disable=no-member def test_courses_sync(self, mock_catalog_course_runs): mock_catalog_course_runs.return_value = self.catalog_course_runs diff --git a/cms/djangoapps/contentstore/management/commands/utils.py b/cms/djangoapps/contentstore/management/commands/utils.py index d970d23e6d..be697e0306 100644 --- a/cms/djangoapps/contentstore/management/commands/utils.py +++ b/cms/djangoapps/contentstore/management/commands/utils.py @@ -3,7 +3,7 @@ Common methods for cms commands to use """ -from django.contrib.auth.models import User +from django.contrib.auth.models import User # lint-amnesty, pylint: disable=imported-auth-user from opaque_keys.edx.keys import CourseKey from xmodule.modulestore.django import modulestore diff --git a/cms/djangoapps/contentstore/proctoring.py b/cms/djangoapps/contentstore/proctoring.py index 42e8250956..fc9ea55c97 100644 --- a/cms/djangoapps/contentstore/proctoring.py +++ b/cms/djangoapps/contentstore/proctoring.py @@ -39,7 +39,7 @@ def register_special_exams(course_key): course = modulestore().get_course(course_key) if course is None: - raise ItemNotFoundError(u"Course {} does not exist", six.text_type(course_key)) + raise ItemNotFoundError(u"Course {} does not exist", six.text_type(course_key)) # lint-amnesty, pylint: disable=raising-format-tuple if not course.enable_proctored_exams and not course.enable_timed_exams: # likewise if course does not have these features turned on diff --git a/cms/djangoapps/contentstore/signals/handlers.py b/cms/djangoapps/contentstore/signals/handlers.py index baadf49a02..69c1421df3 100644 --- a/cms/djangoapps/contentstore/signals/handlers.py +++ b/cms/djangoapps/contentstore/signals/handlers.py @@ -30,7 +30,7 @@ log = logging.getLogger(__name__) GRADING_POLICY_COUNTDOWN_SECONDS = 3600 -def locked(expiry_seconds, key): +def locked(expiry_seconds, key): # lint-amnesty, pylint: disable=missing-function-docstring def task_decorator(func): @wraps(func) def wrapper(*args, **kwargs): diff --git a/cms/djangoapps/contentstore/storage.py b/cms/djangoapps/contentstore/storage.py index e8aed444e1..0757676676 100644 --- a/cms/djangoapps/contentstore/storage.py +++ b/cms/djangoapps/contentstore/storage.py @@ -16,7 +16,7 @@ class ImportExportS3Storage(S3BotoStorage): # pylint: disable=abstract-method def __init__(self): bucket = setting('COURSE_IMPORT_EXPORT_BUCKET', settings.AWS_STORAGE_BUCKET_NAME) - super(ImportExportS3Storage, self).__init__(bucket=bucket, custom_domain=None, querystring_auth=True) + super(ImportExportS3Storage, self).__init__(bucket=bucket, custom_domain=None, querystring_auth=True) # lint-amnesty, pylint: disable=super-with-arguments # pylint: disable=invalid-name course_import_export_storage = get_storage_class(settings.COURSE_IMPORT_EXPORT_STORAGE)() diff --git a/cms/djangoapps/contentstore/tasks.py b/cms/djangoapps/contentstore/tasks.py index 90935463a5..2768a80525 100644 --- a/cms/djangoapps/contentstore/tasks.py +++ b/cms/djangoapps/contentstore/tasks.py @@ -16,7 +16,7 @@ from celery import shared_task from celery.utils.log import get_task_logger from django.conf import settings from django.contrib.auth import get_user_model -from django.contrib.auth.models import User +from django.contrib.auth.models import User # lint-amnesty, pylint: disable=imported-auth-user from django.core.exceptions import SuspiciousOperation from django.core.files import File from django.test import RequestFactory @@ -384,7 +384,7 @@ class CourseImportTask(UserTask): # pylint: disable=abstract-method @shared_task(base=CourseImportTask, bind=True) -# Note: The decorator @set_code_owner_attribute could not be used because +# Note: The decorator @set_code_owner_attribute could not be used because # lint-amnesty, pylint: disable=too-many-statements # the implementation of this task breaks with any additional decorators. def import_olx(self, user_id, course_key_string, archive_path, archive_name, language): """ diff --git a/cms/djangoapps/contentstore/tests/test_clone_course.py b/cms/djangoapps/contentstore/tests/test_clone_course.py index d37ddb6823..120944d63a 100644 --- a/cms/djangoapps/contentstore/tests/test_clone_course.py +++ b/cms/djangoapps/contentstore/tests/test_clone_course.py @@ -79,7 +79,7 @@ class CloneCourseTest(CourseTestCase): # Get & verify all assets of the course assets, count = contentstore().get_all_content_for_course(course.id) self.assertEqual(count, 1) - self.assertEqual(set([asset['asset_key'].block_id for asset in assets]), course_assets) + self.assertEqual(set([asset['asset_key'].block_id for asset in assets]), course_assets) # lint-amnesty, pylint: disable=consider-using-set-comprehension # rerun from split into split split_rerun_id = CourseLocator(org=org, course=course_number, run="2012_Q2") @@ -126,7 +126,7 @@ class CloneCourseTest(CourseTestCase): ) # try to hit the generic exception catch - with patch('xmodule.modulestore.split_mongo.mongo_connection.MongoConnection.insert_course_index', Mock(side_effect=Exception)): + with patch('xmodule.modulestore.split_mongo.mongo_connection.MongoConnection.insert_course_index', Mock(side_effect=Exception)): # lint-amnesty, pylint: disable=line-too-long split_course4_id = CourseLocator(org="edx3", course="split3", run="rerun_fail") fields = {'display_name': 'total failure'} CourseRerunState.objects.initiated(split_course3_id, split_course4_id, self.user, fields['display_name']) diff --git a/cms/djangoapps/contentstore/tests/test_contentstore.py b/cms/djangoapps/contentstore/tests/test_contentstore.py index f8fadc33c5..33aee44986 100644 --- a/cms/djangoapps/contentstore/tests/test_contentstore.py +++ b/cms/djangoapps/contentstore/tests/test_contentstore.py @@ -1,4 +1,4 @@ -# -*- coding: utf-8 -*- +# lint-amnesty, pylint: disable=missing-module-docstring import copy @@ -15,8 +15,8 @@ import lxml.html import mock import six from django.conf import settings -from django.contrib.auth.models import User -from django.middleware.csrf import _compare_salted_tokens +from django.contrib.auth.models import User # lint-amnesty, pylint: disable=imported-auth-user +from django.middleware.csrf import _compare_salted_tokens # lint-amnesty, pylint: disable=unused-import from django.test import TestCase from django.test.utils import override_settings from edxval.api import create_video, get_videos_for_course @@ -76,7 +76,7 @@ def requires_pillow_jpeg(func): try: from PIL import Image except ImportError: - raise SkipTest("Pillow is not installed (or not found)") + raise SkipTest("Pillow is not installed (or not found)") # lint-amnesty, pylint: disable=raise-missing-from if not getattr(Image.core, "jpeg_decoder", False): raise SkipTest("Pillow cannot open JPEG files") return func(*args, **kwargs) @@ -297,7 +297,7 @@ class ImportRequiredTestCases(ContentStoreTestCase): html_module = self.store.get_item(html_module_location) self.assertIn('/jump_to_id/nonportable_link', html_module.data) - def verify_content_existence(self, store, root_dir, course_id, dirname, category_name, filename_suffix=''): + def verify_content_existence(self, store, root_dir, course_id, dirname, category_name, filename_suffix=''): # lint-amnesty, pylint: disable=missing-function-docstring filesystem = OSFS(root_dir / 'test_export') self.assertTrue(filesystem.exists(dirname)) @@ -614,7 +614,7 @@ class MiscCourseTests(ContentStoreTestCase): """ def setUp(self): - super(MiscCourseTests, self).setUp() + super(MiscCourseTests, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments # save locs not items b/c the items won't have the subsequently created children in them until refetched self.chapter_loc = self.store.create_child( self.user.id, self.course.location, 'chapter', 'test_chapter' @@ -802,7 +802,7 @@ class MiscCourseTests(ContentStoreTestCase): """Verifies rendering the editor in all the verticals in the given test course""" self._check_verticals([self.vert_loc]) - def _get_draft_counts(self, item): + def _get_draft_counts(self, item): # lint-amnesty, pylint: disable=missing-function-docstring cnt = 1 if getattr(item, 'is_draft', False) else 0 for child in item.get_children(): cnt = cnt + self._get_draft_counts(child) @@ -1161,7 +1161,7 @@ class ContentStoreTest(ContentStoreTestCase): "Please change either organization or course number to be unique.") def setUp(self): - super(ContentStoreTest, self).setUp() + super(ContentStoreTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.course_data = { 'org': 'MITx', @@ -1494,7 +1494,7 @@ class ContentStoreTest(ContentStoreTestCase): resp = self._show_course_overview(course.id) self.assertContains( resp, - '
'.format( + '
'.format( # lint-amnesty, pylint: disable=line-too-long locator=text_type(course.location), course_key=text_type(course.id), ), @@ -1536,7 +1536,7 @@ class ContentStoreTest(ContentStoreTestCase): self.assertIsInstance(problem, ProblemBlock, "New problem is not a ProblemBlock") context = problem.get_context() self.assertIn('markdown', context, "markdown is missing from context") - self.assertNotIn('markdown', problem.editable_metadata_fields, "Markdown slipped into the editable metadata fields") + self.assertNotIn('markdown', problem.editable_metadata_fields, "Markdown slipped into the editable metadata fields") # lint-amnesty, pylint: disable=line-too-long def test_cms_imported_course_walkthrough(self): """ @@ -1806,7 +1806,7 @@ class MetadataSaveTestCase(ContentStoreTestCase): """Test that metadata is correctly cached and decached.""" def setUp(self): - super(MetadataSaveTestCase, self).setUp() + super(MetadataSaveTestCase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments course = CourseFactory.create() @@ -1866,7 +1866,7 @@ class RerunCourseTest(ContentStoreTestCase): """ def setUp(self): - super(RerunCourseTest, self).setUp() + super(RerunCourseTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.destination_course_data = { 'org': 'MITx', 'number': '111', @@ -2174,7 +2174,7 @@ class EntryPageTestCase(TestCase): """ def setUp(self): - super(EntryPageTestCase, self).setUp() + super(EntryPageTestCase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.client = AjaxEnabledTestClient() def _test_page(self, page, status_code=200): diff --git a/cms/djangoapps/contentstore/tests/test_course_create_rerun.py b/cms/djangoapps/contentstore/tests/test_course_create_rerun.py index 391815f278..4961e010ce 100644 --- a/cms/djangoapps/contentstore/tests/test_course_create_rerun.py +++ b/cms/djangoapps/contentstore/tests/test_course_create_rerun.py @@ -37,7 +37,7 @@ class TestCourseListing(ModuleStoreTestCase): """ Add a user and a course """ - super(TestCourseListing, self).setUp() + super(TestCourseListing, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments # create and log in a staff user. # create and log in a non-staff user self.user = UserFactory() diff --git a/cms/djangoapps/contentstore/tests/test_course_listing.py b/cms/djangoapps/contentstore/tests/test_course_listing.py index e80e506404..0502bf9201 100644 --- a/cms/djangoapps/contentstore/tests/test_course_listing.py +++ b/cms/djangoapps/contentstore/tests/test_course_listing.py @@ -51,7 +51,7 @@ class TestCourseListing(ModuleStoreTestCase): """ Add a user and a course """ - super(TestCourseListing, self).setUp() + super(TestCourseListing, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments # create and log in a staff user. # create and log in a non-staff user self.user = UserFactory() diff --git a/cms/djangoapps/contentstore/tests/test_course_settings.py b/cms/djangoapps/contentstore/tests/test_course_settings.py index deaab43e11..0d52d95d1a 100644 --- a/cms/djangoapps/contentstore/tests/test_course_settings.py +++ b/cms/djangoapps/contentstore/tests/test_course_settings.py @@ -100,7 +100,7 @@ class CourseAdvanceSettingViewTest(CourseTestCase, MilestonesTestCaseMixin): """ def setUp(self): - super(CourseAdvanceSettingViewTest, self).setUp() + super(CourseAdvanceSettingViewTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.fullcourse = CourseFactory.create() self.course_setting_url = get_url(self.course.id, 'advanced_settings_handler') @@ -916,7 +916,7 @@ class CourseMetadataEditingTest(CourseTestCase): """ def setUp(self): - super(CourseMetadataEditingTest, self).setUp() + super(CourseMetadataEditingTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.fullcourse = CourseFactory.create() self.course_setting_url = get_url(self.course.id, 'advanced_settings_handler') self.fullcourse_setting_url = get_url(self.fullcourse.id, 'advanced_settings_handler') @@ -1175,7 +1175,7 @@ class CourseMetadataEditingTest(CourseTestCase): self.assertEqual(len(errors), 3) self.assertFalse(test_model) - error_keys = set([error_obj['model']['display_name'] for error_obj in errors]) + error_keys = set([error_obj['model']['display_name'] for error_obj in errors]) # lint-amnesty, pylint: disable=consider-using-set-comprehension test_keys = set(['Advanced Module List', 'Course Advertised Start Date', 'Days Early for Beta Users']) self.assertEqual(error_keys, test_keys) @@ -1527,7 +1527,7 @@ class CourseGraderUpdatesTest(CourseTestCase): def setUp(self): """Compute the url to use in tests""" - super(CourseGraderUpdatesTest, self).setUp() + super(CourseGraderUpdatesTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.url = get_url(self.course.id, 'grading_handler') self.starting_graders = CourseGradingModel(self.course).graders @@ -1625,7 +1625,7 @@ id=\"course-enrollment-end-time\" value=\"\" placeholder=\"HH:MM\" autocomplete= """ Initialize course used to test enrollment fields. """ - super(CourseEnrollmentEndFieldTest, self).setUp() + super(CourseEnrollmentEndFieldTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.course = CourseFactory.create(org='edX', number='dummy', display_name='Marketing Site Course') self.course_details_url = reverse_course_url('settings_handler', six.text_type(self.course.id)) diff --git a/cms/djangoapps/contentstore/tests/test_courseware_index.py b/cms/djangoapps/contentstore/tests/test_courseware_index.py index 5c54f70952..5c175d1ab8 100644 --- a/cms/djangoapps/contentstore/tests/test_courseware_index.py +++ b/cms/djangoapps/contentstore/tests/test_courseware_index.py @@ -18,7 +18,7 @@ from mock import patch from pytz import UTC from search.search_engine_base import SearchEngine from six.moves import range -from xblock.core import XBlock +from xblock.core import XBlock # lint-amnesty, pylint: disable=unused-import from cms.djangoapps.contentstore.courseware_index import ( CourseAboutSearchIndexer, @@ -71,7 +71,7 @@ def create_children(store, parent, category, load_factor): child_object = ItemFactory.create( parent_location=parent.location, category=category, - display_name=u"{} {} {}".format(category, child_index, time.clock()), + display_name=u"{} {} {}".format(category, child_index, time.clock()), # lint-amnesty, pylint: disable=no-member modulestore=store, publish_item=True, start=datetime(2015, 3, 1, tzinfo=UTC), @@ -140,7 +140,7 @@ class MixedWithOptionsTestCase(MixedSplitTestCase): def setup_course_base(self, store): """ base version of setup_course_base is a no-op """ - pass + pass # lint-amnesty, pylint: disable=unnecessary-pass @lazy def searcher(self): @@ -195,7 +195,7 @@ class TestCoursewareSearchIndexer(MixedWithOptionsTestCase): WORKS_WITH_STORES = (ModuleStoreEnum.Type.mongo, ModuleStoreEnum.Type.split) def setUp(self): - super(TestCoursewareSearchIndexer, self).setUp() + super(TestCoursewareSearchIndexer, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.course = None self.chapter = None @@ -605,11 +605,11 @@ class TestLargeCourseDeletions(MixedWithOptionsTestCase): self.course_id = None def setUp(self): - super(TestLargeCourseDeletions, self).setUp() + super(TestLargeCourseDeletions, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.course_id = None def tearDown(self): - super(TestLargeCourseDeletions, self).tearDown() + super(TestLargeCourseDeletions, self).tearDown() # lint-amnesty, pylint: disable=super-with-arguments self._clean_course_id() def assert_search_count(self, expected_count): @@ -787,7 +787,7 @@ class TestLibrarySearchIndexer(MixedWithOptionsTestCase): WORKS_WITH_STORES = (ModuleStoreEnum.Type.split, ) def setUp(self): - super(TestLibrarySearchIndexer, self).setUp() + super(TestLibrarySearchIndexer, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.library = None self.html_unit1 = None @@ -937,7 +937,7 @@ class GroupConfigurationSearchMongo(CourseTestCase, MixedWithOptionsTestCase): INDEX_NAME = CoursewareSearchIndexer.INDEX_NAME def setUp(self): - super(GroupConfigurationSearchMongo, self).setUp() + super(GroupConfigurationSearchMongo, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self._setup_course_with_content() self._setup_split_test_module() @@ -1427,7 +1427,7 @@ class GroupConfigurationSearchMongo(CourseTestCase, MixedWithOptionsTestCase): mock_index.reset_mock() -class GroupConfigurationSearchSplit(GroupConfigurationSearchMongo): +class GroupConfigurationSearchSplit(GroupConfigurationSearchMongo): # lint-amnesty, pylint: disable=test-inherits-tests """ Tests indexing of content groups on course modules using split modulestore. """ diff --git a/cms/djangoapps/contentstore/tests/test_export_git.py b/cms/djangoapps/contentstore/tests/test_export_git.py index 147ff63a25..bfbd98d3f2 100644 --- a/cms/djangoapps/contentstore/tests/test_export_git.py +++ b/cms/djangoapps/contentstore/tests/test_export_git.py @@ -32,7 +32,7 @@ class TestExportGit(CourseTestCase): """ Setup test course, user, and url. """ - super(TestExportGit, self).setUp() + super(TestExportGit, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.course_module = modulestore().get_course(self.course.id) self.test_url = reverse_course_url('export_git', self.course.id) diff --git a/cms/djangoapps/contentstore/tests/test_gating.py b/cms/djangoapps/contentstore/tests/test_gating.py index 70be15a98a..7ed635f732 100644 --- a/cms/djangoapps/contentstore/tests/test_gating.py +++ b/cms/djangoapps/contentstore/tests/test_gating.py @@ -22,7 +22,7 @@ class TestHandleItemDeleted(ModuleStoreTestCase, MilestonesTestCaseMixin): """ Initial data setup """ - super(TestHandleItemDeleted, self).setUp() + super(TestHandleItemDeleted, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.course = CourseFactory.create() self.course.enable_subsection_gating = True diff --git a/cms/djangoapps/contentstore/tests/test_i18n.py b/cms/djangoapps/contentstore/tests/test_i18n.py index 69963c5903..8d0344143f 100644 --- a/cms/djangoapps/contentstore/tests/test_i18n.py +++ b/cms/djangoapps/contentstore/tests/test_i18n.py @@ -8,7 +8,7 @@ import gettext from unittest import skip import mock -from django.contrib.auth.models import User +from django.contrib.auth.models import User # lint-amnesty, pylint: disable=imported-auth-user from django.utils import translation from django.utils.translation import get_language @@ -62,7 +62,7 @@ class TestModuleI18nService(ModuleStoreTestCase): def setUp(self): """ Setting up tests """ - super(TestModuleI18nService, self).setUp() + super(TestModuleI18nService, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.test_language = 'dummy language' self.request = mock.Mock() self.course = CourseFactory.create() @@ -187,7 +187,7 @@ class InternationalizationTest(ModuleStoreTestCase): will be cleared out before each test case execution and deleted afterwards. """ - super(InternationalizationTest, self).setUp() + super(InternationalizationTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.uname = 'testuser' self.email = 'test+courses@edx.org' @@ -211,7 +211,7 @@ class InternationalizationTest(ModuleStoreTestCase): def test_course_plain_english(self): """Test viewing the index page with no courses""" - self.client = AjaxEnabledTestClient() + self.client = AjaxEnabledTestClient() # lint-amnesty, pylint: disable=attribute-defined-outside-init self.client.login(username=self.uname, password=self.password) resp = self.client.get_html('/home/') @@ -222,7 +222,7 @@ class InternationalizationTest(ModuleStoreTestCase): def test_course_explicit_english(self): """Test viewing the index page with no courses""" - self.client = AjaxEnabledTestClient() + self.client = AjaxEnabledTestClient() # lint-amnesty, pylint: disable=attribute-defined-outside-init self.client.login(username=self.uname, password=self.password) resp = self.client.get_html( @@ -247,7 +247,7 @@ class InternationalizationTest(ModuleStoreTestCase): @skip def test_course_with_accents(self): """Test viewing the index page with no courses""" - self.client = AjaxEnabledTestClient() + self.client = AjaxEnabledTestClient() # lint-amnesty, pylint: disable=attribute-defined-outside-init self.client.login(username=self.uname, password=self.password) resp = self.client.get_html( diff --git a/cms/djangoapps/contentstore/tests/test_import.py b/cms/djangoapps/contentstore/tests/test_import.py index 2e808ccfcb..61b8854f23 100644 --- a/cms/djangoapps/contentstore/tests/test_import.py +++ b/cms/djangoapps/contentstore/tests/test_import.py @@ -37,7 +37,7 @@ class ContentStoreImportTest(ModuleStoreTestCase): NOTE: refactor using CourseFactory so they do not. """ def setUp(self): - super(ContentStoreImportTest, self).setUp() + super(ContentStoreImportTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.client = Client() self.client.login(username=self.user.username, password=self.user_password) @@ -48,7 +48,7 @@ class ContentStoreImportTest(ModuleStoreTestCase): def tearDown(self): self.task_patcher.stop() - super(ContentStoreImportTest, self).tearDown() + super(ContentStoreImportTest, self).tearDown() # lint-amnesty, pylint: disable=super-with-arguments def load_test_import_course(self, target_id=None, create_if_not_present=True, module_store=None): ''' @@ -252,7 +252,7 @@ class ContentStoreImportTest(ModuleStoreTestCase): {"0": '9f0941d021414798836ef140fb5f6841', "1": '0faf29473cf1497baa33fcc828b179cd'}, ) - def _verify_split_test_import(self, target_course_name, source_course_name, split_test_name, groups_to_verticals): + def _verify_split_test_import(self, target_course_name, source_course_name, split_test_name, groups_to_verticals): # lint-amnesty, pylint: disable=missing-function-docstring module_store = modulestore() target_id = module_store.make_course_key('testX', target_course_name, 'copy_run') import_course_from_xml( diff --git a/cms/djangoapps/contentstore/tests/test_import_draft_order.py b/cms/djangoapps/contentstore/tests/test_import_draft_order.py index 95764ab9b2..f87efc043f 100644 --- a/cms/djangoapps/contentstore/tests/test_import_draft_order.py +++ b/cms/djangoapps/contentstore/tests/test_import_draft_order.py @@ -14,7 +14,7 @@ TEST_DATA_DIR = settings.COMMON_TEST_DATA_ROOT # This test is in the CMS module because the test configuration to use a draft # modulestore is dependent on django. -class DraftReorderTestCase(ModuleStoreTestCase): +class DraftReorderTestCase(ModuleStoreTestCase): # lint-amnesty, pylint: disable=missing-class-docstring def test_order(self): """ diff --git a/cms/djangoapps/contentstore/tests/test_libraries.py b/cms/djangoapps/contentstore/tests/test_libraries.py index f387764916..27edd08d24 100644 --- a/cms/djangoapps/contentstore/tests/test_libraries.py +++ b/cms/djangoapps/contentstore/tests/test_libraries.py @@ -41,7 +41,7 @@ class LibraryTestCase(ModuleStoreTestCase): """ def setUp(self): - super(LibraryTestCase, self).setUp() + super(LibraryTestCase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.user = UserFactory(password=self.user_password, is_staff=True) self.client = AjaxEnabledTestClient() @@ -504,7 +504,7 @@ class TestLibraryAccess(LibraryTestCase): def setUp(self): """ Create a library, staff user, and non-staff user """ - super(TestLibraryAccess, self).setUp() + super(TestLibraryAccess, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.non_staff_user_password = 'foo' self.non_staff_user = UserFactory(password=self.non_staff_user_password, is_staff=False) @@ -544,7 +544,7 @@ class TestLibraryAccess(LibraryTestCase): Log out when done each test """ self.client.logout() - super(TestLibraryAccess, self).tearDown() + super(TestLibraryAccess, self).tearDown() # lint-amnesty, pylint: disable=super-with-arguments def test_creation(self): """ @@ -837,7 +837,7 @@ class TestOverrides(LibraryTestCase): """ def setUp(self): - super(TestOverrides, self).setUp() + super(TestOverrides, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.original_display_name = "A Problem Block" self.original_weight = 1 @@ -1022,7 +1022,7 @@ class TestIncompatibleModuleStore(LibraryTestCase): """ def setUp(self): - super(TestIncompatibleModuleStore, self).setUp() + super(TestIncompatibleModuleStore, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments # Create a course in an incompatible modulestore. with modulestore().default_store(ModuleStoreEnum.Type.mongo): self.course = CourseFactory.create() diff --git a/cms/djangoapps/contentstore/tests/test_permissions.py b/cms/djangoapps/contentstore/tests/test_permissions.py index 210c8f0bcb..4a5e005c9a 100644 --- a/cms/djangoapps/contentstore/tests/test_permissions.py +++ b/cms/djangoapps/contentstore/tests/test_permissions.py @@ -5,7 +5,7 @@ Test CRUD for authorization. import copy -from django.contrib.auth.models import User +from django.contrib.auth.models import User # lint-amnesty, pylint: disable=imported-auth-user from six.moves import range from cms.djangoapps.contentstore.tests.utils import AjaxEnabledTestClient @@ -25,7 +25,7 @@ class TestCourseAccess(ModuleStoreTestCase): Create a pool of users w/o granting them any permissions """ - super(TestCourseAccess, self).setUp() + super(TestCourseAccess, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.client = AjaxEnabledTestClient() self.client.login(username=self.user.username, password=self.user_password) @@ -94,7 +94,7 @@ class TestCourseAccess(ModuleStoreTestCase): user = users.pop() group.add_users(user) user_by_role[role].append(user) - self.assertTrue(auth.has_course_author_access(user, self.course_key), "{} does not have access".format(user)) + self.assertTrue(auth.has_course_author_access(user, self.course_key), "{} does not have access".format(user)) # lint-amnesty, pylint: disable=line-too-long course_team_url = reverse_course_url('course_team_handler', self.course_key) response = self.client.get_html(course_team_url) @@ -132,4 +132,4 @@ class TestCourseAccess(ModuleStoreTestCase): auth.remove_users(self.user, role(self.course_key.org), user) else: auth.remove_users(self.user, role(self.course_key), user) - self.assertFalse(auth.has_course_author_access(user, self.course_key), u"{} remove didn't work".format(user)) + self.assertFalse(auth.has_course_author_access(user, self.course_key), u"{} remove didn't work".format(user)) # lint-amnesty, pylint: disable=line-too-long diff --git a/cms/djangoapps/contentstore/tests/test_proctoring.py b/cms/djangoapps/contentstore/tests/test_proctoring.py index 1df4e6a6b7..aedb929b08 100644 --- a/cms/djangoapps/contentstore/tests/test_proctoring.py +++ b/cms/djangoapps/contentstore/tests/test_proctoring.py @@ -28,7 +28,7 @@ class TestProctoredExams(ModuleStoreTestCase): """ Initial data setup """ - super(TestProctoredExams, self).setUp() + super(TestProctoredExams, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.course = CourseFactory.create( org='edX', diff --git a/cms/djangoapps/contentstore/tests/test_signals.py b/cms/djangoapps/contentstore/tests/test_signals.py index c92928808b..ae81839a3f 100644 --- a/cms/djangoapps/contentstore/tests/test_signals.py +++ b/cms/djangoapps/contentstore/tests/test_signals.py @@ -17,7 +17,7 @@ class LockedTest(ModuleStoreTestCase): """Test class to verify locking of mocked resources""" def setUp(self): - super(LockedTest, self).setUp() + super(LockedTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.course = CourseFactory.create( org='edx', name='course', diff --git a/cms/djangoapps/contentstore/tests/test_tasks.py b/cms/djangoapps/contentstore/tests/test_tasks.py index 1239f85373..8d927a0bad 100644 --- a/cms/djangoapps/contentstore/tests/test_tasks.py +++ b/cms/djangoapps/contentstore/tests/test_tasks.py @@ -9,7 +9,7 @@ from uuid import uuid4 import mock from django.conf import settings -from django.contrib.auth.models import User +from django.contrib.auth.models import User # lint-amnesty, pylint: disable=imported-auth-user from django.test.utils import override_settings from opaque_keys.edx.locator import CourseLocator from organizations.models import OrganizationCourse @@ -114,7 +114,7 @@ class ExportLibraryTestCase(LibraryTestCase): @override_settings(CONTENTSTORE=TEST_DATA_CONTENTSTORE) -class RerunCourseTaskTestCase(CourseTestCase): +class RerunCourseTaskTestCase(CourseTestCase): # lint-amnesty, pylint: disable=missing-class-docstring def _rerun_course(self, old_course_key, new_course_key): CourseRerunState.objects.initiated(old_course_key, new_course_key, self.user, 'Test Re-run') rerun_course(str(old_course_key), str(new_course_key), self.user.id) diff --git a/cms/djangoapps/contentstore/tests/test_transcripts_utils.py b/cms/djangoapps/contentstore/tests/test_transcripts_utils.py index 887a245ea3..b21cc74e24 100644 --- a/cms/djangoapps/contentstore/tests/test_transcripts_utils.py +++ b/cms/djangoapps/contentstore/tests/test_transcripts_utils.py @@ -33,7 +33,7 @@ TEST_DATA_CONTENTSTORE['DOC_STORE_CONFIG']['db'] = 'test_xcontent_%s' % uuid4(). class TestGenerateSubs(unittest.TestCase): """Tests for `generate_subs` function.""" def setUp(self): - super(TestGenerateSubs, self).setUp() + super(TestGenerateSubs, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.source_subs = { 'start': [100, 200, 240, 390, 1000], @@ -138,7 +138,7 @@ class TestSaveSubsToStore(SharedModuleStoreTestCase): cls.content_location_unjsonable = cls.sub_id_to_location(cls.unjsonable_subs_id) def setUp(self): - super(TestSaveSubsToStore, self).setUp() + super(TestSaveSubsToStore, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.addCleanup(self.clear_subs_content) self.clear_subs_content() @@ -188,7 +188,7 @@ class TestYoutubeSubsBase(SharedModuleStoreTestCase): def setUpClass(cls): super(TestYoutubeSubsBase, cls).setUpClass() cls.course = CourseFactory.create( - org=cls.org, number=cls.number, display_name=cls.display_name) + org=cls.org, number=cls.number, display_name=cls.display_name) # lint-amnesty, pylint: disable=no-member @override_settings(CONTENTSTORE=TEST_DATA_CONTENTSTORE) @@ -280,7 +280,7 @@ class TestDownloadYoutubeSubs(TestYoutubeSubsBase): transcripts_utils.download_youtube_subs(good_youtube_sub, self.course, settings) # Check assets status after importing subtitles. - for subs_id in good_youtube_subs.values(): + for subs_id in good_youtube_subs.values(): # lint-amnesty, pylint: disable=undefined-variable filename = 'subs_{0}.srt.sjson'.format(subs_id) content_location = StaticContent.compute_location( self.course.id, filename @@ -355,7 +355,7 @@ class TestDownloadYoutubeSubs(TestYoutubeSubsBase): ) -class TestGenerateSubsFromSource(TestDownloadYoutubeSubs): +class TestGenerateSubsFromSource(TestDownloadYoutubeSubs): # lint-amnesty, pylint: disable=test-inherits-tests """Tests for `generate_subs_from_source` function.""" def test_success_generating_subs(self): @@ -426,7 +426,7 @@ class TestGenerateSubsFromSource(TestDownloadYoutubeSubs): self.assertEqual(exception_message, "Something wrong with SubRip transcripts file during parsing.") -class TestGenerateSrtFromSjson(TestDownloadYoutubeSubs): +class TestGenerateSrtFromSjson(TestDownloadYoutubeSubs): # lint-amnesty, pylint: disable=test-inherits-tests """Tests for `generate_srt_from_sjson` function.""" def test_success_generating_subs(self): @@ -561,7 +561,7 @@ class TestTranscript(unittest.TestCase): Tests for Transcript class e.g. different transcript conversions. """ def setUp(self): - super(TestTranscript, self).setUp() + super(TestTranscript, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.srt_transcript = textwrap.dedent("""\ 0 @@ -710,7 +710,7 @@ class TestGetTranscript(SharedModuleStoreTestCase): """Tests for `get_transcript` function.""" def setUp(self): - super(TestGetTranscript, self).setUp() + super(TestGetTranscript, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.course = CourseFactory.create() diff --git a/cms/djangoapps/contentstore/tests/test_users_default_role.py b/cms/djangoapps/contentstore/tests/test_users_default_role.py index e968fd8cae..eb92b9c308 100644 --- a/cms/djangoapps/contentstore/tests/test_users_default_role.py +++ b/cms/djangoapps/contentstore/tests/test_users_default_role.py @@ -19,7 +19,7 @@ class TestUsersDefaultRole(ModuleStoreTestCase): """ Add a user and a course """ - super(TestUsersDefaultRole, self).setUp() + super(TestUsersDefaultRole, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments # create and log in a staff user. self.user = UserFactory(is_staff=True) self.client = AjaxEnabledTestClient() @@ -49,7 +49,7 @@ class TestUsersDefaultRole(ModuleStoreTestCase): Reverse the setup """ self.client.logout() - super(TestUsersDefaultRole, self).tearDown() + super(TestUsersDefaultRole, self).tearDown() # lint-amnesty, pylint: disable=super-with-arguments def test_user_forum_default_role_on_course_deletion(self): """ diff --git a/cms/djangoapps/contentstore/tests/test_utils.py b/cms/djangoapps/contentstore/tests/test_utils.py index 28f0d71342..642a379b06 100644 --- a/cms/djangoapps/contentstore/tests/test_utils.py +++ b/cms/djangoapps/contentstore/tests/test_utils.py @@ -168,7 +168,7 @@ class ReleaseDateSourceTest(CourseTestCase): """Tests for finding the source of an xblock's release date.""" def setUp(self): - super(ReleaseDateSourceTest, self).setUp() + super(ReleaseDateSourceTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.chapter = ItemFactory.create(category='chapter', parent_location=self.course.location) self.sequential = ItemFactory.create(category='sequential', parent_location=self.chapter.location) @@ -222,7 +222,7 @@ class StaffLockTest(CourseTestCase): """Base class for testing staff lock functions.""" def setUp(self): - super(StaffLockTest, self).setUp() + super(StaffLockTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.chapter = ItemFactory.create(category='chapter', parent_location=self.course.location) self.sequential = ItemFactory.create(category='sequential', parent_location=self.chapter.location) @@ -332,7 +332,7 @@ class GroupVisibilityTest(CourseTestCase): """ def setUp(self): - super(GroupVisibilityTest, self).setUp() + super(GroupVisibilityTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments chapter = ItemFactory.create(category='chapter', parent_location=self.course.location) sequential = ItemFactory.create(category='sequential', parent_location=chapter.location) @@ -432,7 +432,7 @@ class GetUserPartitionInfoTest(ModuleStoreTestCase): def setUp(self): """Create a dummy course. """ - super(GetUserPartitionInfoTest, self).setUp() + super(GetUserPartitionInfoTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.course = CourseFactory() self.block = ItemFactory.create(category="problem", parent_location=self.course.location) diff --git a/cms/djangoapps/contentstore/tests/test_video_utils.py b/cms/djangoapps/contentstore/tests/test_video_utils.py index f5abd76dbf..71e9643fad 100644 --- a/cms/djangoapps/contentstore/tests/test_video_utils.py +++ b/cms/djangoapps/contentstore/tests/test_video_utils.py @@ -59,7 +59,7 @@ class ScrapeVideoThumbnailsTestCase(CourseTestCase): """ def setUp(self): - super(ScrapeVideoThumbnailsTestCase, self).setUp() + super(ScrapeVideoThumbnailsTestCase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments course_ids = [six.text_type(self.course.id)] profiles = ['youtube'] created = datetime.now(pytz.utc) @@ -214,7 +214,7 @@ class ScrapeVideoThumbnailsTestCase(CourseTestCase): mocked_responses = [] for resolution in YOUTUBE_THUMBNAIL_SIZES: mocked_content = resolutions.get(resolution, '') - error_response = False if mocked_content else True + error_response = False if mocked_content else True # lint-amnesty, pylint: disable=simplifiable-if-expression mocked_responses.append(self.mocked_youtube_thumbnail_response(mocked_content, error_response)) return mocked_responses diff --git a/cms/djangoapps/contentstore/tests/tests.py b/cms/djangoapps/contentstore/tests/tests.py index 958d877a69..19837e7136 100644 --- a/cms/djangoapps/contentstore/tests/tests.py +++ b/cms/djangoapps/contentstore/tests/tests.py @@ -91,7 +91,7 @@ class AuthTestCase(ContentStoreTestCase): ENABLED_CACHES = ['default', 'mongo_metadata_inheritance', 'loc_cache'] def setUp(self): - super(AuthTestCase, self).setUp() + super(AuthTestCase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.email = 'a@b.com' self.pw = 'xyz' @@ -191,7 +191,7 @@ class ForumTestCase(CourseTestCase): def setUp(self): """ Creates the test course. """ - super(ForumTestCase, self).setUp() + super(ForumTestCase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.course = CourseFactory.create(org='testX', number='727', display_name='Forum Course') def set_blackout_dates(self, blackout_dates): @@ -242,7 +242,7 @@ class CourseKeyVerificationTestCase(CourseTestCase): """ Create test course. """ - super(CourseKeyVerificationTestCase, self).setUp() + super(CourseKeyVerificationTestCase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.course = CourseFactory.create(org='edX', number='test_course_key', display_name='Test Course') @data(('edX/test_course_key/Test_Course', 200), ('garbage:edX+test_course_key+Test_Course', 404)) diff --git a/cms/djangoapps/contentstore/tests/utils.py b/cms/djangoapps/contentstore/tests/utils.py index 0c9dc771a7..f739e6bf86 100644 --- a/cms/djangoapps/contentstore/tests/utils.py +++ b/cms/djangoapps/contentstore/tests/utils.py @@ -8,7 +8,7 @@ import textwrap import six from django.conf import settings -from django.contrib.auth.models import User +from django.contrib.auth.models import User # lint-amnesty, pylint: disable=imported-auth-user from django.test.client import Client from mock import Mock from opaque_keys.edx.keys import AssetKey, CourseKey @@ -84,7 +84,7 @@ class CourseTestCase(ProceduralCourseTestMixin, ModuleStoreTestCase): afterwards. """ - super(CourseTestCase, self).setUp() + super(CourseTestCase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.client = AjaxEnabledTestClient() self.client.login(username=self.user.username, password=self.user_password) @@ -285,8 +285,8 @@ class CourseTestCase(ProceduralCourseTestMixin, ModuleStoreTestCase): course2_items = self.store.get_items(course2_id) self.assertGreater(len(course1_items), 0) # ensure it found content instead of [] == [] if len(course1_items) != len(course2_items): - course1_block_ids = set([item.location.block_id for item in course1_items]) - course2_block_ids = set([item.location.block_id for item in course2_items]) + course1_block_ids = set([item.location.block_id for item in course1_items]) # lint-amnesty, pylint: disable=consider-using-set-comprehension + course2_block_ids = set([item.location.block_id for item in course2_items]) # lint-amnesty, pylint: disable=consider-using-set-comprehension raise AssertionError( u"Course1 extra blocks: {}; course2 extra blocks: {}".format( course1_block_ids - course2_block_ids, course2_block_ids - course1_block_ids diff --git a/cms/djangoapps/contentstore/utils.py b/cms/djangoapps/contentstore/utils.py index aed8c315ef..de69f94654 100644 --- a/cms/djangoapps/contentstore/utils.py +++ b/cms/djangoapps/contentstore/utils.py @@ -99,7 +99,7 @@ def _remove_instructors(course_key): try: remove_all_instructors(course_key) - except Exception as err: + except Exception as err: # lint-amnesty, pylint: disable=broad-except log.error(u"Error in deleting course groups for {0}: {1}".format(course_key, err)) @@ -191,7 +191,7 @@ def is_currently_visible_to_students(xblock): return False # Check start date - if 'detached' not in published._class_tags and published.start is not None: + if 'detached' not in published._class_tags and published.start is not None: # lint-amnesty, pylint: disable=protected-access return datetime.now(UTC) > published.start # No start date, so it's always visible diff --git a/cms/djangoapps/contentstore/video_utils.py b/cms/djangoapps/contentstore/video_utils.py index c05eda9684..887b9d2ac3 100644 --- a/cms/djangoapps/contentstore/video_utils.py +++ b/cms/djangoapps/contentstore/video_utils.py @@ -117,7 +117,7 @@ def validate_and_update_video_image(course_key_string, edx_video_id, image_file, update_video_image(edx_video_id, course_key_string, image_file, image_filename) LOGGER.info( - u'VIDEOS: Scraping youtube video thumbnail for edx_video_id [%s] in course [%s]', edx_video_id, course_key_string + u'VIDEOS: Scraping youtube video thumbnail for edx_video_id [%s] in course [%s]', edx_video_id, course_key_string # lint-amnesty, pylint: disable=line-too-long ) diff --git a/cms/djangoapps/contentstore/views/__init__.py b/cms/djangoapps/contentstore/views/__init__.py index 896789407d..1263976c7b 100644 --- a/cms/djangoapps/contentstore/views/__init__.py +++ b/cms/djangoapps/contentstore/views/__init__.py @@ -3,7 +3,7 @@ from .assets import * from .checklists import * from .component import * -from .course import * +from .course import * # lint-amnesty, pylint: disable=redefined-builtin from .entrance_exam import * from .error import * from .export_git import * diff --git a/cms/djangoapps/contentstore/views/assets.py b/cms/djangoapps/contentstore/views/assets.py index 7974041b56..acfb8b7187 100644 --- a/cms/djangoapps/contentstore/views/assets.py +++ b/cms/djangoapps/contentstore/views/assets.py @@ -150,7 +150,7 @@ def _assets_json(request, course_key): assets, total_count = _get_assets_for_page(course_key, query_options) - if request_options['requested_page'] > 0 and first_asset_to_display_index >= total_count and total_count > 0: + if request_options['requested_page'] > 0 and first_asset_to_display_index >= total_count and total_count > 0: # lint-amnesty, pylint: disable=chained-comparison _update_options_to_requery_final_page(query_options, total_count) current_page = query_options['current_page'] first_asset_to_display_index = _get_first_asset_index(current_page, requested_page_size) @@ -432,7 +432,7 @@ def _upload_asset(request, course_key): }) -def _get_error_if_course_does_not_exist(course_key): +def _get_error_if_course_does_not_exist(course_key): # lint-amnesty, pylint: disable=missing-function-docstring try: modulestore().get_course(course_key) except ItemNotFoundError: @@ -440,7 +440,7 @@ def _get_error_if_course_does_not_exist(course_key): return HttpResponseBadRequest() -def _get_file_metadata_as_dictionary(upload_file): +def _get_file_metadata_as_dictionary(upload_file): # lint-amnesty, pylint: disable=missing-function-docstring # compute a 'filename' which is similar to the location formatting; we're # using the 'filename' nomenclature since we're using a FileSystem paradigm # here; we're just imposing the Location string formatting expectations to @@ -564,15 +564,15 @@ def delete_asset(course_key, asset_key): del_cached_content(content.location) -def _check_existence_and_get_asset_content(asset_key): +def _check_existence_and_get_asset_content(asset_key): # lint-amnesty, pylint: disable=missing-function-docstring try: content = contentstore().find(asset_key) return content except NotFoundError: - raise AssetNotFoundException + raise AssetNotFoundException # lint-amnesty, pylint: disable=raise-missing-from -def _delete_thumbnail(thumbnail_location, course_key, asset_key): +def _delete_thumbnail(thumbnail_location, course_key, asset_key): # lint-amnesty, pylint: disable=missing-function-docstring if thumbnail_location is not None: # We are ignoring the value of the thumbnail_location-- we only care whether diff --git a/cms/djangoapps/contentstore/views/certificates.py b/cms/djangoapps/contentstore/views/certificates.py index 7b16ba6d36..97ba8ad289 100644 --- a/cms/djangoapps/contentstore/views/certificates.py +++ b/cms/djangoapps/contentstore/views/certificates.py @@ -113,14 +113,14 @@ class CertificateException(Exception): """ Base exception for Certificates workflows """ - pass + pass # lint-amnesty, pylint: disable=unnecessary-pass class CertificateValidationError(CertificateException): """ An exception raised when certificate information is invalid. """ - pass + pass # lint-amnesty, pylint: disable=unnecessary-pass class CertificateManager(object): @@ -136,7 +136,7 @@ class CertificateManager(object): try: certificate = json.loads(json_string) except ValueError: - raise CertificateValidationError(_("invalid JSON")) + raise CertificateValidationError(_("invalid JSON")) # lint-amnesty, pylint: disable=raise-missing-from # Include the data contract version certificate["version"] = CERTIFICATE_SCHEMA_VERSION # Ensure a signatories list is always returned diff --git a/cms/djangoapps/contentstore/views/checklists.py b/cms/djangoapps/contentstore/views/checklists.py index a04cf8ec28..2fa27871d0 100644 --- a/cms/djangoapps/contentstore/views/checklists.py +++ b/cms/djangoapps/contentstore/views/checklists.py @@ -1,3 +1,4 @@ +# lint-amnesty, pylint: disable=missing-module-docstring from django.contrib.auth.decorators import login_required from django.core.exceptions import PermissionDenied from django.views.decorators.csrf import ensure_csrf_cookie diff --git a/cms/djangoapps/contentstore/views/component.py b/cms/djangoapps/contentstore/views/component.py index dda94a072e..01b9d4ac1e 100644 --- a/cms/djangoapps/contentstore/views/component.py +++ b/cms/djangoapps/contentstore/views/component.py @@ -113,7 +113,7 @@ def container_handler(request, usage_key_string): try: usage_key = UsageKey.from_string(usage_key_string) except InvalidKeyError: # Raise Http404 on invalid 'usage_key_string' - raise Http404 + raise Http404 # lint-amnesty, pylint: disable=raise-missing-from with modulestore().bulk_operations(usage_key.course_key): try: course, xblock, lms_link, preview_lms_link = _get_item_in_course(request, usage_key) @@ -208,7 +208,7 @@ def container_handler(request, usage_key_string): return HttpResponseBadRequest("Only supports HTML requests") -def get_component_templates(courselike, library=False): +def get_component_templates(courselike, library=False): # lint-amnesty, pylint: disable=too-many-statements """ Returns the applicable component templates that can be used by the specified course or library. """ @@ -298,7 +298,7 @@ def get_component_templates(courselike, library=False): # Content Libraries currently don't allow opting in to unsupported xblocks/problem types. allow_unsupported = getattr(courselike, "allow_unsupported_xblocks", False) - for category in component_types: + for category in component_types: # lint-amnesty, pylint: disable=too-many-nested-blocks authorable_variations = authorable_xblocks(allow_unsupported=allow_unsupported, name=category) support_level_without_template = component_support_level(authorable_variations, category) templates_for_category = [] @@ -338,7 +338,7 @@ def get_component_templates(courselike, library=False): templates_for_category.append( create_template_dict( - _(template['metadata'].get('display_name')), + _(template['metadata'].get('display_name')), # lint-amnesty, pylint: disable=translation-of-non-string category, support_level_with_template, template_id, @@ -504,7 +504,7 @@ def component_handler(request, usage_key_string, handler, suffix=''): resp = handler_descriptor.handle(handler, req, suffix) except NoSuchHandlerError: log.info(u"XBlock %s attempted to access missing handler %r", handler_descriptor, handler, exc_info=True) - raise Http404 + raise Http404 # lint-amnesty, pylint: disable=raise-missing-from # unintentional update to handle any side effects of handle call # could potentially be updating actual course data or simply caching its values diff --git a/cms/djangoapps/contentstore/views/course.py b/cms/djangoapps/contentstore/views/course.py index cdb5fe25dd..9a4887a4d0 100644 --- a/cms/djangoapps/contentstore/views/course.py +++ b/cms/djangoapps/contentstore/views/course.py @@ -133,7 +133,7 @@ class AccessListFallback(Exception): An exception that is raised whenever we need to `fall back` to fetching *all* courses available to a user, rather than using a shorter method (i.e. fetching by group) """ - pass + pass # lint-amnesty, pylint: disable=unnecessary-pass def get_course_and_check_access(course_key, user, depth=0): @@ -289,7 +289,7 @@ def course_handler(request, course_key_string=None): else: return HttpResponseNotFound() except InvalidKeyError: - raise Http404 + raise Http404 # lint-amnesty, pylint: disable=raise-missing-from @login_required @@ -357,7 +357,7 @@ def _course_outline_json(request, course_module): return create_xblock_info( course_module, include_child_info=True, - course_outline=False if is_concise else True, + course_outline=False if is_concise else True, # lint-amnesty, pylint: disable=simplifiable-if-expression include_children_predicate=include_children_predicate, is_concise=is_concise, user=request.user @@ -531,8 +531,8 @@ def course_listing(request): u'org': uca.course_key.org, u'number': uca.course_key.course, u'run': uca.course_key.run, - u'is_failed': True if uca.state == CourseRerunUIStateManager.State.FAILED else False, - u'is_in_progress': True if uca.state == CourseRerunUIStateManager.State.IN_PROGRESS else False, + u'is_failed': True if uca.state == CourseRerunUIStateManager.State.FAILED else False, # lint-amnesty, pylint: disable=simplifiable-if-expression + u'is_in_progress': True if uca.state == CourseRerunUIStateManager.State.IN_PROGRESS else False, # lint-amnesty, pylint: disable=simplifiable-if-expression u'dismiss_link': reverse_course_url( u'course_notifications_handler', uca.course_key, @@ -679,7 +679,7 @@ def course_index(request, course_key): 'lms_link': lms_link, 'sections': sections, 'course_structure': course_structure, - 'initial_state': course_outline_initial_state(locator_to_show, course_structure) if locator_to_show else None, + 'initial_state': course_outline_initial_state(locator_to_show, course_structure) if locator_to_show else None, # lint-amnesty, pylint: disable=line-too-long 'rerun_notification_id': current_action.id if current_action else None, 'course_release_date': course_release_date, 'settings_url': settings_url, @@ -893,7 +893,7 @@ def create_new_course(user, org, number, run, fields): try: org_data = ensure_organization(org) except InvalidOrganizationException: - raise ValidationError(_( + raise ValidationError(_( # lint-amnesty, pylint: disable=raise-missing-from 'You must link this course to an organization in order to continue. Organization ' 'you selected does not exist in the system, you will need to add it to the system' )) @@ -985,7 +985,7 @@ def course_info_handler(request, course_key_string): try: course_key = CourseKey.from_string(course_key_string) except InvalidKeyError: - raise Http404 + raise Http404 # lint-amnesty, pylint: disable=raise-missing-from with modulestore().bulk_operations(course_key): course_module = get_course_and_check_access(course_key, request.user) @@ -1041,7 +1041,7 @@ def course_info_update_handler(request, course_key_string, provided_id=None): elif request.method == 'DELETE': try: return JsonResponse(delete_course_update(usage_key, request.json, provided_id, request.user)) - except: + except: # lint-amnesty, pylint: disable=bare-except return HttpResponseBadRequest( "Failed to delete", content_type="text/plain" @@ -1050,7 +1050,7 @@ def course_info_update_handler(request, course_key_string, provided_id=None): elif request.method in ('POST', 'PUT'): try: return JsonResponse(update_course_updates(usage_key, request.json, provided_id, request.user)) - except: + except: # lint-amnesty, pylint: disable=bare-except return HttpResponseBadRequest( "Failed to save", content_type="text/plain" @@ -1061,7 +1061,7 @@ def course_info_update_handler(request, course_key_string, provided_id=None): @ensure_csrf_cookie @require_http_methods(("GET", "PUT", "POST")) @expect_json -def settings_handler(request, course_key_string): +def settings_handler(request, course_key_string): # lint-amnesty, pylint: disable=too-many-statements """ Course settings for dates and about pages GET @@ -1156,7 +1156,7 @@ def settings_handler(request, course_key_string): # if 'minimum_grade_credit' of a course is not set or 0 then # show warning message to course author. - show_min_grade_warning = False if course_module.minimum_grade_credit > 0 else True + show_min_grade_warning = False if course_module.minimum_grade_credit > 0 else True # lint-amnesty, pylint: disable=simplifiable-if-expression settings_context.update( { 'is_credit_course': True, @@ -1185,7 +1185,7 @@ def settings_handler(request, course_key_string): set_prerequisite_courses(course_key, prerequisite_course_keys) else: # None is chosen, so remove the course prerequisites - course_milestones = milestones_api.get_course_milestones(course_key=course_key, relationship="requires") + course_milestones = milestones_api.get_course_milestones(course_key=course_key, relationship="requires") # lint-amnesty, pylint: disable=line-too-long for milestone in course_milestones: remove_prerequisite_course(course_key, milestone) @@ -1412,7 +1412,7 @@ def advanced_settings_handler(request, course_key_string): class TextbookValidationError(Exception): "An error thrown when a textbook input is invalid" - pass + pass # lint-amnesty, pylint: disable=unnecessary-pass def validate_textbooks_json(text): @@ -1424,7 +1424,7 @@ def validate_textbooks_json(text): try: textbooks = json.loads(text) except ValueError: - raise TextbookValidationError("invalid JSON") + raise TextbookValidationError("invalid JSON") # lint-amnesty, pylint: disable=raise-missing-from if not isinstance(textbooks, (list, tuple)): raise TextbookValidationError("must be JSON list") for textbook in textbooks: @@ -1447,7 +1447,7 @@ def validate_textbook_json(textbook): try: textbook = json.loads(textbook) except ValueError: - raise TextbookValidationError("invalid JSON") + raise TextbookValidationError("invalid JSON") # lint-amnesty, pylint: disable=raise-missing-from if not isinstance(textbook, dict): raise TextbookValidationError("must be JSON object") if not textbook.get("tab_title"): @@ -1768,7 +1768,7 @@ def group_configurations_detail_handler(request, course_key_string, group_config if request.method in ('POST', 'PUT'): # can be either and sometimes django is rewriting one to the other try: - new_configuration = GroupConfiguration(request.body, course, group_configuration_id).get_user_partition() + new_configuration = GroupConfiguration(request.body, course, group_configuration_id).get_user_partition() # lint-amnesty, pylint: disable=line-too-long except GroupConfigurationsValidationError as err: return JsonResponse({"error": text_type(err)}, status=400) diff --git a/cms/djangoapps/contentstore/views/entrance_exam.py b/cms/djangoapps/contentstore/views/entrance_exam.py index 90528c05fa..110609edb4 100644 --- a/cms/djangoapps/contentstore/views/entrance_exam.py +++ b/cms/djangoapps/contentstore/views/entrance_exam.py @@ -178,7 +178,7 @@ def _get_entrance_exam(request, course_key): return HttpResponse(status=404) try: exam_descriptor = modulestore().get_item(exam_key) - return HttpResponse( + return HttpResponse( # lint-amnesty, pylint: disable=http-response-with-content-type-json dump_js_escaped_json({'locator': six.text_type(exam_descriptor.location)}), status=200, content_type='application/json') except ItemNotFoundError: @@ -235,7 +235,7 @@ def _delete_entrance_exam(request, course_key): return HttpResponse(status=204) -def add_entrance_exam_milestone(course_id, x_block): +def add_entrance_exam_milestone(course_id, x_block): # lint-amnesty, pylint: disable=missing-function-docstring # Add an entrance exam milestone if one does not already exist for given xBlock # As this is a standalone method for entrance exam, We should check that given xBlock should be an entrance exam. if x_block.is_entrance_exam: @@ -245,7 +245,7 @@ def add_entrance_exam_milestone(course_id, x_block): course_id ) milestones = milestones_helpers.get_milestones(milestone_namespace) - if len(milestones): + if len(milestones): # lint-amnesty, pylint: disable=len-as-condition milestone = milestones[0] else: description = u'Autogenerated during {} entrance exam creation.'.format(six.text_type(course_id)) diff --git a/cms/djangoapps/contentstore/views/error.py b/cms/djangoapps/contentstore/views/error.py index 9fd2734b67..82d03f7c92 100644 --- a/cms/djangoapps/contentstore/views/error.py +++ b/cms/djangoapps/contentstore/views/error.py @@ -1,3 +1,4 @@ +# lint-amnesty, pylint: disable=missing-module-docstring import functools from django.http import HttpResponse, HttpResponseNotFound, HttpResponseServerError @@ -19,7 +20,7 @@ def jsonable_error(status=500, message="The Studio servers encountered an error" def inner(request, *args, **kwargs): if request.is_ajax(): content = dump_js_escaped_json({"error": message}) - return HttpResponse(content, content_type="application/json", + return HttpResponse(content, content_type="application/json", # lint-amnesty, pylint: disable=http-response-with-content-type-json status=status) else: return func(request, *args, **kwargs) @@ -28,7 +29,7 @@ def jsonable_error(status=500, message="The Studio servers encountered an error" @jsonable_error(404, "Resource not found") -def not_found(request, exception): +def not_found(request, exception): # lint-amnesty, pylint: disable=unused-argument return render_to_response('error.html', {'error': '404'}) @@ -39,7 +40,7 @@ def server_error(request): @fix_crum_request @jsonable_error(404, "Resource not found") -def render_404(request, exception): +def render_404(request, exception): # lint-amnesty, pylint: disable=unused-argument return HttpResponseNotFound(render_to_string('404.html', {}, request=request)) diff --git a/cms/djangoapps/contentstore/views/exception.py b/cms/djangoapps/contentstore/views/exception.py index 3cb3d7a396..98b26286b9 100644 --- a/cms/djangoapps/contentstore/views/exception.py +++ b/cms/djangoapps/contentstore/views/exception.py @@ -7,11 +7,11 @@ class AssetNotFoundException(Exception): """ Raised when asset not found """ - pass + pass # lint-amnesty, pylint: disable=unnecessary-pass class AssetSizeTooLargeException(Exception): """ Raised when the size of an uploaded asset exceeds the maximum size limit. """ - pass + pass # lint-amnesty, pylint: disable=unnecessary-pass diff --git a/cms/djangoapps/contentstore/views/helpers.py b/cms/djangoapps/contentstore/views/helpers.py index bf563b412b..609d8e497e 100644 --- a/cms/djangoapps/contentstore/views/helpers.py +++ b/cms/djangoapps/contentstore/views/helpers.py @@ -142,7 +142,7 @@ def xblock_type_display_name(xblock, default_display_name=None): return _('Unit') component_class = XBlock.load_class(category, select=settings.XBLOCK_SELECT_FUNCTION) if hasattr(component_class, 'display_name') and component_class.display_name.default: - return _(component_class.display_name.default) + return _(component_class.display_name.default) # lint-amnesty, pylint: disable=translation-of-non-string else: return default_display_name diff --git a/cms/djangoapps/contentstore/views/import_export.py b/cms/djangoapps/contentstore/views/import_export.py index 55af032318..0a1f1b809d 100644 --- a/cms/djangoapps/contentstore/views/import_export.py +++ b/cms/djangoapps/contentstore/views/import_export.py @@ -1,4 +1,4 @@ -""" +""" # lint-amnesty, pylint: disable=django-not-configured These views handle all actions in Studio related to import and exporting of courses """ @@ -83,7 +83,7 @@ def import_handler(request, course_key_string): raise PermissionDenied() if 'application/json' in request.META.get('HTTP_ACCEPT', 'application/json'): - if request.method == 'GET': + if request.method == 'GET': # lint-amnesty, pylint: disable=no-else-raise raise NotImplementedError('coming soon') else: return _write_chunk(request, courselike_key) @@ -181,7 +181,7 @@ def _write_chunk(request, courselike_key): elif size > int(content_range['stop']) and size == int(content_range['end']): return JsonResponse({'ImportStatus': 1}) - with open(temp_filepath, mode) as temp_file: # pylint: disable=W6005 + with open(temp_filepath, mode) as temp_file: for chunk in request.FILES['course-data'].chunks(): temp_file.write(chunk) @@ -201,7 +201,7 @@ def _write_chunk(request, courselike_key): }) log.info(u"Course import %s: Upload complete", courselike_key) - with open(temp_filepath, 'rb') as local_file: # pylint: disable=W6005 + with open(temp_filepath, 'rb') as local_file: django_file = File(local_file) storage_path = course_import_export_storage.save(u'olx_import/' + filename, django_file) import_olx.delay( @@ -437,7 +437,7 @@ def export_output_handler(request, course_key_string): tarball = course_import_export_storage.open(artifact.file.name) return send_tarball(tarball, artifact.file.storage.size(artifact.file.name)) except UserTaskArtifact.DoesNotExist: - raise Http404 + raise Http404 # lint-amnesty, pylint: disable=raise-missing-from finally: if artifact: artifact.file.close() diff --git a/cms/djangoapps/contentstore/views/item.py b/cms/djangoapps/contentstore/views/item.py index d8bcf7bca6..d9ed71c0ae 100644 --- a/cms/djangoapps/contentstore/views/item.py +++ b/cms/djangoapps/contentstore/views/item.py @@ -1,7 +1,7 @@ """Views for items (modules).""" -import hashlib +import hashlib # lint-amnesty, pylint: disable=unused-import import logging from collections import OrderedDict from datetime import datetime @@ -10,7 +10,7 @@ from uuid import uuid4 from django.conf import settings from django.contrib.auth.decorators import login_required -from django.contrib.auth.models import User +from django.contrib.auth.models import User # lint-amnesty, pylint: disable=imported-auth-user from django.core.exceptions import PermissionDenied from django.http import Http404, HttpResponse, HttpResponseBadRequest from django.utils.translation import ugettext as _ @@ -528,7 +528,7 @@ def _update_with_callback(xblock, user, old_metadata=None, old_content=None): return modulestore().update_item(xblock, user.id) -def _save_xblock(user, xblock, data=None, children_strings=None, metadata=None, nullout=None, +def _save_xblock(user, xblock, data=None, children_strings=None, metadata=None, nullout=None, # lint-amnesty, pylint: disable=too-many-statements grader_type=None, is_prereq=None, prereq_usage_key=None, prereq_min_score=None, prereq_min_completion=None, publish=None, fields=None): """ @@ -1124,7 +1124,7 @@ def _get_gating_info(course, xblock): return info -def create_xblock_info(xblock, data=None, metadata=None, include_ancestor_info=False, include_child_info=False, +def create_xblock_info(xblock, data=None, metadata=None, include_ancestor_info=False, include_child_info=False, # lint-amnesty, pylint: disable=too-many-statements course_outline=False, include_children_predicate=NEVER, parent_xblock=None, graders=None, user=None, course=None, is_concise=False): """ diff --git a/cms/djangoapps/contentstore/views/organization.py b/cms/djangoapps/contentstore/views/organization.py index d0dd98e5b0..7ece98201a 100644 --- a/cms/djangoapps/contentstore/views/organization.py +++ b/cms/djangoapps/contentstore/views/organization.py @@ -18,8 +18,8 @@ class OrganizationListView(View): """ @method_decorator(login_required) - def get(self, request, *args, **kwargs): + def get(self, request, *args, **kwargs): # lint-amnesty, pylint: disable=unused-argument """Returns organization list as json.""" organizations = get_organizations() org_names_list = [(org["short_name"]) for org in organizations] - return HttpResponse(dump_js_escaped_json(org_names_list), content_type='application/json; charset=utf-8') + return HttpResponse(dump_js_escaped_json(org_names_list), content_type='application/json; charset=utf-8') # lint-amnesty, pylint: disable=http-response-with-content-type-json diff --git a/cms/djangoapps/contentstore/views/preview.py b/cms/djangoapps/contentstore/views/preview.py index fde3acbdc0..49569ee145 100644 --- a/cms/djangoapps/contentstore/views/preview.py +++ b/cms/djangoapps/contentstore/views/preview.py @@ -1,4 +1,4 @@ - +# lint-amnesty, pylint: disable=missing-module-docstring import logging from functools import partial @@ -74,11 +74,11 @@ def preview_handler(request, usage_key_string, handler, suffix=''): except NoSuchHandlerError: log.exception(u"XBlock %s attempted to access missing handler %r", instance, handler) - raise Http404 + raise Http404 # lint-amnesty, pylint: disable=raise-missing-from except NotFoundError: log.exception("Module indicating to user that request doesn't exist") - raise Http404 + raise Http404 # lint-amnesty, pylint: disable=raise-missing-from except ProcessingError: log.warning("Module raised an error while processing AJAX request", @@ -121,7 +121,7 @@ class PreviewModuleSystem(ModuleSystem): # pylint: disable=abstract-method # (see https://openedx.atlassian.net/browse/TE-811) return [ aside_type - for aside_type in super(PreviewModuleSystem, self).applicable_aside_types(block) + for aside_type in super(PreviewModuleSystem, self).applicable_aside_types(block) # lint-amnesty, pylint: disable=super-with-arguments if aside_type != 'acid_aside' ] @@ -285,7 +285,7 @@ def _studio_wrap_xblock(xblock, view, frag, context, display_name_only=False): is_reorderable = _is_xblock_reorderable(xblock, context) selected_groups_label = get_visibility_partition_info(xblock)['selected_groups_label'] if selected_groups_label: - selected_groups_label = _(u'Access restricted to: {list_of_groups}').format(list_of_groups=selected_groups_label) + selected_groups_label = _(u'Access restricted to: {list_of_groups}').format(list_of_groups=selected_groups_label) # lint-amnesty, pylint: disable=line-too-long course = modulestore().get_course(xblock.location.course_key) template_context = { 'xblock_context': context, diff --git a/cms/djangoapps/contentstore/views/session_kv_store.py b/cms/djangoapps/contentstore/views/session_kv_store.py index a67bca06a1..e39753c725 100644 --- a/cms/djangoapps/contentstore/views/session_kv_store.py +++ b/cms/djangoapps/contentstore/views/session_kv_store.py @@ -10,7 +10,7 @@ def stringify(key): return repr(tuple(key)) -class SessionKeyValueStore(KeyValueStore): +class SessionKeyValueStore(KeyValueStore): # lint-amnesty, pylint: disable=missing-class-docstring def __init__(self, request): # lint-amnesty, pylint: disable=super-init-not-called self._session = request.session diff --git a/cms/djangoapps/contentstore/views/tabs.py b/cms/djangoapps/contentstore/views/tabs.py index 11438ae3e4..b299a760e1 100644 --- a/cms/djangoapps/contentstore/views/tabs.py +++ b/cms/djangoapps/contentstore/views/tabs.py @@ -48,7 +48,7 @@ def tabs_handler(request, course_key_string): course_item = modulestore().get_course(course_key) if 'application/json' in request.META.get('HTTP_ACCEPT', 'application/json'): - if request.method == 'GET': + if request.method == 'GET': # lint-amnesty, pylint: disable=no-else-raise raise NotImplementedError('coming soon') else: if 'tabs' in request.json: diff --git a/cms/djangoapps/contentstore/views/tests/test_access.py b/cms/djangoapps/contentstore/views/tests/test_access.py index fa7cff61cd..5b171173c8 100644 --- a/cms/djangoapps/contentstore/views/tests/test_access.py +++ b/cms/djangoapps/contentstore/views/tests/test_access.py @@ -3,7 +3,7 @@ Tests access.py """ -from django.contrib.auth.models import User +from django.contrib.auth.models import User # lint-amnesty, pylint: disable=imported-auth-user from django.test import TestCase from opaque_keys.edx.locator import CourseLocator @@ -20,7 +20,7 @@ class RolesTest(TestCase): """ def setUp(self): """ Test case setup """ - super(RolesTest, self).setUp() + super(RolesTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.global_admin = AdminFactory() self.instructor = User.objects.create_user('testinstructor', 'testinstructor+courses@edx.org', 'foo') diff --git a/cms/djangoapps/contentstore/views/tests/test_assets.py b/cms/djangoapps/contentstore/views/tests/test_assets.py index 872922a7f0..96ae66cad5 100644 --- a/cms/djangoapps/contentstore/views/tests/test_assets.py +++ b/cms/djangoapps/contentstore/views/tests/test_assets.py @@ -43,7 +43,7 @@ class AssetsTestCase(CourseTestCase): Parent class for all asset tests. """ def setUp(self): - super(AssetsTestCase, self).setUp() + super(AssetsTestCase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.url = reverse_course_url('assets_handler', self.course.id) def upload_asset(self, name="asset-1", asset_type='text'): @@ -343,7 +343,7 @@ class UploadTestCase(AssetsTestCase): Unit tests for uploading a file """ def setUp(self): - super(UploadTestCase, self).setUp() + super(UploadTestCase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.url = reverse_course_url('assets_handler', self.course.id) def test_happy_path(self): @@ -378,7 +378,7 @@ class DownloadTestCase(AssetsTestCase): Unit tests for downloading a file. """ def setUp(self): - super(DownloadTestCase, self).setUp() + super(DownloadTestCase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.url = reverse_course_url('assets_handler', self.course.id) # First, upload something. self.asset_name = 'download_test' @@ -502,7 +502,7 @@ class DeleteAssetTestCase(AssetsTestCase): """ def setUp(self): """ Scaffolding """ - super(DeleteAssetTestCase, self).setUp() + super(DeleteAssetTestCase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.url = reverse_course_url('assets_handler', self.course.id) # First, upload something. self.asset_name = 'delete_test' diff --git a/cms/djangoapps/contentstore/views/tests/test_certificates.py b/cms/djangoapps/contentstore/views/tests/test_certificates.py index 4b36da9212..24ca0b4628 100644 --- a/cms/djangoapps/contentstore/views/tests/test_certificates.py +++ b/cms/djangoapps/contentstore/views/tests/test_certificates.py @@ -208,11 +208,11 @@ class CertificatesListHandlerTestCase( Test cases for certificates_list_handler. """ - def setUp(self): + def setUp(self): # lint-amnesty, pylint: disable=arguments-differ """ Set up CertificatesListHandlerTestCase. """ - super(CertificatesListHandlerTestCase, self).setUp('cms.djangoapps.contentstore.views.certificates.tracker') + super(CertificatesListHandlerTestCase, self).setUp('cms.djangoapps.contentstore.views.certificates.tracker') # lint-amnesty, pylint: disable=super-with-arguments self.reset_urls() def _url(self): @@ -437,7 +437,7 @@ class CertificatesDetailHandlerTestCase( """ Set up CertificatesDetailHandlerTestCase. """ - super(CertificatesDetailHandlerTestCase, self).setUp('cms.djangoapps.contentstore.views.certificates.tracker') + super(CertificatesDetailHandlerTestCase, self).setUp('cms.djangoapps.contentstore.views.certificates.tracker') # lint-amnesty, pylint: disable=super-with-arguments self.reset_urls() def _url(self, cid=-1): diff --git a/cms/djangoapps/contentstore/views/tests/test_container_page.py b/cms/djangoapps/contentstore/views/tests/test_container_page.py index ff5d9cc16a..f1c82a60e2 100644 --- a/cms/djangoapps/contentstore/views/tests/test_container_page.py +++ b/cms/djangoapps/contentstore/views/tests/test_container_page.py @@ -31,7 +31,7 @@ class ContainerPageTestCase(StudioPageTestCase, LibraryTestCase): reorderable_child_view = 'reorderable_container_child_preview' def setUp(self): - super(ContainerPageTestCase, self).setUp() + super(ContainerPageTestCase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.vertical = self._create_item(self.sequential.location, 'vertical', 'Unit') self.html = self._create_item(self.vertical.location, "html", "HTML") self.child_container = self._create_item(self.vertical.location, 'split_test', 'Split Test') diff --git a/cms/djangoapps/contentstore/views/tests/test_course_index.py b/cms/djangoapps/contentstore/views/tests/test_course_index.py index 4ac5f6cf76..a172ae597a 100644 --- a/cms/djangoapps/contentstore/views/tests/test_course_index.py +++ b/cms/djangoapps/contentstore/views/tests/test_course_index.py @@ -44,7 +44,7 @@ class TestCourseIndex(CourseTestCase): """ Add a course with odd characters in the fields """ - super(TestCourseIndex, self).setUp() + super(TestCourseIndex, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments # had a problem where index showed course but has_access failed to retrieve it for non-staff self.odd_course = CourseFactory.create( org='test.org_1-2', @@ -75,7 +75,7 @@ class TestCourseIndex(CourseTestCase): self.assertEqual(len(library_tab), 1) # Add a library: - lib1 = LibraryFactory.create() + lib1 = LibraryFactory.create() # lint-amnesty, pylint: disable=unused-variable index_url = '/home/' index_response = self.client.get(index_url, {}, HTTP_ACCEPT='text/html') @@ -329,7 +329,7 @@ class TestCourseIndexArchived(CourseTestCase): """ Add courses with the end date set to various values """ - super(TestCourseIndexArchived, self).setUp() + super(TestCourseIndexArchived, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments # Base course has no end date (so is active) self.course.end = None @@ -426,7 +426,7 @@ class TestCourseOutline(CourseTestCase): """ Set up the for the course outline tests. """ - super(TestCourseOutline, self).setUp() + super(TestCourseOutline, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.chapter = ItemFactory.create( parent_location=self.course.location, category='chapter', display_name="Week 1" @@ -604,7 +604,7 @@ class TestCourseReIndex(CourseTestCase): Set up the for the course outline tests. """ - super(TestCourseReIndex, self).setUp() + super(TestCourseReIndex, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.course.start = datetime.datetime(2014, 1, 1, tzinfo=pytz.utc) modulestore().update_item(self.course, self.user.id) diff --git a/cms/djangoapps/contentstore/views/tests/test_course_updates.py b/cms/djangoapps/contentstore/views/tests/test_course_updates.py index 2b1c055e2b..2a7c1e1dbb 100644 --- a/cms/djangoapps/contentstore/views/tests/test_course_updates.py +++ b/cms/djangoapps/contentstore/views/tests/test_course_updates.py @@ -5,8 +5,8 @@ unit tests for course_info views and models. import json -from django.test.utils import override_settings -from mock import patch +from django.test.utils import override_settings # lint-amnesty, pylint: disable=unused-import +from mock import patch # lint-amnesty, pylint: disable=unused-import from opaque_keys.edx.keys import UsageKey from cms.djangoapps.contentstore.tests.test_course_settings import CourseTestCase @@ -15,7 +15,7 @@ from openedx.core.lib.xblock_utils import get_course_update_items from xmodule.modulestore.django import modulestore -class CourseUpdateTest(CourseTestCase): +class CourseUpdateTest(CourseTestCase): # lint-amnesty, pylint: disable=missing-class-docstring def create_update_url(self, provided_id=None, course_key=None): if course_key is None: @@ -45,7 +45,7 @@ class CourseUpdateTest(CourseTestCase): ) self.assertContains(resp, 'Course Updates', status_code=200) - init_content = '' payload = get_response(content, 'January 8, 2013') self.assertHTMLEqual(payload['content'], content) @@ -223,7 +223,7 @@ class CourseUpdateTest(CourseTestCase): course_updates.data = 'bad news' modulestore().update_item(course_updates, self.user.id) - init_content = '' payload = {'content': content, 'date': 'January 8, 2013'} diff --git a/cms/djangoapps/contentstore/views/tests/test_credit_eligibility.py b/cms/djangoapps/contentstore/views/tests/test_credit_eligibility.py index 95a623c935..58ff6b7639 100644 --- a/cms/djangoapps/contentstore/views/tests/test_credit_eligibility.py +++ b/cms/djangoapps/contentstore/views/tests/test_credit_eligibility.py @@ -20,7 +20,7 @@ class CreditEligibilityTest(CourseTestCase): eligibility requirements. """ def setUp(self): - super(CreditEligibilityTest, self).setUp() + super(CreditEligibilityTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.course = CourseFactory.create(org='edX', number='dummy', display_name='Credit Course') self.course_details_url = reverse_course_url('settings_handler', six.text_type(self.course.id)) diff --git a/cms/djangoapps/contentstore/views/tests/test_entrance_exam.py b/cms/djangoapps/contentstore/views/tests/test_entrance_exam.py index bb80d7fa89..0dcc9acb0a 100644 --- a/cms/djangoapps/contentstore/views/tests/test_entrance_exam.py +++ b/cms/djangoapps/contentstore/views/tests/test_entrance_exam.py @@ -7,7 +7,7 @@ import json import six from django.conf import settings -from django.contrib.auth.models import User +from django.contrib.auth.models import User # lint-amnesty, pylint: disable=imported-auth-user from django.test.client import RequestFactory from milestones.tests.utils import MilestonesTestCaseMixin from mock import patch @@ -40,7 +40,7 @@ class EntranceExamHandlerTests(CourseTestCase, MilestonesTestCaseMixin): """ Shared scaffolding for individual test runs """ - super(EntranceExamHandlerTests, self).setUp() + super(EntranceExamHandlerTests, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.course_key = self.course.id self.usage_key = self.course.location self.course_url = '/course/{}'.format(six.text_type(self.course.id)) diff --git a/cms/djangoapps/contentstore/views/tests/test_exam_settings_view.py b/cms/djangoapps/contentstore/views/tests/test_exam_settings_view.py index c24d3fa044..c7a0e5d585 100644 --- a/cms/djangoapps/contentstore/views/tests/test_exam_settings_view.py +++ b/cms/djangoapps/contentstore/views/tests/test_exam_settings_view.py @@ -32,7 +32,7 @@ class TestExamSettingsView(CourseTestCase, UrlResetMixin): """ Set up the for the exam settings view tests. """ - super(TestExamSettingsView, self).setUp() + super(TestExamSettingsView, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.reset_urls() @staticmethod diff --git a/cms/djangoapps/contentstore/views/tests/test_gating.py b/cms/djangoapps/contentstore/views/tests/test_gating.py index 16a95dcf13..e12842e61b 100644 --- a/cms/djangoapps/contentstore/views/tests/test_gating.py +++ b/cms/djangoapps/contentstore/views/tests/test_gating.py @@ -30,7 +30,7 @@ class TestSubsectionGating(CourseTestCase): """ Initial data setup """ - super(TestSubsectionGating, self).setUp() + super(TestSubsectionGating, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments # Enable subsection gating for the test course self.course.enable_subsection_gating = True diff --git a/cms/djangoapps/contentstore/views/tests/test_group_configurations.py b/cms/djangoapps/contentstore/views/tests/test_group_configurations.py index 9ad6f81caa..c62f237619 100644 --- a/cms/djangoapps/contentstore/views/tests/test_group_configurations.py +++ b/cms/djangoapps/contentstore/views/tests/test_group_configurations.py @@ -267,7 +267,7 @@ class GroupConfigurationsListHandlerTestCase(CourseTestCase, GroupConfigurations # This creates a random UserPartition. self.course.user_partitions = [ - UserPartition(0, 'First name', 'First description', [Group(0, 'Group A'), Group(1, 'Group B'), Group(2, 'Group C')]), + UserPartition(0, 'First name', 'First description', [Group(0, 'Group A'), Group(1, 'Group B'), Group(2, 'Group C')]), # lint-amnesty, pylint: disable=line-too-long ] self.save_course() @@ -873,7 +873,7 @@ class GroupConfigurationsUsageInfoTestCase(CourseTestCase, HelperMethods): ] self.store.update_item(self.course, ModuleStoreEnum.UserID.test) - __, split_test, problem = self._create_content_experiment(cid=0, name_suffix='0', group_id=3, cid_for_problem=1) + __, split_test, problem = self._create_content_experiment(cid=0, name_suffix='0', group_id=3, cid_for_problem=1) # lint-amnesty, pylint: disable=unused-variable expected = { 'id': 1, diff --git a/cms/djangoapps/contentstore/views/tests/test_header_menu.py b/cms/djangoapps/contentstore/views/tests/test_header_menu.py index f2fd6e8c2d..9f38f07429 100644 --- a/cms/djangoapps/contentstore/views/tests/test_header_menu.py +++ b/cms/djangoapps/contentstore/views/tests/test_header_menu.py @@ -31,7 +31,7 @@ class TestHeaderMenu(CourseTestCase, UrlResetMixin): """ Set up the for the course header menu tests. """ - super(TestHeaderMenu, self).setUp() + super(TestHeaderMenu, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.reset_urls() def test_header_menu_without_web_certs_enabled(self): diff --git a/cms/djangoapps/contentstore/views/tests/test_import_export.py b/cms/djangoapps/contentstore/views/tests/test_import_export.py index 0d1d637529..9a4dbd94a3 100644 --- a/cms/djangoapps/contentstore/views/tests/test_import_export.py +++ b/cms/djangoapps/contentstore/views/tests/test_import_export.py @@ -57,7 +57,7 @@ class ImportEntranceExamTestCase(CourseTestCase, MilestonesTestCaseMixin): """ def setUp(self): - super(ImportEntranceExamTestCase, self).setUp() + super(ImportEntranceExamTestCase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.url = reverse_course_url('import_handler', self.course.id) self.content_dir = path(tempfile.mkdtemp()) self.addCleanup(shutil.rmtree, self.content_dir) @@ -94,7 +94,7 @@ class ImportEntranceExamTestCase(CourseTestCase, MilestonesTestCaseMixin): self.assertIsNotNone(course) self.assertEqual(course.entrance_exam_enabled, False) - with open(self.entrance_exam_tar, 'rb') as gtar: # pylint: disable=open-builtin + with open(self.entrance_exam_tar, 'rb') as gtar: # lint-amnesty, pylint: disable=bad-option-value, open-builtin args = {"name": self.entrance_exam_tar, "course-data": [gtar]} resp = self.client.post(self.url, args) self.assertEqual(resp.status_code, 200) @@ -126,7 +126,7 @@ class ImportEntranceExamTestCase(CourseTestCase, MilestonesTestCaseMixin): self.assertTrue(len(content_milestones)) # Now import entrance exam course - with open(self.entrance_exam_tar, 'rb') as gtar: # pylint: disable=open-builtin + with open(self.entrance_exam_tar, 'rb') as gtar: # lint-amnesty, pylint: disable=bad-option-value, open-builtin args = {"name": self.entrance_exam_tar, "course-data": [gtar]} resp = self.client.post(self.url, args) self.assertEqual(resp.status_code, 200) @@ -145,14 +145,14 @@ class ImportTestCase(CourseTestCase): CREATE_USER = True def setUp(self): - super(ImportTestCase, self).setUp() + super(ImportTestCase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.url = reverse_course_url('import_handler', self.course.id) self.content_dir = path(tempfile.mkdtemp()) self.addCleanup(shutil.rmtree, self.content_dir) def touch(name): """ Equivalent to shell's 'touch'""" - with open(name, 'a'): # pylint: disable=W6005 + with open(name, 'a'): os.utime(name, None) # Create tar test files ----------------------------------------------- @@ -185,7 +185,7 @@ class ImportTestCase(CourseTestCase): Check that the response for a tar.gz import without a course.xml is correct. """ - with open(self.bad_tar, 'rb') as btar: # pylint: disable=open-builtin + with open(self.bad_tar, 'rb') as btar: # lint-amnesty, pylint: disable=bad-option-value, open-builtin resp = self.client.post( self.url, { @@ -210,7 +210,7 @@ class ImportTestCase(CourseTestCase): Check that the response for a tar.gz import with a course.xml is correct. """ - with open(self.good_tar, 'rb') as gtar: # pylint: disable=open-builtin + with open(self.good_tar, 'rb') as gtar: # lint-amnesty, pylint: disable=bad-option-value, open-builtin args = {"name": self.good_tar, "course-data": [gtar]} resp = self.client.post(self.url, args) @@ -229,7 +229,7 @@ class ImportTestCase(CourseTestCase): display_name_before_import = course.display_name # Check that global staff user can import course - with open(self.good_tar, 'rb') as gtar: # pylint: disable=open-builtin + with open(self.good_tar, 'rb') as gtar: # lint-amnesty, pylint: disable=bad-option-value, open-builtin args = {"name": self.good_tar, "course-data": [gtar]} resp = self.client.post(self.url, args) self.assertEqual(resp.status_code, 200) @@ -247,7 +247,7 @@ class ImportTestCase(CourseTestCase): # Now course staff user can also successfully import course self.client.login(username=nonstaff_user.username, password='foo') - with open(self.good_tar, 'rb') as gtar: # pylint: disable=open-builtin + with open(self.good_tar, 'rb') as gtar: # lint-amnesty, pylint: disable=bad-option-value, open-builtin args = {"name": self.good_tar, "course-data": [gtar]} resp = self.client.post(self.url, args) self.assertEqual(resp.status_code, 200) @@ -341,7 +341,7 @@ class ImportTestCase(CourseTestCase): def try_tar(tarpath): """ Attempt to tar an unacceptable file """ - with open(tarpath, 'rb') as tar: # pylint: disable=open-builtin + with open(tarpath, 'rb') as tar: # lint-amnesty, pylint: disable=bad-option-value, open-builtin args = {"name": tarpath, "course-data": [tar]} resp = self.client.post(self.url, args) self.assertEqual(resp.status_code, 200) @@ -501,7 +501,7 @@ class ImportTestCase(CourseTestCase): # Construct the modulestore for storing the import (using the previously created contentstore) with SPLIT_MODULESTORE_SETUP.build(contentstore=source_content) as source_store: # Use the test branch setting. - with source_store.branch_setting(branch_setting): + with source_store.branch_setting(branch_setting): # lint-amnesty, pylint: disable=no-member source_library_key = LibraryLocator(org='TestOrg', library='TestProbs') extract_dir = path(tempfile.mkdtemp(dir=settings.DATA_DIR)) @@ -538,7 +538,7 @@ class ExportTestCase(CourseTestCase): """ Sets up the test course. """ - super(ExportTestCase, self).setUp() + super(ExportTestCase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.url = reverse_course_url('export_handler', self.course.id) self.status_url = reverse_course_url('export_status_handler', self.course.id) @@ -854,7 +854,7 @@ class TestLibraryImportExport(CourseTestCase): """ def setUp(self): - super(TestLibraryImportExport, self).setUp() + super(TestLibraryImportExport, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.export_dir = tempfile.mkdtemp() self.addCleanup(shutil.rmtree, self.export_dir, ignore_errors=True) @@ -912,7 +912,7 @@ class TestCourseExportImport(LibraryTestCase): """ def setUp(self): - super(TestCourseExportImport, self).setUp() + super(TestCourseExportImport, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.export_dir = tempfile.mkdtemp() # Create a problem in library @@ -1035,7 +1035,7 @@ class TestCourseExportImportProblem(CourseTestCase): """ def setUp(self): - super(TestCourseExportImportProblem, self).setUp() + super(TestCourseExportImportProblem, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.export_dir = tempfile.mkdtemp() self.source_course = CourseFactory.create(default_store=ModuleStoreEnum.Type.split) self.addCleanup(shutil.rmtree, self.export_dir, ignore_errors=True) diff --git a/cms/djangoapps/contentstore/views/tests/test_item.py b/cms/djangoapps/contentstore/views/tests/test_item.py index 38a6318206..2124f572e3 100644 --- a/cms/djangoapps/contentstore/views/tests/test_item.py +++ b/cms/djangoapps/contentstore/views/tests/test_item.py @@ -89,7 +89,7 @@ class AsideTest(XBlockAside): class ItemTest(CourseTestCase): """ Base test class for create, save, and delete """ def setUp(self): - super(ItemTest, self).setUp() + super(ItemTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.course_key = self.course.id self.usage_key = self.course.location @@ -115,7 +115,7 @@ class ItemTest(CourseTestCase): key = key.map_into_course(CourseKey.from_string(parsed['courseKey'])) return key - def create_xblock(self, parent_usage_key=None, display_name=None, category=None, boilerplate=None): + def create_xblock(self, parent_usage_key=None, display_name=None, category=None, boilerplate=None): # lint-amnesty, pylint: disable=missing-function-docstring data = { 'parent_locator': six.text_type( self.usage_key @@ -680,7 +680,7 @@ class TestDuplicateItem(ItemTest, DuplicateHelper): def setUp(self): """ Creates the test course structure and a few components to 'duplicate'. """ - super(TestDuplicateItem, self).setUp() + super(TestDuplicateItem, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments # Create a parent chapter (for testing children of children). resp = self.create_xblock(parent_usage_key=self.usage_key, category='chapter') self.chapter_usage_key = self.response_usage_key(resp) @@ -789,7 +789,7 @@ class TestMoveItem(ItemTest): """ Creates the test course structure to build course outline tree. """ - super(TestMoveItem, self).setUp() + super(TestMoveItem, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.setup_course() def setup_course(self, default_store=None): @@ -1208,7 +1208,7 @@ class TestMoveItem(ItemTest): self.course, course_id=self.course.id, ) - html.runtime._services['partitions'] = partitions_service + html.runtime._services['partitions'] = partitions_service # lint-amnesty, pylint: disable=protected-access # Set access settings so html will contradict vert2 when moved into that unit vert2.group_access = {self.course.user_partitions[0].id: [group1.id]} @@ -1341,7 +1341,7 @@ class TestDuplicateItemWithAsides(ItemTest, DuplicateHelper): def setUp(self): """ Creates the test course structure and a few components to 'duplicate'. """ - super(TestDuplicateItemWithAsides, self).setUp() + super(TestDuplicateItemWithAsides, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments # Create a parent chapter resp = self.create_xblock(parent_usage_key=self.usage_key, category='chapter') self.chapter_usage_key = self.response_usage_key(resp) @@ -1402,7 +1402,7 @@ class TestEditItemSetup(ItemTest): def setUp(self): """ Creates the test course structure and a couple problems to 'edit'. """ - super(TestEditItemSetup, self).setUp() + super(TestEditItemSetup, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments # create a chapter display_name = 'chapter created' resp = self.create_xblock(display_name=display_name, category='chapter') @@ -1768,7 +1768,7 @@ class TestEditItem(TestEditItemSetup): data={'publish': 'make_public'} ) self._verify_published_with_no_draft(self.problem_usage_key) - published = modulestore().get_item(self.problem_usage_key, revision=ModuleStoreEnum.RevisionOption.published_only) + published = modulestore().get_item(self.problem_usage_key, revision=ModuleStoreEnum.RevisionOption.published_only) # lint-amnesty, pylint: disable=line-too-long # Update the draft version and check that published is different. self.client.ajax_post( @@ -1924,7 +1924,7 @@ class TestEditSplitModule(ItemTest): """ def setUp(self): - super(TestEditSplitModule, self).setUp() + super(TestEditSplitModule, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.user = UserFactory() self.first_user_partition_group_1 = Group(six.text_type(MINIMUM_STATIC_PARTITION_ID + 1), 'alpha') @@ -2147,7 +2147,7 @@ class TestComponentHandler(TestCase): """Tests for component handler api""" def setUp(self): - super(TestComponentHandler, self).setUp() + super(TestComponentHandler, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.request_factory = RequestFactory() @@ -2179,7 +2179,7 @@ class TestComponentHandler(TestCase): @ddt.data('GET', 'POST', 'PUT', 'DELETE') def test_request_method(self, method): - def check_handler(handler, request, suffix): + def check_handler(handler, request, suffix): # lint-amnesty, pylint: disable=unused-argument self.assertEqual(request.method, method) return Response() @@ -2194,7 +2194,7 @@ class TestComponentHandler(TestCase): @ddt.data(200, 404, 500) def test_response_code(self, status_code): - def create_response(handler, request, suffix): + def create_response(handler, request, suffix): # lint-amnesty, pylint: disable=unused-argument return Response(status_code=status_code) self.descriptor.handle = create_response @@ -2208,7 +2208,7 @@ class TestComponentHandler(TestCase): """ test get_aside_from_xblock called """ - def create_response(handler, request, suffix): + def create_response(handler, request, suffix): # lint-amnesty, pylint: disable=unused-argument """create dummy response""" return Response(status_code=200) @@ -2246,7 +2246,7 @@ class TestComponentTemplates(CourseTestCase): """ def setUp(self): - super(TestComponentTemplates, self).setUp() + super(TestComponentTemplates, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments # Advanced Module support levels. XBlockStudioConfiguration.objects.create(name='poll', enabled=True, support_level="fs") XBlockStudioConfiguration.objects.create(name='survey', enabled=True, support_level="ps") @@ -2508,7 +2508,7 @@ class TestXBlockInfo(ItemTest): Unit tests for XBlock's outline handling. """ def setUp(self): - super(TestXBlockInfo, self).setUp() + super(TestXBlockInfo, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments user_id = self.user.id self.chapter = ItemFactory.create( parent_location=self.course.location, category='chapter', display_name="Week 1", user_id=user_id, @@ -2953,7 +2953,7 @@ class TestLibraryXBlockInfo(ModuleStoreTestCase): """ def setUp(self): - super(TestLibraryXBlockInfo, self).setUp() + super(TestLibraryXBlockInfo, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments user_id = self.user.id self.library = LibraryFactory.create() self.top_level_html = ItemFactory.create( diff --git a/cms/djangoapps/contentstore/views/tests/test_library.py b/cms/djangoapps/contentstore/views/tests/test_library.py index c7ea9cbfdb..2cd1e53fde 100644 --- a/cms/djangoapps/contentstore/views/tests/test_library.py +++ b/cms/djangoapps/contentstore/views/tests/test_library.py @@ -44,7 +44,7 @@ class UnitTestLibraries(CourseTestCase): """ def setUp(self): - super(UnitTestLibraries, self).setUp() + super(UnitTestLibraries, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.client = AjaxEnabledTestClient() self.client.login(username=self.user.username, password=self.user_password) diff --git a/cms/djangoapps/contentstore/views/tests/test_organizations.py b/cms/djangoapps/contentstore/views/tests/test_organizations.py index ce12b9899f..b48252ec61 100644 --- a/cms/djangoapps/contentstore/views/tests/test_organizations.py +++ b/cms/djangoapps/contentstore/views/tests/test_organizations.py @@ -13,7 +13,7 @@ from common.djangoapps.student.tests.factories import UserFactory class TestOrganizationListing(TestCase): """Verify Organization listing behavior.""" def setUp(self): - super(TestOrganizationListing, self).setUp() + super(TestOrganizationListing, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.staff = UserFactory(is_staff=True) self.client.login(username=self.staff.username, password='test') self.org_names_listing_url = reverse('organizations') diff --git a/cms/djangoapps/contentstore/views/tests/test_preview.py b/cms/djangoapps/contentstore/views/tests/test_preview.py index 86fd30e1c6..054e9bd2fa 100644 --- a/cms/djangoapps/contentstore/views/tests/test_preview.py +++ b/cms/djangoapps/contentstore/views/tests/test_preview.py @@ -174,7 +174,7 @@ class PureXBlock(XBlock): """ Pure XBlock to use in tests. """ - pass + pass # lint-amnesty, pylint: disable=unnecessary-pass @ddt.ddt @@ -186,7 +186,7 @@ class StudioXBlockServiceBindingTest(ModuleStoreTestCase): """ Set up the user and request that will be used. """ - super(StudioXBlockServiceBindingTest, self).setUp() + super(StudioXBlockServiceBindingTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.user = UserFactory() self.course = CourseFactory.create() self.request = mock.Mock() diff --git a/cms/djangoapps/contentstore/views/tests/test_tabs.py b/cms/djangoapps/contentstore/views/tests/test_tabs.py index b4b3c02918..0d3a470c04 100644 --- a/cms/djangoapps/contentstore/views/tests/test_tabs.py +++ b/cms/djangoapps/contentstore/views/tests/test_tabs.py @@ -20,7 +20,7 @@ class TabsPageTests(CourseTestCase): """Common setup for tests""" # call super class to setup course, etc. - super(TabsPageTests, self).setUp() + super(TabsPageTests, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments # Set the URL for tests self.url = reverse_course_url('tabs_handler', self.course.id) diff --git a/cms/djangoapps/contentstore/views/tests/test_textbooks.py b/cms/djangoapps/contentstore/views/tests/test_textbooks.py index e7122f128f..ed42db2c94 100644 --- a/cms/djangoapps/contentstore/views/tests/test_textbooks.py +++ b/cms/djangoapps/contentstore/views/tests/test_textbooks.py @@ -14,7 +14,7 @@ class TextbookIndexTestCase(CourseTestCase): "Test cases for the textbook index page" def setUp(self): "Set the URL for tests" - super(TextbookIndexTestCase, self).setUp() + super(TextbookIndexTestCase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.url = reverse_course_url('textbooks_list_handler', self.course.id) def test_view_index(self): @@ -113,7 +113,7 @@ class TextbookCreateTestCase(CourseTestCase): def setUp(self): "Set up a url and some textbook content for tests" - super(TextbookCreateTestCase, self).setUp() + super(TextbookCreateTestCase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.url = reverse_course_url('textbooks_list_handler', self.course.id) self.textbook = { @@ -173,7 +173,7 @@ class TextbookDetailTestCase(CourseTestCase): def setUp(self): "Set some useful content and URLs for tests" - super(TextbookDetailTestCase, self).setUp() + super(TextbookDetailTestCase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.textbook1 = { "tab_title": "Economics", "id": 1, @@ -295,7 +295,7 @@ class TextbookValidationTestCase(TestCase): def setUp(self): "Set some useful content for tests" - super(TextbookValidationTestCase, self).setUp() + super(TextbookValidationTestCase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.tb1 = { "tab_title": "Hi, mom!", diff --git a/cms/djangoapps/contentstore/views/tests/test_transcript_settings.py b/cms/djangoapps/contentstore/views/tests/test_transcript_settings.py index 90ce580450..3d6b3ed876 100644 --- a/cms/djangoapps/contentstore/views/tests/test_transcript_settings.py +++ b/cms/djangoapps/contentstore/views/tests/test_transcript_settings.py @@ -1,8 +1,8 @@ -# -*- coding: utf-8 -*- +# lint-amnesty, pylint: disable=missing-module-docstring import json -from io import BytesIO +from io import BytesIO # lint-amnesty, pylint: disable=unused-import import ddt import six diff --git a/cms/djangoapps/contentstore/views/tests/test_transcripts.py b/cms/djangoapps/contentstore/views/tests/test_transcripts.py index 263b513c42..ada70cf196 100644 --- a/cms/djangoapps/contentstore/views/tests/test_transcripts.py +++ b/cms/djangoapps/contentstore/views/tests/test_transcripts.py @@ -82,7 +82,7 @@ class BaseTranscripts(CourseTestCase): def setUp(self): """Create initial data.""" - super(BaseTranscripts, self).setUp() + super(BaseTranscripts, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments # Add video module data = { @@ -156,7 +156,7 @@ class TestUploadTranscripts(BaseTranscripts): Tests for '/transcripts/upload' endpoint. """ def setUp(self): - super(TestUploadTranscripts, self).setUp() + super(TestUploadTranscripts, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.contents = { 'good': SRT_TRANSCRIPT_CONTENT, 'bad': u'Some BAD data', @@ -388,7 +388,7 @@ class TestChooseTranscripts(BaseTranscripts): Tests for '/transcripts/choose' endpoint. """ def setUp(self): - super(TestChooseTranscripts, self).setUp() + super(TestChooseTranscripts, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments # Create test transcript in contentstore self.chosen_html5_id = 'test_html5_subs' @@ -507,7 +507,7 @@ class TestRenameTranscripts(BaseTranscripts): Tests for '/transcripts/rename' endpoint. """ def setUp(self): - super(TestRenameTranscripts, self).setUp() + super(TestRenameTranscripts, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments # Create test transcript in contentstore and update item's sub. self.item.sub = 'test_video_subs' @@ -633,7 +633,7 @@ class TestReplaceTranscripts(BaseTranscripts): Tests for '/transcripts/replace' endpoint. """ def setUp(self): - super(TestReplaceTranscripts, self).setUp() + super(TestReplaceTranscripts, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.youtube_id = 'test_yt_id' # Setup a VEDA produced video and persist `edx_video_id` in VAL. diff --git a/cms/djangoapps/contentstore/views/tests/test_unit_page.py b/cms/djangoapps/contentstore/views/tests/test_unit_page.py index 02851c1c13..78a36cb12d 100644 --- a/cms/djangoapps/contentstore/views/tests/test_unit_page.py +++ b/cms/djangoapps/contentstore/views/tests/test_unit_page.py @@ -16,7 +16,7 @@ class UnitPageTestCase(StudioPageTestCase): """ def setUp(self): - super(UnitPageTestCase, self).setUp() + super(UnitPageTestCase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.vertical = ItemFactory.create(parent_location=self.sequential.location, category='vertical', display_name='Unit') self.video = ItemFactory.create(parent_location=self.vertical.location, @@ -27,7 +27,7 @@ class UnitPageTestCase(StudioPageTestCase): """ Verify that a public xblock's preview returns the expected HTML. """ - published_video = self.store.publish(self.video.location, self.user.id) + published_video = self.store.publish(self.video.location, self.user.id) # lint-amnesty, pylint: disable=unused-variable self.validate_preview_html(self.video, STUDENT_VIEW, can_add=False) def test_draft_component_preview_html(self): diff --git a/cms/djangoapps/contentstore/views/tests/test_user.py b/cms/djangoapps/contentstore/views/tests/test_user.py index c0ccf75122..9f30d18a8d 100644 --- a/cms/djangoapps/contentstore/views/tests/test_user.py +++ b/cms/djangoapps/contentstore/views/tests/test_user.py @@ -5,7 +5,7 @@ Tests for contentstore/views/user.py. import json -from django.contrib.auth.models import User +from django.contrib.auth.models import User # lint-amnesty, pylint: disable=imported-auth-user from cms.djangoapps.contentstore.tests.utils import CourseTestCase from cms.djangoapps.contentstore.utils import reverse_course_url @@ -14,9 +14,9 @@ from common.djangoapps.student.models import CourseEnrollment from common.djangoapps.student.roles import CourseInstructorRole, CourseStaffRole -class UsersTestCase(CourseTestCase): +class UsersTestCase(CourseTestCase): # lint-amnesty, pylint: disable=missing-class-docstring def setUp(self): - super(UsersTestCase, self).setUp() + super(UsersTestCase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.ext_user = User.objects.create_user( "joe", "joe@comedycentral.com", "haha") self.ext_user.is_active = True diff --git a/cms/djangoapps/contentstore/views/tests/test_videos.py b/cms/djangoapps/contentstore/views/tests/test_videos.py index b3148b0451..8b5d1c44ad 100644 --- a/cms/djangoapps/contentstore/views/tests/test_videos.py +++ b/cms/djangoapps/contentstore/views/tests/test_videos.py @@ -64,16 +64,16 @@ class VideoUploadTestBase(object): def get_url_for_course_key(self, course_key, kwargs=None): """Return video handler URL for the given course""" - return reverse_course_url(self.VIEW_NAME, course_key, kwargs) + return reverse_course_url(self.VIEW_NAME, course_key, kwargs) # lint-amnesty, pylint: disable=no-member def setUp(self): - super(VideoUploadTestBase, self).setUp() + super(VideoUploadTestBase, self).setUp() # lint-amnesty, pylint: disable=no-member, super-with-arguments self.url = self.get_url_for_course_key(self.course.id) self.test_token = "test_token" self.course.video_upload_pipeline = { "course_video_upload_token": self.test_token, } - self.save_course() + self.save_course() # lint-amnesty, pylint: disable=no-member # create another course for videos belonging to multiple courses self.course2 = CourseFactory.create() @@ -81,7 +81,7 @@ class VideoUploadTestBase(object): "course_video_upload_token": self.test_token, } self.course2.save() - self.store.update_item(self.course2, self.user.id) + self.store.update_item(self.course2, self.user.id) # lint-amnesty, pylint: disable=no-member # course ids for videos course_ids = [six.text_type(self.course.id), six.text_type(self.course2.id)] @@ -1046,7 +1046,7 @@ class VideoImageTestCase(VideoUploadTestBase, CourseTestCase): 'width': 16, # 16x9 'height': 9 }, - u'Recommended image resolution is {image_file_max_width}x{image_file_max_height}. The minimum resolution is {image_file_min_width}x{image_file_min_height}.'.format( + u'Recommended image resolution is {image_file_max_width}x{image_file_max_height}. The minimum resolution is {image_file_min_width}x{image_file_min_height}.'.format( # lint-amnesty, pylint: disable=line-too-long image_file_max_width=settings.VIDEO_IMAGE_MAX_WIDTH, image_file_max_height=settings.VIDEO_IMAGE_MAX_HEIGHT, image_file_min_width=settings.VIDEO_IMAGE_MIN_WIDTH, @@ -1058,7 +1058,7 @@ class VideoImageTestCase(VideoUploadTestBase, CourseTestCase): 'width': settings.VIDEO_IMAGE_MIN_WIDTH - 10, 'height': settings.VIDEO_IMAGE_MIN_HEIGHT }, - u'Recommended image resolution is {image_file_max_width}x{image_file_max_height}. The minimum resolution is {image_file_min_width}x{image_file_min_height}.'.format( + u'Recommended image resolution is {image_file_max_width}x{image_file_max_height}. The minimum resolution is {image_file_min_width}x{image_file_min_height}.'.format( # lint-amnesty, pylint: disable=line-too-long image_file_max_width=settings.VIDEO_IMAGE_MAX_WIDTH, image_file_max_height=settings.VIDEO_IMAGE_MAX_HEIGHT, image_file_min_width=settings.VIDEO_IMAGE_MIN_WIDTH, @@ -1487,7 +1487,7 @@ class VideoUrlsCsvTestCase(VideoUploadTestMixin, CourseTestCase): VIEW_NAME = "video_encodings_download" def setUp(self): - super(VideoUrlsCsvTestCase, self).setUp() + super(VideoUrlsCsvTestCase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments VideoUploadConfig(profile_whitelist="profile1").save() def _check_csv_response(self, expected_profiles): diff --git a/cms/djangoapps/contentstore/views/tests/utils.py b/cms/djangoapps/contentstore/views/tests/utils.py index c2bb78d538..9d53bf5cd5 100644 --- a/cms/djangoapps/contentstore/views/tests/utils.py +++ b/cms/djangoapps/contentstore/views/tests/utils.py @@ -17,7 +17,7 @@ class StudioPageTestCase(CourseTestCase): """ def setUp(self): - super(StudioPageTestCase, self).setUp() + super(StudioPageTestCase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.chapter = ItemFactory.create(parent_location=self.course.location, category='chapter', display_name="Week 1") self.sequential = ItemFactory.create(parent_location=self.chapter.location, diff --git a/cms/djangoapps/contentstore/views/transcript_settings.py b/cms/djangoapps/contentstore/views/transcript_settings.py index f92722160b..f86ae7ed9e 100644 --- a/cms/djangoapps/contentstore/views/transcript_settings.py +++ b/cms/djangoapps/contentstore/views/transcript_settings.py @@ -193,7 +193,7 @@ def validate_transcript_upload_data(data, files): data['language_code'] != data['new_language_code'] and data['new_language_code'] in get_available_transcript_languages(video_id=data['edx_video_id']) ): - error = _(u'A transcript with the "{language_code}" language code already exists.'.format( + error = _(u'A transcript with the "{language_code}" language code already exists.'.format( # lint-amnesty, pylint: disable=translation-of-non-string language_code=data['new_language_code'] )) elif 'file' not in files: diff --git a/cms/djangoapps/contentstore/views/transcripts_ajax.py b/cms/djangoapps/contentstore/views/transcripts_ajax.py index 461fd9deb2..f66a5247c4 100644 --- a/cms/djangoapps/contentstore/views/transcripts_ajax.py +++ b/cms/djangoapps/contentstore/views/transcripts_ajax.py @@ -260,7 +260,7 @@ def download_transcripts(request): try: content, filename, mimetype = get_transcript(video, lang=u'en') except NotFoundError: - raise Http404 + raise Http404 # lint-amnesty, pylint: disable=raise-missing-from # Construct an HTTP response response = HttpResponse(content, content_type=mimetype) @@ -269,7 +269,7 @@ def download_transcripts(request): @login_required -def check_transcripts(request): +def check_transcripts(request): # lint-amnesty, pylint: disable=too-many-statements """ Check state of transcripts availability. @@ -463,7 +463,7 @@ def _validate_transcripts_data(request): try: item = _get_item(request, data) except (InvalidKeyError, ItemNotFoundError): - raise TranscriptsRequestValidationException(_("Can't find item by locator.")) + raise TranscriptsRequestValidationException(_("Can't find item by locator.")) # lint-amnesty, pylint: disable=raise-missing-from if item.category != 'video': raise TranscriptsRequestValidationException(_('Transcripts are supported only for "video" modules.')) diff --git a/cms/djangoapps/contentstore/views/user.py b/cms/djangoapps/contentstore/views/user.py index 3af7087d24..cc8acf5bb5 100644 --- a/cms/djangoapps/contentstore/views/user.py +++ b/cms/djangoapps/contentstore/views/user.py @@ -2,7 +2,7 @@ from django.contrib.auth.decorators import login_required -from django.contrib.auth.models import User +from django.contrib.auth.models import User # lint-amnesty, pylint: disable=imported-auth-user from django.core.exceptions import PermissionDenied from django.http import HttpResponseNotFound from django.utils.translation import ugettext as _ diff --git a/cms/djangoapps/contentstore/views/videos.py b/cms/djangoapps/contentstore/views/videos.py index c17d3826df..03150f7697 100644 --- a/cms/djangoapps/contentstore/views/videos.py +++ b/cms/djangoapps/contentstore/views/videos.py @@ -14,7 +14,7 @@ from uuid import uuid4 import six from boto import s3 -from boto.sts import STSConnection +from boto.sts import STSConnection # lint-amnesty, pylint: disable=unused-import from django.conf import settings from django.contrib.auth.decorators import login_required from django.contrib.staticfiles.storage import staticfiles_storage diff --git a/cms/envs/common.py b/cms/envs/common.py index 3c5f8b9f32..9255b03eae 100644 --- a/cms/envs/common.py +++ b/cms/envs/common.py @@ -210,7 +210,14 @@ FEATURES = { # Turn off account locking if failed login attempts exceeds a limit 'ENABLE_MAX_FAILED_LOGIN_ATTEMPTS': False, - # Allow editing of short description in course settings in cms + # .. toggle_name: FEATURES['EDITABLE_SHORT_DESCRIPTION'] + # .. toggle_implementation: DjangoSetting + # .. toggle_default: True + # .. toggle_description: This feature flag allows editing of short descriptions on the Schedule & Details page in + # Open edX Studio. Set to False if you want to disable the editing of the course short description. + # .. toggle_use_cases: open_edx + # .. toggle_creation_date: 2014-02-13 + # .. toggle_tickets: https://github.com/edx/edx-platform/pull/2334 'EDITABLE_SHORT_DESCRIPTION': True, # Hide any Personally Identifiable Information from application logs diff --git a/common/djangoapps/student/models.py b/common/djangoapps/student/models.py index e74b2989a6..a0245e74e0 100644 --- a/common/djangoapps/student/models.py +++ b/common/djangoapps/student/models.py @@ -168,19 +168,6 @@ def anonymous_id_for_user(user, course_id, save=True): else: create new anonymous_id, save it in AnonymousUserId, and return anonymous id """ - # .. toggle_name: ANONYMOUS_USER_ID_REVERT_TO_STABLE_HASH - # .. toggle_implementation: SettingToggle - # .. toggle_default: False - # .. toggle_description: Used to make sure we can quickly revert back to old behaviour in case our refractoring - # of anonymous_id_for_user function does not work as intended. Our concern is that our refractoring adds a - # database lookup on every call and we are worried this will cause preformance issues. - # .. toggle_use_cases: temporary - # .. toggle_creation_date: 2021-01-26 - # .. toggle_target_removal_date: 2021-01-29 - # .. toggle_tickets: https://openedx.atlassian.net/browse/ARCHBOM-1645 - if getattr(settings, "ANONYMOUS_USER_ID_REVERT_TO_STABLE_HASH", False): - return deprecated_anonymous_id_for_user(user, course_id, save) - # This part is for ability to get xblock instance in xblock_noauth handlers, where user is unauthenticated. assert user @@ -236,66 +223,6 @@ def anonymous_id_for_user(user, course_id, save=True): return anonymous_user_id -def deprecated_anonymous_id_for_user(user, course_id, save=True): - """ - Return a unique id for a (user, course) pair, suitable for inserting - into e.g. personalized survey links. - If user is an `AnonymousUser`, returns `None` - Keyword arguments: - save -- Whether the id should be saved in an AnonymousUserId object. - """ - # This part is for ability to get xblock instance in xblock_noauth handlers, where user is unauthenticated. - assert user - - if user.is_anonymous: - return None - - # ARCHBOM-1674: Get a sense of what fraction of anonymous_user_id calls are - # cached, stored in the DB, or retrieved from the DB. This will help inform - # us on decisions about whether we can move to always save IDs, - # pregenerate them, use random instead of deterministic IDs, etc. - monitoring.increment('temp_anon_uid_v1.requested') - - cached_id = getattr(user, '_anonymous_id', {}).get(course_id) - if cached_id is not None: - monitoring.increment('temp_anon_uid_v1.returned_from_cache') - return cached_id - - # include the secret key as a salt, and to make the ids unique across different LMS installs. - hasher = hashlib.md5() - hasher.update(settings.SECRET_KEY.encode('utf8')) - hasher.update(text_type(user.id).encode('utf8')) - if course_id: - hasher.update(text_type(course_id).encode('utf-8')) - digest = hasher.hexdigest() - - if not hasattr(user, '_anonymous_id'): - user._anonymous_id = {} # pylint: disable=protected-access - - user._anonymous_id[course_id] = digest # pylint: disable=protected-access - - if save is False: - monitoring.increment('temp_anon_uid_v1.computed_unsaved') - return digest - - try: - _, created = AnonymousUserId.objects.get_or_create( - user=user, - course_id=course_id, - anonymous_user_id=digest, - ) - if created: - monitoring.increment('temp_anon_uid_v1.stored') - else: - monitoring.increment('temp_anon_uid_v1.computed_existing') - except IntegrityError: - # Another thread has already created this entry, so - # continue - monitoring.increment('temp_anon_uid_v1.store_db_error') - - return digest - - def user_by_anonymous_id(uid): """ Return user by anonymous_user_id using AnonymousUserId lookup table. diff --git a/common/lib/symmath/symmath/__init__.py b/common/lib/symmath/symmath/__init__.py index a4233e4dde..f492a56f65 100644 --- a/common/lib/symmath/symmath/__init__.py +++ b/common/lib/symmath/symmath/__init__.py @@ -1,2 +1,3 @@ +# lint-amnesty, pylint: disable=django-not-configured, missing-module-docstring from .formula import * from .symmath_check import * diff --git a/common/lib/symmath/symmath/formula.py b/common/lib/symmath/symmath/formula.py index edc4ad580a..d72389b72c 100644 --- a/common/lib/symmath/symmath/formula.py +++ b/common/lib/symmath/symmath/formula.py @@ -21,7 +21,7 @@ import unicodedata #import subprocess from copy import deepcopy from functools import reduce -from xml.sax.saxutils import unescape +from xml.sax.saxutils import unescape # lint-amnesty, pylint: disable=unused-import import six import sympy @@ -210,7 +210,7 @@ class formula(object): for k in xml: tag = gettag(k) - if tag == 'mi' or tag == 'ci': + if tag == 'mi' or tag == 'ci': # lint-amnesty, pylint: disable=consider-using-in usym = six.text_type(k.text) try: udata = unicodedata.name(usym) @@ -227,7 +227,7 @@ class formula(object): self.fix_greek_in_mathml(k) return xml - def preprocess_pmathml(self, xml): + def preprocess_pmathml(self, xml): # lint-amnesty, pylint: disable=too-many-statements r""" Pre-process presentation MathML from ASCIIMathML to make it more acceptable for SnuggleTeX, and also to accomodate some sympy @@ -420,7 +420,7 @@ class formula(object): self.xml = xml # pylint: disable=attribute-defined-outside-init return self.xml - def get_content_mathml(self): + def get_content_mathml(self): # lint-amnesty, pylint: disable=missing-function-docstring if self.the_cmathml: return self.the_cmathml @@ -436,7 +436,7 @@ class formula(object): cmathml = property(get_content_mathml, None, None, 'content MathML representation') - def make_sympy(self, xml=None): + def make_sympy(self, xml=None): # lint-amnesty, pylint: disable=too-many-statements """ Return sympy expression for the math formula. The math formula is converted to Content MathML then that is parsed. @@ -457,11 +457,11 @@ class formula(object): cmml = self.cmathml xml = etree.fromstring(str(cmml)) except Exception as err: - if 'conversion from Presentation MathML to Content MathML was not successful' in cmml: + if 'conversion from Presentation MathML to Content MathML was not successful' in cmml: # lint-amnesty, pylint: disable=unsupported-membership-test msg = "Illegal math expression" else: msg = 'Err %s while converting cmathml to xml; cmml=%s' % (err, cmml) - raise Exception(msg) + raise Exception(msg) # lint-amnesty, pylint: disable=raise-missing-from xml = self.fix_greek_in_mathml(xml) self.the_sympy = self.make_sympy(xml[0]) else: @@ -482,14 +482,14 @@ class formula(object): def op_minus(*args): if len(args) == 1: return -args[0] - if not len(args) == 2: + if not len(args) == 2: # lint-amnesty, pylint: disable=unneeded-not raise Exception('minus given wrong number of arguments!') #return sympy.Add(args[0],-args[1]) return args[0] - args[1] opdict = { 'plus': op_plus, - 'divide': operator.div, + 'divide': operator.div, # lint-amnesty, pylint: disable=no-member 'times': op_times, 'minus': op_minus, 'root': sympy.sqrt, @@ -546,7 +546,7 @@ class formula(object): except Exception as err: self.args = args # pylint: disable=attribute-defined-outside-init self.op = op # pylint: disable=attribute-defined-outside-init, invalid-name - raise Exception('[formula] error=%s failed to apply %s to args=%s' % (err, opstr, args)) + raise Exception('[formula] error=%s failed to apply %s to args=%s' % (err, opstr, args)) # lint-amnesty, pylint: disable=raise-missing-from return res else: raise Exception('[formula]: unknown operator tag %s' % (opstr)) diff --git a/common/lib/symmath/symmath/symmath_check.py b/common/lib/symmath/symmath/symmath_check.py index 5a1a2171a7..6ac03a47d2 100644 --- a/common/lib/symmath/symmath/symmath_check.py +++ b/common/lib/symmath/symmath/symmath_check.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python # lint-amnesty, pylint: disable=missing-module-docstring # -*- coding: utf-8 -*- # # File: symmath_check.py @@ -16,7 +16,7 @@ from markupsafe import escape from openedx.core.djangolib.markup import HTML -from .formula import * +from .formula import * # lint-amnesty, pylint: disable=wildcard-import log = logging.getLogger(__name__) @@ -26,7 +26,7 @@ log = logging.getLogger(__name__) # This is one of the main entry points to call. -def symmath_check_simple(expect, ans, adict={}, symtab=None, extra_options=None): +def symmath_check_simple(expect, ans, adict={}, symtab=None, extra_options=None): # lint-amnesty, pylint: disable=dangerous-default-value, unused-argument """ Check a symbolic mathematical expression using sympy. The input is an ascii string (not MathML) converted to math using sympy.sympify. @@ -51,7 +51,7 @@ def symmath_check_simple(expect, ans, adict={}, symtab=None, extra_options=None) abcsym=options['__ABC__'], symtab=symtab, ) - except Exception as err: + except Exception as err: # lint-amnesty, pylint: disable=broad-except return {'ok': False, 'msg': HTML('Error {err}
Failed in evaluating check({expect},{ans})').format( err=err, expect=expect, ans=ans @@ -62,7 +62,7 @@ def symmath_check_simple(expect, ans, adict={}, symtab=None, extra_options=None) # pretty generic checking function -def check(expect, given, numerical=False, matrix=False, normphase=False, abcsym=False, do_qubit=True, symtab=None, dosimplify=False): +def check(expect, given, numerical=False, matrix=False, normphase=False, abcsym=False, do_qubit=True, symtab=None, dosimplify=False): # lint-amnesty, pylint: disable=line-too-long """ Returns dict with @@ -93,19 +93,19 @@ def check(expect, given, numerical=False, matrix=False, normphase=False, abcsym= threshold = float(st) numerical = True - if str(given) == '' and not str(expect) == '': + if str(given) == '' and not str(expect) == '': # lint-amnesty, pylint: disable=unneeded-not return {'ok': False, 'msg': ''} try: xgiven = my_sympify(given, normphase, matrix, do_qubit=do_qubit, abcsym=abcsym, symtab=symtab) - except Exception as err: + except Exception as err: # lint-amnesty, pylint: disable=broad-except return {'ok': False, 'msg': HTML('Error {err}
in evaluating your expression "{given}"').format( err=err, given=given )} try: xexpect = my_sympify(expect, normphase, matrix, do_qubit=do_qubit, abcsym=abcsym, symtab=symtab) - except Exception as err: + except Exception as err: # lint-amnesty, pylint: disable=broad-except return {'ok': False, 'msg': HTML('Error {err}
in evaluating OUR expression "{expect}"').format( err=err, expect=expect )} @@ -113,12 +113,12 @@ def check(expect, given, numerical=False, matrix=False, normphase=False, abcsym= if 'autonorm' in flags: # normalize trace of matrices try: xgiven /= xgiven.trace() - except Exception as err: + except Exception as err: # lint-amnesty, pylint: disable=broad-except return {'ok': False, 'msg': HTML('Error {err}
in normalizing trace of your expression {xgiven}'). format(err=err, xgiven=to_latex(xgiven))} try: xexpect /= xexpect.trace() - except Exception as err: + except Exception as err: # lint-amnesty, pylint: disable=broad-except return {'ok': False, 'msg': HTML('Error {err}
in normalizing trace of OUR expression {xexpect}'). format(err=err, xexpect=to_latex(xexpect))} @@ -172,7 +172,7 @@ def is_within_tolerance(expected, actual, tolerance): # This is one of the main entry points to call. -def symmath_check(expect, ans, dynamath=None, options=None, debug=None, xml=None): +def symmath_check(expect, ans, dynamath=None, options=None, debug=None, xml=None): # lint-amnesty, pylint: disable=too-many-statements """ Check a symbolic mathematical expression using sympy. The input may be presentation MathML. Uses formula. @@ -220,7 +220,7 @@ def symmath_check(expect, ans, dynamath=None, options=None, debug=None, xml=None # parse expected answer try: fexpect = my_sympify(str(expect), matrix=do_matrix, do_qubit=do_qubit) - except Exception as err: + except Exception as err: # lint-amnesty, pylint: disable=broad-except msg += HTML('

Error {err} in parsing OUR expected answer "{expect}"

').format(err=err, expect=expect) return {'ok': False, 'msg': make_error_message(msg)} @@ -228,7 +228,7 @@ def symmath_check(expect, ans, dynamath=None, options=None, debug=None, xml=None # if expected answer is a number, try parsing provided answer as a number also try: fans = my_sympify(str(ans), matrix=do_matrix, do_qubit=do_qubit) - except Exception as err: + except Exception as err: # lint-amnesty, pylint: disable=broad-except fans = None # do a numerical comparison if both expected and answer are numbers @@ -256,7 +256,7 @@ def symmath_check(expect, ans, dynamath=None, options=None, debug=None, xml=None # convert mathml answer to formula try: mmlans = dynamath[0] if dynamath else None - except Exception as err: + except Exception as err: # lint-amnesty, pylint: disable=broad-except mmlans = None if not mmlans: return {'ok': False, 'msg': '[symmath_check] failed to get MathML for input; dynamath=%s' % dynamath} @@ -268,7 +268,7 @@ def symmath_check(expect, ans, dynamath=None, options=None, debug=None, xml=None try: fsym = f.sympy msg += HTML('

You entered: {sympy}

').format(sympy=to_latex(f.sympy)) - except Exception as err: + except Exception as err: # lint-amnesty, pylint: disable=broad-except log.exception("Error evaluating expression '%s' as a valid equation", ans) msg += HTML("

Error in evaluating your expression '{ans}' as a valid equation

").format(ans=ans) if "Illegal math" in str(err): @@ -309,7 +309,7 @@ def symmath_check(expect, ans, dynamath=None, options=None, debug=None, xml=None except sympy.ShapeError: msg += HTML("

Error - your input vector or matrix has the wrong dimensions") return {'ok': False, 'msg': make_error_message(msg)} - except Exception as err: + except Exception as err: # lint-amnesty, pylint: disable=broad-except msg += HTML("

Error %s in comparing expected (a list) and your answer

").format(escape(str(err))) if DEBUG: msg += HTML("

{format_exc}
").format(format_exc=traceback.format_exc()) @@ -320,7 +320,7 @@ def symmath_check(expect, ans, dynamath=None, options=None, debug=None, xml=None #fexpect = fexpect.simplify() try: diff = (fexpect - fsym) - except Exception as err: + except Exception as err: # lint-amnesty, pylint: disable=broad-except diff = None if DEBUG: diff --git a/common/lib/symmath/symmath/test_formula.py b/common/lib/symmath/symmath/test_formula.py index 3895157fd8..25d163f059 100644 --- a/common/lib/symmath/symmath/test_formula.py +++ b/common/lib/symmath/symmath/test_formula.py @@ -16,13 +16,13 @@ def stripXML(xml): return xml -class FormulaTest(unittest.TestCase): +class FormulaTest(unittest.TestCase): # lint-amnesty, pylint: disable=missing-class-docstring # for readability later mathml_start = '' mathml_end = '' def setUp(self): - super(FormulaTest, self).setUp() + super(FormulaTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.formulaInstance = formula('') def test_replace_mathvariants(self): diff --git a/common/lib/symmath/symmath/test_symmath_check.py b/common/lib/symmath/symmath/test_symmath_check.py index 0e2f1c7cc0..0271f42ecc 100644 --- a/common/lib/symmath/symmath/test_symmath_check.py +++ b/common/lib/symmath/symmath/test_symmath_check.py @@ -1,4 +1,4 @@ - +# lint-amnesty, pylint: disable=missing-module-docstring from unittest import TestCase from six.moves import range @@ -6,9 +6,9 @@ from six.moves import range from .symmath_check import symmath_check -class SymmathCheckTest(TestCase): +class SymmathCheckTest(TestCase): # lint-amnesty, pylint: disable=missing-class-docstring def test_symmath_check_integers(self): - number_list = [i for i in range(-100, 100)] + number_list = [i for i in range(-100, 100)] # lint-amnesty, pylint: disable=unnecessary-comprehension self._symmath_check_numbers(number_list) def test_symmath_check_floats(self): @@ -73,7 +73,7 @@ class SymmathCheckTest(TestCase): self.assertTrue('ok' in result and not result['ok']) self.assertNotIn('fail', result['msg']) - def _symmath_check_numbers(self, number_list): + def _symmath_check_numbers(self, number_list): # lint-amnesty, pylint: disable=missing-function-docstring for n in number_list: diff --git a/common/lib/xmodule/xmodule/course_module.py b/common/lib/xmodule/xmodule/course_module.py index b0b08df980..cd69c89831 100644 --- a/common/lib/xmodule/xmodule/course_module.py +++ b/common/lib/xmodule/xmodule/course_module.py @@ -374,7 +374,7 @@ class CourseFields(object): scope=Scope.settings ) display_name = String( - help=_("Enter the name of the course as it should appear in the edX.org course list."), + help=_("Enter the name of the course as it should appear in the course list."), default="Empty", display_name=_("Course Display Name"), scope=Scope.settings, @@ -443,7 +443,7 @@ class CourseFields(object): is_new = Boolean( display_name=_("Course Is New"), help=_( - "Enter true or false. If true, the course appears in the list of new courses on edx.org, and a New! " + "Enter true or false. If true, the course appears in the list of new courses, and a New! " "badge temporarily appears next to the course image." ), scope=Scope.settings @@ -742,7 +742,7 @@ class CourseFields(object): allow_public_wiki_access = Boolean( display_name=_("Allow Public Wiki Access"), help=_( - "Enter true or false. If true, edX users can view the course wiki even " + "Enter true or false. If true, students can view the course wiki even " "if they're not enrolled in the course." ), default=False, diff --git a/common/lib/xmodule/xmodule/graders.py b/common/lib/xmodule/xmodule/graders.py index 3ce3dfa329..ecab922afb 100644 --- a/common/lib/xmodule/xmodule/graders.py +++ b/common/lib/xmodule/xmodule/graders.py @@ -333,7 +333,7 @@ class AssignmentFormatGrader(CourseGrader): min_count = 2 would produce the labels "Assignment 3", "Assignment 4" """ - def __init__( + def __init__( # lint-amnesty, pylint: disable=super-init-not-called self, type, # pylint: disable=redefined-builtin min_count, diff --git a/common/lib/xmodule/xmodule/seq_module.py b/common/lib/xmodule/xmodule/seq_module.py index 5f56f0da17..3fe16f99bd 100644 --- a/common/lib/xmodule/xmodule/seq_module.py +++ b/common/lib/xmodule/xmodule/seq_module.py @@ -27,7 +27,6 @@ from xblock.fields import Boolean, Integer, List, Scope, String from edx_toggles.toggles import LegacyWaffleFlag from edx_toggles.toggles import WaffleFlag from lms.djangoapps.courseware.toggles import COURSEWARE_PROCTORING_IMPROVEMENTS -from openedx.core.lib.graph_traversals import get_children, leaf_filter, traverse_pre_order from .exceptions import NotFoundError from .fields import Date @@ -283,37 +282,6 @@ class SequenceModule(SequenceFields, ProctoringFields, XModule): datetime.now(UTC) < date ) - def _get_user(self): - """ - Return the current runtime Django user. - """ - return get_user_model().objects.get(id=self.runtime.user_id) - - def _check_children_for_content_type_gating_paywall(self, item): - """ - If: - This xblock contains problems which this user cannot load due to content type gating - Then: - Return the first content type gating paywall (Fragment) - Else: - Return None - """ - try: - user = self._get_user() - course_id = self.runtime.course_id - content_type_gating_service = self.runtime.service(self, 'content_type_gating') - if not (content_type_gating_service and - content_type_gating_service.enabled_for_enrollment(user=user, course_key=course_id)): - return None - - for block in traverse_pre_order(item, get_children, leaf_filter): - gate_fragment = content_type_gating_service.content_type_gate_for_block(user, block, course_id) - if gate_fragment is not None: - return gate_fragment.content - except get_user_model().DoesNotExist: - pass - return None - def gate_entire_sequence_if_it_is_a_timed_exam_and_contains_content_type_gated_problems(self): """ Problem: @@ -344,7 +312,11 @@ class SequenceModule(SequenceFields, ProctoringFields, XModule): Note that this will break compatability with using sequences outside of edx-platform but we are ok with this for now """ - self.gated_sequence_paywall = self._check_children_for_content_type_gating_paywall(self) + content_type_gating_service = self.runtime.service(self, 'content_type_gating') + if content_type_gating_service: + self.gated_sequence_paywall = content_type_gating_service.check_children_for_content_type_gating_paywall( + self, self.course_id + ) def student_view(self, context): _ = self.runtime.service(self, "i18n").ugettext @@ -669,7 +641,12 @@ class SequenceModule(SequenceFields, ProctoringFields, XModule): else: content = '' - contains_content_type_gated_content = self._check_children_for_content_type_gating_paywall(item) is not None + content_type_gating_service = self.runtime.service(self, 'content_type_gating') + contains_content_type_gated_content = False + if content_type_gating_service: + contains_content_type_gated_content = content_type_gating_service.check_children_for_content_type_gating_paywall( # pylint:disable=line-too-long + item, self.course_id + ) is not None iteminfo = { 'content': content, 'page_title': getattr(item, 'tooltip_title', ''), diff --git a/common/lib/xmodule/xmodule/tests/test_sequence.py b/common/lib/xmodule/xmodule/tests/test_sequence.py index 00bfbd3d4e..e8c93923e9 100644 --- a/common/lib/xmodule/xmodule/tests/test_sequence.py +++ b/common/lib/xmodule/xmodule/tests/test_sequence.py @@ -144,13 +144,12 @@ class SequenceBlockTestCase(XModuleXmlImportTest): seq_module = SequenceModule(runtime=Mock(position=2), descriptor=Mock(), scope_ids=Mock()) self.assertEqual(seq_module.position, 2) # matches position set in the runtime - @patch('xmodule.seq_module.SequenceModule._get_user', return_value=UserFactory.build()) @ddt.unpack @ddt.data( {'view': STUDENT_VIEW}, {'view': PUBLIC_VIEW}, ) - def test_render_student_view(self, mocked_user, view): # pylint: disable=unused-argument + def test_render_student_view(self, view): html = self._get_rendered_view( self.sequence_3_1, extra_context=dict(next_url='NextSequential', prev_url='PrevSequential'), @@ -164,9 +163,8 @@ class SequenceBlockTestCase(XModuleXmlImportTest): self.assertNotIn("fa fa-check-circle check-circle is-hidden", html) # pylint: disable=line-too-long - @patch('xmodule.seq_module.SequenceModule._get_user', return_value=UserFactory.build()) @patch('xmodule.seq_module.SequenceModule.gate_entire_sequence_if_it_is_a_timed_exam_and_contains_content_type_gated_problems') - def test_timed_exam_gating_waffle_flag(self, mocked_function, mocked_user): # pylint: disable=unused-argument + def test_timed_exam_gating_waffle_flag(self, mocked_function): # pylint: disable=unused-argument """ Verify the code inside the waffle flag is not executed with the flag off Verify the code inside the waffle flag is executed with the flag on @@ -190,11 +188,9 @@ class SequenceBlockTestCase(XModuleXmlImportTest): mocked_function.assert_called_once() @override_waffle_flag(TIMED_EXAM_GATING_WAFFLE_FLAG, active=True) - @patch('xmodule.seq_module.SequenceModule._get_user', return_value=UserFactory.build()) - def test_that_timed_sequence_gating_respects_access_configurations(self, mocked_user): # pylint: disable=unused-argument + def test_that_timed_sequence_gating_respects_access_configurations(self): """ Verify that if a time limited sequence contains content type gated problems, we gate the sequence - Verify that if a time limited sequence does not contain content type gated problems, we do not gate the sequence """ # the one problem in this sequence needs to have graded set to true in order to test content type gating self.sequence_5_1.get_children()[0].get_children()[0].graded = True @@ -202,8 +198,7 @@ class SequenceBlockTestCase(XModuleXmlImportTest): # When a time limited sequence contains content type gated problems, the sequence itself is gated self.sequence_5_1.runtime._services['content_type_gating'] = Mock(return_value=Mock( # pylint: disable=protected-access - enabled_for_enrollment=Mock(return_value=True), - content_type_gate_for_block=Mock(return_value=gated_fragment) + check_children_for_content_type_gating_paywall=Mock(return_value=gated_fragment.content), )) view = self._get_rendered_view( self.sequence_5_1, @@ -216,62 +211,27 @@ class SequenceBlockTestCase(XModuleXmlImportTest): self.assertIn('NextSequential', view) self.assertIn('PrevSequential', view) - # When enabled_for_enrollment is false, the sequence itself is not gated - self.sequence_5_1.runtime._services['content_type_gating'] = Mock(return_value=Mock( # pylint: disable=protected-access - enabled_for_enrollment=Mock(return_value=False), - content_type_gate_for_block=Mock(return_value=gated_fragment) - )) - view = self._get_rendered_view( - self.sequence_5_1, - extra_context=dict(next_url='NextSequential', prev_url='PrevSequential'), - view=STUDENT_VIEW - ) - self.assertNotIn('i_am_gated', view) - # check a few elements to ensure the correct page was loaded - self.assertIn("seq_module.html", view) - self.assertIn('NextSequential', view) - self.assertIn('PrevSequential', view) - - # When content_type_gate_for_block returns None, the sequence itself is not gated - self.sequence_5_1.runtime._services['content_type_gating'] = Mock(return_value=Mock( # pylint: disable=protected-access - enabled_for_enrollment=Mock(return_value=True), - content_type_gate_for_block=Mock(return_value=None) - )) - view = self._get_rendered_view( - self.sequence_5_1, - extra_context=dict(next_url='NextSequential', prev_url='PrevSequential'), - view=STUDENT_VIEW - ) - self.assertNotIn('i_am_gated', view) - # check a few elements to ensure the correct page was loaded - self.assertIn("seq_module.html", view) - self.assertIn('NextSequential', view) - self.assertIn('PrevSequential', view) - - @patch('xmodule.seq_module.SequenceModule._get_user', return_value=UserFactory.build()) @ddt.unpack @ddt.data( {'view': STUDENT_VIEW}, {'view': PUBLIC_VIEW}, ) - def test_student_view_first_child(self, mocked_user, view): # pylint: disable=unused-argument + def test_student_view_first_child(self, view): html = self._get_rendered_view( self.sequence_3_1, requested_child='first', view=view ) self._assert_view_at_position(html, expected_position=1) - @patch('xmodule.seq_module.SequenceModule._get_user', return_value=UserFactory.build()) @ddt.unpack @ddt.data( {'view': STUDENT_VIEW}, {'view': PUBLIC_VIEW}, ) - def test_student_view_last_child(self, mocked_user, view): # pylint: disable=unused-argument + def test_student_view_last_child(self, view): html = self._get_rendered_view(self.sequence_3_1, requested_child='last', view=view) self._assert_view_at_position(html, expected_position=3) - @patch('xmodule.seq_module.SequenceModule._get_user', return_value=UserFactory.build()) - def test_tooltip(self, mocked_user): # pylint: disable=unused-argument + def test_tooltip(self): html = self._get_rendered_view(self.sequence_3_1, requested_child=None) for child in self.sequence_3_1.children: self.assertIn("'page_title': '{}'".format(child.block_id), html) @@ -445,8 +405,7 @@ class SequenceBlockTestCase(XModuleXmlImportTest): ) self.assertIs(completion_return, None) - @patch('xmodule.seq_module.SequenceModule._get_user', return_value=UserFactory.build()) - def test_handle_ajax_metadata(self, mocked_user): # pylint: disable=unused-argument + def test_handle_ajax_metadata(self): """ Test that the sequence metadata is returned from the metadata ajax handler. @@ -459,11 +418,10 @@ class SequenceBlockTestCase(XModuleXmlImportTest): self.assertEqual(metadata['tag'], 'sequential') self.assertEqual(metadata['display_name'], self.sequence_3_1.display_name_with_default) - @patch('xmodule.seq_module.SequenceModule._get_user', return_value=UserFactory.build()) @override_settings(FIELD_OVERRIDE_PROVIDERS=( 'openedx.features.content_type_gating.field_override.ContentTypeGatingFieldOverride', )) - def test_handle_ajax_metadata_content_type_gated_content(self, mocked_user): # pylint: disable=unused-argument + def test_handle_ajax_metadata_content_type_gated_content(self): """ The contains_content_type_gated_content field should reflect whether the given item contains content type gated content diff --git a/lms/djangoapps/certificates/services.py b/lms/djangoapps/certificates/services.py index d499367cdc..45532b2403 100644 --- a/lms/djangoapps/certificates/services.py +++ b/lms/djangoapps/certificates/services.py @@ -8,6 +8,7 @@ import logging from django.core.exceptions import ObjectDoesNotExist from opaque_keys.edx.keys import CourseKey +from lms.djangoapps.certificates.generation_handler import is_using_certificate_allowlist_and_is_on_allowlist from lms.djangoapps.certificates.models import GeneratedCertificate from lms.djangoapps.utils import _get_key @@ -21,9 +22,15 @@ class CertificateService(object): def invalidate_certificate(self, user_id, course_key_or_id): """ - Invalidate the user certificate in a given course if it exists. + Invalidate the user certificate in a given course if it exists and the user is not on the allowlist for this + course run. """ course_key = _get_key(course_key_or_id, CourseKey) + if is_using_certificate_allowlist_and_is_on_allowlist(user_id, course_key): + log.info('{course_key} is using allowlist certificates, and the user {user_id} is on its allowlist. The ' + 'certificate will not be invalidated.'.format(course_key=course_key, user_id=user_id)) + return False + try: generated_certificate = GeneratedCertificate.objects.get( user=user_id, @@ -41,3 +48,6 @@ class CertificateService(object): user_id, course_key ) + return False + + return True diff --git a/lms/djangoapps/certificates/signals.py b/lms/djangoapps/certificates/signals.py index c42316c326..d0a6c177c3 100644 --- a/lms/djangoapps/certificates/signals.py +++ b/lms/djangoapps/certificates/signals.py @@ -84,6 +84,11 @@ def _listen_for_failing_grade(sender, user, course_id, grade, **kwargs): # pyli if it is currently passing, downstream signal from COURSE_GRADE_CHANGED """ + if is_using_certificate_allowlist_and_is_on_allowlist(user, course_id): + log.info('{course_id} is using allowlist certificates, and the user {user_id} is on its allowlist. The ' + 'failing grade will not affect the certificate.'.format(course_id=course_id, user_id=user.id)) + return + cert = GeneratedCertificate.certificate_for_student(user, course_id) if cert is not None: if CertificateStatuses.is_passing_status(cert.status): diff --git a/lms/djangoapps/certificates/tests/test_services.py b/lms/djangoapps/certificates/tests/test_services.py index febf9c3555..b9df23710c 100644 --- a/lms/djangoapps/certificates/tests/test_services.py +++ b/lms/djangoapps/certificates/tests/test_services.py @@ -2,14 +2,17 @@ Unit Tests for the Certificate service """ - -from lms.djangoapps.certificates.models import CertificateStatuses, GeneratedCertificate -from lms.djangoapps.certificates.services import CertificateService -from lms.djangoapps.certificates.tests.factories import GeneratedCertificateFactory -from common.djangoapps.student.tests.factories import UserFactory +from edx_toggles.toggles.testutils import override_waffle_flag from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase from xmodule.modulestore.tests.factories import CourseFactory +from common.djangoapps.student.tests.factories import UserFactory +from lms.djangoapps.certificates.generation_handler import CERTIFICATES_USE_ALLOWLIST +from lms.djangoapps.certificates.models import CertificateStatuses, GeneratedCertificate +from lms.djangoapps.certificates.services import CertificateService +from lms.djangoapps.certificates.tests.factories import CertificateWhitelistFactory +from lms.djangoapps.certificates.tests.factories import GeneratedCertificateFactory + class CertificateServiceTests(ModuleStoreTestCase): """ @@ -46,7 +49,9 @@ class CertificateServiceTests(ModuleStoreTestCase): """ Verify that CertificateService invalidates the user certificate """ - self.service.invalidate_certificate(self.user_id, self.course_id) + success = self.service.invalidate_certificate(self.user_id, self.course_id) + self.assertTrue(success) + invalid_generated_certificate = GeneratedCertificate.objects.get( user=self.user_id, course_id=self.course_id @@ -61,3 +66,27 @@ class CertificateServiceTests(ModuleStoreTestCase): 'status': CertificateStatuses.unavailable } ) + + @override_waffle_flag(CERTIFICATES_USE_ALLOWLIST, active=True) + def test_invalidate_certificate_allowlist(self): + """ + Verify that CertificateService does not invalidate the certificate if it is allowlisted + """ + u = UserFactory.create() + c = CourseFactory() + course_key = c.id # pylint: disable=no-member + GeneratedCertificateFactory.create( + status=CertificateStatuses.downloadable, + user=u, + course_id=course_key, + grade=1.0 + ) + CertificateWhitelistFactory( + user=u, + course_id=course_key + ) + success = self.service.invalidate_certificate(u.id, course_key) + self.assertFalse(success) + + cert = GeneratedCertificate.objects.get(user=u.id, course_id=course_key) + self.assertEqual(cert.status, CertificateStatuses.downloadable) diff --git a/lms/djangoapps/certificates/tests/test_signals.py b/lms/djangoapps/certificates/tests/test_signals.py index 4e92a1ede0..523cc3e13c 100644 --- a/lms/djangoapps/certificates/tests/test_signals.py +++ b/lms/djangoapps/certificates/tests/test_signals.py @@ -337,6 +337,35 @@ class FailingGradeCertsTest(ModuleStoreTestCase): cert = GeneratedCertificate.certificate_for_student(self.user, self.course.id) self.assertEqual(cert.status, expected_status) + @override_waffle_flag(CERTIFICATES_USE_ALLOWLIST, active=True) + def test_failing_grade_allowlist(self): + # User who is not on the allowlist + GeneratedCertificateFactory( + user=self.user, + course_id=self.course.id, + status=CertificateStatuses.downloadable + ) + CourseGradeFactory().update(self.user, self.course) + cert = GeneratedCertificate.certificate_for_student(self.user, self.course.id) + self.assertEqual(cert.status, CertificateStatuses.notpassing) + + # User who is on the allowlist + u = UserFactory.create() + c = CourseFactory() + course_key = c.id # pylint: disable=no-member + CertificateWhitelistFactory( + user=u, + course_id=course_key + ) + GeneratedCertificateFactory( + user=u, + course_id=course_key, + status=CertificateStatuses.downloadable + ) + CourseGradeFactory().update(u, c) + cert = GeneratedCertificate.certificate_for_student(u, course_key) + self.assertEqual(cert.status, CertificateStatuses.downloadable) + class LearnerTrackChangeCertsTest(ModuleStoreTestCase): """ diff --git a/lms/djangoapps/courseware/model_data.py b/lms/djangoapps/courseware/model_data.py index f74dc1df7e..af372a49ff 100644 --- a/lms/djangoapps/courseware/model_data.py +++ b/lms/djangoapps/courseware/model_data.py @@ -109,7 +109,7 @@ class DjangoKeyValueStore(KeyValueStore): Scope.user_info, ) - def __init__(self, field_data_cache): + def __init__(self, field_data_cache): # lint-amnesty, pylint: disable=super-init-not-called self._field_data_cache = field_data_cache def get(self, key): diff --git a/lms/djangoapps/courseware/tests/test_views.py b/lms/djangoapps/courseware/tests/test_views.py index cc3451958f..ec3427c690 100644 --- a/lms/djangoapps/courseware/tests/test_views.py +++ b/lms/djangoapps/courseware/tests/test_views.py @@ -269,8 +269,8 @@ class IndexQueryTestCase(ModuleStoreTestCase): NUM_PROBLEMS = 20 @ddt.data( - (ModuleStoreEnum.Type.mongo, 10, 174), - (ModuleStoreEnum.Type.split, 4, 170), + (ModuleStoreEnum.Type.mongo, 10, 172), + (ModuleStoreEnum.Type.split, 4, 168), ) @ddt.unpack def test_index_query_counts(self, store_type, expected_mongo_query_count, expected_mysql_query_count): diff --git a/lms/djangoapps/grades/tests/test_course_grade_factory.py b/lms/djangoapps/grades/tests/test_course_grade_factory.py index d4d5ee392c..72709fe576 100644 --- a/lms/djangoapps/grades/tests/test_course_grade_factory.py +++ b/lms/djangoapps/grades/tests/test_course_grade_factory.py @@ -121,7 +121,7 @@ class TestCourseGradeFactory(GradeTestBase): with self.assertNumQueries(3): _assert_read(expected_pass=True, expected_percent=1.0) # updated to grade of 1.0 - num_queries = 28 + num_queries = 30 with self.assertNumQueries(num_queries), mock_get_score(0, 0): # the subsection now is worth zero grade_factory.update(self.request.user, self.course, force_update_subsections=True) diff --git a/lms/djangoapps/grades/tests/test_tasks.py b/lms/djangoapps/grades/tests/test_tasks.py index 6c1d0fa962..115f970a10 100644 --- a/lms/djangoapps/grades/tests/test_tasks.py +++ b/lms/djangoapps/grades/tests/test_tasks.py @@ -164,10 +164,10 @@ class RecalculateSubsectionGradeTest(HasCourseWithProblemsMixin, ModuleStoreTest self.assertEqual(mock_block_structure_create.call_count, 1) @ddt.data( - (ModuleStoreEnum.Type.mongo, 1, 36, True), - (ModuleStoreEnum.Type.mongo, 1, 36, False), - (ModuleStoreEnum.Type.split, 3, 36, True), - (ModuleStoreEnum.Type.split, 3, 36, False), + (ModuleStoreEnum.Type.mongo, 1, 38, True), + (ModuleStoreEnum.Type.mongo, 1, 38, False), + (ModuleStoreEnum.Type.split, 3, 38, True), + (ModuleStoreEnum.Type.split, 3, 38, False), ) @ddt.unpack def test_query_counts(self, default_store, num_mongo_calls, num_sql_calls, create_multiple_subsections): @@ -179,8 +179,8 @@ class RecalculateSubsectionGradeTest(HasCourseWithProblemsMixin, ModuleStoreTest self._apply_recalculate_subsection_grade() @ddt.data( - (ModuleStoreEnum.Type.mongo, 1, 36), - (ModuleStoreEnum.Type.split, 3, 36), + (ModuleStoreEnum.Type.mongo, 1, 38), + (ModuleStoreEnum.Type.split, 3, 38), ) @ddt.unpack def test_query_counts_dont_change_with_more_content(self, default_store, num_mongo_calls, num_sql_calls): @@ -225,8 +225,8 @@ class RecalculateSubsectionGradeTest(HasCourseWithProblemsMixin, ModuleStoreTest ) @ddt.data( - (ModuleStoreEnum.Type.mongo, 1, 19), - (ModuleStoreEnum.Type.split, 3, 19), + (ModuleStoreEnum.Type.mongo, 1, 21), + (ModuleStoreEnum.Type.split, 3, 21), ) @ddt.unpack def test_persistent_grades_not_enabled_on_course(self, default_store, num_mongo_queries, num_sql_queries): @@ -240,8 +240,8 @@ class RecalculateSubsectionGradeTest(HasCourseWithProblemsMixin, ModuleStoreTest self.assertEqual(len(PersistentSubsectionGrade.bulk_read_grades(self.user.id, self.course.id)), 0) @ddt.data( - (ModuleStoreEnum.Type.mongo, 1, 37), - (ModuleStoreEnum.Type.split, 3, 37), + (ModuleStoreEnum.Type.mongo, 1, 39), + (ModuleStoreEnum.Type.split, 3, 39), ) @ddt.unpack def test_persistent_grades_enabled_on_course(self, default_store, num_mongo_queries, num_sql_queries): diff --git a/lms/djangoapps/instructor/views/__init__.py b/lms/djangoapps/instructor/views/__init__.py index 2b14fd387e..83d462cd07 100644 --- a/lms/djangoapps/instructor/views/__init__.py +++ b/lms/djangoapps/instructor/views/__init__.py @@ -1,4 +1,4 @@ -""" +""" # lint-amnesty, pylint: disable=django-not-configured This is the UserPreference key for the user's recipient invoice copy """ INVOICE_KEY = 'pref-invoice-copy' diff --git a/lms/djangoapps/instructor/views/api.py b/lms/djangoapps/instructor/views/api.py index 3cf21cd0d8..3f09cacf2a 100644 --- a/lms/djangoapps/instructor/views/api.py +++ b/lms/djangoapps/instructor/views/api.py @@ -16,7 +16,7 @@ import string import six import unicodecsv from django.conf import settings -from django.contrib.auth.models import User +from django.contrib.auth.models import User # lint-amnesty, pylint: disable=imported-auth-user from django.core.exceptions import MultipleObjectsReturned, ObjectDoesNotExist, PermissionDenied, ValidationError from django.core.validators import validate_email from django.db import IntegrityError, transaction @@ -44,7 +44,7 @@ from submissions import api as sub_api # installed from the edx-submissions rep from lms.djangoapps.instructor_analytics import basic as instructor_analytics_basic from lms.djangoapps.instructor_analytics import csvs as instructor_analytics_csvs -from lms.djangoapps.instructor_analytics import distributions as instructor_analytics_distributions +from lms.djangoapps.instructor_analytics import distributions as instructor_analytics_distributions # lint-amnesty, pylint: disable=unused-import from lms.djangoapps.bulk_email.api import is_bulk_email_feature_enabled from lms.djangoapps.bulk_email.models import CourseEmail from common.djangoapps.course_modes.models import CourseMode @@ -337,7 +337,7 @@ def register_and_enroll_students(request, course_id): # pylint: disable=too-man try: upload_file = request.FILES.get('students_list') if upload_file.name.endswith('.csv'): - students = [row for row in csv.reader(upload_file.read().decode('utf-8').splitlines())] + students = [row for row in csv.reader(upload_file.read().decode('utf-8').splitlines())] # lint-amnesty, pylint: disable=unnecessary-comprehension course = get_course_by_id(course_id) else: general_errors.append({ @@ -434,7 +434,7 @@ def register_and_enroll_students(request, course_id): # pylint: disable=too-man 'email': email, 'response': _(u'Invalid email {email_address}.').format(email_address=email), }) - log.warning(u'Email address %s is associated with a retired user, so course enrollment was ' + + log.warning(u'Email address %s is associated with a retired user, so course enrollment was ' + # lint-amnesty, pylint: disable=logging-not-lazy u'blocked.', email) else: # This email does not yet exist, so we need to create a new account @@ -610,14 +610,14 @@ def create_and_enroll_user(email, username, name, country, password, course_id, @cache_control(no_cache=True, no_store=True, must_revalidate=True) @require_course_permission(permissions.CAN_ENROLL) @require_post_params(action="enroll or unenroll", identifiers="stringified list of emails and/or usernames") -def students_update_enrollment(request, course_id): +def students_update_enrollment(request, course_id): # lint-amnesty, pylint: disable=too-many-statements """ Enroll or unenroll students by email. Requires staff access. Query Parameters: - action in ['enroll', 'unenroll'] - - identifiers is string containing a list of emails and/or usernames separated by anything split_input_list can handle. + - identifiers is string containing a list of emails and/or usernames separated by anything split_input_list can handle. # lint-amnesty, pylint: disable=line-too-long - auto_enroll is a boolean (defaults to false) If auto_enroll is false, students will be allowed to enroll. If auto_enroll is true, students will be enrolled as soon as they register. @@ -675,7 +675,7 @@ def students_update_enrollment(request, course_id): email_params = get_email_params(course, auto_enroll, secure=request.is_secure()) results = [] - for identifier in identifiers: + for identifier in identifiers: # lint-amnesty, pylint: disable=too-many-nested-blocks # First try to get a user object from the identifer user = None email = None @@ -1052,7 +1052,7 @@ def get_problem_responses(request, course_id): try: for problem_location in problem_locations.split(','): - problem_key = UsageKey.from_string(problem_location).map_into_course(course_key) + problem_key = UsageKey.from_string(problem_location).map_into_course(course_key) # lint-amnesty, pylint: disable=unused-variable except InvalidKeyError: return JsonResponseBadRequest(_("Could not find problem with this location.")) @@ -1748,7 +1748,7 @@ def rescore_problem(request, course_id): @require_course_permission(permissions.OVERRIDE_GRADES) @require_post_params(problem_to_reset="problem urlname to reset", score='overriding score') @common_exceptions_400 -def override_problem_score(request, course_id): +def override_problem_score(request, course_id): # lint-amnesty, pylint: disable=missing-function-docstring course_key = CourseKey.from_string(course_id) score = strip_if_string(request.POST.get('score')) problem_to_reset = strip_if_string(request.POST.get('problem_to_reset')) @@ -2325,7 +2325,7 @@ def update_forum_role_membership(request, course_id): @require_POST -def get_user_invoice_preference(request, course_id): +def get_user_invoice_preference(request, course_id): # lint-amnesty, pylint: disable=unused-argument """ Gets invoice copy user's preferences. """ @@ -2691,7 +2691,7 @@ def remove_certificate_exception(course_key, student): try: certificate_exception = CertificateWhitelist.objects.get(user=student, course_id=course_key) except ObjectDoesNotExist: - raise ValueError( + raise ValueError( # lint-amnesty, pylint: disable=raise-missing-from _(u'Certificate exception (user={user}) does not exist in certificate white list. ' 'Please refresh the page and try again.').format(user=student.username) ) @@ -2744,7 +2744,7 @@ def parse_request_data(request): try: data = json.loads(request.body.decode('utf8') or u'{}') except ValueError: - raise ValueError(_('The record is not in the correct format. Please add a valid username or email address.')) + raise ValueError(_('The record is not in the correct format. Please add a valid username or email address.')) # lint-amnesty, pylint: disable=raise-missing-from return data @@ -2761,7 +2761,7 @@ def get_student(username_or_email, course_key): try: student = get_user_by_username_or_email(username_or_email) except ObjectDoesNotExist: - raise ValueError(_(u"{user} does not exist in the LMS. Please check your spelling and retry.").format( + raise ValueError(_(u"{user} does not exist in the LMS. Please check your spelling and retry.").format( # lint-amnesty, pylint: disable=raise-missing-from user=username_or_email )) @@ -2851,7 +2851,7 @@ def generate_bulk_certificate_exceptions(request, course_id): try: upload_file = request.FILES.get('students_list') if upload_file.name.endswith('.csv'): - students = [row for row in csv.reader(upload_file.read().decode('utf-8').splitlines())] + students = [row for row in csv.reader(upload_file.read().decode('utf-8').splitlines())] # lint-amnesty, pylint: disable=unnecessary-comprehension else: general_errors.append(_('Make sure that the file you upload is in CSV format with no ' 'extraneous characters or rows.')) @@ -3009,7 +3009,7 @@ def re_validate_certificate(request, course_key, generated_certificate): # Fetch CertificateInvalidation object certificate_invalidation = CertificateInvalidation.objects.get(generated_certificate=generated_certificate) except ObjectDoesNotExist: - raise ValueError(_("Certificate Invalidation does not exist, Please refresh the page and try again.")) + raise ValueError(_("Certificate Invalidation does not exist, Please refresh the page and try again.")) # lint-amnesty, pylint: disable=raise-missing-from else: # Deactivate certificate invalidation if it was fetched successfully. certificate_invalidation.deactivate() diff --git a/lms/djangoapps/instructor/views/gradebook_api.py b/lms/djangoapps/instructor/views/gradebook_api.py index 9a20ecdcbe..fb61ecdf1b 100644 --- a/lms/djangoapps/instructor/views/gradebook_api.py +++ b/lms/djangoapps/instructor/views/gradebook_api.py @@ -6,7 +6,7 @@ which is currently use by ccx and instructor apps. import math -from django.contrib.auth.models import User +from django.contrib.auth.models import User # lint-amnesty, pylint: disable=imported-auth-user from django.db import transaction from django.urls import reverse from django.views.decorators.cache import cache_control diff --git a/lms/djangoapps/instructor/views/instructor_dashboard.py b/lms/djangoapps/instructor/views/instructor_dashboard.py index b75acb4d06..d24c9bc954 100644 --- a/lms/djangoapps/instructor/views/instructor_dashboard.py +++ b/lms/djangoapps/instructor/views/instructor_dashboard.py @@ -1,4 +1,4 @@ -""" +""" # lint-amnesty, pylint: disable=django-not-configured Instructor Dashboard Views """ @@ -25,7 +25,7 @@ from mock import patch from opaque_keys import InvalidKeyError from opaque_keys.edx.keys import CourseKey from six import text_type -from six.moves.urllib.parse import urljoin +from six.moves.urllib.parse import urljoin # lint-amnesty, pylint: disable=unused-import from xblock.field_data import DictFieldData from xblock.fields import ScopeIds diff --git a/lms/djangoapps/instructor_task/tasks_helper/certs.py b/lms/djangoapps/instructor_task/tasks_helper/certs.py index 77ed261c44..e9827b502f 100644 --- a/lms/djangoapps/instructor_task/tasks_helper/certs.py +++ b/lms/djangoapps/instructor_task/tasks_helper/certs.py @@ -5,15 +5,15 @@ Instructor tasks related to certificates. from time import time -from django.contrib.auth.models import User # lint-amnesty, pylint: disable=imported-auth-user +from django.contrib.auth import get_user_model from django.db.models import Q - -from lms.djangoapps.certificates.api import generate_user_certificates -from lms.djangoapps.certificates.models import CertificateStatuses, GeneratedCertificate -from common.djangoapps.student.models import CourseEnrollment from xmodule.modulestore.django import modulestore +from common.djangoapps.student.models import CourseEnrollment +from lms.djangoapps.certificates.api import generate_user_certificates +from lms.djangoapps.certificates.models import CertificateStatuses, GeneratedCertificate from .runner import TaskProgress +User = get_user_model() def generate_students_certificates( @@ -65,7 +65,7 @@ def generate_students_certificates( # Mark existing generated certificates as 'unavailable' before regenerating # We need to call this method after "students_require_certificate" otherwise "students_require_certificate" # would return no results. - invalidate_generated_certificates(course_id, students_to_generate_certs_for, statuses_to_regenerate) + _invalidate_generated_certificates(course_id, students_to_generate_certs_for, statuses_to_regenerate) task_progress.skipped = task_progress.total - len(students_require_certs) @@ -122,7 +122,7 @@ def students_require_certificate(course_id, enrolled_students, statuses_to_regen return list(set(enrolled_students) - set(students_already_have_certs)) -def invalidate_generated_certificates(course_id, enrolled_students, certificate_statuses): +def _invalidate_generated_certificates(course_id, enrolled_students, certificate_statuses): """ Invalidate generated certificates for all enrolled students in the given course having status in 'certificate_statuses'. diff --git a/lms/djangoapps/instructor_task/tests/test_tasks_helper.py b/lms/djangoapps/instructor_task/tests/test_tasks_helper.py index 41da827b42..bd23fa3587 100644 --- a/lms/djangoapps/instructor_task/tests/test_tasks_helper.py +++ b/lms/djangoapps/instructor_task/tests/test_tasks_helper.py @@ -15,14 +15,12 @@ import tempfile from collections import OrderedDict from contextlib import contextmanager, ExitStack from datetime import datetime, timedelta -from io import BytesIO # lint-amnesty, pylint: disable=unused-import -from zipfile import ZipFile # lint-amnesty, pylint: disable=unused-import import ddt import unicodecsv +from capa.tests.response_xml_factory import MultipleChoiceResponseXMLFactory from django.conf import settings from django.test.utils import override_settings -from django.urls import reverse # lint-amnesty, pylint: disable=unused-import from edx_django_utils.cache import RequestCache from freezegun import freeze_time from mock import ANY, MagicMock, Mock, patch @@ -30,16 +28,21 @@ from pytz import UTC from six import text_type from six.moves import range, zip from six.moves.urllib.parse import quote -from waffle.testutils import override_switch # lint-amnesty, pylint: disable=unused-import +from xmodule.modulestore import ModuleStoreEnum +from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase +from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory, check_mongo_calls +from xmodule.partitions.partitions import Group, UserPartition import openedx.core.djangoapps.user_api.course_tag.api as course_tag_api -from capa.tests.response_xml_factory import MultipleChoiceResponseXMLFactory from common.djangoapps.course_modes.models import CourseMode -from common.djangoapps.course_modes.tests.factories import CourseModeFactory # lint-amnesty, pylint: disable=unused-import -from lms.djangoapps.courseware.models import StudentModule +from common.djangoapps.student.models import ( + CourseEnrollment, + CourseEnrollmentAllowed +) +from common.djangoapps.student.tests.factories import CourseEnrollmentFactory, UserFactory from lms.djangoapps.certificates.models import CertificateStatuses, GeneratedCertificate from lms.djangoapps.certificates.tests.factories import CertificateWhitelistFactory, GeneratedCertificateFactory -from lms.djangoapps.courseware.tests.factories import InstructorFactory # lint-amnesty, pylint: disable=unused-import +from lms.djangoapps.courseware.models import StudentModule from lms.djangoapps.grades.course_data import CourseData from lms.djangoapps.grades.models import PersistentCourseGrade, PersistentSubsectionGradeOverride from lms.djangoapps.grades.subsection_grade import CreateSubsectionGrade @@ -68,6 +71,7 @@ from lms.djangoapps.instructor_task.tests.test_base import ( InstructorTaskModuleTestCase, TestReportMixin ) +from lms.djangoapps.survey.models import SurveyAnswer, SurveyForm from lms.djangoapps.teams.tests.factories import CourseTeamFactory, CourseTeamMembershipFactory from lms.djangoapps.verify_student.tests.factories import SoftwareSecurePhotoVerificationFactory from openedx.core.djangoapps.course_groups.models import CohortMembership, CourseUserGroupPartitionGroup @@ -76,14 +80,6 @@ from openedx.core.djangoapps.credit.tests.factories import CreditCourseFactory from openedx.core.djangoapps.user_api.partition_schemes import RandomUserPartitionScheme from openedx.core.djangoapps.util.testing import ContentGroupTestCase, TestConditionalContent from openedx.core.lib.teams_config import TeamsConfig -from common.djangoapps.student.models import ALLOWEDTOENROLL_TO_ENROLLED, CourseEnrollment, CourseEnrollmentAllowed, ManualEnrollmentAudit # lint-amnesty, pylint: disable=line-too-long, unused-import -from common.djangoapps.student.tests.factories import CourseEnrollmentFactory, UserFactory -from lms.djangoapps.survey.models import SurveyAnswer, SurveyForm -from xmodule.modulestore import ModuleStoreEnum -from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase -from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory, check_mongo_calls -from xmodule.partitions.partitions import Group, UserPartition - from ..models import ReportStore from ..tasks_helper.utils import UPDATE_STATUS_FAILED, UPDATE_STATUS_SUCCEEDED @@ -121,7 +117,7 @@ class TestInstructorGradeReport(InstructorGradeReportTestCase): Tests that CSV grade report generation works. """ def setUp(self): - super(TestInstructorGradeReport, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments + super().setUp() self.course = CourseFactory.create() @ddt.data([u'student@example.com', u'ni\xf1o@example.com']) @@ -344,7 +340,7 @@ class TestInstructorGradeReport(InstructorGradeReportTestCase): "N" in the report. Also confirms that a persisted passing grade will result in a Certificate Eligibility - of "Y" incase of verified learners and "N" incase of audit laerners. + of "Y" for verified learners and "N" for audit learners. """ course = CourseFactory.create() audit_user = CourseEnrollment.enroll(UserFactory.create(), course.id) @@ -445,7 +441,7 @@ class TestTeamGradeReport(InstructorGradeReportTestCase): """ Test that teams appear correctly in the grade report when it is enabled for the course. """ def setUp(self): - super(TestTeamGradeReport, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments + super().setUp() self.course = CourseFactory.create(teams_configuration=_TEAMS_CONFIG) self.student1 = UserFactory.create() CourseEnrollment.enroll(self.student1, self.course.id) @@ -485,7 +481,7 @@ class TestProblemResponsesReport(TestReportMixin, InstructorTaskModuleTestCase): """ def setUp(self): - super(TestProblemResponsesReport, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments + super().setUp() self.initialize_course() self.instructor = self.create_instructor('instructor') self.student = self.create_student('student') @@ -811,7 +807,7 @@ class TestProblemGradeReport(TestReportMixin, InstructorTaskModuleTestCase): Test that the problem CSV generation works. """ def setUp(self): - super(TestProblemGradeReport, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments + super().setUp() self.initialize_course() # Add unicode data to CSV even though unicode usernames aren't # technically possible in openedx. @@ -959,7 +955,7 @@ class TestProblemReportSplitTestContent(TestReportMixin, TestConditionalContent, OPTION_2 = 'Option 2' def setUp(self): - super(TestProblemReportSplitTestContent, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments + super().setUp() self.problem_a_url = u'problem_a_url' self.problem_b_url = u'problem_b_url' self.define_option_problem(self.problem_a_url, parent=self.vertical_a) @@ -1088,7 +1084,7 @@ class TestProblemReportCohortedContent(TestReportMixin, ContentGroupTestCase, In Test the problem report on a course that has cohorted content. """ def setUp(self): - super(TestProblemReportCohortedContent, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments + super().setUp() # construct cohorted problems to work on. self.add_course_content() vertical = ItemFactory.create( @@ -1184,7 +1180,7 @@ class TestCourseSurveyReport(TestReportMixin, InstructorTaskCourseTestCase): Tests that Course Survey report generation works. """ def setUp(self): - super(TestCourseSurveyReport, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments + super().setUp() self.course = CourseFactory.create() self.question1 = "question1" @@ -1279,7 +1275,7 @@ class TestStudentReport(TestReportMixin, InstructorTaskCourseTestCase): Tests that CSV student profile report generation works. """ def setUp(self): - super(TestStudentReport, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments + super().setUp() self.course = CourseFactory.create() def test_success(self): @@ -1320,10 +1316,12 @@ class TestStudentReport(TestReportMixin, InstructorTaskCourseTestCase): class TestTeamStudentReport(TestReportMixin, InstructorTaskCourseTestCase): - "Test the student report when including teams information. " + """ + Test the student report when including teams information. + """ def setUp(self): - super(TestTeamStudentReport, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments + super().setUp() self.course = CourseFactory.create(teams_configuration=_TEAMS_CONFIG) self.student1 = UserFactory.create() CourseEnrollment.enroll(self.student1, self.course.id) @@ -1387,13 +1385,15 @@ class TestListMayEnroll(TestReportMixin, InstructorTaskCourseTestCase): for it yet) works. """ def _create_enrollment(self, email): - "Factory method for creating CourseEnrollmentAllowed objects." + """ + Factory method for creating CourseEnrollmentAllowed objects. + """ return CourseEnrollmentAllowed.objects.create( email=email, course_id=self.course.id ) def setUp(self): - super(TestListMayEnroll, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments + super().setUp() self.course = CourseFactory.create() def test_success(self): @@ -1440,7 +1440,7 @@ class TestCohortStudents(TestReportMixin, InstructorTaskCourseTestCase): Tests that bulk student cohorting works. """ def setUp(self): - super(TestCohortStudents, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments + super().setUp() self.course = CourseFactory.create() self.cohort_1 = CohortFactory(course_id=self.course.id, name='Cohort 1') @@ -1585,7 +1585,7 @@ class TestCohortStudents(TestReportMixin, InstructorTaskCourseTestCase): def test_too_few_commas(self): """ - A CSV file may be malformed and lack traling commas at the end of a row. + A CSV file may be malformed and lack trailing commas at the end of a row. In this case, those cells take on the value None by the CSV parser. Make sure we handle None values appropriately. @@ -1699,7 +1699,7 @@ class TestGradeReport(TestReportMixin, InstructorTaskModuleTestCase): Test that grade report has correct grade values. """ def setUp(self): - super(TestGradeReport, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments + super().setUp() self.create_course() self.student = self.create_student(u'üser_1') @@ -1858,7 +1858,7 @@ class TestGradeReportEnrollmentAndCertificateInfo(TestReportMixin, InstructorTas Test that grade report has correct user enrollment, verification, and certificate information. """ def setUp(self): - super(TestGradeReportEnrollmentAndCertificateInfo, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments + super().setUp() today = datetime.now(UTC) course_factory_kwargs = { @@ -1899,7 +1899,7 @@ class TestGradeReportEnrollmentAndCertificateInfo(TestReportMixin, InstructorTas def user_is_embargoed(self, user, is_embargoed): """ - Set a users emabargo state. + Set a users embargoed state. """ user_profile = UserFactory(username=user.username, email=user.email).profile user_profile.allow_certificate = not is_embargoed @@ -2010,7 +2010,7 @@ class TestCertificateGeneration(InstructorTaskModuleTestCase): ENABLED_CACHES = ['default', 'mongo_metadata_inheritance', 'loc_cache'] def setUp(self): - super(TestCertificateGeneration, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments + super().setUp() self.initialize_course() def test_certificate_generation_for_students(self): @@ -2498,7 +2498,7 @@ class TestCertificateGeneration(InstructorTaskModuleTestCase): mode='honor' ) - # mark 7th students to have certificates generated with status 'norpassing' + # mark 7th students to have certificates generated with status 'notpassing' for student in students[6:7]: GeneratedCertificateFactory.create( user=student, @@ -2569,13 +2569,13 @@ class TestInstructorOra2Report(SharedModuleStoreTestCase): cls.course = CourseFactory.create() def setUp(self): - super(TestInstructorOra2Report, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments + super().setUp() self.current_task = Mock() self.current_task.update_state = Mock() def tearDown(self): - super(TestInstructorOra2Report, self).tearDown() # lint-amnesty, pylint: disable=super-with-arguments + super().tearDown() if os.path.exists(settings.GRADES_DOWNLOAD['ROOT_PATH']): shutil.rmtree(settings.GRADES_DOWNLOAD['ROOT_PATH']) diff --git a/lms/envs/common.py b/lms/envs/common.py index 8183a05c10..c2fa5e5935 100644 --- a/lms/envs/common.py +++ b/lms/envs/common.py @@ -169,7 +169,16 @@ FEATURES = { # .. toggle_tickets: https://github.com/edx/edx-platform/pull/14729 'ENABLE_UNICODE_USERNAME': False, - 'ENABLE_DJANGO_ADMIN_SITE': True, # set true to enable django's admin site, even on prod (e.g. for course ops) + # .. toggle_name: FEATURES['ENABLE_DJANGO_ADMIN_SITE'] + # .. toggle_implementation: DjangoSetting + # .. toggle_default: True + # .. toggle_description: Set to False if you want to disable Django's admin site. + # .. toggle_use_cases: open_edx + # .. toggle_creation_date: 2013-09-26 + # .. toggle_warnings: It is not recommended to disable this feature as there are many settings available on + # Django's admin site and will be inaccessible to the superuser. + # .. toggle_tickets: https://github.com/edx/edx-platform/pull/829 + 'ENABLE_DJANGO_ADMIN_SITE': True, 'ENABLE_LMS_MIGRATION': False, # .. toggle_name: FEATURES['ENABLE_MASQUERADE'] @@ -248,12 +257,24 @@ FEATURES = { # .. toggle_tickets: https://github.com/edx/edx-platform/pull/1073 'COURSES_ARE_BROWSABLE': True, - # Set to hide the courses list on the Learner Dashboard if they are not enrolled in - # any courses yet. + # .. toggle_name: FEATURES['HIDE_DASHBOARD_COURSES_UNTIL_ACTIVATED'] + # .. toggle_implementation: DjangoSetting + # .. toggle_default: False + # .. toggle_description: When set, it hides the Courses list on the Learner Dashboard page if the learner has not + # yet activated the account and not enrolled in any courses. + # .. toggle_use_cases: open_edx + # .. toggle_creation_date: 2018-05-18 + # .. toggle_tickets: https://openedx.atlassian.net/browse/OSPR-1814 'HIDE_DASHBOARD_COURSES_UNTIL_ACTIVATED': False, - # Give a UI to show a student's submission history in a problem by the - # Staff Debug tool. + # .. toggle_name: FEATURES['ENABLE_STUDENT_HISTORY_VIEW'] + # .. toggle_implementation: DjangoSetting + # .. toggle_default: True + # .. toggle_description: This provides a UI to show a student's submission history in a problem by the Staff Debug + # tool. Set to False if you want to hide Submission History from the courseware page. + # .. toggle_use_cases: open_edx + # .. toggle_creation_date: 2013-02-15 + # .. toggle_tickets: https://github.com/edx/edx-platform/commit/8f17e6ae9ed76fa75b3caf867b65ccb632cb6870 'ENABLE_STUDENT_HISTORY_VIEW': True, # Turn on a page that lets staff enter Python code to be run in the @@ -465,7 +486,17 @@ FEATURES = { # Enable organizational email opt-in 'ENABLE_MKTG_EMAIL_OPT_IN': False, - # Show the mobile app links in the footer + # .. toggle_name: FEATURES['ENABLE_FOOTER_MOBILE_APP_LINKS'] + # .. toggle_implementation: DjangoSetting + # .. toggle_default: False + # .. toggle_description: Set to True if you want show the mobile app links (Apple App Store & Google Play Store) in + # the footer. + # .. toggle_use_cases: open_edx + # .. toggle_creation_date: 2015-01-13 + # .. toggle_warnings: If you set this to True then you should also set your mobile application's app store and play + # store URLs in the MOBILE_STORE_URLS settings dictionary. These links are not part of the default theme. If you + # want these links on your footer then you should use the edx.org theme. + # .. toggle_tickets: https://github.com/edx/edx-platform/pull/6588 'ENABLE_FOOTER_MOBILE_APP_LINKS': False, # Let students save and manage their annotations @@ -4347,13 +4378,27 @@ USERNAME_REPLACEMENT_WORKER = "REPLACE WITH VALID USERNAME" # If running a Gradebook container locally, # modify lms/envs/private.py to give it a non-null value WRITABLE_GRADEBOOK_URL = None - +# .. setting_name: PROFILE_MICROFRONTEND_URL +# .. setting_default: None +# .. setting_description: Base URL of the micro-frontend-based profile page. +# .. setting_warning: Also set site's ENABLE_PROFILE_MICROFRONTEND and +# learner_profile.redirect_to_microfrontend waffle flag PROFILE_MICROFRONTEND_URL = None ORDER_HISTORY_MICROFRONTEND_URL = None +# .. setting_name: ACCOUNT_MICROFRONTEND_URL +# .. setting_default: None +# .. setting_description: Base URL of the micro-frontend-based account settings page. +# .. setting_warning: Also set site's ENABLE_ACCOUNT_MICROFRONTEND and +# account.redirect_to_microfrontend waffle flag ACCOUNT_MICROFRONTEND_URL = None AUTHN_MICROFRONTEND_URL = None AUTHN_MICROFRONTEND_DOMAIN = None PROGRAM_CONSOLE_MICROFRONTEND_URL = None +# .. setting_name: LEARNING_MICROFRONTEND_URL +# .. setting_default: None +# .. setting_description: Base URL of the micro-frontend-based courseware page. +# .. setting_warning: Also set site's ENABLE_COURSEWARE_MICROFRONTEND or +# FEATURES['ENABLE_COURSEWARE_MICROFRONTEND'] and courseware.courseware_mfe waffle flag LEARNING_MICROFRONTEND_URL = None ############### Settings for the ace_common plugin ################# diff --git a/lms/envs/devstack.py b/lms/envs/devstack.py index 919ed49376..e33a17d4fa 100644 --- a/lms/envs/devstack.py +++ b/lms/envs/devstack.py @@ -434,3 +434,7 @@ FEATURES['ENABLE_PREREQUISITE_COURSES'] = True # Don't tolerate deprecated edx-platform import usage in devstack. ERROR_ON_DEPRECATED_EDX_PLATFORM_IMPORTS = True + +# Used in edx-proctoring for ID generation in lieu of SECRET_KEY - dummy value +# (ref MST-637) +PROCTORING_USER_OBFUSCATION_KEY = '85920908f28904ed733fe576320db18cabd7b6cd' diff --git a/lms/envs/test.py b/lms/envs/test.py index 1d2924c6e1..43f1fdea7d 100644 --- a/lms/envs/test.py +++ b/lms/envs/test.py @@ -583,6 +583,10 @@ PROCTORING_SETTINGS = { } } +# Used in edx-proctoring for ID generation in lieu of SECRET_KEY - dummy value +# (ref MST-637) +PROCTORING_USER_OBFUSCATION_KEY = '85920908f28904ed733fe576320db18cabd7b6cd' + ############### Settings for Django Rate limit ##################### RATELIMIT_RATE = '2/m' diff --git a/lms/templates/dashboard.html b/lms/templates/dashboard.html index 063dea1bcf..5369df1551 100644 --- a/lms/templates/dashboard.html +++ b/lms/templates/dashboard.html @@ -196,8 +196,10 @@ from common.djangoapps.student.models import CourseEnrollment enrollment = CourseEnrollment(user=user, course=CourseOverview.get_from_id(pseudo_key), mode=pseudo_session['type']) # We only show email settings for entitlement cards if the entitlement has an associated enrollment show_email_settings = is_fulfilled_entitlement and (entitlement_session.course_id in show_email_settings_for) + course_overview = enrollment.course_overview else: show_email_settings = (enrollment.course_id in show_email_settings_for) + course_overview = CourseOverview.get_from_id(enrollment.course_id) session_id = enrollment.course_id show_courseware_link = show_courseware_links_for.get(session_id, False) @@ -212,7 +214,6 @@ from common.djangoapps.student.models import CourseEnrollment course_requirements = courses_requirements_not_met.get(session_id) related_programs = inverted_programs.get(six.text_type(entitlement.course_uuid if is_unfulfilled_entitlement else session_id)) show_consent_link = (session_id in consent_required_courses) - course_overview = enrollment.course_overview resume_button_url = resume_button_urls[dashboard_index] %> <%include file='dashboard/_dashboard_course_listing.html' args='course_overview=course_overview, course_card_index=dashboard_index, enrollment=enrollment, is_unfulfilled_entitlement=is_unfulfilled_entitlement, is_fulfilled_entitlement=is_fulfilled_entitlement, entitlement=entitlement, entitlement_session=entitlement_session, entitlement_available_sessions=entitlement_available_sessions, entitlement_expiration_date=entitlement_expiration_date, entitlement_expired_at=entitlement_expired_at, show_courseware_link=show_courseware_link, cert_status=cert_status, can_refund_entitlement=can_refund_entitlement, can_unenroll=can_unenroll, credit_status=credit_status, show_email_settings=show_email_settings, course_mode_info=course_mode_info, is_paid_course=is_paid_course, verification_status=course_verification_status, course_requirements=course_requirements, dashboard_index=dashboard_index, share_settings=share_settings, user=user, related_programs=related_programs, display_course_modes_on_dashboard=display_course_modes_on_dashboard, show_consent_link=show_consent_link, enterprise_customer_name=enterprise_customer_name, resume_button_url=resume_button_url, partner_managed_enrollment=partner_managed_enrollment' /> diff --git a/openedx/core/constants.py b/openedx/core/constants.py index ad16e9e595..a82065679e 100644 --- a/openedx/core/constants.py +++ b/openedx/core/constants.py @@ -1,4 +1,4 @@ -""" +""" # lint-amnesty, pylint: disable=django-not-configured Constants that are relevant to all of Open edX """ # These are standard regexes for pulling out info like course_ids, usage_ids, etc. diff --git a/openedx/core/djangoapps/api_admin/api/v1/tests/test_views.py b/openedx/core/djangoapps/api_admin/api/v1/tests/test_views.py index 0ce9380c06..d22fb9db7d 100644 --- a/openedx/core/djangoapps/api_admin/api/v1/tests/test_views.py +++ b/openedx/core/djangoapps/api_admin/api/v1/tests/test_views.py @@ -47,8 +47,8 @@ class ApiAccessRequestViewTests(TestCase): Assert API response on `API Access Request` endpoint. """ json_content = json.loads(api_response.content.decode('utf-8')) - self.assertEqual(api_response.status_code, 200) - self.assertEqual(json_content['count'], expected_results_count) + assert api_response.status_code == 200 + assert json_content['count'] == expected_results_count def test_list_view_for_not_authenticated_user(self): """ @@ -66,7 +66,7 @@ class ApiAccessRequestViewTests(TestCase): self.client.logout() response = self.client.get(self.url) - self.assertEqual(response.status_code, 401) + assert response.status_code == 401 def test_list_view_for_staff_user(self): """ @@ -94,5 +94,5 @@ class ApiAccessRequestViewTests(TestCase): self.update_user_and_re_login(is_staff=True) response = self.client.get(self.url + '?user__username={}'.format('non-existing-user-name')) - self.assertEqual(response.status_code, 200) + assert response.status_code == 200 self._assert_api_access_request_response(api_response=response, expected_results_count=0) diff --git a/openedx/core/djangoapps/api_admin/management/commands/tests/test_create_api_access_request.py b/openedx/core/djangoapps/api_admin/management/commands/tests/test_create_api_access_request.py index 3111f98356..159bb9fcd4 100644 --- a/openedx/core/djangoapps/api_admin/management/commands/tests/test_create_api_access_request.py +++ b/openedx/core/djangoapps/api_admin/management/commands/tests/test_create_api_access_request.py @@ -25,14 +25,8 @@ class TestCreateApiAccessRequest(TestCase): cls.user = UserFactory() def assert_models_exist(self, expect_request_exists, expect_config_exists): - self.assertEqual( - ApiAccessRequest.objects.filter(user=self.user).exists(), - expect_request_exists - ) - self.assertEqual( - ApiAccessConfig.objects.filter(enabled=True).exists(), - expect_config_exists - ) + assert ApiAccessRequest.objects.filter(user=self.user).exists() == expect_request_exists + assert ApiAccessConfig.objects.filter(enabled=True).exists() == expect_config_exists @ddt.data(False, True) def test_create_api_access_request(self, create_config): @@ -45,14 +39,14 @@ class TestCreateApiAccessRequest(TestCase): self.assert_models_exist(False, False) call_command(self.command, self.user.username, create_config=True, disconnect_signals=True) self.assert_models_exist(True, True) - self.assertFalse(mock_send_new_pending_email.called) + assert not mock_send_new_pending_email.called @patch('openedx.core.djangoapps.api_admin.models._send_new_pending_email') def test_create_api_access_request_signals_connected(self, mock_send_new_pending_email): self.assert_models_exist(False, False) call_command(self.command, self.user.username, create_config=True, disconnect_signals=False) self.assert_models_exist(True, True) - self.assertTrue(mock_send_new_pending_email.called) + assert mock_send_new_pending_email.called def test_config_already_exists(self): ApiAccessConfig.objects.create(enabled=True) @@ -125,12 +119,12 @@ class TestCreateApiAccessRequest(TestCase): ) self.assert_models_exist(True, False) request = ApiAccessRequest.objects.get(user=self.user) - self.assertEqual(request.status, 'approved') - self.assertEqual(request.reason, 'whatever') - self.assertEqual(request.website, 'test-site.edx.horse') + assert request.status == 'approved' + assert request.reason == 'whatever' + assert request.website == 'test-site.edx.horse' def test_default_values(self): call_command(self.command, self.user.username) request = ApiAccessRequest.objects.get(user=self.user) - self.assertEqual(request.site, Site.objects.get_current()) - self.assertEqual(request.status, ApiAccessRequest.APPROVED) + assert request.site == Site.objects.get_current() + assert request.status == ApiAccessRequest.APPROVED diff --git a/openedx/core/djangoapps/api_admin/tests/test_forms.py b/openedx/core/djangoapps/api_admin/tests/test_forms.py index 39c79c8081..af79e4b277 100644 --- a/openedx/core/djangoapps/api_admin/tests/test_forms.py +++ b/openedx/core/djangoapps/api_admin/tests/test_forms.py @@ -21,7 +21,7 @@ class ApiAccessFormTest(TestCase): @ddt.unpack def test_form_valid(self, data, is_valid): form = ApiAccessRequestForm(data) - self.assertEqual(form.is_valid(), is_valid) + assert form.is_valid() == is_valid @skip_unless_lms @@ -43,8 +43,8 @@ class ViewersWidgetTest(TestCase): extra_formating=extra_formating, ) output = self.widget.render(name=input_field_name, value=dummy_string_value) - self.assertEqual(expected_widget_html, output) + assert expected_widget_html == output dummy_list_value = ['staff', 'verified'] output = self.widget.render(name=input_field_name, value=dummy_list_value) - self.assertEqual(expected_widget_html, output) + assert expected_widget_html == output diff --git a/openedx/core/djangoapps/api_admin/tests/test_models.py b/openedx/core/djangoapps/api_admin/tests/test_models.py index 2db6fc8af3..98305e8966 100644 --- a/openedx/core/djangoapps/api_admin/tests/test_models.py +++ b/openedx/core/djangoapps/api_admin/tests/test_models.py @@ -3,6 +3,7 @@ from smtplib import SMTPException +import pytest import ddt import mock import six @@ -27,21 +28,21 @@ class ApiAccessRequestTests(TestCase): self.request = ApiAccessRequestFactory(user=self.user) def test_default_status(self): - self.assertEqual(self.request.status, ApiAccessRequest.PENDING) - self.assertFalse(ApiAccessRequest.has_api_access(self.user)) + assert self.request.status == ApiAccessRequest.PENDING + assert not ApiAccessRequest.has_api_access(self.user) def test_approve(self): self.request.approve() - self.assertEqual(self.request.status, ApiAccessRequest.APPROVED) + assert self.request.status == ApiAccessRequest.APPROVED def test_deny(self): self.request.deny() - self.assertEqual(self.request.status, ApiAccessRequest.DENIED) + assert self.request.status == ApiAccessRequest.DENIED def test_nonexistent_request(self): """Test that users who have not requested API access do not get it.""" other_user = UserFactory() - self.assertFalse(ApiAccessRequest.has_api_access(other_user)) + assert not ApiAccessRequest.has_api_access(other_user) @ddt.data( (ApiAccessRequest.PENDING, False), @@ -52,46 +53,40 @@ class ApiAccessRequestTests(TestCase): def test_has_access(self, status, should_have_access): self.request.status = status self.request.save() - self.assertEqual(ApiAccessRequest.has_api_access(self.user), should_have_access) + assert ApiAccessRequest.has_api_access(self.user) == should_have_access def test_unique_per_user(self): - with self.assertRaises(IntegrityError): + with pytest.raises(IntegrityError): ApiAccessRequestFactory(user=self.user) def test_no_access(self): self.request.delete() - self.assertIsNone(ApiAccessRequest.api_access_status(self.user)) + assert ApiAccessRequest.api_access_status(self.user) is None def test_unicode(self): request_unicode = six.text_type(self.request) - self.assertIn(self.request.website, request_unicode) - self.assertIn(self.request.status, request_unicode) + assert self.request.website in request_unicode + assert self.request.status in request_unicode def test_retire_user_success(self): retire_result = self.request.retire_user(self.user) - self.assertTrue(retire_result) - self.assertEqual(self.request.company_address, '') - self.assertEqual(self.request.company_name, '') - self.assertEqual(self.request.website, '') - self.assertEqual(self.request.reason, '') + assert retire_result + assert self.request.company_address == '' + assert self.request.company_name == '' + assert self.request.website == '' + assert self.request.reason == '' def test_retire_user_do_not_exist(self): user2 = UserFactory() retire_result = self.request.retire_user(user2) - self.assertFalse(retire_result) + assert not retire_result class ApiAccessConfigTests(TestCase): def test_unicode(self): - self.assertEqual( - six.text_type(ApiAccessConfig(enabled=True)), - u'ApiAccessConfig [enabled=True]' - ) - self.assertEqual( - six.text_type(ApiAccessConfig(enabled=False)), - u'ApiAccessConfig [enabled=False]' - ) + assert six.text_type(ApiAccessConfig(enabled=True)) == u'ApiAccessConfig [enabled=True]' + assert six.text_type(ApiAccessConfig(enabled=False)) == u'ApiAccessConfig [enabled=False]' @skip_unless_lms @@ -110,7 +105,7 @@ class ApiAccessRequestSignalTests(TestCase): self.api_access_request.save() mock_new_email.assert_called_once_with(self.api_access_request) - self.assertFalse(mock_decision_email.called) + assert not mock_decision_email.called def test_save_signal_success_decision_email(self): """ Verify that updating request status sends decision email and no new email. """ @@ -121,7 +116,7 @@ class ApiAccessRequestSignalTests(TestCase): self.api_access_request.approve() mock_decision_email.assert_called_once_with(self.api_access_request) - self.assertFalse(mock_new_email.called) + assert not mock_new_email.called def test_save_signal_success_no_emails(self): """ Verify that updating request status again sends no emails. """ @@ -132,12 +127,12 @@ class ApiAccessRequestSignalTests(TestCase): with mock.patch(self.send_decision_email_function) as mock_decision_email: self.api_access_request.deny() - self.assertFalse(mock_decision_email.called) - self.assertFalse(mock_new_email.called) + assert not mock_decision_email.called + assert not mock_new_email.called def test_save_signal_failure_email(self): """ Verify that saving still functions even on email errors. """ - self.assertIsNone(self.api_access_request.id) + assert self.api_access_request.id is None mail_function = 'openedx.core.djangoapps.api_admin.models.send_mail' with mock.patch(mail_function, side_effect=SMTPException): @@ -149,7 +144,7 @@ class ApiAccessRequestSignalTests(TestCase): u'Error sending API user notification email for request [%s].', self.api_access_request.id ) # Verify object saved - self.assertIsNotNone(self.api_access_request.id) + assert self.api_access_request.id is not None with mock.patch(mail_function, side_effect=SMTPException): with mock.patch.object(model_log, 'exception') as mock_model_log_exception: @@ -159,4 +154,4 @@ class ApiAccessRequestSignalTests(TestCase): u'Error sending API user notification email for request [%s].', self.api_access_request.id ) # Verify object saved - self.assertEqual(self.api_access_request.status, ApiAccessRequest.APPROVED) + assert self.api_access_request.status == ApiAccessRequest.APPROVED diff --git a/openedx/core/djangoapps/api_admin/tests/test_views.py b/openedx/core/djangoapps/api_admin/tests/test_views.py index b376c554e7..92416050f9 100644 --- a/openedx/core/djangoapps/api_admin/tests/test_views.py +++ b/openedx/core/djangoapps/api_admin/tests/test_views.py @@ -48,13 +48,13 @@ class ApiRequestViewTest(ApiAdminTest): def test_get(self): """Verify that a logged-in can see the API request form.""" response = self.client.get(self.url) - self.assertEqual(response.status_code, 200) + assert response.status_code == 200 def test_get_anonymous(self): """Verify that users must be logged in to see the page.""" self.client.logout() response = self.client.get(self.url) - self.assertEqual(response.status_code, 302) + assert response.status_code == 302 def test_get_with_existing_request(self): """ @@ -72,12 +72,12 @@ class ApiRequestViewTest(ApiAdminTest): """ self.assertRedirects(response, reverse('api_admin:api-status')) api_request = ApiAccessRequest.objects.get(user=self.user) - self.assertEqual(api_request.status, ApiAccessRequest.PENDING) + assert api_request.status == ApiAccessRequest.PENDING return api_request def test_post_valid(self): """Verify that a logged-in user can create an API request.""" - self.assertFalse(ApiAccessRequest.objects.all().exists()) + assert not ApiAccessRequest.objects.all().exists() response = self.client.post(self.url, VALID_DATA) self._assert_post_success(response) @@ -86,20 +86,20 @@ class ApiRequestViewTest(ApiAdminTest): self.client.logout() response = self.client.post(self.url, VALID_DATA) - self.assertEqual(response.status_code, 302) - self.assertFalse(ApiAccessRequest.objects.all().exists()) + assert response.status_code == 302 + assert not ApiAccessRequest.objects.all().exists() def test_get_with_feature_disabled(self): """Verify that the view can be disabled via ApiAccessConfig.""" ApiAccessConfig(enabled=False).save() response = self.client.get(self.url) - self.assertEqual(response.status_code, 404) + assert response.status_code == 404 def test_post_with_feature_disabled(self): """Verify that the view can be disabled via ApiAccessConfig.""" ApiAccessConfig(enabled=False).save() response = self.client.post(self.url) - self.assertEqual(response.status_code, 404) + assert response.status_code == 404 @skip_unless_lms @@ -155,13 +155,13 @@ class ApiRequestStatusViewTest(ApiAdminTest): """Verify that users must be logged in to see the page.""" self.client.logout() response = self.client.get(self.url) - self.assertEqual(response.status_code, 302) + assert response.status_code == 302 def test_get_with_feature_disabled(self): """Verify that the view can be disabled via ApiAccessConfig.""" ApiAccessConfig(enabled=False).save() response = self.client.get(self.url) - self.assertEqual(response.status_code, 404) + assert response.status_code == 404 @ddt.data( (ApiAccessRequest.APPROVED, True, True), @@ -188,15 +188,15 @@ class ApiRequestStatusViewTest(ApiAdminTest): }) applications = Application.objects.filter(user=self.user) if application_exists and new_application_created: - self.assertEqual(applications.count(), 1) - self.assertNotEqual(old_application, applications[0]) + assert applications.count() == 1 + assert old_application != applications[0] elif application_exists: - self.assertEqual(applications.count(), 1) - self.assertEqual(old_application, applications[0]) + assert applications.count() == 1 + assert old_application == applications[0] elif new_application_created: - self.assertEqual(applications.count(), 1) + assert applications.count() == 1 else: - self.assertEqual(applications.count(), 0) + assert applications.count() == 0 def test_post_with_errors(self): ApiAccessRequestFactory(user=self.user, status=ApiAccessRequest.APPROVED) @@ -233,7 +233,7 @@ class CatalogTest(ApiAdminTest): def mock_catalog_endpoint(self, data, catalog_id=None, method=httpretty.GET, status_code=200): """ Mock the Course Catalog API's catalog endpoint. """ - self.assertTrue(httpretty.is_enabled(), msg='httpretty must be enabled to mock Catalog API calls.') + assert httpretty.is_enabled(), 'httpretty must be enabled to mock Catalog API calls.' url = '{root}/catalogs/'.format(root=settings.COURSE_CATALOG_API_URL.rstrip('/')) if catalog_id: @@ -259,7 +259,7 @@ class CatalogSearchViewTest(CatalogTest): def test_get(self): response = self.client.get(self.url) - self.assertEqual(response.status_code, 200) + assert response.status_code == 200 @httpretty.activate def test_post(self): @@ -295,7 +295,7 @@ class CatalogListViewTest(CatalogTest): """Verify that the view works when no catalogs are set up.""" self.mock_catalog_endpoint({}, status_code=404) response = self.client.get(self.url) - self.assertEqual(response.status_code, 200) + assert response.status_code == 200 @httpretty.activate def test_post(self): @@ -307,7 +307,7 @@ class CatalogListViewTest(CatalogTest): catalog_id = 123 self.mock_catalog_endpoint(dict(catalog_data, id=catalog_id), method=httpretty.POST) response = self.client.post(self.url, catalog_data) - self.assertEqual(httpretty.last_request().method, 'POST') + assert httpretty.last_request().method == 'POST' self.mock_catalog_endpoint(CatalogFactory().attributes, catalog_id=catalog_id) self.assertRedirects(response, reverse('api_admin:catalog-edit', kwargs={'catalog_id': catalog_id})) @@ -320,9 +320,9 @@ class CatalogListViewTest(CatalogTest): 'query': '*', 'viewers': [self.catalog_user.username] }) - self.assertEqual(response.status_code, 400) + assert response.status_code == 400 # Assert that no POST was made to the catalog API - self.assertEqual(len([r for r in httpretty.httpretty.latest_requests if r.method == 'POST']), 0) + assert len([r for r in httpretty.httpretty.latest_requests if r.method == 'POST']) == 0 @skip_unless_lms @@ -351,12 +351,10 @@ class CatalogEditViewTest(CatalogTest): ) response = self.client.post(self.url, {'delete-catalog': 'on'}) self.assertRedirects(response, reverse('api_admin:catalog-search')) - self.assertEqual(httpretty.last_request().method, 'DELETE') - self.assertEqual( - httpretty.last_request().path, # lint-amnesty, pylint: disable=no-member - '/api/v1/catalogs/{}/'.format(self.catalog.id) - ) - self.assertEqual(len(httpretty.httpretty.latest_requests), 1) + 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 + assert len(httpretty.httpretty.latest_requests) == 1 @httpretty.activate def test_edit(self): @@ -371,9 +369,9 @@ class CatalogEditViewTest(CatalogTest): self.mock_catalog_endpoint(self.catalog.attributes, catalog_id=self.catalog.id) new_attributes = dict(self.catalog.attributes, **{'delete-catalog': 'off', 'name': ''}) response = self.client.post(self.url, new_attributes) - self.assertEqual(response.status_code, 400) + assert response.status_code == 400 # Assert that no PATCH was made to the Catalog API - self.assertEqual(len([r for r in httpretty.httpretty.latest_requests if r.method == 'PATCH']), 0) + assert len([r for r in httpretty.httpretty.latest_requests if r.method == 'PATCH']) == 0 @skip_unless_lms @@ -395,13 +393,10 @@ class CatalogPreviewViewTest(CatalogTest): content_type='application/json' ) response = self.client.get(self.url, {'q': '*'}) - self.assertEqual(response.status_code, 200) - self.assertEqual(json.loads(response.content.decode('utf-8')), data) + assert response.status_code == 200 + assert json.loads(response.content.decode('utf-8')) == data def test_get_without_query(self): response = self.client.get(self.url) - self.assertEqual(response.status_code, 200) - self.assertEqual( - json.loads(response.content.decode('utf-8')), - {'count': 0, 'results': [], 'next': None, 'prev': None} - ) + assert response.status_code == 200 + assert json.loads(response.content.decode('utf-8')) == {'count': 0, 'results': [], 'next': None, 'prev': None} diff --git a/openedx/core/djangoapps/bookmarks/tasks.py b/openedx/core/djangoapps/bookmarks/tasks.py index 179261852b..b656d48db8 100644 --- a/openedx/core/djangoapps/bookmarks/tasks.py +++ b/openedx/core/djangoapps/bookmarks/tasks.py @@ -6,7 +6,7 @@ Tasks for bookmarks. import logging import six -from celery.task import task +from celery import shared_task from django.db import transaction from edx_django_utils.monitoring import set_code_owner_attribute from opaque_keys.edx.keys import CourseKey @@ -145,7 +145,7 @@ def _update_xblocks_cache(course_key): update_block_cache_if_needed(block_cache, block_data) -@task(name=u'openedx.core.djangoapps.bookmarks.tasks.update_xblocks_cache') +@shared_task(name=u'openedx.core.djangoapps.bookmarks.tasks.update_xblocks_cache') @set_code_owner_attribute def update_xblocks_cache(course_id): """ diff --git a/openedx/core/djangoapps/ccxcon/tasks.py b/openedx/core/djangoapps/ccxcon/tasks.py index 2b36c0ae7a..65e7d0f085 100644 --- a/openedx/core/djangoapps/ccxcon/tasks.py +++ b/openedx/core/djangoapps/ccxcon/tasks.py @@ -3,7 +3,7 @@ This file contains celery tasks for ccxcon """ -from celery.task import task +from celery import shared_task from celery.utils.log import get_task_logger from edx_django_utils.monitoring import set_code_owner_attribute from opaque_keys.edx.keys import CourseKey @@ -14,7 +14,7 @@ from openedx.core.djangoapps.ccxcon import api log = get_task_logger(__name__) -@task(name='openedx.core.djangoapps.ccxcon.tasks.update_ccxcon') +@shared_task(name='openedx.core.djangoapps.ccxcon.tasks.update_ccxcon') @set_code_owner_attribute def update_ccxcon(course_id, cur_retry=0): """ diff --git a/openedx/core/djangoapps/content/block_structure/admin.py b/openedx/core/djangoapps/content/block_structure/admin.py index e3279c4c76..48c328bce6 100644 --- a/openedx/core/djangoapps/content/block_structure/admin.py +++ b/openedx/core/djangoapps/content/block_structure/admin.py @@ -17,7 +17,7 @@ class BlockStructureAdmin(ConfigurationModelAdmin): """ Excludes unused 'enabled field from super's list. """ - displayable_field_names = super(BlockStructureAdmin, self).get_displayable_field_names() + displayable_field_names = super(BlockStructureAdmin, self).get_displayable_field_names() # lint-amnesty, pylint: disable=super-with-arguments displayable_field_names.remove('enabled') return displayable_field_names diff --git a/openedx/core/djangoapps/content/block_structure/apps.py b/openedx/core/djangoapps/content/block_structure/apps.py index 48338f0d5f..23116e1fc7 100644 --- a/openedx/core/djangoapps/content/block_structure/apps.py +++ b/openedx/core/djangoapps/content/block_structure/apps.py @@ -21,4 +21,4 @@ class BlockStructureConfig(AppConfig): These happen at import time. Hence the unused imports """ - from . import signals, tasks # pylint: disable=unused-variable + from . import signals, tasks # lint-amnesty, pylint: disable=unused-import, unused-variable diff --git a/openedx/core/djangoapps/content/block_structure/block_structure.py b/openedx/core/djangoapps/content/block_structure/block_structure.py index c3568d3563..af2f3474cb 100644 --- a/openedx/core/djangoapps/content/block_structure/block_structure.py +++ b/openedx/core/djangoapps/content/block_structure/block_structure.py @@ -299,21 +299,21 @@ class FieldData(object): def __getattr__(self, field_name): if self._is_own_field(field_name): - return super(FieldData, self).__getattr__(field_name) + return super(FieldData, self).__getattr__(field_name) # lint-amnesty, pylint: disable=no-member, super-with-arguments try: return self.fields[field_name] except KeyError: - raise AttributeError(u"Field {0} does not exist".format(field_name)) + raise AttributeError(u"Field {0} does not exist".format(field_name)) # lint-amnesty, pylint: disable=raise-missing-from def __setattr__(self, field_name, field_value): if self._is_own_field(field_name): - return super(FieldData, self).__setattr__(field_name, field_value) + return super(FieldData, self).__setattr__(field_name, field_value) # lint-amnesty, pylint: disable=super-with-arguments else: self.fields[field_name] = field_value def __delattr__(self, field_name): if self._is_own_field(field_name): - return super(FieldData, self).__delattr__(field_name) + return super(FieldData, self).__delattr__(field_name) # lint-amnesty, pylint: disable=super-with-arguments else: del self.fields[field_name] @@ -329,7 +329,7 @@ class TransformerData(FieldData): """ Data structure to encapsulate collected data for a transformer. """ - pass + pass # lint-amnesty, pylint: disable=unnecessary-pass class TransformerDataMap(dict): @@ -383,10 +383,10 @@ class BlockData(FieldData): Data structure to encapsulate collected data for a single block. """ def class_field_names(self): - return super(BlockData, self).class_field_names() + ['location', 'transformer_data'] + return super(BlockData, self).class_field_names() + ['location', 'transformer_data'] # lint-amnesty, pylint: disable=super-with-arguments def __init__(self, usage_key): - super(BlockData, self).__init__() + super(BlockData, self).__init__() # lint-amnesty, pylint: disable=super-with-arguments # Location (or usage key) of the block. self.location = usage_key @@ -407,7 +407,7 @@ class BlockStructureBlockData(BlockStructure): VERSION = 2 def __init__(self, root_block_usage_key): - super(BlockStructureBlockData, self).__init__(root_block_usage_key) + super(BlockStructureBlockData, self).__init__(root_block_usage_key) # lint-amnesty, pylint: disable=super-with-arguments # Map of a block's usage key to its collected data, including # its xBlock fields and block-specific transformer data. @@ -750,7 +750,7 @@ class BlockStructureBlockData(BlockStructure): its current version number. """ if transformer.WRITE_VERSION == 0: - raise TransformerException(u'Version attributes are not set on transformer {0}.', transformer.name()) + raise TransformerException(u'Version attributes are not set on transformer {0}.', transformer.name()) # lint-amnesty, pylint: disable=raising-format-tuple self.set_transformer_data(transformer, TRANSFORMER_VERSION_KEY, transformer.WRITE_VERSION) def _get_or_create_block(self, usage_key): @@ -778,7 +778,7 @@ class BlockStructureModulestoreData(BlockStructureBlockData): interface and implementation of an xBlock. """ def __init__(self, root_block_usage_key): - super(BlockStructureModulestoreData, self).__init__(root_block_usage_key) + super(BlockStructureModulestoreData, self).__init__(root_block_usage_key) # lint-amnesty, pylint: disable=super-with-arguments # Map of a block's usage key to its instantiated xBlock. # dict {UsageKey: XBlock} diff --git a/openedx/core/djangoapps/content/block_structure/exceptions.py b/openedx/core/djangoapps/content/block_structure/exceptions.py index 750ac7a8f0..61e0356567 100644 --- a/openedx/core/djangoapps/content/block_structure/exceptions.py +++ b/openedx/core/djangoapps/content/block_structure/exceptions.py @@ -7,21 +7,21 @@ class BlockStructureException(Exception): """ Base class for all Block Structure framework exceptions. """ - pass + pass # lint-amnesty, pylint: disable=unnecessary-pass class TransformerException(BlockStructureException): """ Exception class for Transformer related errors. """ - pass + pass # lint-amnesty, pylint: disable=unnecessary-pass class UsageKeyNotInBlockStructure(BlockStructureException): """ Exception for when a usage key is not found within a block structure. """ - pass + pass # lint-amnesty, pylint: disable=unnecessary-pass class TransformerDataIncompatible(BlockStructureException): @@ -29,7 +29,7 @@ class TransformerDataIncompatible(BlockStructureException): Exception for when the version of a Transformer's data is not compatible with the current version of the Transformer. """ - pass + pass # lint-amnesty, pylint: disable=unnecessary-pass class BlockStructureNotFound(BlockStructureException): @@ -37,6 +37,6 @@ class BlockStructureNotFound(BlockStructureException): Exception for when a Block Structure is not found. """ def __init__(self, root_block_usage_key): - super(BlockStructureNotFound, self).__init__( + super(BlockStructureNotFound, self).__init__( # lint-amnesty, pylint: disable=super-with-arguments u'Block structure not found; data_usage_key: {}'.format(root_block_usage_key) ) diff --git a/openedx/core/djangoapps/content/block_structure/management/commands/tests/test_generate_course_blocks.py b/openedx/core/djangoapps/content/block_structure/management/commands/tests/test_generate_course_blocks.py index 150962713d..2c61c8f9b7 100644 --- a/openedx/core/djangoapps/content/block_structure/management/commands/tests/test_generate_course_blocks.py +++ b/openedx/core/djangoapps/content/block_structure/management/commands/tests/test_generate_course_blocks.py @@ -32,7 +32,7 @@ class TestGenerateCourseBlocks(ModuleStoreTestCase): """ Create courses in modulestore. """ - super(TestGenerateCourseBlocks, self).setUp() + super(TestGenerateCourseBlocks, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.courses = [CourseFactory.create() for _ in range(self.num_courses)] self.course_keys = [course.id for course in self.courses] self.command = generate_course_blocks.Command() diff --git a/openedx/core/djangoapps/content/block_structure/manager.py b/openedx/core/djangoapps/content/block_structure/manager.py index 63aa2fe3a6..5e95129253 100644 --- a/openedx/core/djangoapps/content/block_structure/manager.py +++ b/openedx/core/djangoapps/content/block_structure/manager.py @@ -71,7 +71,7 @@ class BlockStructureManager(object): # requested location. The rest of the structure will be pruned # as part of the transformation. if starting_block_usage_key not in block_structure: - raise UsageKeyNotInBlockStructure( + raise UsageKeyNotInBlockStructure( # lint-amnesty, pylint: disable=raising-format-tuple u"The requested usage_key '{0}' is not found in the block_structure with root '{1}'", six.text_type(starting_block_usage_key), six.text_type(self.root_block_usage_key), diff --git a/openedx/core/djangoapps/content/block_structure/models.py b/openedx/core/djangoapps/content/block_structure/models.py index f04f97dba5..d92767e5c7 100644 --- a/openedx/core/djangoapps/content/block_structure/models.py +++ b/openedx/core/djangoapps/content/block_structure/models.py @@ -102,10 +102,10 @@ class CustomizableFileField(models.FileField): storage=_bs_model_storage(), max_length=500, # allocate enough for base path + prefix + usage_key + timestamp in filepath )) - super(CustomizableFileField, self).__init__(*args, **kwargs) + super(CustomizableFileField, self).__init__(*args, **kwargs) # lint-amnesty, pylint: disable=super-with-arguments - def deconstruct(self): - name, path, args, kwargs = super(CustomizableFileField, self).deconstruct() + def deconstruct(self): # lint-amnesty, pylint: disable=missing-function-docstring + name, path, args, kwargs = super(CustomizableFileField, self).deconstruct() # lint-amnesty, pylint: disable=super-with-arguments del kwargs['upload_to'] del kwargs['storage'] del kwargs['max_length'] @@ -136,13 +136,13 @@ def _storage_error_handling(bs_model, operation, is_read_operation=False): yield except Exception as error: # pylint: disable=broad-except log.exception(u'BlockStructure: Exception %s on store %s; %s.', error.__class__, operation, bs_model) - if isinstance(error, OSError) and error.errno in (errno.EACCES, errno.EPERM): # pylint: disable=no-member + if isinstance(error, OSError) and error.errno in (errno.EACCES, errno.EPERM): # lint-amnesty, pylint: disable=no-else-raise, no-member raise elif is_read_operation and isinstance(error, (IOError, SuspiciousOperation)): # May have been caused by one of the possible error # situations listed above. Raise BlockStructureNotFound # so the block structure can be regenerated and restored. - raise BlockStructureNotFound(bs_model.data_usage_key) + raise BlockStructureNotFound(bs_model.data_usage_key) # lint-amnesty, pylint: disable=raise-missing-from else: raise @@ -216,7 +216,7 @@ class BlockStructureModel(TimeStampedModel): return cls.objects.get(data_usage_key=data_usage_key) except cls.DoesNotExist: log.info(u'BlockStructure: Not found in table; %s.', data_usage_key) - raise BlockStructureNotFound(data_usage_key) + raise BlockStructureNotFound(data_usage_key) # lint-amnesty, pylint: disable=raise-missing-from @classmethod def update_or_create(cls, serialized_data, data_usage_key, **kwargs): @@ -263,7 +263,7 @@ class BlockStructureModel(TimeStampedModel): try: all_files_by_date = sorted(cls._get_all_files(data_usage_key)) - files_to_delete = all_files_by_date[:-num_to_keep] if num_to_keep > 0 else all_files_by_date + files_to_delete = all_files_by_date[:-num_to_keep] if num_to_keep > 0 else all_files_by_date # lint-amnesty, pylint: disable=invalid-unary-operand-type cls._delete_files(files_to_delete) log.info( u'BlockStructure: Deleted %d out of total %d files in store; data_usage_key: %s, num_to_keep: %d.', diff --git a/openedx/core/djangoapps/content/block_structure/store.py b/openedx/core/djangoapps/content/block_structure/store.py index df1a23144b..cd249c9179 100644 --- a/openedx/core/djangoapps/content/block_structure/store.py +++ b/openedx/core/djangoapps/content/block_structure/store.py @@ -39,7 +39,7 @@ class StubModel(object): """ Noop delete method. """ - pass + pass # lint-amnesty, pylint: disable=unnecessary-pass class BlockStructureStore(object): @@ -216,7 +216,7 @@ class BlockStructureStore(object): # Somehow failed to de-serialized the data, assume it's corrupt. bs_model = self._get_model(root_block_usage_key) logger.exception(u"BlockStructure: Failed to load data from cache for %s", bs_model) - raise BlockStructureNotFound(bs_model.data_usage_key) + raise BlockStructureNotFound(bs_model.data_usage_key) # lint-amnesty, pylint: disable=raise-missing-from return BlockStructureFactory.create_new( root_block_usage_key, diff --git a/openedx/core/djangoapps/content/block_structure/tasks.py b/openedx/core/djangoapps/content/block_structure/tasks.py index 970f48e4cd..92fabc72b0 100644 --- a/openedx/core/djangoapps/content/block_structure/tasks.py +++ b/openedx/core/djangoapps/content/block_structure/tasks.py @@ -5,7 +5,7 @@ Asynchronous tasks related to the Course Blocks sub-application. import logging -from celery.task import task +from celery import shared_task from django.conf import settings from edx_django_utils.monitoring import set_code_owner_attribute from edxval.api import ValInternalError @@ -28,7 +28,7 @@ def block_structure_task(**kwargs): """ Decorator for block structure tasks. """ - return task( + return shared_task( default_retry_delay=settings.BLOCK_STRUCTURES_SETTINGS['TASK_DEFAULT_RETRY_DELAY'], max_retries=settings.BLOCK_STRUCTURES_SETTINGS['TASK_MAX_RETRIES'], bind=True, diff --git a/openedx/core/djangoapps/content/block_structure/tests/helpers.py b/openedx/core/djangoapps/content/block_structure/tests/helpers.py index d7750da7b8..effe8ef1ce 100644 --- a/openedx/core/djangoapps/content/block_structure/tests/helpers.py +++ b/openedx/core/djangoapps/content/block_structure/tests/helpers.py @@ -63,7 +63,7 @@ class MockXBlock(object): try: return self.field_map[attr] except KeyError: - raise AttributeError + raise AttributeError # lint-amnesty, pylint: disable=raise-missing-from def get_children(self): """ @@ -211,7 +211,7 @@ def clear_registered_transformers_cache(): """ Test helper to clear out any cached values of registered transformers. """ - TransformerRegistry.get_write_version_hash.cache.clear() + TransformerRegistry.get_write_version_hash.cache.clear() # lint-amnesty, pylint: disable=no-member @contextmanager @@ -224,7 +224,7 @@ def mock_registered_transformers(transformers): 'openedx.core.djangoapps.content.block_structure.transformer_registry.' 'TransformerRegistry.get_registered_transformers' ) as mock_available_transforms: - mock_available_transforms.return_value = {transformer for transformer in transformers} + mock_available_transforms.return_value = {transformer for transformer in transformers} # lint-amnesty, pylint: disable=unnecessary-comprehension yield @@ -336,7 +336,7 @@ class UsageKeyFactoryMixin(object): ChildrenMapTestMixin use integers for block_ids. """ def setUp(self): - super(UsageKeyFactoryMixin, self).setUp() + super(UsageKeyFactoryMixin, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.course_key = CourseLocator('org', 'course', six.text_type(uuid4())) def block_key_factory(self, block_id): diff --git a/openedx/core/djangoapps/content/block_structure/tests/test_factory.py b/openedx/core/djangoapps/content/block_structure/tests/test_factory.py index a79171e180..d2a8db4fb1 100644 --- a/openedx/core/djangoapps/content/block_structure/tests/test_factory.py +++ b/openedx/core/djangoapps/content/block_structure/tests/test_factory.py @@ -19,7 +19,7 @@ class TestBlockStructureFactory(TestCase, ChildrenMapTestMixin): """ def setUp(self): - super(TestBlockStructureFactory, self).setUp() + super(TestBlockStructureFactory, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.children_map = self.SIMPLE_CHILDREN_MAP self.modulestore = MockModulestoreFactory.create(self.children_map, self.block_key_factory) diff --git a/openedx/core/djangoapps/content/block_structure/tests/test_manager.py b/openedx/core/djangoapps/content/block_structure/tests/test_manager.py index 1c0d921426..7fca176020 100644 --- a/openedx/core/djangoapps/content/block_structure/tests/test_manager.py +++ b/openedx/core/djangoapps/content/block_structure/tests/test_manager.py @@ -102,7 +102,7 @@ class TestBlockStructureManager(UsageKeyFactoryMixin, ChildrenMapTestMixin, Test """ def setUp(self): - super(TestBlockStructureManager, self).setUp() + super(TestBlockStructureManager, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments TestTransformer1.collect_call_count = 0 self.registered_transformers = [TestTransformer1()] diff --git a/openedx/core/djangoapps/content/block_structure/tests/test_models.py b/openedx/core/djangoapps/content/block_structure/tests/test_models.py index 6e614874ea..81b4dd4f65 100644 --- a/openedx/core/djangoapps/content/block_structure/tests/test_models.py +++ b/openedx/core/djangoapps/content/block_structure/tests/test_models.py @@ -28,7 +28,7 @@ class BlockStructureModelTestCase(TestCase): Tests for BlockStructureModel. """ def setUp(self): - super(BlockStructureModelTestCase, self).setUp() + super(BlockStructureModelTestCase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.course_key = CourseLocator('org', 'course', six.text_type(uuid4())) self.usage_key = BlockUsageLocator(course_key=self.course_key, block_type='course', block_id='course') @@ -36,7 +36,7 @@ class BlockStructureModelTestCase(TestCase): def tearDown(self): BlockStructureModel._prune_files(self.usage_key, num_to_keep=0) - super(BlockStructureModelTestCase, self).tearDown() + super(BlockStructureModelTestCase, self).tearDown() # lint-amnesty, pylint: disable=super-with-arguments def _assert_bsm_fields(self, bsm, expected_serialized_data): """ @@ -161,7 +161,7 @@ class BlockStructureModelTestCase(TestCase): bs_model, _ = BlockStructureModel.update_or_create('test data', **self.params) with self.assertRaises(expected_error_raised): with _storage_error_handling(bs_model, 'operation', is_read_operation): - if errno_raised is not None: + if errno_raised is not None: # lint-amnesty, pylint: disable=no-else-raise raise error_raised_in_operation(errno_raised, message_raised) else: raise error_raised_in_operation diff --git a/openedx/core/djangoapps/content/block_structure/tests/test_signals.py b/openedx/core/djangoapps/content/block_structure/tests/test_signals.py index 99e3db6a61..33801db2da 100644 --- a/openedx/core/djangoapps/content/block_structure/tests/test_signals.py +++ b/openedx/core/djangoapps/content/block_structure/tests/test_signals.py @@ -25,7 +25,7 @@ class CourseBlocksSignalTest(ModuleStoreTestCase): ENABLED_SIGNALS = ['course_deleted', 'course_published'] def setUp(self): - super(CourseBlocksSignalTest, self).setUp() + super(CourseBlocksSignalTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.course = CourseFactory.create() self.course_usage_key = self.store.make_course_usage_key(self.course.id) diff --git a/openedx/core/djangoapps/content/block_structure/tests/test_store.py b/openedx/core/djangoapps/content/block_structure/tests/test_store.py index ef35a70139..7f1869bf02 100644 --- a/openedx/core/djangoapps/content/block_structure/tests/test_store.py +++ b/openedx/core/djangoapps/content/block_structure/tests/test_store.py @@ -23,7 +23,7 @@ class TestBlockStructureStore(UsageKeyFactoryMixin, ChildrenMapTestMixin, CacheI ENABLED_CACHES = ['default'] def setUp(self): - super(TestBlockStructureStore, self).setUp() + super(TestBlockStructureStore, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.children_map = self.SIMPLE_CHILDREN_MAP self.block_structure = self.create_block_structure(self.children_map) diff --git a/openedx/core/djangoapps/content/block_structure/tests/test_transformer_registry.py b/openedx/core/djangoapps/content/block_structure/tests/test_transformer_registry.py index 2f46bb34b9..214e95e51d 100644 --- a/openedx/core/djangoapps/content/block_structure/tests/test_transformer_registry.py +++ b/openedx/core/djangoapps/content/block_structure/tests/test_transformer_registry.py @@ -15,21 +15,21 @@ class TestTransformer1(MockTransformer): """ 1st test instance of the MockTransformer that is registered. """ - pass + pass # lint-amnesty, pylint: disable=unnecessary-pass class TestTransformer2(MockTransformer): """ 2nd test instance of the MockTransformer that is registered. """ - pass + pass # lint-amnesty, pylint: disable=unnecessary-pass class UnregisteredTestTransformer3(MockTransformer): """ 3rd test instance of the MockTransformer that is not registered. """ - pass + pass # lint-amnesty, pylint: disable=unnecessary-pass @ddt.ddt @@ -39,7 +39,7 @@ class TransformerRegistryTestCase(TestCase): """ def tearDown(self): - super(TransformerRegistryTestCase, self).tearDown() + super(TransformerRegistryTestCase, self).tearDown() # lint-amnesty, pylint: disable=super-with-arguments clear_registered_transformers_cache() @ddt.data( diff --git a/openedx/core/djangoapps/content/block_structure/tests/test_transformers.py b/openedx/core/djangoapps/content/block_structure/tests/test_transformers.py index 7cfbbdc2e2..48e3a0d670 100644 --- a/openedx/core/djangoapps/content/block_structure/tests/test_transformers.py +++ b/openedx/core/djangoapps/content/block_structure/tests/test_transformers.py @@ -22,10 +22,10 @@ class TestBlockStructureTransformers(ChildrenMapTestMixin, TestCase): """ Mock transformer that is not registered. """ - pass + pass # lint-amnesty, pylint: disable=unnecessary-pass def setUp(self): - super(TestBlockStructureTransformers, self).setUp() + super(TestBlockStructureTransformers, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.transformers = BlockStructureTransformers(usage_info=MagicMock()) self.registered_transformers = [MockTransformer(), MockFilteringTransformer()] diff --git a/openedx/core/djangoapps/content/block_structure/transformer.py b/openedx/core/djangoapps/content/block_structure/transformer.py index 31099a4a41..c63f2b082c 100644 --- a/openedx/core/djangoapps/content/block_structure/transformer.py +++ b/openedx/core/djangoapps/content/block_structure/transformer.py @@ -106,7 +106,7 @@ class BlockStructureTransformer(object): block structure that is to be modified with collected data to be cached for the transformer. """ - pass + pass # lint-amnesty, pylint: disable=unnecessary-pass @abstractmethod def transform(self, usage_info, block_structure): diff --git a/openedx/core/djangoapps/content/block_structure/transformers.py b/openedx/core/djangoapps/content/block_structure/transformers.py index 4c535e8e5e..a8ad687123 100644 --- a/openedx/core/djangoapps/content/block_structure/transformers.py +++ b/openedx/core/djangoapps/content/block_structure/transformers.py @@ -3,7 +3,7 @@ Module for a collection of BlockStructureTransformers. """ -import functools +import functools # lint-amnesty, pylint: disable=unused-import from logging import getLogger from .exceptions import TransformerDataIncompatible, TransformerException @@ -100,7 +100,7 @@ class BlockStructureTransformers(object): outdated_transformers.append(transformer) if outdated_transformers: - raise TransformerDataIncompatible( + raise TransformerDataIncompatible( # lint-amnesty, pylint: disable=raising-format-tuple u"Collected Block Structure data for the following transformers is outdated: '%s'.", [(transformer.name(), transformer.READ_VERSION) for transformer in outdated_transformers], ) diff --git a/openedx/core/djangoapps/content/course_overviews/apps.py b/openedx/core/djangoapps/content/course_overviews/apps.py index 82c04a0d19..d7976cf219 100644 --- a/openedx/core/djangoapps/content/course_overviews/apps.py +++ b/openedx/core/djangoapps/content/course_overviews/apps.py @@ -16,4 +16,4 @@ class CourseOverviewsConfig(AppConfig): def ready(self): # Import signals to activate signal handler which invalidates # the CourseOverview cache every time a course is published. - from . import signals # pylint: disable=unused-variable + from . import signals # lint-amnesty, pylint: disable=unused-import, unused-variable diff --git a/openedx/core/djangoapps/content/course_overviews/management/commands/generate_course_overview.py b/openedx/core/djangoapps/content/course_overviews/management/commands/generate_course_overview.py index aa42b5c11b..d235a07c85 100644 --- a/openedx/core/djangoapps/content/course_overviews/management/commands/generate_course_overview.py +++ b/openedx/core/djangoapps/content/course_overviews/management/commands/generate_course_overview.py @@ -73,4 +73,4 @@ class Command(BaseCommand): **kwargs ) except InvalidKeyError as exc: - raise CommandError(u'Invalid Course Key: ' + six.text_type(exc)) + raise CommandError(u'Invalid Course Key: ' + six.text_type(exc)) # lint-amnesty, pylint: disable=raise-missing-from diff --git a/openedx/core/djangoapps/content/course_overviews/management/commands/simulate_publish.py b/openedx/core/djangoapps/content/course_overviews/management/commands/simulate_publish.py index 5250ef5ca8..d132cc74c7 100644 --- a/openedx/core/djangoapps/content/course_overviews/management/commands/simulate_publish.py +++ b/openedx/core/djangoapps/content/course_overviews/management/commands/simulate_publish.py @@ -86,7 +86,7 @@ class Command(BaseCommand): dest='show_receivers', action='store_true', help=(u'Display the list of possible receiver functions and exit.') - ), + ), # lint-amnesty, pylint: disable=trailing-comma-tuple parser.add_argument( '--dry-run', dest='dry_run', @@ -96,7 +96,7 @@ class Command(BaseCommand): u"expensive modulestore query to find courses, but it will " u"not emit any signals." ) - ), + ), # lint-amnesty, pylint: disable=trailing-comma-tuple parser.add_argument( '--receivers', dest='receivers', @@ -142,7 +142,7 @@ class Command(BaseCommand): u"process. However, if you know what you're doing and need to " u"override that behavior, use this flag." ) - ), + ), # lint-amnesty, pylint: disable=trailing-comma-tuple parser.add_argument( '--skip-ccx', dest='skip_ccx', @@ -156,12 +156,12 @@ class Command(BaseCommand): u"if you know what you're doing, you can disable this behavior " u"with this flag, so that CCX receivers are omitted." ) - ), + ), # lint-amnesty, pylint: disable=trailing-comma-tuple parser.add_argument( '--args-from-database', action='store_true', help='Use arguments from the SimulateCoursePublishConfig model instead of the command line.', - ), + ), # lint-amnesty, pylint: disable=trailing-comma-tuple def get_args_from_database(self): """ Returns an options dictionary from the current SimulateCoursePublishConfig model. """ @@ -194,7 +194,7 @@ class Command(BaseCommand): if options['force_lms']: log.info("Forcing simulate_publish to run in LMS process.") else: - log.fatal( + log.fatal( # lint-amnesty, pylint: disable=logging-not-lazy u"simulate_publish should be run as a CMS (Studio) " + u"command, not %s (override with --force-lms).", os.environ.get('SERVICE_VARIANT') @@ -245,7 +245,7 @@ class Command(BaseCommand): log.info(u"%d receivers specified: %s", len(receiver_names), ", ".join(receiver_names)) receiver_names_set = set(receiver_names) for receiver_fn in get_receiver_fns(): - if receiver_fn == ccx_receiver_fn and not skip_ccx: + if receiver_fn == ccx_receiver_fn and not skip_ccx: # lint-amnesty, pylint: disable=comparison-with-callable continue fn_name = name_from_fn(receiver_fn) if fn_name not in receiver_names_set: diff --git a/openedx/core/djangoapps/content/course_overviews/management/commands/tests/test_generate_course_overview.py b/openedx/core/djangoapps/content/course_overviews/management/commands/tests/test_generate_course_overview.py index 6caab5297a..7c15e158e5 100644 --- a/openedx/core/djangoapps/content/course_overviews/management/commands/tests/test_generate_course_overview.py +++ b/openedx/core/djangoapps/content/course_overviews/management/commands/tests/test_generate_course_overview.py @@ -22,7 +22,7 @@ class TestGenerateCourseOverview(ModuleStoreTestCase): """ Create courses in modulestore. """ - super(TestGenerateCourseOverview, self).setUp() + super(TestGenerateCourseOverview, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.course_key_1 = CourseFactory.create().id self.course_key_2 = CourseFactory.create().id self.command = generate_course_overview.Command() diff --git a/openedx/core/djangoapps/content/course_overviews/management/commands/tests/test_simulate_publish.py b/openedx/core/djangoapps/content/course_overviews/management/commands/tests/test_simulate_publish.py index 103201fded..1be962f1a1 100644 --- a/openedx/core/djangoapps/content/course_overviews/management/commands/tests/test_simulate_publish.py +++ b/openedx/core/djangoapps/content/course_overviews/management/commands/tests/test_simulate_publish.py @@ -47,7 +47,7 @@ class TestSimulatePublish(SharedModuleStoreTestCase): might look like you can move this to setUpClass, but be very careful if doing so, to make sure side-effects don't leak out between tests. """ - super(TestSimulatePublish, self).setUp() + super(TestSimulatePublish, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments # Instead of using the process global SignalHandler.course_published, we # create our own SwitchedSignal to manually send to. @@ -79,7 +79,7 @@ class TestSimulatePublish(SharedModuleStoreTestCase): ) Command.course_published_signal.disconnect(self.sample_receiver_1) Command.course_published_signal.disconnect(self.sample_receiver_2) - super(TestSimulatePublish, self).tearDown() + super(TestSimulatePublish, self).tearDown() # lint-amnesty, pylint: disable=super-with-arguments def options(self, **kwargs): """ diff --git a/openedx/core/djangoapps/content/course_overviews/models.py b/openedx/core/djangoapps/content/course_overviews/models.py index 92922d5d1a..bab37b1e9e 100644 --- a/openedx/core/djangoapps/content/course_overviews/models.py +++ b/openedx/core/djangoapps/content/course_overviews/models.py @@ -131,7 +131,7 @@ class CourseOverview(TimeStampedModel): history = HistoricalRecords() @classmethod - def _create_or_update(cls, course): + def _create_or_update(cls, course): # lint-amnesty, pylint: disable=too-many-statements """ Creates or updates a CourseOverview object from a CourseDescriptor. @@ -184,7 +184,7 @@ class CourseOverview(TimeStampedModel): course_overview.version = cls.VERSION course_overview.id = course.id - course_overview._location = course.location + course_overview._location = course.location # lint-amnesty, pylint: disable=protected-access course_overview.org = course.location.org course_overview.display_name = display_name course_overview.display_number_with_default = course.display_number_with_default @@ -215,7 +215,7 @@ class CourseOverview(TimeStampedModel): course_overview.days_early_for_beta = course.days_early_for_beta course_overview.mobile_available = course.mobile_available course_overview.visible_to_staff_only = course.visible_to_staff_only - course_overview._pre_requisite_courses_json = json.dumps(course.pre_requisite_courses) + course_overview._pre_requisite_courses_json = json.dumps(course.pre_requisite_courses) # lint-amnesty, pylint: disable=protected-access course_overview.enrollment_start = course.enrollment_start course_overview.enrollment_end = course.enrollment_end @@ -306,7 +306,7 @@ class CourseOverview(TimeStampedModel): return course_overview elif course is not None: - raise IOError( + raise IOError( # lint-amnesty, pylint: disable=raising-format-tuple "Error while loading CourseOverview for course {} " "from the module store: {}", six.text_type(course_id), @@ -372,8 +372,14 @@ class CourseOverview(TimeStampedModel): # Regenerate the thumbnail images if they're missing (either because # they were never generated, or because they were flushed out after # a change to CourseOverviewImageConfig. - if course_overview and not hasattr(course_overview, 'image_set'): - CourseOverviewImageSet.create(course_overview) + if course_overview: + if hasattr(course_overview, 'image_set'): + image_set = course_overview.image_set + if not image_set.small_url or not image_set.large_url: + CourseOverviewImageSet.objects.filter(course_overview=course_overview).delete() + CourseOverviewImageSet.create(course_overview) + else: + CourseOverviewImageSet.create(course_overview) return course_overview or cls.load_from_module_store(course_id) @@ -586,7 +592,7 @@ class CourseOverview(TimeStampedModel): cause a lot of issues. These should not be mutable after construction, so for now we just eat this. """ - pass + pass # lint-amnesty, pylint: disable=unnecessary-pass @classmethod def update_select_courses(cls, course_keys, force_update=False): diff --git a/openedx/core/djangoapps/content/course_overviews/serializers.py b/openedx/core/djangoapps/content/course_overviews/serializers.py index 8e79d25e68..4559de94e9 100644 --- a/openedx/core/djangoapps/content/course_overviews/serializers.py +++ b/openedx/core/djangoapps/content/course_overviews/serializers.py @@ -17,7 +17,7 @@ class CourseOverviewBaseSerializer(serializers.ModelSerializer): fields = '__all__' def to_representation(self, instance): - representation = super(CourseOverviewBaseSerializer, self).to_representation(instance) + representation = super(CourseOverviewBaseSerializer, self).to_representation(instance) # lint-amnesty, pylint: disable=super-with-arguments representation['display_name_with_default'] = instance.display_name_with_default representation['has_started'] = instance.has_started() representation['has_ended'] = instance.has_ended() diff --git a/openedx/core/djangoapps/content/course_overviews/signals.py b/openedx/core/djangoapps/content/course_overviews/signals.py index 1ce66e3b0d..474391c4eb 100644 --- a/openedx/core/djangoapps/content/course_overviews/signals.py +++ b/openedx/core/djangoapps/content/course_overviews/signals.py @@ -62,7 +62,7 @@ def _check_for_course_date_changes(previous_course_overview, updated_course_over ) -def _log_start_date_change(previous_course_overview, updated_course_overview): +def _log_start_date_change(previous_course_overview, updated_course_overview): # lint-amnesty, pylint: disable=missing-function-docstring previous_start_str = 'None' if previous_course_overview.start is not None: previous_start_str = previous_course_overview.start.isoformat() diff --git a/openedx/core/djangoapps/content/course_overviews/tasks.py b/openedx/core/djangoapps/content/course_overviews/tasks.py index fd9e0e9387..2cb35b6deb 100644 --- a/openedx/core/djangoapps/content/course_overviews/tasks.py +++ b/openedx/core/djangoapps/content/course_overviews/tasks.py @@ -1,9 +1,9 @@ - +# lint-amnesty, pylint: disable=missing-module-docstring import logging import six -from celery import task +from celery import shared_task from celery_utils.persist_on_failure import LoggedPersistOnFailureTask from django.conf import settings from edx_django_utils.monitoring import set_code_owner_attribute @@ -27,7 +27,7 @@ def chunks(sequence, chunk_size): return (sequence[index: index + chunk_size] for index in range(0, len(sequence), chunk_size)) -def _task_options(routing_key): +def _task_options(routing_key): # lint-amnesty, pylint: disable=missing-function-docstring task_options = {} if getattr(settings, 'HIGH_MEM_QUEUE', None): task_options['routing_key'] = settings.HIGH_MEM_QUEUE @@ -36,7 +36,7 @@ def _task_options(routing_key): return task_options -def enqueue_async_course_overview_update_tasks( +def enqueue_async_course_overview_update_tasks( # lint-amnesty, pylint: disable=missing-function-docstring course_ids, all_courses=False, force_update=False, @@ -59,7 +59,7 @@ def enqueue_async_course_overview_update_tasks( ) -@task(base=LoggedPersistOnFailureTask) +@shared_task(base=LoggedPersistOnFailureTask) @set_code_owner_attribute def async_course_overview_update(*args, **kwargs): course_keys = [CourseKey.from_string(arg) for arg in args] diff --git a/openedx/core/djangoapps/content/course_overviews/tests/factories.py b/openedx/core/djangoapps/content/course_overviews/tests/factories.py index 8ade26bb10..5e6a758b78 100644 --- a/openedx/core/djangoapps/content/course_overviews/tests/factories.py +++ b/openedx/core/djangoapps/content/course_overviews/tests/factories.py @@ -1,4 +1,4 @@ - +# lint-amnesty, pylint: disable=missing-module-docstring from datetime import timedelta import json @@ -11,7 +11,7 @@ from opaque_keys.edx.locator import CourseLocator from ..models import CourseOverview -class CourseOverviewFactory(DjangoModelFactory): +class CourseOverviewFactory(DjangoModelFactory): # lint-amnesty, pylint: disable=missing-class-docstring class Meta(object): model = CourseOverview django_get_or_create = ('id', ) diff --git a/openedx/core/djangoapps/content/course_overviews/tests/test_api.py b/openedx/core/djangoapps/content/course_overviews/tests/test_api.py index 0735151fb2..452c263c4e 100644 --- a/openedx/core/djangoapps/content/course_overviews/tests/test_api.py +++ b/openedx/core/djangoapps/content/course_overviews/tests/test_api.py @@ -16,7 +16,7 @@ class TestCourseOverviewsApi(TestCase): """ def setUp(self): - super(TestCourseOverviewsApi, self).setUp() + super(TestCourseOverviewsApi, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments for _ in range(3): CourseOverviewFactory.create() diff --git a/openedx/core/djangoapps/content/course_overviews/tests/test_course_overviews.py b/openedx/core/djangoapps/content/course_overviews/tests/test_course_overviews.py index 96eb908749..86709ebe54 100644 --- a/openedx/core/djangoapps/content/course_overviews/tests/test_course_overviews.py +++ b/openedx/core/djangoapps/content/course_overviews/tests/test_course_overviews.py @@ -605,7 +605,7 @@ class CourseOverviewImageSetTestCase(ModuleStoreTestCase): def setUp(self): """Create an active CourseOverviewImageConfig with non-default values.""" self.set_config(True) - super(CourseOverviewImageSetTestCase, self).setUp() + super(CourseOverviewImageSetTestCase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments def _create_course_image(self, course, image_name): """ diff --git a/openedx/core/djangoapps/content/course_overviews/tests/test_serializers.py b/openedx/core/djangoapps/content/course_overviews/tests/test_serializers.py index 7dc5d6c1d0..87347038c9 100644 --- a/openedx/core/djangoapps/content/course_overviews/tests/test_serializers.py +++ b/openedx/core/djangoapps/content/course_overviews/tests/test_serializers.py @@ -16,7 +16,7 @@ class TestCourseOverviewSerializer(TestCase): """ def setUp(self): - super(TestCourseOverviewSerializer, self).setUp() + super(TestCourseOverviewSerializer, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments CourseOverviewFactory.create() def test_get_course_overview_serializer(self): diff --git a/openedx/core/djangoapps/content/course_overviews/tests/test_signals.py b/openedx/core/djangoapps/content/course_overviews/tests/test_signals.py index 7849a9d36f..37e9763ea9 100644 --- a/openedx/core/djangoapps/content/course_overviews/tests/test_signals.py +++ b/openedx/core/djangoapps/content/course_overviews/tests/test_signals.py @@ -1,4 +1,4 @@ - +# lint-amnesty, pylint: disable=missing-module-docstring import datetime @@ -70,7 +70,7 @@ class CourseOverviewSignalsTestCase(ModuleStoreTestCase): self.store.delete_course(course.id, ModuleStoreEnum.UserID.test) CourseOverview.get_from_id(course.id) - def assert_changed_signal_sent(self, field_name, initial_value, changed_value, mock_signal): + def assert_changed_signal_sent(self, field_name, initial_value, changed_value, mock_signal): # lint-amnesty, pylint: disable=missing-function-docstring course = CourseFactory.create(emit_signals=True, **{field_name: initial_value}) # changing display name doesn't fire the signal diff --git a/openedx/core/djangoapps/content/course_overviews/tests/test_tasks.py b/openedx/core/djangoapps/content/course_overviews/tests/test_tasks.py index 336ad2dcfe..ebb3f27914 100644 --- a/openedx/core/djangoapps/content/course_overviews/tests/test_tasks.py +++ b/openedx/core/djangoapps/content/course_overviews/tests/test_tasks.py @@ -1,4 +1,4 @@ - +# lint-amnesty, pylint: disable=missing-module-docstring import mock import six @@ -10,9 +10,9 @@ from xmodule.modulestore.tests.factories import CourseFactory from ..tasks import enqueue_async_course_overview_update_tasks -class BatchedAsyncCourseOverviewUpdateTests(ModuleStoreTestCase): +class BatchedAsyncCourseOverviewUpdateTests(ModuleStoreTestCase): # lint-amnesty, pylint: disable=missing-class-docstring def setUp(self): - super(BatchedAsyncCourseOverviewUpdateTests, self).setUp() + super(BatchedAsyncCourseOverviewUpdateTests, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.course_1 = CourseFactory.create(default_store=ModuleStoreEnum.Type.mongo) self.course_2 = CourseFactory.create(default_store=ModuleStoreEnum.Type.mongo) self.course_3 = CourseFactory.create(default_store=ModuleStoreEnum.Type.mongo) diff --git a/openedx/core/djangoapps/content/learning_sequences/api/__init__.py b/openedx/core/djangoapps/content/learning_sequences/api/__init__.py index 9436136139..e64f8bc293 100644 --- a/openedx/core/djangoapps/content/learning_sequences/api/__init__.py +++ b/openedx/core/djangoapps/content/learning_sequences/api/__init__.py @@ -1,3 +1,4 @@ +# lint-amnesty, pylint: disable=missing-module-docstring from .outlines import ( get_course_outline, get_user_course_outline, diff --git a/openedx/core/djangoapps/content/learning_sequences/api/outlines.py b/openedx/core/djangoapps/content/learning_sequences/api/outlines.py index 71c1ed49f6..764a000af1 100644 --- a/openedx/core/djangoapps/content/learning_sequences/api/outlines.py +++ b/openedx/core/djangoapps/content/learning_sequences/api/outlines.py @@ -6,14 +6,14 @@ __init__.py imports from here, and is a more stable place to import from. import logging from collections import defaultdict from datetime import datetime -from typing import Optional +from typing import Optional # lint-amnesty, pylint: disable=unused-import -import attr +import attr # lint-amnesty, pylint: disable=unused-import from django.contrib.auth import get_user_model from django.db import transaction -from edx_django_utils.cache import TieredCache, get_cache_key +from edx_django_utils.cache import TieredCache, get_cache_key # lint-amnesty, pylint: disable=unused-import from edx_django_utils.monitoring import function_trace -from opaque_keys.edx.keys import CourseKey, UsageKey +from opaque_keys.edx.keys import CourseKey, UsageKey # lint-amnesty, pylint: disable=unused-import from ..data import ( CourseLearningSequenceData, @@ -153,7 +153,7 @@ def _get_course_context_for_outline(course_key: CourseKey) -> CourseContext: ) except LearningContext.DoesNotExist: # Could happen if it hasn't been published. - raise CourseOutlineData.DoesNotExist( + raise CourseOutlineData.DoesNotExist( # lint-amnesty, pylint: disable=raise-missing-from "No CourseOutlineData for {}".format(course_key) ) return course_context @@ -197,7 +197,7 @@ def get_user_course_outline_details(course_key: CourseKey, ) -def _get_user_course_outline_and_processors(course_key: CourseKey, +def _get_user_course_outline_and_processors(course_key: CourseKey, # lint-amnesty, pylint: disable=missing-function-docstring user: User, at_time: datetime): full_course_outline = get_course_outline(course_key) diff --git a/openedx/core/djangoapps/content/learning_sequences/api/processors/base.py b/openedx/core/djangoapps/content/learning_sequences/api/processors/base.py index af98cb984c..773e8b0ed4 100644 --- a/openedx/core/djangoapps/content/learning_sequences/api/processors/base.py +++ b/openedx/core/djangoapps/content/learning_sequences/api/processors/base.py @@ -6,7 +6,7 @@ import logging from datetime import datetime from django.contrib.auth import get_user_model -from opaque_keys.edx.keys import CourseKey, UsageKey +from opaque_keys.edx.keys import CourseKey, UsageKey # lint-amnesty, pylint: disable=unused-import User = get_user_model() log = logging.getLogger(__name__) @@ -57,9 +57,9 @@ class OutlineProcessor: tens of milliseconds, even on courses with hundreds of learning sequences. """ - pass + pass # lint-amnesty, pylint: disable=unnecessary-pass - def inaccessible_sequences(self, full_course_outline): + def inaccessible_sequences(self, full_course_outline): # lint-amnesty, pylint: disable=unused-argument """ Return a set/frozenset of Sequence UsageKeys that are not accessible. @@ -68,7 +68,7 @@ class OutlineProcessor: """ return frozenset() - def usage_keys_to_remove(self, full_course_outline): + def usage_keys_to_remove(self, full_course_outline): # lint-amnesty, pylint: disable=unused-argument """ Return a set/frozenset of UsageKeys to remove altogether. diff --git a/openedx/core/djangoapps/content/learning_sequences/api/processors/content_gating.py b/openedx/core/djangoapps/content/learning_sequences/api/processors/content_gating.py index e327856230..0d779161d5 100644 --- a/openedx/core/djangoapps/content/learning_sequences/api/processors/content_gating.py +++ b/openedx/core/djangoapps/content/learning_sequences/api/processors/content_gating.py @@ -1,3 +1,4 @@ +# lint-amnesty, pylint: disable=missing-module-docstring import logging from datetime import datetime diff --git a/openedx/core/djangoapps/content/learning_sequences/api/processors/milestones.py b/openedx/core/djangoapps/content/learning_sequences/api/processors/milestones.py index d99398a102..03f8763faa 100644 --- a/openedx/core/djangoapps/content/learning_sequences/api/processors/milestones.py +++ b/openedx/core/djangoapps/content/learning_sequences/api/processors/milestones.py @@ -1,7 +1,8 @@ +# lint-amnesty, pylint: disable=missing-module-docstring import logging from django.contrib.auth import get_user_model -from opaque_keys.edx.keys import CourseKey +from opaque_keys.edx.keys import CourseKey # lint-amnesty, pylint: disable=unused-import from common.djangoapps.util import milestones_helpers from .base import OutlineProcessor diff --git a/openedx/core/djangoapps/content/learning_sequences/api/processors/schedule.py b/openedx/core/djangoapps/content/learning_sequences/api/processors/schedule.py index 5d2a437383..156202a68a 100644 --- a/openedx/core/djangoapps/content/learning_sequences/api/processors/schedule.py +++ b/openedx/core/djangoapps/content/learning_sequences/api/processors/schedule.py @@ -1,10 +1,11 @@ +# lint-amnesty, pylint: disable=missing-module-docstring import logging -from collections import defaultdict, OrderedDict +from collections import defaultdict, OrderedDict # lint-amnesty, pylint: disable=unused-import from datetime import datetime, timedelta from django.contrib.auth import get_user_model from edx_when.api import get_dates_for_course -from opaque_keys.edx.keys import CourseKey, UsageKey +from opaque_keys.edx.keys import CourseKey, UsageKey # lint-amnesty, pylint: disable=unused-import from common.djangoapps.student.auth import user_has_role from common.djangoapps.student.roles import CourseBetaTesterRole @@ -119,7 +120,7 @@ class ScheduleOutlineProcessor(OutlineProcessor): specified_dates = [date for date in dates if date is not None] return max(specified_dates) if specified_dates else None - pruned_section_keys = {section.usage_key for section in pruned_course_outline.sections} + pruned_section_keys = {section.usage_key for section in pruned_course_outline.sections} # lint-amnesty, pylint: disable=unused-variable course_usage_key = self.course_key.make_usage_key('course', 'course') course_start = self.keys_to_schedule_fields[course_usage_key].get('start') course_end = self.keys_to_schedule_fields[course_usage_key].get('end') diff --git a/openedx/core/djangoapps/content/learning_sequences/api/processors/special_exams.py b/openedx/core/djangoapps/content/learning_sequences/api/processors/special_exams.py index ee656ab24c..67d4ad8350 100644 --- a/openedx/core/djangoapps/content/learning_sequences/api/processors/special_exams.py +++ b/openedx/core/djangoapps/content/learning_sequences/api/processors/special_exams.py @@ -32,7 +32,7 @@ class SpecialExamsOutlineProcessor(OutlineProcessor): """ Check if special exams are enabled """ - self.special_exams_enabled = settings.FEATURES.get('ENABLE_SPECIAL_EXAMS', False) + self.special_exams_enabled = settings.FEATURES.get('ENABLE_SPECIAL_EXAMS', False) # lint-amnesty, pylint: disable=attribute-defined-outside-init def exam_data(self, pruned_course_outline: UserCourseOutlineData) -> SpecialExamAttemptData: """ diff --git a/openedx/core/djangoapps/content/learning_sequences/api/tests/test_data.py b/openedx/core/djangoapps/content/learning_sequences/api/tests/test_data.py index 47ed7d2579..d242a061cc 100644 --- a/openedx/core/djangoapps/content/learning_sequences/api/tests/test_data.py +++ b/openedx/core/djangoapps/content/learning_sequences/api/tests/test_data.py @@ -1,3 +1,4 @@ +# lint-amnesty, pylint: disable=missing-module-docstring from datetime import datetime, timezone from unittest import TestCase @@ -22,7 +23,7 @@ class TestCourseOutlineData(TestCase): test as needed. """ super().setUpClass() - normal_visibility = VisibilityData( + normal_visibility = VisibilityData( # lint-amnesty, pylint: disable=unused-variable hide_from_toc=False, visible_to_staff_only=False ) diff --git a/openedx/core/djangoapps/content/learning_sequences/api/tests/test_outlines.py b/openedx/core/djangoapps/content/learning_sequences/api/tests/test_outlines.py index d30a4e2af4..b4a0209ec7 100644 --- a/openedx/core/djangoapps/content/learning_sequences/api/tests/test_outlines.py +++ b/openedx/core/djangoapps/content/learning_sequences/api/tests/test_outlines.py @@ -7,18 +7,18 @@ from mock import patch import attr from django.conf import settings -from django.contrib.auth.models import AnonymousUser, User +from django.contrib.auth.models import AnonymousUser, User # lint-amnesty, pylint: disable=imported-auth-user from edx_proctoring.exceptions import ProctoredExamNotFoundException from edx_when.api import set_dates_for_course -from opaque_keys.edx.keys import CourseKey, UsageKey -from opaque_keys.edx.locator import BlockUsageLocator +from opaque_keys.edx.keys import CourseKey, UsageKey # lint-amnesty, pylint: disable=unused-import +from opaque_keys.edx.locator import BlockUsageLocator # lint-amnesty, pylint: disable=unused-import from edx_toggles.toggles.testutils import override_waffle_flag from lms.djangoapps.courseware.tests.factories import BetaTesterFactory from openedx.core.djangolib.testing.utils import CacheIsolationTestCase from openedx.features.course_experience import COURSE_ENABLE_UNENROLLED_ACCESS_FLAG from common.djangoapps.student.auth import user_has_role -from common.djangoapps.student.models import CourseEnrollment +from common.djangoapps.student.models import CourseEnrollment # lint-amnesty, pylint: disable=unused-import from common.djangoapps.student.roles import CourseBetaTesterRole from ...data import ( @@ -43,9 +43,9 @@ class CourseOutlineTestCase(CacheIsolationTestCase): Simple tests around reading and writing CourseOutlineData. No user info. """ @classmethod - def setUpTestData(cls): + def setUpTestData(cls): # lint-amnesty, pylint: disable=super-method-not-called cls.course_key = CourseKey.from_string("course-v1:OpenEdX+Learn+Roundtrip") - normal_visibility = VisibilityData( + normal_visibility = VisibilityData( # lint-amnesty, pylint: disable=unused-variable hide_from_toc=False, visible_to_staff_only=False ) @@ -65,12 +65,12 @@ class CourseOutlineTestCase(CacheIsolationTestCase): """Don't allow Old Mongo Courses at all.""" old_course_key = CourseKey.from_string("Org/Course/Run") with self.assertRaises(ValueError): - outline = get_course_outline(old_course_key) + outline = get_course_outline(old_course_key) # lint-amnesty, pylint: disable=unused-variable def test_simple_roundtrip(self): """Happy path for writing/reading-back a course outline.""" with self.assertRaises(CourseOutlineData.DoesNotExist): - course_outline = get_course_outline(self.course_key) + course_outline = get_course_outline(self.course_key) # lint-amnesty, pylint: disable=unused-variable replace_course_outline(self.course_outline) outline = get_course_outline(self.course_key) @@ -120,8 +120,8 @@ class CourseOutlineTestCase(CacheIsolationTestCase): # Make sure this new outline is returned instead of the previously # cached one. with self.assertNumQueries(3): - uncached_new_version_outline = get_course_outline(self.course_key) - assert new_version_outline == new_version_outline + uncached_new_version_outline = get_course_outline(self.course_key) # lint-amnesty, pylint: disable=unused-variable + assert new_version_outline == new_version_outline # lint-amnesty, pylint: disable=comparison-with-itself class UserCourseOutlineTestCase(CacheIsolationTestCase): @@ -130,7 +130,7 @@ class UserCourseOutlineTestCase(CacheIsolationTestCase): """ @classmethod - def setUpTestData(cls): + def setUpTestData(cls): # lint-amnesty, pylint: disable=super-method-not-called course_key = CourseKey.from_string("course-v1:OpenEdX+Outline+T1") # Users... cls.global_staff = User.objects.create_user( @@ -194,9 +194,9 @@ class UserCourseOutlineTestCase(CacheIsolationTestCase): assert global_staff_outline_details.outline == global_staff_outline -class OutlineProcessorTestCase(CacheIsolationTestCase): +class OutlineProcessorTestCase(CacheIsolationTestCase): # lint-amnesty, pylint: disable=missing-class-docstring @classmethod - def setUpTestData(cls): + def setUpTestData(cls): # lint-amnesty, pylint: disable=super-method-not-called cls.course_key = CourseKey.from_string("course-v1:OpenEdX+Outline+T1") # Users... @@ -221,7 +221,7 @@ class OutlineProcessorTestCase(CacheIsolationTestCase): def set_sequence_keys(cls, keys): cls.all_seq_keys = keys - def get_sequence_keys(self, exclude=None): + def get_sequence_keys(self, exclude=None): # lint-amnesty, pylint: disable=missing-function-docstring if exclude is None: exclude = [] if not isinstance(exclude, list): @@ -346,10 +346,10 @@ class ContentGatingTestCase(OutlineProcessorTestCase): """ Currently returns all, and only, sequences in required content, not just the first. This logic matches the existing transformer. Is this right? - """ + """ # lint-amnesty, pylint: disable=pointless-string-statement - @patch('openedx.core.djangoapps.content.learning_sequences.api.processors.content_gating.EntranceExamConfiguration.user_can_skip_entrance_exam') - @patch('openedx.core.djangoapps.content.learning_sequences.api.processors.content_gating.milestones_helpers.get_required_content') + @patch('openedx.core.djangoapps.content.learning_sequences.api.processors.content_gating.EntranceExamConfiguration.user_can_skip_entrance_exam') # lint-amnesty, pylint: disable=line-too-long + @patch('openedx.core.djangoapps.content.learning_sequences.api.processors.content_gating.milestones_helpers.get_required_content') # lint-amnesty, pylint: disable=line-too-long def test_user_can_skip_entrance_exam(self, required_content_mock, user_can_skip_entrance_exam_mock): required_content_mock.return_value = [str(self.entrance_exam_section_key)] user_can_skip_entrance_exam_mock.return_value = True @@ -363,8 +363,8 @@ class ContentGatingTestCase(OutlineProcessorTestCase): # Student can access all sequences assert len(student_details.outline.accessible_sequences) == 3 - @patch('openedx.core.djangoapps.content.learning_sequences.api.processors.content_gating.EntranceExamConfiguration.user_can_skip_entrance_exam') - @patch('openedx.core.djangoapps.content.learning_sequences.api.processors.content_gating.milestones_helpers.get_required_content') + @patch('openedx.core.djangoapps.content.learning_sequences.api.processors.content_gating.EntranceExamConfiguration.user_can_skip_entrance_exam') # lint-amnesty, pylint: disable=line-too-long + @patch('openedx.core.djangoapps.content.learning_sequences.api.processors.content_gating.milestones_helpers.get_required_content') # lint-amnesty, pylint: disable=line-too-long def test_user_can_not_skip_entrance_exam(self, required_content_mock, user_can_skip_entrance_exam_mock): required_content_mock.return_value = [str(self.entrance_exam_section_key)] user_can_skip_entrance_exam_mock.return_value = False @@ -460,7 +460,7 @@ class MilestonesTestCase(OutlineProcessorTestCase): # Enroll student in the course cls.student.courseenrollment_set.create(course_id=cls.course_key, is_active=True, mode="audit") - @patch('openedx.core.djangoapps.content.learning_sequences.api.processors.milestones.milestones_helpers.get_course_content_milestones') + @patch('openedx.core.djangoapps.content.learning_sequences.api.processors.milestones.milestones_helpers.get_course_content_milestones') # lint-amnesty, pylint: disable=line-too-long def test_user_can_skip_entrance_exam(self, get_course_content_milestones_mock): # Only return that there are milestones required for the # milestones_required_seq_key usage key @@ -763,7 +763,7 @@ class ScheduleTestCase(OutlineProcessorTestCase): assert len(beta_tester_details.outline.accessible_sequences) == 4 -class SelfPacedTestCase(OutlineProcessorTestCase): +class SelfPacedTestCase(OutlineProcessorTestCase): # lint-amnesty, pylint: disable=missing-class-docstring @classmethod def setUpTestData(cls): @@ -844,7 +844,7 @@ class SelfPacedTestCase(OutlineProcessorTestCase): cls.student.courseenrollment_set.create(course_id=cls.course_key, is_active=True, mode="audit") def test_sequences_accessible_after_due(self): - at_time = datetime(2020, 5, 22, tzinfo=timezone.utc) + at_time = datetime(2020, 5, 22, tzinfo=timezone.utc) # lint-amnesty, pylint: disable=unused-variable staff_details, student_details, _ = self.get_details( datetime(2020, 5, 25, tzinfo=timezone.utc) @@ -859,7 +859,7 @@ class SelfPacedTestCase(OutlineProcessorTestCase): assert len(student_details.outline.accessible_sequences) == 2 -class SpecialExamsTestCase(OutlineProcessorTestCase): +class SpecialExamsTestCase(OutlineProcessorTestCase): # lint-amnesty, pylint: disable=missing-class-docstring @classmethod def setUpTestData(cls): @@ -964,7 +964,7 @@ class SpecialExamsTestCase(OutlineProcessorTestCase): @patch.dict(settings.FEATURES, {'ENABLE_SPECIAL_EXAMS': True}) def test_special_exams_enabled_all_sequences_visible(self): - at_time = datetime(2020, 5, 22, tzinfo=timezone.utc) + at_time = datetime(2020, 5, 22, tzinfo=timezone.utc) # lint-amnesty, pylint: disable=unused-variable staff_details, student_details, _ = self.get_details( datetime(2020, 5, 25, tzinfo=timezone.utc) @@ -980,7 +980,7 @@ class SpecialExamsTestCase(OutlineProcessorTestCase): @patch.dict(settings.FEATURES, {'ENABLE_SPECIAL_EXAMS': False}) def test_special_exams_disabled_preserves_exam_sequences(self): - at_time = datetime(2020, 5, 22, tzinfo=timezone.utc) + at_time = datetime(2020, 5, 22, tzinfo=timezone.utc) # lint-amnesty, pylint: disable=unused-variable staff_details, student_details, _ = self.get_details( datetime(2020, 5, 25, tzinfo=timezone.utc) @@ -1000,7 +1000,7 @@ class SpecialExamsTestCase(OutlineProcessorTestCase): @patch.dict(settings.FEATURES, {'ENABLE_SPECIAL_EXAMS': True}) @patch('openedx.core.djangoapps.content.learning_sequences.api.processors.special_exams.get_attempt_status_summary') def test_special_exam_attempt_data_in_details(self, mock_get_attempt_status_summary): - at_time = datetime(2020, 5, 22, tzinfo=timezone.utc) + at_time = datetime(2020, 5, 22, tzinfo=timezone.utc) # lint-amnesty, pylint: disable=unused-variable def get_attempt_status_side_effect(user_id, _course_key, usage_key): """ @@ -1011,7 +1011,7 @@ class SpecialExamsTestCase(OutlineProcessorTestCase): for sequence_key in self.get_sequence_keys(exclude=[self.seq_normal_key]): if usage_key == str(sequence_key): - num_fake_attempts = mock_get_attempt_status_summary.call_count % len(self.all_seq_keys) + num_fake_attempts = mock_get_attempt_status_summary.call_count % len(self.all_seq_keys) # lint-amnesty, pylint: disable=unused-variable return { "summary": { "usage_key": usage_key @@ -1028,13 +1028,13 @@ class SpecialExamsTestCase(OutlineProcessorTestCase): for sequence_key in self.get_sequence_keys(exclude=[self.seq_normal_key]): assert sequence_key in student_details.special_exam_attempts.sequences attempt_summary = student_details.special_exam_attempts.sequences[sequence_key] - assert type(attempt_summary) == dict + assert type(attempt_summary) == dict # lint-amnesty, pylint: disable=unidiomatic-typecheck assert attempt_summary["summary"]["usage_key"] == str(sequence_key) @patch.dict(settings.FEATURES, {'ENABLE_SPECIAL_EXAMS': False}) @patch('openedx.core.djangoapps.content.learning_sequences.api.processors.special_exams.get_attempt_status_summary') def test_special_exam_attempt_data_empty_when_disabled(self, mock_get_attempt_status_summary): - at_time = datetime(2020, 5, 22, tzinfo=timezone.utc) + at_time = datetime(2020, 5, 22, tzinfo=timezone.utc) # lint-amnesty, pylint: disable=unused-variable _, student_details, _ = self.get_details( datetime(2020, 5, 25, tzinfo=timezone.utc) @@ -1130,7 +1130,7 @@ class VisbilityTestCase(OutlineProcessorTestCase): cls.student.courseenrollment_set.create(course_id=cls.course_key, is_active=True, mode="audit") def test_visibility(self): - at_time = datetime(2020, 5, 21, tzinfo=timezone.utc) # Exact value doesn't matter + at_time = datetime(2020, 5, 21, tzinfo=timezone.utc) # Exact value doesn't matter # lint-amnesty, pylint: disable=unused-variable staff_details, student_details, _ = self.get_details( datetime(2020, 5, 25, tzinfo=timezone.utc) diff --git a/openedx/core/djangoapps/content/learning_sequences/apps.py b/openedx/core/djangoapps/content/learning_sequences/apps.py index 0cddb30949..580e39f6ec 100644 --- a/openedx/core/djangoapps/content/learning_sequences/apps.py +++ b/openedx/core/djangoapps/content/learning_sequences/apps.py @@ -1,8 +1,9 @@ +# lint-amnesty, pylint: disable=missing-module-docstring from django.apps import AppConfig from django.utils.translation import ugettext_lazy as _ -class LearningSequencesConfig(AppConfig): +class LearningSequencesConfig(AppConfig): # lint-amnesty, pylint: disable=missing-class-docstring name = 'openedx.core.djangoapps.content.learning_sequences' verbose_name = _('Learning Sequences') diff --git a/openedx/core/djangoapps/content/learning_sequences/data.py b/openedx/core/djangoapps/content/learning_sequences/data.py index 4e37a5c0df..d82e7707a7 100644 --- a/openedx/core/djangoapps/content/learning_sequences/data.py +++ b/openedx/core/djangoapps/content/learning_sequences/data.py @@ -24,7 +24,7 @@ Note: we're using old-style syntax for attrs because we need to support Python TODO: Validate all datetimes to be UTC. """ import logging -from datetime import datetime, timezone +from datetime import datetime, timezone # lint-amnesty, pylint: disable=unused-import from enum import Enum from typing import Dict, List, Optional, Set @@ -47,7 +47,7 @@ class ObjectDoesNotExist(Exception): Imitating Django model conventions, we put a subclass of this in some of our data classes to indicate when something is not found. """ - pass + pass # lint-amnesty, pylint: disable=unnecessary-pass @attr.s(frozen=True) @@ -168,7 +168,7 @@ class CourseOutlineData: sequences = {} for section in self.sections: for seq in section.sequences: - if seq.usage_key in sequences: + if seq.usage_key in sequences: # lint-amnesty, pylint: disable=no-else-raise raise ValueError( "Sequence {} appears in more than one Section." .format(seq.usage_key) @@ -220,7 +220,7 @@ class CourseOutlineData: ) @days_early_for_beta.validator - def validate_days_early_for_beta(self, attribute, value): + def validate_days_early_for_beta(self, attribute, value): # lint-amnesty, pylint: disable=unused-argument """ Ensure that days_early_for_beta isn't negative. """ diff --git a/openedx/core/djangoapps/content/learning_sequences/models.py b/openedx/core/djangoapps/content/learning_sequences/models.py index e5e37dc151..1bad6a2757 100644 --- a/openedx/core/djangoapps/content/learning_sequences/models.py +++ b/openedx/core/djangoapps/content/learning_sequences/models.py @@ -40,7 +40,7 @@ not guaranteed to stick around, and values may be deleted unexpectedly. from django.db import models from model_utils.models import TimeStampedModel -from opaque_keys.edx.django.models import ( +from opaque_keys.edx.django.models import ( # lint-amnesty, pylint: disable=unused-import CourseKeyField, LearningContextKeyField, UsageKeyField ) from .data import CourseVisibility diff --git a/openedx/core/djangoapps/content/learning_sequences/tests/test_views.py b/openedx/core/djangoapps/content/learning_sequences/tests/test_views.py index 7bac8f10f4..24b95ba927 100644 --- a/openedx/core/djangoapps/content/learning_sequences/tests/test_views.py +++ b/openedx/core/djangoapps/content/learning_sequences/tests/test_views.py @@ -15,8 +15,8 @@ from this app, edx-when's set_dates_for_course). """ from datetime import datetime, timezone -from django.contrib.auth.models import User -from opaque_keys.edx.keys import CourseKey, UsageKey +from django.contrib.auth.models import User # lint-amnesty, pylint: disable=imported-auth-user, unused-import +from opaque_keys.edx.keys import CourseKey, UsageKey # lint-amnesty, pylint: disable=unused-import from rest_framework.test import APITestCase, APIClient from openedx.core.djangolib.testing.utils import CacheIsolationTestCase @@ -27,10 +27,10 @@ from ..data import CourseOutlineData, CourseVisibility from ..api.tests.test_data import generate_sections -class CourseOutlineViewTest(CacheIsolationTestCase, APITestCase): +class CourseOutlineViewTest(CacheIsolationTestCase, APITestCase): # lint-amnesty, pylint: disable=missing-class-docstring @classmethod - def setUpTestData(cls): + def setUpTestData(cls): # lint-amnesty, pylint: disable=super-method-not-called cls.staff = UserFactory.create( username='staff', email='staff@example.com', is_staff=True, password='staff_pass' ) diff --git a/openedx/core/djangoapps/content/learning_sequences/urls.py b/openedx/core/djangoapps/content/learning_sequences/urls.py index 7681ecbbbb..c4c00ce51e 100644 --- a/openedx/core/djangoapps/content/learning_sequences/urls.py +++ b/openedx/core/djangoapps/content/learning_sequences/urls.py @@ -1,3 +1,4 @@ +# lint-amnesty, pylint: disable=missing-module-docstring from django.conf.urls import url from .views import CourseOutlineView diff --git a/openedx/core/djangoapps/content/learning_sequences/views.py b/openedx/core/djangoapps/content/learning_sequences/views.py index f39d8764d2..aab74427bb 100644 --- a/openedx/core/djangoapps/content/learning_sequences/views.py +++ b/openedx/core/djangoapps/content/learning_sequences/views.py @@ -3,7 +3,7 @@ The views.py for this app is intentionally thin, and only exists to translate user input/output to and from the business logic in the `api` package. """ from datetime import datetime, timezone -import json +import json # lint-amnesty, pylint: disable=unused-import import logging from django.conf import settings @@ -15,7 +15,7 @@ from opaque_keys.edx.keys import CourseKey from rest_framework.views import APIView from rest_framework.response import Response from rest_framework import serializers -import attr +import attr # lint-amnesty, pylint: disable=unused-import from openedx.core.lib.api.permissions import IsStaff from .api import get_user_course_outline_details @@ -34,7 +34,7 @@ class CourseOutlineView(APIView): # For early testing, restrict this to only global staff... permission_classes = (IsStaff,) - class UserCourseOutlineDataSerializer(serializers.BaseSerializer): + class UserCourseOutlineDataSerializer(serializers.BaseSerializer): # lint-amnesty, pylint: disable=abstract-method """ Read-only serializer for CourseOutlineData for this endpoint. @@ -54,7 +54,7 @@ class CourseOutlineView(APIView): are a critical part of the internals of edx-platform, so the in-process API uses them, but we translate them to "ids" for REST API clients. """ - def to_representation(self, user_course_outline_details): + def to_representation(self, user_course_outline_details): # lint-amnesty, pylint: disable=arguments-differ """ Convert to something DRF knows how to serialize (so no custom types) @@ -150,7 +150,7 @@ class CourseOutlineView(APIView): **schedule_item_dict, } - def get(self, request, course_key_str, format=None): + def get(self, request, course_key_str, format=None): # lint-amnesty, pylint: disable=redefined-builtin, unused-argument """ The CourseOutline, customized for a given user. @@ -169,11 +169,11 @@ class CourseOutlineView(APIView): serializer = self.UserCourseOutlineDataSerializer(user_course_outline_details) return Response(serializer.data) - def _validate_course_key(self, course_key_str): + def _validate_course_key(self, course_key_str): # lint-amnesty, pylint: disable=missing-function-docstring try: course_key = CourseKey.from_string(course_key_str) except InvalidKeyError: - raise serializers.ValidationError( + raise serializers.ValidationError( # lint-amnesty, pylint: disable=raise-missing-from "{} is not a valid CourseKey".format(course_key_str) ) if course_key.deprecated: diff --git a/openedx/core/djangoapps/content_libraries/api.py b/openedx/core/djangoapps/content_libraries/api.py index 728432f0c1..75f0510fe2 100644 --- a/openedx/core/djangoapps/content_libraries/api.py +++ b/openedx/core/djangoapps/content_libraries/api.py @@ -222,7 +222,7 @@ class LibraryBundleLink: opaque_key = attr.ib(type=LearningContextKey, default=None) -class AccessLevel: +class AccessLevel: # lint-amnesty, pylint: disable=function-redefined """ Enum defining library access levels/permissions """ ADMIN_LEVEL = ContentLibraryPermission.ADMIN_LEVEL AUTHOR_LEVEL = ContentLibraryPermission.AUTHOR_LEVEL @@ -407,7 +407,7 @@ def create_library( ) except IntegrityError: delete_bundle(bundle.uuid) - raise LibraryAlreadyExists(slug) + raise LibraryAlreadyExists(slug) # lint-amnesty, pylint: disable=raise-missing-from CONTENT_LIBRARY_CREATED.send(sender=None, library_key=ref.library_key) return ContentLibraryMetadata( key=ref.library_key, @@ -1015,7 +1015,7 @@ def update_bundle_link(library_key, link_id, version=None, delete=False): try: link = links[link_id] except KeyError: - raise InvalidNameError("That link does not exist.") + raise InvalidNameError("That link does not exist.") # lint-amnesty, pylint: disable=raise-missing-from if version is None: version = get_bundle(link.bundle_uuid).latest_version set_draft_link(draft.uuid, link_id, link.bundle_uuid, version) diff --git a/openedx/core/djangoapps/content_libraries/library_bundle.py b/openedx/core/djangoapps/content_libraries/library_bundle.py index 9a566652a9..98716a3615 100644 --- a/openedx/core/djangoapps/content_libraries/library_bundle.py +++ b/openedx/core/djangoapps/content_libraries/library_bundle.py @@ -3,7 +3,7 @@ Helper code for working with Blockstore bundles that contain OLX """ import dateutil.parser -import logging +import logging # lint-amnesty, pylint: disable=wrong-import-order from django.utils.lru_cache import lru_cache from opaque_keys.edx.locator import BundleDefinitionLocator, LibraryUsageLocatorV2 diff --git a/openedx/core/djangoapps/content_libraries/library_context.py b/openedx/core/djangoapps/content_libraries/library_context.py index f7d6ac010a..b65aa12f16 100644 --- a/openedx/core/djangoapps/content_libraries/library_context.py +++ b/openedx/core/djangoapps/content_libraries/library_context.py @@ -27,7 +27,7 @@ class LibraryContextImpl(LearningContext): """ def __init__(self, **kwargs): - super(LibraryContextImpl, self).__init__(**kwargs) + super(LibraryContextImpl, self).__init__(**kwargs) # lint-amnesty, pylint: disable=super-with-arguments self.use_draft = kwargs.get('use_draft', None) def can_edit_block(self, user, usage_key): @@ -88,7 +88,7 @@ class LibraryContextImpl(LearningContext): bundle_uuid = bundle_uuid_for_library_key(library_key) except ContentLibrary.DoesNotExist: return None - if 'force_draft' in kwargs: + if 'force_draft' in kwargs: # lint-amnesty, pylint: disable=consider-using-get use_draft = kwargs['force_draft'] else: use_draft = self.use_draft diff --git a/openedx/core/djangoapps/content_libraries/management/commands/reindex_content_library.py b/openedx/core/djangoapps/content_libraries/management/commands/reindex_content_library.py index 8a3f3fa2c4..a316729d6c 100644 --- a/openedx/core/djangoapps/content_libraries/management/commands/reindex_content_library.py +++ b/openedx/core/djangoapps/content_libraries/management/commands/reindex_content_library.py @@ -1,4 +1,4 @@ -""" Management command to update content libraries' search index """ +""" Management command to update content libraries' search index """ # lint-amnesty, pylint: disable=cyclic-import import logging diff --git a/openedx/core/djangoapps/content_libraries/models.py b/openedx/core/djangoapps/content_libraries/models.py index 94b23189f2..11dd330745 100644 --- a/openedx/core/djangoapps/content_libraries/models.py +++ b/openedx/core/djangoapps/content_libraries/models.py @@ -11,8 +11,8 @@ from openedx.core.djangoapps.content_libraries.constants import ( LIBRARY_TYPES, COMPLEX, LICENSE_OPTIONS, ALL_RIGHTS_RESERVED, ) -from organizations.models import Organization -import six +from organizations.models import Organization # lint-amnesty, pylint: disable=wrong-import-order +import six # lint-amnesty, pylint: disable=wrong-import-order User = get_user_model() @@ -113,7 +113,7 @@ class ContentLibraryPermission(models.Model): ('library', 'group'), ] - def save(self, *args, **kwargs): # pylint: disable=arguments-differ + def save(self, *args, **kwargs): # lint-amnesty, pylint: disable=arguments-differ, signature-differs """ Validate any constraints on the model. diff --git a/openedx/core/djangoapps/content_libraries/permissions.py b/openedx/core/djangoapps/content_libraries/permissions.py index e8d3261ee6..6e3ea45a08 100644 --- a/openedx/core/djangoapps/content_libraries/permissions.py +++ b/openedx/core/djangoapps/content_libraries/permissions.py @@ -3,7 +3,7 @@ Permissions for Content Libraries (v2, Blockstore-based) """ from bridgekeeper import perms, rules from bridgekeeper.rules import Attribute, ManyRelation, Relation, in_current_groups -from django.contrib.auth.models import Group +from django.contrib.auth.models import Group # lint-amnesty, pylint: disable=unused-import from openedx.core.djangoapps.content_libraries.models import ContentLibraryPermission diff --git a/openedx/core/djangoapps/content_libraries/serializers.py b/openedx/core/djangoapps/content_libraries/serializers.py index 52978eeb8b..83bc207551 100644 --- a/openedx/core/djangoapps/content_libraries/serializers.py +++ b/openedx/core/djangoapps/content_libraries/serializers.py @@ -176,7 +176,7 @@ class LibraryXBlockStaticFileSerializer(serializers.Serializer): """ Generate the serialized representation of this static asset file. """ - result = super(LibraryXBlockStaticFileSerializer, self).to_representation(instance) + result = super(LibraryXBlockStaticFileSerializer, self).to_representation(instance) # lint-amnesty, pylint: disable=super-with-arguments # Make sure the URL is one that will work from the user's browser, # not one that only works from within a docker container: result['url'] = blockstore_api.force_browser_url(result['url']) diff --git a/openedx/core/djangoapps/content_libraries/tests/test_content_libraries.py b/openedx/core/djangoapps/content_libraries/tests/test_content_libraries.py index f01d531b09..970793d8bb 100644 --- a/openedx/core/djangoapps/content_libraries/tests/test_content_libraries.py +++ b/openedx/core/djangoapps/content_libraries/tests/test_content_libraries.py @@ -728,7 +728,7 @@ class ContentLibrariesTest(ContentLibrariesRestApiTest): Test that libraries don't allow more than specified blocks """ with self.settings(MAX_BLOCKS_PER_CONTENT_LIBRARY=1): - lib = self._create_library(slug="test_lib_limits", title="Limits Test Library", description="Testing XBlocks limits in a library") + lib = self._create_library(slug="test_lib_limits", title="Limits Test Library", description="Testing XBlocks limits in a library") # lint-amnesty, pylint: disable=line-too-long lib_id = lib["id"] block_data = self._add_block_to_library(lib_id, "unit", "unit1") # Second block should throw error diff --git a/openedx/core/djangoapps/content_libraries/tests/test_runtime.py b/openedx/core/djangoapps/content_libraries/tests/test_runtime.py index 534c287380..a5f4b060c7 100644 --- a/openedx/core/djangoapps/content_libraries/tests/test_runtime.py +++ b/openedx/core/djangoapps/content_libraries/tests/test_runtime.py @@ -184,7 +184,7 @@ class ContentLibraryXBlockUserStateTest(ContentLibraryContentTestMixin, TestCase if the library allows direct learning. """ - databases = {alias for alias in connections} + databases = {alias for alias in connections} # lint-amnesty, pylint: disable=unnecessary-comprehension @XBlock.register_temp_plugin(UserStateTestBlock, UserStateTestBlock.BLOCK_TYPE) def test_default_values(self): @@ -488,7 +488,7 @@ class ContentLibraryXBlockCompletionTest(ContentLibraryContentTestMixin, Complet """ def setUp(self): - super(ContentLibraryXBlockCompletionTest, self).setUp() + super(ContentLibraryXBlockCompletionTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments # Enable the completion waffle flag for these tests self.override_waffle_switch(True) diff --git a/openedx/core/djangoapps/content_libraries/views.py b/openedx/core/djangoapps/content_libraries/views.py index bf94dc2dd1..b1a596a228 100644 --- a/openedx/core/djangoapps/content_libraries/views.py +++ b/openedx/core/djangoapps/content_libraries/views.py @@ -55,19 +55,19 @@ def convert_exceptions(fn): return fn(*args, **kwargs) except api.ContentLibraryNotFound: log.exception("Content library not found") - raise NotFound + raise NotFound # lint-amnesty, pylint: disable=raise-missing-from except api.ContentLibraryBlockNotFound: log.exception("XBlock not found in content library") - raise NotFound + raise NotFound # lint-amnesty, pylint: disable=raise-missing-from except api.LibraryBlockAlreadyExists as exc: log.exception(str(exc)) - raise ValidationError(str(exc)) + raise ValidationError(str(exc)) # lint-amnesty, pylint: disable=raise-missing-from except api.InvalidNameError as exc: log.exception(str(exc)) - raise ValidationError(str(exc)) + raise ValidationError(str(exc)) # lint-amnesty, pylint: disable=raise-missing-from except api.BlockLimitReachedError as exc: log.exception(str(exc)) - raise ValidationError(str(exc)) + raise ValidationError(str(exc)) # lint-amnesty, pylint: disable=raise-missing-from return wrapped_fn @@ -166,14 +166,14 @@ class LibraryRootView(APIView): try: ensure_organization(org_name) except InvalidOrganizationException: - raise ValidationError( + raise ValidationError( # lint-amnesty, pylint: disable=raise-missing-from detail={"org": "No such organization '{}' found.".format(org_name)} ) org = Organization.objects.get(short_name=org_name) try: result = api.create_library(org=org, **data) except api.LibraryAlreadyExists: - raise ValidationError(detail={"slug": "A library with that ID already exists."}) + raise ValidationError(detail={"slug": "A library with that ID already exists."}) # lint-amnesty, pylint: disable=raise-missing-from # Grant the current user admin permissions on the library: api.set_library_user_permissions(result.key, request.user, api.AccessLevel.ADMIN_LEVEL) return Response(ContentLibraryMetadataSerializer(result).data) @@ -212,7 +212,7 @@ class LibraryDetailsView(APIView): try: api.update_library(key, **data) except api.IncompatibleTypesError as err: - raise ValidationError({'type': str(err)}) + raise ValidationError({'type': str(err)}) # lint-amnesty, pylint: disable=raise-missing-from result = api.get_library(key) return Response(ContentLibraryMetadataSerializer(result).data) @@ -249,7 +249,7 @@ class LibraryTeamView(APIView): try: user = User.objects.get(email=serializer.validated_data.get('email')) except User.DoesNotExist: - raise ValidationError({'email': _('We could not find a user with that email address.')}) + raise ValidationError({'email': _('We could not find a user with that email address.')}) # lint-amnesty, pylint: disable=raise-missing-from grant = api.get_library_user_permissions(key, user) if grant: return Response( @@ -259,7 +259,7 @@ class LibraryTeamView(APIView): try: api.set_library_user_permissions(key, user, access_level=serializer.validated_data["access_level"]) except api.LibraryPermissionIntegrityError as err: - raise ValidationError(detail=str(err)) + raise ValidationError(detail=str(err)) # lint-amnesty, pylint: disable=raise-missing-from grant = api.get_library_user_permissions(key, user) return Response(ContentLibraryPermissionSerializer(grant).data) @@ -295,7 +295,7 @@ class LibraryTeamUserView(APIView): try: api.set_library_user_permissions(key, user, access_level=serializer.validated_data["access_level"]) except api.LibraryPermissionIntegrityError as err: - raise ValidationError(detail=str(err)) + raise ValidationError(detail=str(err)) # lint-amnesty, pylint: disable=raise-missing-from grant = api.get_library_user_permissions(key, user) return Response(ContentLibraryPermissionSerializer(grant).data) @@ -324,7 +324,7 @@ class LibraryTeamUserView(APIView): try: api.set_library_user_permissions(key, user, access_level=None) except api.LibraryPermissionIntegrityError as err: - raise ValidationError(detail=str(err)) + raise ValidationError(detail=str(err)) # lint-amnesty, pylint: disable=raise-missing-from return Response({}) @@ -542,7 +542,7 @@ class LibraryBlocksView(APIView): try: result = api.create_library_block(library_key, **serializer.validated_data) except api.IncompatibleTypesError as err: - raise ValidationError( + raise ValidationError( # lint-amnesty, pylint: disable=raise-missing-from detail={'block_type': str(err)}, ) return Response(LibraryXBlockMetadataSerializer(result).data) @@ -613,7 +613,7 @@ class LibraryBlockOlxView(APIView): try: api.set_library_block_olx(key, new_olx_str) except ValueError as err: - raise ValidationError(detail=str(err)) + raise ValidationError(detail=str(err)) # lint-amnesty, pylint: disable=raise-missing-from return Response(LibraryXBlockOlxSerializer({"olx": new_olx_str}).data) @@ -672,7 +672,7 @@ class LibraryBlockAssetView(APIView): try: result = api.add_library_block_static_asset_file(usage_key, file_path, file_content) except ValueError: - raise ValidationError("Invalid file path") + raise ValidationError("Invalid file path") # lint-amnesty, pylint: disable=raise-missing-from return Response(LibraryXBlockStaticFileSerializer(result).data) @convert_exceptions @@ -687,5 +687,5 @@ class LibraryBlockAssetView(APIView): try: api.delete_library_block_static_asset_file(usage_key, file_path) except ValueError: - raise ValidationError("Invalid file path") + raise ValidationError("Invalid file path") # lint-amnesty, pylint: disable=raise-missing-from return Response(status=status.HTTP_204_NO_CONTENT) diff --git a/openedx/core/djangoapps/contentserver/__init__.py b/openedx/core/djangoapps/contentserver/__init__.py index 63136758e8..6433e6479f 100644 --- a/openedx/core/djangoapps/contentserver/__init__.py +++ b/openedx/core/djangoapps/contentserver/__init__.py @@ -1,3 +1,3 @@ -""" +""" # lint-amnesty, pylint: disable=django-not-configured Serves course assets to end users. """ diff --git a/openedx/core/djangoapps/contentserver/middleware.py b/openedx/core/djangoapps/contentserver/middleware.py index 21ab1d68d0..937e2a8226 100644 --- a/openedx/core/djangoapps/contentserver/middleware.py +++ b/openedx/core/djangoapps/contentserver/middleware.py @@ -63,7 +63,7 @@ class StaticContentServer(MiddlewareMixin): """Process the given request""" asset_path = request.path - if self.is_asset_request(request): + if self.is_asset_request(request): # lint-amnesty, pylint: disable=too-many-nested-blocks # Make sure we can convert this request into a location. if AssetLocator.CANONICAL_NAMESPACE in asset_path: asset_path = asset_path.replace('block/', 'block@', 1) @@ -292,7 +292,7 @@ class StaticContentServer(MiddlewareMixin): # Not in cache, so just try and load it from the asset manager. try: content = AssetManager.find(location, as_stream=True) - except (ItemNotFoundError, NotFoundError): + except (ItemNotFoundError, NotFoundError): # lint-amnesty, pylint: disable=try-except-raise raise # Now that we fetched it, let's go ahead and try to cache it. We cap this at 1MB @@ -324,7 +324,7 @@ def parse_range_header(header_value, content_length): for byte_range_string in byte_ranges_string.split(','): byte_range_string = byte_range_string.strip() # Case 0: - if '-' not in byte_range_string: # Invalid syntax of header value. + if '-' not in byte_range_string: # Invalid syntax of header value. # lint-amnesty, pylint: disable=no-else-raise raise ValueError('Invalid syntax.') # Case 1: -500 elif byte_range_string.startswith('-'): diff --git a/openedx/core/djangoapps/contentserver/test/test_contentserver.py b/openedx/core/djangoapps/contentserver/test/test_contentserver.py index 80987ec227..f5c242bfe8 100644 --- a/openedx/core/djangoapps/contentserver/test/test_contentserver.py +++ b/openedx/core/djangoapps/contentserver/test/test_contentserver.py @@ -7,10 +7,10 @@ import copy import datetime import ddt -import logging +import logging # lint-amnesty, pylint: disable=wrong-import-order import six -import unittest -from uuid import uuid4 +import unittest # lint-amnesty, pylint: disable=wrong-import-order +from uuid import uuid4 # lint-amnesty, pylint: disable=wrong-import-order from django.conf import settings from django.test import RequestFactory @@ -24,7 +24,7 @@ from xmodule.modulestore.django import modulestore from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase from xmodule.modulestore.xml_importer import import_course_from_xml from xmodule.assetstore.assetmgr import AssetManager -from opaque_keys import InvalidKeyError +from opaque_keys import InvalidKeyError # lint-amnesty, pylint: disable=wrong-import-order from xmodule.modulestore.exceptions import ItemNotFoundError from common.djangoapps.student.models import CourseEnrollment @@ -108,7 +108,7 @@ class ContentStoreToyCourseTest(SharedModuleStoreTestCase): """ Create user and login. """ - super(ContentStoreToyCourseTest, self).setUp() + super(ContentStoreToyCourseTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.staff_usr = AdminFactory.create() self.non_staff_usr = UserFactory.create() @@ -244,7 +244,7 @@ class ContentStoreToyCourseTest(SharedModuleStoreTestCase): """ first_byte = self.length_unlocked / 4 last_byte = self.length_unlocked / 2 - # pylint: disable=unicode-format-string + # lint-amnesty, pylint: disable=bad-option-value, unicode-format-string resp = self.client.get(self.url_unlocked, HTTP_RANGE='bytes={first}-{last}, -100'.format( first=first_byte, last=last_byte)) @@ -409,7 +409,7 @@ class ParseRangeHeaderTestCase(unittest.TestCase): """ def setUp(self): - super(ParseRangeHeaderTestCase, self).setUp() + super(ParseRangeHeaderTestCase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.content_length = 10000 def test_bytes_unit(self): diff --git a/openedx/core/djangoapps/cors_csrf/authentication.py b/openedx/core/djangoapps/cors_csrf/authentication.py index 9bedb94353..5d4d39695d 100644 --- a/openedx/core/djangoapps/cors_csrf/authentication.py +++ b/openedx/core/djangoapps/cors_csrf/authentication.py @@ -27,7 +27,7 @@ class SessionAuthenticationCrossDomainCsrf(authentication.SessionAuthentication) """ def _process_enforce_csrf(self, request): CsrfViewMiddleware().process_request(request) - return super(SessionAuthenticationCrossDomainCsrf, self).enforce_csrf(request) + return super(SessionAuthenticationCrossDomainCsrf, self).enforce_csrf(request) # lint-amnesty, pylint: disable=super-with-arguments def enforce_csrf(self, request): """ diff --git a/openedx/core/djangoapps/cors_csrf/middleware.py b/openedx/core/djangoapps/cors_csrf/middleware.py index 0367b5f269..a1b4175879 100644 --- a/openedx/core/djangoapps/cors_csrf/middleware.py +++ b/openedx/core/djangoapps/cors_csrf/middleware.py @@ -65,7 +65,7 @@ class CorsCSRFMiddleware(CsrfViewMiddleware, MiddlewareMixin): """Disable the middleware if the feature flag is disabled. """ if not settings.FEATURES.get('ENABLE_CORS_HEADERS'): raise MiddlewareNotUsed() - super(CorsCSRFMiddleware, self).__init__(*args, **kwargs) + super(CorsCSRFMiddleware, self).__init__(*args, **kwargs) # lint-amnesty, pylint: disable=super-with-arguments def process_view(self, request, callback, callback_args, callback_kwargs): """Skip the usual CSRF referer check if this is an allowed cross-domain request. """ @@ -74,7 +74,7 @@ class CorsCSRFMiddleware(CsrfViewMiddleware, MiddlewareMixin): return with skip_cross_domain_referer_check(request): - return super(CorsCSRFMiddleware, self).process_view(request, callback, callback_args, callback_kwargs) + return super(CorsCSRFMiddleware, self).process_view(request, callback, callback_args, callback_kwargs) # lint-amnesty, pylint: disable=super-with-arguments class CsrfCrossDomainCookieMiddleware(MiddlewareMixin): @@ -110,7 +110,7 @@ class CsrfCrossDomainCookieMiddleware(MiddlewareMixin): "You must set `CROSS_DOMAIN_CSRF_COOKIE_DOMAIN` when " "`FEATURES['ENABLE_CROSS_DOMAIN_CSRF_COOKIE']` is True." ) - super(CsrfCrossDomainCookieMiddleware, self).__init__(*args, **kwargs) + super(CsrfCrossDomainCookieMiddleware, self).__init__(*args, **kwargs) # lint-amnesty, pylint: disable=super-with-arguments def process_response(self, request, response): """Set the cross-domain CSRF cookie. """ diff --git a/openedx/core/djangoapps/cors_csrf/tests/test_authentication.py b/openedx/core/djangoapps/cors_csrf/tests/test_authentication.py index 6deff4d1fd..e6d1f75826 100644 --- a/openedx/core/djangoapps/cors_csrf/tests/test_authentication.py +++ b/openedx/core/djangoapps/cors_csrf/tests/test_authentication.py @@ -26,7 +26,7 @@ class CrossDomainAuthTest(TestCase): REFERER = "https://www.edx.org" def setUp(self): - super(CrossDomainAuthTest, self).setUp() + super(CrossDomainAuthTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.auth = SessionAuthenticationCrossDomainCsrf() self.csrf_token = get_token(FakeRequest()) diff --git a/openedx/core/djangoapps/cors_csrf/tests/test_decorators.py b/openedx/core/djangoapps/cors_csrf/tests/test_decorators.py index 6153a8bf3c..ccf88d6c23 100644 --- a/openedx/core/djangoapps/cors_csrf/tests/test_decorators.py +++ b/openedx/core/djangoapps/cors_csrf/tests/test_decorators.py @@ -11,7 +11,7 @@ from ..decorators import ensure_csrf_cookie_cross_domain def fake_view(request): """Fake view that returns the request META as a JSON-encoded string. """ - return HttpResponse(json.dumps(request.META)) + return HttpResponse(json.dumps(request.META)) # lint-amnesty, pylint: disable=http-response-with-json-dumps class TestEnsureCsrfCookieCrossDomain(TestCase): diff --git a/openedx/core/djangoapps/cors_csrf/tests/test_middleware.py b/openedx/core/djangoapps/cors_csrf/tests/test_middleware.py index 5158f854b8..64b61ff91c 100644 --- a/openedx/core/djangoapps/cors_csrf/tests/test_middleware.py +++ b/openedx/core/djangoapps/cors_csrf/tests/test_middleware.py @@ -34,7 +34,7 @@ class TestCorsMiddlewareProcessRequest(TestCase): @override_settings(FEATURES={'ENABLE_CORS_HEADERS': True}) def setUp(self): - super(TestCorsMiddlewareProcessRequest, self).setUp() + super(TestCorsMiddlewareProcessRequest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.middleware = CorsCSRFMiddleware() def check_not_enabled(self, request): @@ -114,7 +114,7 @@ class TestCsrfCrossDomainCookieMiddleware(TestCase): CROSS_DOMAIN_CSRF_COOKIE_DOMAIN=COOKIE_DOMAIN ) def setUp(self): - super(TestCsrfCrossDomainCookieMiddleware, self).setUp() + super(TestCsrfCrossDomainCookieMiddleware, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.middleware = CsrfCrossDomainCookieMiddleware() @override_settings(FEATURES={'ENABLE_CROSS_DOMAIN_CSRF_COOKIE': False}) @@ -264,7 +264,7 @@ class TestCsrfCrossDomainCookieMiddleware(TestCase): if is_set: self.assertIn(self.COOKIE_NAME, response.cookies) cookie_header = six.text_type(response.cookies[self.COOKIE_NAME]) - # pylint: disable=unicode-format-string + # lint-amnesty, pylint: disable=bad-option-value, unicode-format-string expected = six.u('Set-Cookie: {name}={value}; Domain={domain};').format( name=self.COOKIE_NAME, value=self.COOKIE_VALUE, diff --git a/openedx/core/djangoapps/cors_csrf/tests/test_views.py b/openedx/core/djangoapps/cors_csrf/tests/test_views.py index 6ab7e5d833..bec88dfdc2 100644 --- a/openedx/core/djangoapps/cors_csrf/tests/test_views.py +++ b/openedx/core/djangoapps/cors_csrf/tests/test_views.py @@ -23,7 +23,7 @@ class XDomainProxyTest(TestCase): def setUp(self): """Clear model-based config cache. """ - super(XDomainProxyTest, self).setUp() + super(XDomainProxyTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments try: self.url = reverse('xdomain_proxy') except NoReverseMatch: diff --git a/openedx/core/djangoapps/coursegraph/tasks.py b/openedx/core/djangoapps/coursegraph/tasks.py index 034af64a65..716de57916 100644 --- a/openedx/core/djangoapps/coursegraph/tasks.py +++ b/openedx/core/djangoapps/coursegraph/tasks.py @@ -6,7 +6,7 @@ neo4j, a graph database. import logging -from celery import task +from celery import shared_task from django.conf import settings # lint-amnesty, pylint: disable=unused-import from django.utils import six, timezone from edx_django_utils.cache import RequestCache @@ -247,7 +247,7 @@ def should_dump_course(course_key, graph): return last_this_command_was_run < course_last_published_date -@task +@shared_task @set_code_owner_attribute def dump_course_to_neo4j(course_key_string, credentials): """ diff --git a/openedx/core/djangoapps/courseware_api/views.py b/openedx/core/djangoapps/courseware_api/views.py index 9e77979f21..a5ab33630c 100644 --- a/openedx/core/djangoapps/courseware_api/views.py +++ b/openedx/core/djangoapps/courseware_api/views.py @@ -479,6 +479,13 @@ class SequenceMetadata(DeveloperErrorViewMixin, APIView): except InvalidKeyError: raise NotFound("Invalid usage key: '{}'.".format(usage_key_string)) # lint-amnesty, pylint: disable=raise-missing-from + _, request.user = setup_masquerade( + request, + usage_key.course_key, + staff_access=has_access(request.user, 'staff', usage_key.course_key), + reset_masquerade_data=True, + ) + sequence, _ = get_module_by_usage_id( self.request, str(usage_key.course_key), diff --git a/openedx/core/djangoapps/credentials/tasks/v1/tasks.py b/openedx/core/djangoapps/credentials/tasks/v1/tasks.py index 9bbe787f43..da2c76de9e 100644 --- a/openedx/core/djangoapps/credentials/tasks/v1/tasks.py +++ b/openedx/core/djangoapps/credentials/tasks/v1/tasks.py @@ -3,7 +3,7 @@ This file contains celery tasks for credentials-related functionality. """ -from celery import task +from celery import shared_task from celery.utils.log import get_task_logger from django.conf import settings from django.contrib.auth.models import User # lint-amnesty, pylint: disable=imported-auth-user @@ -21,7 +21,7 @@ logger = get_task_logger(__name__) MAX_RETRIES = 11 -@task(bind=True, ignore_result=True) +@shared_task(bind=True, ignore_result=True) @set_code_owner_attribute def send_grade_to_credentials(self, username, course_run_key, verified, letter_grade, percent_grade): """ Celery task to notify the Credentials IDA of a grade change via POST. """ diff --git a/openedx/core/djangoapps/credit/tasks.py b/openedx/core/djangoapps/credit/tasks.py index f1e78e8f32..5532e452cb 100644 --- a/openedx/core/djangoapps/credit/tasks.py +++ b/openedx/core/djangoapps/credit/tasks.py @@ -4,7 +4,7 @@ This file contains celery tasks for credit course views. import six -from celery import task +from celery import shared_task from celery.utils.log import get_task_logger from django.conf import settings from edx_django_utils.monitoring import set_code_owner_attribute @@ -20,7 +20,7 @@ from xmodule.modulestore.exceptions import ItemNotFoundError LOGGER = get_task_logger(__name__) -@task(default_retry_delay=settings.CREDIT_TASK_DEFAULT_RETRY_DELAY, max_retries=settings.CREDIT_TASK_MAX_RETRIES) +@shared_task(default_retry_delay=settings.CREDIT_TASK_DEFAULT_RETRY_DELAY, max_retries=settings.CREDIT_TASK_MAX_RETRIES) @set_code_owner_attribute def update_credit_course_requirements(course_id): """ diff --git a/openedx/core/djangoapps/heartbeat/tasks.py b/openedx/core/djangoapps/heartbeat/tasks.py index 962d249d12..0c18560755 100644 --- a/openedx/core/djangoapps/heartbeat/tasks.py +++ b/openedx/core/djangoapps/heartbeat/tasks.py @@ -3,11 +3,11 @@ A trivial task for health checks """ -from celery.task import task +from celery import shared_task from edx_django_utils.monitoring import set_code_owner_attribute -@task +@shared_task @set_code_owner_attribute def sample_task(): return True diff --git a/openedx/core/djangoapps/profile_images/urls.py b/openedx/core/djangoapps/profile_images/urls.py index d7062e8bf1..9383999b2b 100644 --- a/openedx/core/djangoapps/profile_images/urls.py +++ b/openedx/core/djangoapps/profile_images/urls.py @@ -1,4 +1,3 @@ -# lint-amnesty, pylint: disable=bad-option-value, unicode-format-string """ Defines the URL routes for this app. diff --git a/openedx/core/djangoapps/programs/tasks.py b/openedx/core/djangoapps/programs/tasks.py index 5c2bbaf20f..93dc8ffadc 100644 --- a/openedx/core/djangoapps/programs/tasks.py +++ b/openedx/core/djangoapps/programs/tasks.py @@ -3,7 +3,7 @@ This file contains celery tasks for programs-related functionality. """ -from celery import task +from celery import shared_task from celery.exceptions import MaxRetriesExceededError from celery.utils.log import get_task_logger from django.conf import settings @@ -121,7 +121,7 @@ def award_program_certificate(client, username, program_uuid, visible_date): }) -@task(bind=True, ignore_result=True) +@shared_task(bind=True, ignore_result=True) @set_code_owner_attribute def award_program_certificates(self, username): # lint-amnesty, pylint: disable=too-many-statements """ @@ -284,7 +284,7 @@ def post_course_certificate(client, username, certificate, visible_date): }) -@task(bind=True, ignore_result=True) +@shared_task(bind=True, ignore_result=True) @set_code_owner_attribute def award_course_certificate(self, username, course_run_key): """ @@ -399,7 +399,7 @@ def revoke_program_certificate(client, username, program_uuid): }) -@task(bind=True, ignore_result=True) +@shared_task(bind=True, ignore_result=True) @set_code_owner_attribute def revoke_program_certificates(self, username, course_key): """ @@ -523,7 +523,7 @@ def revoke_program_certificates(self, username, course_key): LOGGER.info(u'Successfully completed the task revoke_program_certificates for username %s', username) -@task(bind=True, ignore_result=True) +@shared_task(bind=True, ignore_result=True) @set_code_owner_attribute def update_certificate_visible_date_on_course_update(self, course_key): """ diff --git a/openedx/core/djangoapps/schedules/tasks.py b/openedx/core/djangoapps/schedules/tasks.py index e6c8b85dad..721b5654c9 100644 --- a/openedx/core/djangoapps/schedules/tasks.py +++ b/openedx/core/djangoapps/schedules/tasks.py @@ -5,7 +5,7 @@ import logging import six from six.moves import range -from celery import task, current_app +from celery import shared_task, current_app from celery_utils.logged_task import LoggedTask from celery_utils.persist_on_failure import LoggedPersistOnFailureTask from django.conf import settings @@ -46,7 +46,7 @@ COURSE_UPDATE_LOG_PREFIX = 'Course Update' COURSE_NEXT_SECTION_UPDATE_LOG_PREFIX = 'Course Next Section Update' -@task(base=LoggedPersistOnFailureTask, bind=True, default_retry_delay=30) +@shared_task(base=LoggedPersistOnFailureTask, bind=True, default_retry_delay=30) @set_code_owner_attribute def update_course_schedules(self, **kwargs): # lint-amnesty, pylint: disable=missing-function-docstring course_key = CourseKey.from_string(kwargs['course_id']) @@ -150,7 +150,7 @@ class BinnedScheduleMessageBaseTask(ScheduleMessageBaseTask): raise NotImplementedError -@task(base=LoggedTask, ignore_result=True) +@shared_task(base=LoggedTask, ignore_result=True) @set_code_owner_attribute def _recurring_nudge_schedule_send(site_id, msg_str): _schedule_send( @@ -161,7 +161,7 @@ def _recurring_nudge_schedule_send(site_id, msg_str): ) -@task(base=LoggedTask, ignore_result=True) +@shared_task(base=LoggedTask, ignore_result=True) @set_code_owner_attribute def _upgrade_reminder_schedule_send(site_id, msg_str): _schedule_send( @@ -172,7 +172,7 @@ def _upgrade_reminder_schedule_send(site_id, msg_str): ) -@task(base=LoggedTask, ignore_result=True) +@shared_task(base=LoggedTask, ignore_result=True) @set_code_owner_attribute def _course_update_schedule_send(site_id, msg_str): _schedule_send( diff --git a/openedx/core/djangoapps/site_configuration/helpers.py b/openedx/core/djangoapps/site_configuration/helpers.py index a910c4fb71..a4bf26660f 100644 --- a/openedx/core/djangoapps/site_configuration/helpers.py +++ b/openedx/core/djangoapps/site_configuration/helpers.py @@ -1,4 +1,4 @@ -""" +""" # lint-amnesty, pylint: disable=django-not-configured Helpers methods for site configuration. """ diff --git a/openedx/core/djangoapps/user_authn/utils.py b/openedx/core/djangoapps/user_authn/utils.py index 238f2ac770..2bf24cd81e 100644 --- a/openedx/core/djangoapps/user_authn/utils.py +++ b/openedx/core/djangoapps/user_authn/utils.py @@ -10,7 +10,7 @@ from django.utils import http from oauth2_provider.models import Application from six.moves.urllib.parse import urlparse # pylint: disable=import-error -from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers +from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers # lint-amnesty, pylint: disable=unused-import def is_safe_login_or_logout_redirect(redirect_to, request_host, dot_client_id, require_https): diff --git a/openedx/core/djangoapps/user_authn/views/login.py b/openedx/core/djangoapps/user_authn/views/login.py index 6fca722081..4b24c44ad2 100644 --- a/openedx/core/djangoapps/user_authn/views/login.py +++ b/openedx/core/djangoapps/user_authn/views/login.py @@ -125,24 +125,22 @@ def _generate_locked_out_error_message(): """ locked_out_period_in_sec = settings.MAX_FAILED_LOGIN_ATTEMPTS_LOCKOUT_PERIOD_SECS - if not should_redirect_to_authn_microfrontend(): # pylint: disable=no-else-raise - raise AuthFailedError(Text(_('To protect your account, it’s been temporarily ' - 'locked. Try again in {locked_out_period} minutes.' - '{li_start}To be on the safe side, you can reset your ' - 'password {link_start}here{link_end} before you try again.')).format( - link_start=HTML(''), - link_end=HTML(''), - li_start=HTML('
  • '), - li_end=HTML('
  • '), - locked_out_period=int(locked_out_period_in_sec / 60))) - else: - raise AuthFailedError(Text(_('To protect your account, it’s been temporarily ' - 'locked. Try again in {locked_out_period} minutes.\n' - 'To be on the safe side, you can reset your ' - 'password {link_start}here{link_end} before you try again.\n')).format( - link_start=HTML(''), - link_end=HTML(''), - locked_out_period=int(locked_out_period_in_sec / 60))) + error_message = Text(_('To protect your account, it’s been temporarily ' + 'locked. Try again in {locked_out_period} minutes.' + '{li_start}To be on the safe side, you can reset your ' + 'password {link_start}here{link_end} before you try again.')).format( + link_start=HTML(''), + link_end=HTML(''), + li_start=HTML('
  • '), + li_end=HTML('
  • '), + locked_out_period=int(locked_out_period_in_sec / 60)) + raise AuthFailedError( + error_message, + error_code='account-locked-out', + context={ + 'locked_out_period': int(locked_out_period_in_sec / 60) + } + ) def _enforce_password_policy_compliance(request, user): # lint-amnesty, pylint: disable=missing-function-docstring @@ -238,35 +236,29 @@ def _handle_failed_authentication(user, authenticated_user): if not LoginFailures.is_user_locked_out(user): max_failures_allowed = settings.MAX_FAILED_LOGIN_ATTEMPTS_ALLOWED remaining_attempts = max_failures_allowed - failure_count - if not should_redirect_to_authn_microfrontend(): # pylint: disable=no-else-raise - raise AuthFailedError(Text(_('Email or password is incorrect.' - '{li_start}You have {remaining_attempts} more sign-in ' - 'attempts before your account is temporarily locked.{li_end}' - '{li_start}If you\'ve forgotten your password, click ' - '{link_start}here{link_end} to reset.{li_end}' - )) - .format( - link_start=HTML(''), - link_end=HTML(''), - li_start=HTML('
  • '), - li_end=HTML('
  • '), - remaining_attempts=remaining_attempts)) - else: - raise AuthFailedError(Text(_('Email or password is incorrect.\n' - 'You have {remaining_attempts} more sign-in ' - 'attempts before your account is temporarily locked.\n' - 'If you{quote}ve forgotten your password, click ' - '{link_start}here{link_end} to reset.\n' - )) - .format( - quote=HTML("'"), - link_start=HTML(''), - link_end=HTML(''), - remaining_attempts=remaining_attempts)) - else: - _generate_locked_out_error_message() + error_message = Text(_('Email or password is incorrect.' + '{li_start}You have {remaining_attempts} more sign-in ' + 'attempts before your account is temporarily locked.{li_end}' + '{li_start}If you\'ve forgotten your password, click ' + '{link_start}here{link_end} to reset.{li_end}')).format( + link_start=HTML( + '' + ), + link_end=HTML(''), + li_start=HTML('
  • '), + li_end=HTML('
  • '), + remaining_attempts=remaining_attempts) + raise AuthFailedError( + error_message, + error_code='failed-login-attempt', + context={ + 'remaining_attempts': remaining_attempts, + } + ) - raise AuthFailedError(_('Email or password is incorrect.')) + _generate_locked_out_error_message() + + raise AuthFailedError(_('Email or password is incorrect.'), error_code='incorrect-email-or-password') def _handle_successful_authentication_and_login(user, request): diff --git a/openedx/core/djangoapps/user_authn/views/password_reset.py b/openedx/core/djangoapps/user_authn/views/password_reset.py index ef218dca67..bf6c9da8b9 100644 --- a/openedx/core/djangoapps/user_authn/views/password_reset.py +++ b/openedx/core/djangoapps/user_authn/views/password_reset.py @@ -715,10 +715,10 @@ class LogistrationPasswordResetView(APIView): # lint-amnesty, pylint: disable=m } ) user.save() - send_password_reset_success_email(user, request) except ObjectDoesNotExist: err = 'Account recovery process initiated without AccountRecovery instance for user {username}' log.error(err.format(username=user.username)) + send_password_reset_success_email(user, request) except ValidationError as err: AUDIT_LOG.exception("Password validation failed") error_status = { diff --git a/openedx/core/djangoapps/user_authn/views/tests/test_reset_password.py b/openedx/core/djangoapps/user_authn/views/tests/test_reset_password.py index 08ab304498..1ab15fac24 100644 --- a/openedx/core/djangoapps/user_authn/views/tests/test_reset_password.py +++ b/openedx/core/djangoapps/user_authn/views/tests/test_reset_password.py @@ -824,12 +824,13 @@ class ResetPasswordAPITests(EventTestMixin, CacheIsolationTestCase): new=updated_user.email ) - def test_password_reset_email_sent_on_account_recovery_email(self): + @ddt.data(True, False) + def test_password_reset_email_successfully_sent(self, is_account_recovery): """ Test that with is_account_recovery query param available, password reset email is sent to newly updated email address. """ - post_request = self.create_reset_request(self.uidb36, self.token, True) + post_request = self.create_reset_request(self.uidb36, self.token, is_account_recovery) post_request.user = AnonymousUser() post_request.site = Mock(domain='example.com') reset_view = LogistrationPasswordResetView.as_view() diff --git a/openedx/core/djangoapps/util/tests/test_signals.py b/openedx/core/djangoapps/util/tests/test_signals.py index 4f8ff7abe3..8cdc6ee10e 100644 --- a/openedx/core/djangoapps/util/tests/test_signals.py +++ b/openedx/core/djangoapps/util/tests/test_signals.py @@ -4,7 +4,7 @@ from unittest import TestCase from pytest import mark -from celery.task import task +from celery import shared_task from django.test.utils import override_settings from edx_django_utils.cache import RequestCache @@ -17,7 +17,7 @@ class TestClearRequestCache(TestCase): def _get_cache(self): return RequestCache("TestClearRequestCache") - @task + @shared_task def _dummy_task(self): """ A task that adds stuff to the request cache. """ self._get_cache().set("cache_key", "blah blah") diff --git a/openedx/core/djangoapps/verified_track_content/tasks.py b/openedx/core/djangoapps/verified_track_content/tasks.py index b40f530b97..2592ff96fb 100644 --- a/openedx/core/djangoapps/verified_track_content/tasks.py +++ b/openedx/core/djangoapps/verified_track_content/tasks.py @@ -5,7 +5,7 @@ Celery task for Automatic Verifed Track Cohorting MVP feature. import six -from celery.task import task +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 from edx_django_utils.monitoring import set_code_owner_attribute @@ -17,7 +17,7 @@ from common.djangoapps.student.models import CourseEnrollment, CourseMode LOGGER = get_task_logger(__name__) -@task(bind=True, default_retry_delay=60, max_retries=2) +@shared_task(bind=True, default_retry_delay=60, max_retries=2) @set_code_owner_attribute def sync_cohort_with_mode(self, course_id, user_id, verified_cohort_name, default_cohort_name): """ diff --git a/openedx/core/process_warnings.py b/openedx/core/process_warnings.py index d990f55157..8c712d64cc 100644 --- a/openedx/core/process_warnings.py +++ b/openedx/core/process_warnings.py @@ -1,4 +1,4 @@ -""" +""" # lint-amnesty, pylint: disable=django-not-configured Script to process pytest warnings output by pytest-json-report plugin and output it as a html """ diff --git a/openedx/core/pytest_hooks.py b/openedx/core/pytest_hooks.py index 211680d362..b34ebcbf07 100644 --- a/openedx/core/pytest_hooks.py +++ b/openedx/core/pytest_hooks.py @@ -1,4 +1,4 @@ -""" +""" # lint-amnesty, pylint: disable=django-not-configured Module to put all pytest hooks that modify pytest behaviour """ import os diff --git a/openedx/core/release.py b/openedx/core/release.py index 6aa63d17d0..0bd53fac59 100644 --- a/openedx/core/release.py +++ b/openedx/core/release.py @@ -1,4 +1,4 @@ -""" +""" # lint-amnesty, pylint: disable=django-not-configured Information about the release line of this Open edX code. """ diff --git a/openedx/core/storage.py b/openedx/core/storage.py index a016915c31..338c55829c 100644 --- a/openedx/core/storage.py +++ b/openedx/core/storage.py @@ -1,4 +1,4 @@ -""" +""" # lint-amnesty, pylint: disable=django-not-configured Django storage backends for Open edX. """ diff --git a/openedx/core/tests/test_admin_view.py b/openedx/core/tests/test_admin_view.py index d6275b464e..4779021b49 100644 --- a/openedx/core/tests/test_admin_view.py +++ b/openedx/core/tests/test_admin_view.py @@ -1,4 +1,4 @@ -""" +""" # lint-amnesty, pylint: disable=django-not-configured Tests that verify that the admin view loads. This is not inside a django app because it is a global property of the system. diff --git a/openedx/core/toggles.py b/openedx/core/toggles.py index c47d25e9dc..32634e6f03 100644 --- a/openedx/core/toggles.py +++ b/openedx/core/toggles.py @@ -1,4 +1,4 @@ -""" +""" # lint-amnesty, pylint: disable=django-not-configured Feature toggles used across the platform. Toggles should only be added to this module if we don't have a better place for them. Generally speaking, they should be added to the most appropriate app or repo. """ diff --git a/openedx/core/write_to_html.py b/openedx/core/write_to_html.py index 108ea179a9..d62b0e36a2 100644 --- a/openedx/core/write_to_html.py +++ b/openedx/core/write_to_html.py @@ -1,4 +1,4 @@ -""" +""" # lint-amnesty, pylint: disable=django-not-configured Class used to write pytest warning data into html format """ import textwrap diff --git a/openedx/features/content_type_gating/services.py b/openedx/features/content_type_gating/services.py index b1c8f6622b..f7b2381867 100644 --- a/openedx/features/content_type_gating/services.py +++ b/openedx/features/content_type_gating/services.py @@ -1,8 +1,13 @@ """ Content Type Gating service. """ +import crum from lms.djangoapps.courseware.access import has_access +from lms.djangoapps.courseware.masquerade import ( + is_masquerading_as_limited_access, is_masquerading_as_audit_enrollment, +) +from openedx.core.lib.graph_traversals import get_children, leaf_filter, traverse_pre_order from openedx.features.content_type_gating.models import ContentTypeGatingConfig @@ -12,13 +17,23 @@ class ContentTypeGatingService(object): and field overrides to gate course content. This service was created as a helper class for handling timed exams that contain content type gated problems. """ - def enabled_for_enrollment(self, **kwargs): + def _enabled_for_enrollment(self, **kwargs): """ Returns whether content type gating is enabled for a given user/course pair """ return ContentTypeGatingConfig.enabled_for_enrollment(**kwargs) - def content_type_gate_for_block(self, user, block, course_id): + def _is_masquerading_as_audit_or_limited_access(self, user, course_id): + return (is_masquerading_as_limited_access(user, course_id) or + is_masquerading_as_audit_enrollment(user, course_id)) + + def _get_user(self): + """ + Return the current request user. + """ + return crum.get_current_user() + + def _content_type_gate_for_block(self, user, block, course_id): """ Returns a Fragment of the content type gate (if any) that would appear for a given block """ @@ -29,4 +44,33 @@ class ContentTypeGatingService(object): access = has_access(user, 'load', block, course_id) if (not access and access.error_code == 'incorrect_user_group'): return access.user_fragment + + return None + + def check_children_for_content_type_gating_paywall(self, item, course_id): + """ + Arguments: + item (xblock such as a sequence or vertical block) + course_id (CourseLocator) + + If: + This xblock contains problems which this user cannot load due to content type gating + Then: + Return the first content type gating paywall (Fragment) + Else: + Return None + """ + user = self._get_user() + if not user: return None + + if not self._enabled_for_enrollment(user=user, course_key=course_id): + return None + + # Check children for content type gated content + for block in traverse_pre_order(item, get_children, leaf_filter): + gate_fragment = self._content_type_gate_for_block(user, block, course_id) + if gate_fragment is not None: + return gate_fragment.content + + return None diff --git a/openedx/features/content_type_gating/tests/test_access.py b/openedx/features/content_type_gating/tests/test_access.py index faa0baae42..4134518e45 100644 --- a/openedx/features/content_type_gating/tests/test_access.py +++ b/openedx/features/content_type_gating/tests/test_access.py @@ -1156,7 +1156,7 @@ class TestContentTypeGatingService(ModuleStoreTestCase): # The method returns a content type gate for blocks that should be gated self.assertIn( 'content-paywall', - ContentTypeGatingService().content_type_gate_for_block( + ContentTypeGatingService()._content_type_gate_for_block( self.user, blocks_dict['graded_1'], course['course'].id ).content ) @@ -1164,7 +1164,47 @@ class TestContentTypeGatingService(ModuleStoreTestCase): # The method returns None for blocks that should not be gated self.assertEquals( None, - ContentTypeGatingService().content_type_gate_for_block( + ContentTypeGatingService()._content_type_gate_for_block( self.user, blocks_dict['not_graded_1'], course['course'].id ) ) + + @patch.object(ContentTypeGatingService, '_get_user', return_value=UserFactory.build()) + def test_check_children_for_content_type_gating_paywall(self, mocked_user): # pylint: disable=unused-argument + ''' Verify that the method returns a content type gate when appropriate ''' + course = self._create_course() + blocks_dict = course['blocks'] + CourseEnrollmentFactory.create( + user=self.user, + course_id=course['course'].id, + mode='audit' + ) + blocks_dict['not_graded_1'] = ItemFactory.create( + parent=blocks_dict['vertical'], + category='problem', + graded=False, + metadata=METADATA, + ) + + # The method returns a content type gate for blocks that should be gated + self.assertEquals( + None, + ContentTypeGatingService().check_children_for_content_type_gating_paywall( + blocks_dict['vertical'], course['course'].id + ) + ) + + blocks_dict['graded_1'] = ItemFactory.create( + parent=blocks_dict['vertical'], + category='problem', + graded=True, + metadata=METADATA, + ) + + # The method returns None for blocks that should not be gated + self.assertIn( + 'content-paywall', + ContentTypeGatingService().check_children_for_content_type_gating_paywall( + blocks_dict['vertical'], course['course'].id + ) + ) diff --git a/openedx/features/enterprise_support/tasks.py b/openedx/features/enterprise_support/tasks.py index b553183c92..f0b8506658 100644 --- a/openedx/features/enterprise_support/tasks.py +++ b/openedx/features/enterprise_support/tasks.py @@ -5,7 +5,7 @@ Tasks for Enterprise. import logging -from celery import task +from celery import shared_task from edx_django_utils.monitoring import set_code_owner_attribute from enterprise.models import EnterpriseCourseEnrollment @@ -14,7 +14,7 @@ from openedx.features.enterprise_support.utils import clear_data_consent_share_c log = logging.getLogger('edx.celery.task') -@task(name=u'openedx.features.enterprise_support.tasks.clear_enterprise_customer_data_consent_share_cache') +@shared_task(name=u'openedx.features.enterprise_support.tasks.clear_enterprise_customer_data_consent_share_cache') @set_code_owner_attribute def clear_enterprise_customer_data_consent_share_cache(enterprise_customer_uuid): """ diff --git a/requirements/constraints.txt b/requirements/constraints.txt index 07d2a62f42..0effbf1f29 100644 --- a/requirements/constraints.txt +++ b/requirements/constraints.txt @@ -34,7 +34,7 @@ django-storages<1.9 # The team that owns this package will manually bump this package rather than having it pulled in automatically. # This is to allow them to better control its deployment and to do it in a process that works better # for them. -edx-enterprise==3.17.21 +edx-enterprise==3.17.22 # Upgrading to 2.12.0 breaks several test classes due to API changes, need to update our code accordingly factory-boy==2.8.1 @@ -89,7 +89,7 @@ path<13.2.0 pillow<8.0.0 # ARCHBOM-1141: pip-tools upgrade requires pip upgrade -pip-tools<5.0.0 +pip-tools<5.4 # Upgrading to 2.5.3 on 2020-01-03 triggered "'tzlocal' object has no attribute '_std_offset'" errors in production python-dateutil==2.4.0 diff --git a/requirements/edx-sandbox/py35.txt b/requirements/edx-sandbox/py35.txt index 7ee120f327..4df71849bf 100644 --- a/requirements/edx-sandbox/py35.txt +++ b/requirements/edx-sandbox/py35.txt @@ -20,7 +20,7 @@ matplotlib==2.2.4 # via -c requirements/edx-sandbox/../constraints.txt, mpmath==1.1.0 # via sympy networkx==2.2 # via -r requirements/edx-sandbox/py35.in nltk==3.5 # via -r requirements/edx-sandbox/shared.txt, chem -numpy==1.16.5 # via -c requirements/edx-sandbox/../constraints.txt, -r requirements/edx-sandbox/py35.in, chem, matplotlib, openedx-calc +numpy==1.16.5 # via -c requirements/edx-sandbox/../constraints.txt, -r requirements/edx-sandbox/py35.in, chem, matplotlib, openedx-calc, scipy openedx-calc==1.0.9 # via -r requirements/edx-sandbox/py35.in pycparser==2.20 # via -r requirements/edx-sandbox/shared.txt, cffi pyparsing==2.2.0 # via -r requirements/edx-sandbox/py35.in, chem, matplotlib, openedx-calc diff --git a/requirements/edx/base.txt b/requirements/edx/base.txt index f0b3b65fdf..0fff98c767 100644 --- a/requirements/edx/base.txt +++ b/requirements/edx/base.txt @@ -99,14 +99,14 @@ edx-django-release-util==1.0.0 # via -r requirements/edx/base.in edx-django-sites-extensions==3.0.0 # via -r requirements/edx/base.in edx-django-utils==3.13.0 # via -r requirements/edx/base.in, django-config-models, edx-drf-extensions, edx-enterprise, edx-rest-api-client, edx-toggles, edx-when, ora2, super-csv edx-drf-extensions==6.4.0 # via -r requirements/edx/base.in, edx-completion, edx-enterprise, edx-organizations, edx-proctoring, edx-rbac, edx-when, edxval -edx-enterprise==3.17.21 # via -c requirements/edx/../constraints.txt, -r requirements/edx/base.in +edx-enterprise==3.17.22 # via -c requirements/edx/../constraints.txt, -r requirements/edx/base.in edx-event-routing-backends==4.0.1 # via -r requirements/edx/base.in edx-i18n-tools==0.5.3 # via ora2 edx-milestones==0.3.0 # via -r requirements/edx/base.in edx-opaque-keys[django]==2.2.0 # via -r requirements/edx/paver.txt, edx-bulk-grades, edx-ccx-keys, edx-completion, edx-drf-extensions, edx-enterprise, edx-milestones, edx-organizations, edx-proctoring, edx-user-state-client, edx-when, lti-consumer-xblock, xmodule edx-organizations==6.8.0 # via -r requirements/edx/base.in edx-proctoring-proctortrack==1.0.5 # via -r requirements/edx/base.in -edx-proctoring==2.6.7 # via -r requirements/edx/base.in, edx-proctoring-proctortrack +edx-proctoring==3.0.0 # via -r requirements/edx/base.in, edx-proctoring-proctortrack edx-rbac==1.4.1 # via edx-enterprise edx-rest-api-client==5.3.0 # via -r requirements/edx/base.in, edx-enterprise, edx-proctoring edx-search==3.0.0 # via -r requirements/edx/base.in @@ -116,7 +116,7 @@ edx-tincan-py35==1.0.0 # via edx-enterprise edx-toggles==3.1.0 # via -r requirements/edx/base.in, edx-completion, edx-event-routing-backends, edxval, ora2 edx-user-state-client==1.3.0 # via -r requirements/edx/base.in edx-when==2.0.0 # via -r requirements/edx/base.in, edx-proctoring -edxval==2.0.0 # via -r requirements/edx/base.in +edxval==2.0.1 # via -r requirements/edx/base.in elasticsearch==7.10.1 # via edx-search enmerkar-underscore==2.0.0 # via -r requirements/edx/base.in enmerkar==0.7.1 # via enmerkar-underscore @@ -164,7 +164,7 @@ nodeenv==1.5.0 # via -r requirements/edx/base.in numpy==1.18.5 # via -c requirements/edx/../constraints.txt, chem, openedx-calc, scipy oauthlib==3.0.1 # via -c requirements/edx/../constraints.txt, -r requirements/edx/base.in, django-oauth-toolkit, lti-consumer-xblock, requests-oauthlib, social-auth-core openedx-calc==2.0.0 # via -r requirements/edx/base.in -ora2==3.0.0 # via -r requirements/edx/base.in +ora2==3.1.1 # via -r requirements/edx/base.in packaging==20.9 # via bleach, drf-yasg path.py==12.5.0 # via edx-enterprise, edx-i18n-tools, ora2, staff-graded-xblock, xmodule path==13.1.0 # via -c requirements/edx/../constraints.txt, -r requirements/edx/paver.txt, path.py diff --git a/requirements/edx/coverage.txt b/requirements/edx/coverage.txt index 0992ac3d36..1c7b2c6f76 100644 --- a/requirements/edx/coverage.txt +++ b/requirements/edx/coverage.txt @@ -12,7 +12,7 @@ inflect==3.0.2 # via -c requirements/edx/../constraints.txt, jinja2-p jinja2-pluralize==0.3.0 # via diff-cover jinja2==2.11.3 # via diff-cover, jinja2-pluralize markupsafe==1.1.1 # via jinja2 -more-itertools==8.6.0 # via zipp +more-itertools==8.7.0 # via zipp pluggy==0.13.1 # via diff-cover pygments==2.7.4 # via diff-cover zipp==1.0.0 # via -c requirements/edx/../constraints.txt, importlib-metadata diff --git a/requirements/edx/development.txt b/requirements/edx/development.txt index c2eafcbff8..76a041be8d 100644 --- a/requirements/edx/development.txt +++ b/requirements/edx/development.txt @@ -110,15 +110,15 @@ edx-django-release-util==1.0.0 # via -r requirements/edx/testing.txt edx-django-sites-extensions==3.0.0 # via -r requirements/edx/testing.txt edx-django-utils==3.13.0 # via -r requirements/edx/testing.txt, django-config-models, edx-drf-extensions, edx-enterprise, edx-rest-api-client, edx-toggles, edx-when, ora2, super-csv edx-drf-extensions==6.4.0 # via -r requirements/edx/testing.txt, edx-completion, edx-enterprise, edx-organizations, edx-proctoring, edx-rbac, edx-when, edxval -edx-enterprise==3.17.21 # via -c requirements/edx/../constraints.txt, -r requirements/edx/testing.txt +edx-enterprise==3.17.22 # via -c requirements/edx/../constraints.txt, -r requirements/edx/testing.txt edx-event-routing-backends==4.0.1 # via -r requirements/edx/testing.txt edx-i18n-tools==0.5.3 # via -r requirements/edx/testing.txt, ora2 -edx-lint==3.0.2 # via -r requirements/edx/testing.txt +edx-lint==4.0.1 # via -r requirements/edx/testing.txt edx-milestones==0.3.0 # via -r requirements/edx/testing.txt edx-opaque-keys[django]==2.2.0 # via -r requirements/edx/testing.txt, edx-bulk-grades, edx-ccx-keys, edx-completion, edx-drf-extensions, edx-enterprise, edx-milestones, edx-organizations, edx-proctoring, edx-user-state-client, edx-when, lti-consumer-xblock, xmodule edx-organizations==6.8.0 # via -r requirements/edx/testing.txt edx-proctoring-proctortrack==1.0.5 # via -r requirements/edx/testing.txt -edx-proctoring==2.6.7 # via -r requirements/edx/testing.txt, edx-proctoring-proctortrack +edx-proctoring==3.0.0 # via -r requirements/edx/testing.txt, edx-proctoring-proctortrack edx-rbac==1.4.1 # via -r requirements/edx/testing.txt, edx-enterprise edx-rest-api-client==5.3.0 # via -r requirements/edx/testing.txt, edx-enterprise, edx-proctoring edx-search==3.0.0 # via -r requirements/edx/testing.txt @@ -129,7 +129,7 @@ edx-tincan-py35==1.0.0 # via -r requirements/edx/testing.txt, edx-enterprise edx-toggles==3.1.0 # via -r requirements/edx/testing.txt, edx-completion, edx-event-routing-backends, edxval, ora2 edx-user-state-client==1.3.0 # via -r requirements/edx/testing.txt edx-when==2.0.0 # via -r requirements/edx/testing.txt, edx-proctoring -edxval==2.0.0 # via -r requirements/edx/testing.txt +edxval==2.0.1 # via -r requirements/edx/testing.txt elasticsearch==7.10.1 # via -r requirements/edx/testing.txt, edx-search enmerkar-underscore==2.0.0 # via -r requirements/edx/testing.txt enmerkar==0.7.1 # via -r requirements/edx/testing.txt, enmerkar-underscore @@ -188,7 +188,7 @@ mistune==0.8.4 # via m2r mock==3.0.5 # via -c requirements/edx/../constraints.txt, -r requirements/edx/testing.txt, xblock-drag-and-drop-v2, xblock-poll git+https://github.com/edx/MongoDBProxy.git@d92bafe9888d2940f647a7b2b2383b29c752f35a#egg=MongoDBProxy==0.1.0+edx.2 # via -r requirements/edx/testing.txt mongoengine==0.22.1 # via -r requirements/edx/testing.txt -more-itertools==8.6.0 # via -r requirements/edx/testing.txt, zipp +more-itertools==8.7.0 # via -r requirements/edx/testing.txt, zipp mpmath==1.1.0 # via -r requirements/edx/testing.txt, sympy mysqlclient==2.0.3 # via -r requirements/edx/testing.txt newrelic==6.0.1.155 # via -r requirements/edx/testing.txt, edx-django-utils @@ -197,7 +197,7 @@ nodeenv==1.5.0 # via -r requirements/edx/testing.txt numpy==1.18.5 # via -c requirements/edx/../constraints.txt, -r requirements/edx/testing.txt, chem, openedx-calc, scipy oauthlib==3.0.1 # via -c requirements/edx/../constraints.txt, -r requirements/edx/testing.txt, django-oauth-toolkit, lti-consumer-xblock, requests-oauthlib, social-auth-core openedx-calc==2.0.0 # via -r requirements/edx/testing.txt -ora2==3.0.0 # via -r requirements/edx/testing.txt +ora2==3.1.1 # via -r requirements/edx/testing.txt packaging==20.9 # via -r requirements/edx/testing.txt, bleach, drf-yasg, pytest, sphinx, tox path.py==12.5.0 # via -r requirements/edx/testing.txt, edx-enterprise, edx-i18n-tools, ora2, staff-graded-xblock, xmodule path==13.1.0 # via -c requirements/edx/../constraints.txt, -r requirements/edx/testing.txt, path.py @@ -205,7 +205,7 @@ paver==1.3.4 # via -r requirements/edx/testing.txt pbr==5.5.1 # via -r requirements/edx/testing.txt, stevedore piexif==1.1.3 # via -r requirements/edx/testing.txt pillow==7.2.0 # via -c requirements/edx/../constraints.txt, -r requirements/edx/testing.txt, edx-enterprise, edx-organizations -pip-tools==4.5.1 # via -c requirements/edx/../constraints.txt, -r requirements/edx/pip-tools.txt +pip-tools==5.3.1 # via -c requirements/edx/../constraints.txt, -r requirements/edx/pip-tools.txt pluggy==0.13.1 # via -r requirements/edx/testing.txt, diff-cover, pytest, tox polib==1.1.0 # via -r requirements/edx/testing.txt, edx-i18n-tools psutil==5.8.0 # via -r requirements/edx/testing.txt, edx-django-utils, pytest-xdist @@ -323,4 +323,5 @@ xss-utils==0.2.0 # via -r requirements/edx/testing.txt zipp==1.0.0 # via -c requirements/edx/../constraints.txt, -r requirements/edx/testing.txt, importlib-metadata # The following packages are considered to be unsafe in a requirements file: +# pip # setuptools diff --git a/requirements/edx/pip-tools.txt b/requirements/edx/pip-tools.txt index 38a6e8cbed..446a14c0e7 100644 --- a/requirements/edx/pip-tools.txt +++ b/requirements/edx/pip-tools.txt @@ -5,5 +5,8 @@ # make upgrade # click==7.1.2 # via pip-tools -pip-tools==4.5.1 # via -c requirements/edx/../constraints.txt, -r requirements/edx/pip-tools.in +pip-tools==5.3.1 # via -c requirements/edx/../constraints.txt, -r requirements/edx/pip-tools.in six==1.15.0 # via -r requirements/edx/pip-tools.in, pip-tools + +# The following packages are considered to be unsafe in a requirements file: +# pip diff --git a/requirements/edx/testing.txt b/requirements/edx/testing.txt index 4e44bd8afd..f77625ead8 100644 --- a/requirements/edx/testing.txt +++ b/requirements/edx/testing.txt @@ -107,15 +107,15 @@ edx-django-release-util==1.0.0 # via -r requirements/edx/base.txt edx-django-sites-extensions==3.0.0 # via -r requirements/edx/base.txt edx-django-utils==3.13.0 # via -r requirements/edx/base.txt, django-config-models, edx-drf-extensions, edx-enterprise, edx-rest-api-client, edx-toggles, edx-when, ora2, super-csv edx-drf-extensions==6.4.0 # via -r requirements/edx/base.txt, edx-completion, edx-enterprise, edx-organizations, edx-proctoring, edx-rbac, edx-when, edxval -edx-enterprise==3.17.21 # via -c requirements/edx/../constraints.txt, -r requirements/edx/base.txt +edx-enterprise==3.17.22 # via -c requirements/edx/../constraints.txt, -r requirements/edx/base.txt edx-event-routing-backends==4.0.1 # via -r requirements/edx/base.txt edx-i18n-tools==0.5.3 # via -r requirements/edx/base.txt, -r requirements/edx/testing.in, ora2 -edx-lint==3.0.2 # via -r requirements/edx/testing.in +edx-lint==4.0.1 # via -r requirements/edx/testing.in edx-milestones==0.3.0 # via -r requirements/edx/base.txt edx-opaque-keys[django]==2.2.0 # via -r requirements/edx/base.txt, edx-bulk-grades, edx-ccx-keys, edx-completion, edx-drf-extensions, edx-enterprise, edx-milestones, edx-organizations, edx-proctoring, edx-user-state-client, edx-when, lti-consumer-xblock, xmodule edx-organizations==6.8.0 # via -r requirements/edx/base.txt edx-proctoring-proctortrack==1.0.5 # via -r requirements/edx/base.txt -edx-proctoring==2.6.7 # via -r requirements/edx/base.txt, edx-proctoring-proctortrack +edx-proctoring==3.0.0 # via -r requirements/edx/base.txt, edx-proctoring-proctortrack edx-rbac==1.4.1 # via -r requirements/edx/base.txt, edx-enterprise edx-rest-api-client==5.3.0 # via -r requirements/edx/base.txt, edx-enterprise, edx-proctoring edx-search==3.0.0 # via -r requirements/edx/base.txt @@ -125,7 +125,7 @@ edx-tincan-py35==1.0.0 # via -r requirements/edx/base.txt, edx-enterprise edx-toggles==3.1.0 # via -r requirements/edx/base.txt, edx-completion, edx-event-routing-backends, edxval, ora2 edx-user-state-client==1.3.0 # via -r requirements/edx/base.txt edx-when==2.0.0 # via -r requirements/edx/base.txt, edx-proctoring -edxval==2.0.0 # via -r requirements/edx/base.txt +edxval==2.0.1 # via -r requirements/edx/base.txt elasticsearch==7.10.1 # via -r requirements/edx/base.txt, edx-search enmerkar-underscore==2.0.0 # via -r requirements/edx/base.txt enmerkar==0.7.1 # via -r requirements/edx/base.txt, enmerkar-underscore @@ -180,7 +180,7 @@ mccabe==0.6.1 # via pylint mock==3.0.5 # via -c requirements/edx/../constraints.txt, -r requirements/edx/base.txt, xblock-drag-and-drop-v2, xblock-poll git+https://github.com/edx/MongoDBProxy.git@d92bafe9888d2940f647a7b2b2383b29c752f35a#egg=MongoDBProxy==0.1.0+edx.2 # via -r requirements/edx/base.txt mongoengine==0.22.1 # via -r requirements/edx/base.txt -more-itertools==8.6.0 # via -r requirements/edx/coverage.txt, zipp +more-itertools==8.7.0 # via -r requirements/edx/coverage.txt, zipp mpmath==1.1.0 # via -r requirements/edx/base.txt, sympy mysqlclient==2.0.3 # via -r requirements/edx/base.txt newrelic==6.0.1.155 # via -r requirements/edx/base.txt, edx-django-utils @@ -189,7 +189,7 @@ nodeenv==1.5.0 # via -r requirements/edx/base.txt numpy==1.18.5 # via -c requirements/edx/../constraints.txt, -r requirements/edx/base.txt, chem, openedx-calc, scipy oauthlib==3.0.1 # via -c requirements/edx/../constraints.txt, -r requirements/edx/base.txt, django-oauth-toolkit, lti-consumer-xblock, requests-oauthlib, social-auth-core openedx-calc==2.0.0 # via -r requirements/edx/base.txt -ora2==3.0.0 # via -r requirements/edx/base.txt +ora2==3.1.1 # via -r requirements/edx/base.txt packaging==20.9 # via -r requirements/edx/base.txt, bleach, drf-yasg, pytest, tox path.py==12.5.0 # via -r requirements/edx/base.txt, edx-enterprise, edx-i18n-tools, ora2, staff-graded-xblock, xmodule path==13.1.0 # via -c requirements/edx/../constraints.txt, -r requirements/edx/base.txt, path.py