From 54baec8cd23b3dd1eca44502d5c92078965ee5c6 Mon Sep 17 00:00:00 2001 From: Luis Moreno Date: Thu, 28 Jan 2021 11:20:22 -0400 Subject: [PATCH 01/24] docs: Add annotations for MFE URL settings --- lms/envs/common.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/lms/envs/common.py b/lms/envs/common.py index 16866bfa8f..bbee9b2e0c 100644 --- a/lms/envs/common.py +++ b/lms/envs/common.py @@ -4086,13 +4086,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 LOGISTRATION_MICROFRONTEND_URL = None LOGISTRATION_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 ################# From 70ddda4e71daf9e06bbffbcfd7052f99484e0e28 Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Mon, 1 Feb 2021 07:51:35 -0500 Subject: [PATCH 02/24] fix: messages shouldn't name edx.org These messages appear on 1000 other sites that are not publishing to edx.org. There's no need to be so specific. --- common/lib/xmodule/xmodule/course_module.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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, From d6beb37d729727f02b70f38b3d67ae75dbefa869 Mon Sep 17 00:00:00 2001 From: Carla Duarte Date: Wed, 3 Feb 2021 14:27:35 -0500 Subject: [PATCH 03/24] AA-635: learner dashboard course card image bug --- lms/templates/dashboard.html | 3 ++- .../core/djangoapps/content/course_overviews/models.py | 10 ++++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) 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/djangoapps/content/course_overviews/models.py b/openedx/core/djangoapps/content/course_overviews/models.py index 92922d5d1a..61eb0cd3b9 100644 --- a/openedx/core/djangoapps/content/course_overviews/models.py +++ b/openedx/core/djangoapps/content/course_overviews/models.py @@ -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) From 5199bf7acb2632c852fc6ddc9bf3a4f8fd08f3b2 Mon Sep 17 00:00:00 2001 From: Soban Javed Date: Tue, 29 Dec 2020 13:38:52 +0500 Subject: [PATCH 04/24] Replace task decorator with shared_task in openedx --- openedx/core/djangoapps/bookmarks/tasks.py | 4 ++-- openedx/core/djangoapps/ccxcon/tasks.py | 4 ++-- .../core/djangoapps/content/block_structure/tasks.py | 4 ++-- .../core/djangoapps/content/course_overviews/tasks.py | 4 ++-- openedx/core/djangoapps/coursegraph/tasks.py | 4 ++-- openedx/core/djangoapps/credentials/tasks/v1/tasks.py | 4 ++-- openedx/core/djangoapps/credit/tasks.py | 4 ++-- openedx/core/djangoapps/heartbeat/tasks.py | 4 ++-- openedx/core/djangoapps/programs/tasks.py | 10 +++++----- openedx/core/djangoapps/schedules/tasks.py | 10 +++++----- openedx/core/djangoapps/util/tests/test_signals.py | 4 ++-- .../core/djangoapps/verified_track_content/tasks.py | 4 ++-- openedx/features/enterprise_support/tasks.py | 4 ++-- 13 files changed, 32 insertions(+), 32 deletions(-) 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/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/course_overviews/tasks.py b/openedx/core/djangoapps/content/course_overviews/tasks.py index fd9e0e9387..86b9eed401 100644 --- a/openedx/core/djangoapps/content/course_overviews/tasks.py +++ b/openedx/core/djangoapps/content/course_overviews/tasks.py @@ -3,7 +3,7 @@ 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 @@ -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/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/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/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 81d6092f78..c6ef27c9aa 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): 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/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/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): """ From 583f11363f455328ae609444fb26b72297f76bb2 Mon Sep 17 00:00:00 2001 From: usamasadiq Date: Thu, 4 Feb 2021 20:16:35 +0500 Subject: [PATCH 05/24] Applied pylint amnesty --- openedx/core/apidocs.py | 2 +- openedx/core/constants.py | 2 +- openedx/core/process_warnings.py | 2 +- openedx/core/pytest_hooks.py | 2 +- openedx/core/release.py | 2 +- openedx/core/storage.py | 2 +- openedx/core/tests/test_admin_view.py | 2 +- openedx/core/toggles.py | 2 +- openedx/core/write_to_html.py | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/openedx/core/apidocs.py b/openedx/core/apidocs.py index 86a3847c95..e38ec935df 100644 --- a/openedx/core/apidocs.py +++ b/openedx/core/apidocs.py @@ -1,4 +1,4 @@ -""" # lint-amnesty, pylint: disable=django-not-configured +""" # lint-amnesty, pylint: disable=django-not-configured # lint-amnesty, pylint: disable=django-not-configured Open API support. """ 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/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 From 84e2bf07044602ec3a2da9869bc887cf14d02438 Mon Sep 17 00:00:00 2001 From: Talia Rhodes Date: Thu, 4 Feb 2021 11:53:22 -0500 Subject: [PATCH 06/24] update enterprise --- requirements/constraints.txt | 2 +- requirements/edx/base.txt | 2 +- requirements/edx/development.txt | 2 +- requirements/edx/testing.txt | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/requirements/constraints.txt b/requirements/constraints.txt index 07d2a62f42..3f9573690a 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 diff --git a/requirements/edx/base.txt b/requirements/edx/base.txt index 8b5c6c71d5..5bcbbe0cc5 100644 --- a/requirements/edx/base.txt +++ b/requirements/edx/base.txt @@ -99,7 +99,7 @@ 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 diff --git a/requirements/edx/development.txt b/requirements/edx/development.txt index 2c010f9a97..0ef5530ac9 100644 --- a/requirements/edx/development.txt +++ b/requirements/edx/development.txt @@ -110,7 +110,7 @@ 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 diff --git a/requirements/edx/testing.txt b/requirements/edx/testing.txt index bb0d0a22c8..5dccb99523 100644 --- a/requirements/edx/testing.txt +++ b/requirements/edx/testing.txt @@ -107,7 +107,7 @@ 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 From 8845685fd844a4851b14a854bdcf456a39a7c74a Mon Sep 17 00:00:00 2001 From: Christie Rice <8483753+crice100@users.noreply.github.com> Date: Thu, 4 Feb 2021 13:42:33 -0500 Subject: [PATCH 07/24] MICROBA-918 Check for the allowlist on invalidation and failing grades (#26356) --- lms/djangoapps/certificates/services.py | 12 +++++- lms/djangoapps/certificates/signals.py | 5 +++ .../certificates/tests/test_services.py | 41 ++++++++++++++++--- .../certificates/tests/test_signals.py | 29 +++++++++++++ .../grades/tests/test_course_grade_factory.py | 2 +- lms/djangoapps/grades/tests/test_tasks.py | 20 ++++----- 6 files changed, 91 insertions(+), 18 deletions(-) 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/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): From 2ea5e50b3563571b902a288934c0034d1414bebd Mon Sep 17 00:00:00 2001 From: Usama Sadiq Date: Fri, 5 Feb 2021 00:04:10 +0500 Subject: [PATCH 08/24] squash: remove duplicate amnesty message --- openedx/core/apidocs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openedx/core/apidocs.py b/openedx/core/apidocs.py index e38ec935df..86a3847c95 100644 --- a/openedx/core/apidocs.py +++ b/openedx/core/apidocs.py @@ -1,4 +1,4 @@ -""" # lint-amnesty, pylint: disable=django-not-configured # lint-amnesty, pylint: disable=django-not-configured +""" # lint-amnesty, pylint: disable=django-not-configured Open API support. """ From 1fe0eee9695e12cf92ab103fe01f8c0c9b96557a Mon Sep 17 00:00:00 2001 From: Christie Rice <8483753+crice100@users.noreply.github.com> Date: Thu, 4 Feb 2021 15:45:00 -0500 Subject: [PATCH 09/24] MICROBA-918 Fix warnings (#26397) --- .../instructor_task/tasks_helper/certs.py | 14 ++-- .../tests/test_tasks_helper.py | 76 +++++++++---------- 2 files changed, 45 insertions(+), 45 deletions(-) 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']) From ae7d0a1ed8b32ffe247f5bdb9ae28b50504324f5 Mon Sep 17 00:00:00 2001 From: Matthew Piatetsky Date: Mon, 1 Feb 2021 22:15:42 -0500 Subject: [PATCH 10/24] Return content type gate for staff users when masquerading as the Learner in Audit or Learner in Limited Access Roles This is necessary to display the content type gate in the UI AA-613 --- common/lib/xmodule/xmodule/seq_module.py | 45 ++++---------- .../xmodule/xmodule/tests/test_sequence.py | 60 +++---------------- lms/djangoapps/courseware/tests/test_views.py | 4 +- .../core/djangoapps/courseware_api/views.py | 7 +++ .../features/content_type_gating/services.py | 48 ++++++++++++++- .../content_type_gating/tests/test_access.py | 44 +++++++++++++- 6 files changed, 117 insertions(+), 91 deletions(-) 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/courseware/tests/test_views.py b/lms/djangoapps/courseware/tests/test_views.py index 87ae45ae01..1ec90fbce2 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/openedx/core/djangoapps/courseware_api/views.py b/openedx/core/djangoapps/courseware_api/views.py index 98dd432b31..51dc84bd1a 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)) + _, 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/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 + ) + ) From df517c7c21938a02ecebd2bf106bcaec1206d344 Mon Sep 17 00:00:00 2001 From: Jayram Nai Date: Fri, 5 Feb 2021 18:54:36 +0530 Subject: [PATCH 11/24] docs: Add annotations for ENABLE_STUDENT_HISTORY_VIEW feature flag --- lms/envs/common.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/lms/envs/common.py b/lms/envs/common.py index 8183a05c10..c3809d46dc 100644 --- a/lms/envs/common.py +++ b/lms/envs/common.py @@ -252,8 +252,14 @@ FEATURES = { # any courses yet. '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 From 335915a9335b7655ba3d042c95a726d962bab317 Mon Sep 17 00:00:00 2001 From: Waheed Ahmed Date: Fri, 5 Feb 2021 15:23:36 +0500 Subject: [PATCH 12/24] Fix failed attempts and lockout messages for MFE. VAN-342 --- .../core/djangoapps/user_authn/views/login.py | 84 +++++++++---------- 1 file changed, 38 insertions(+), 46 deletions(-) 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): From ac7a9f405bb5f7bbdffea1abd180b864661d0cf8 Mon Sep 17 00:00:00 2001 From: Tim McCormack Date: Fri, 5 Feb 2021 15:35:16 +0000 Subject: [PATCH 13/24] refactor: Remove old version of anonymous user ID generation (#26398) In commit 2723e0e2/PR #26162, we created a new version of the `anonymous_id_for_user` method that would make it safe to rotate the `SECRET_KEY` setting (without changing existing anonymous IDs). This included a toggle to allow fast reversion to the old code if needed. This commit removes the old code and the toggle as we are satisfied with the correctness and performance of the new code. ref: ARCHBOM-1645 --- common/djangoapps/student/models.py | 73 ----------------------------- 1 file changed, 73 deletions(-) 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. From 38f29c30f8228c4de58dbd295332df1330fdb027 Mon Sep 17 00:00:00 2001 From: Tim McCormack Date: Fri, 5 Feb 2021 16:19:14 +0000 Subject: [PATCH 14/24] feat: Use edx-proctoring 3.0.0 and set required ID generation key (#26408) MST-637: edx-proctoring 3.0.0 now requires a new key for use in ID generation, starting from same value as SECRET_KEY (pre-rotation, but rotation never happened for devstack.) Remote config changes already made for relevant environments. --- lms/envs/devstack.py | 4 ++++ lms/envs/test.py | 4 ++++ requirements/edx/base.txt | 2 +- requirements/edx/development.txt | 2 +- requirements/edx/testing.txt | 2 +- 5 files changed, 11 insertions(+), 3 deletions(-) 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/requirements/edx/base.txt b/requirements/edx/base.txt index f0f04e8dc9..e9198c5a23 100644 --- a/requirements/edx/base.txt +++ b/requirements/edx/base.txt @@ -106,7 +106,7 @@ 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 diff --git a/requirements/edx/development.txt b/requirements/edx/development.txt index 5aaa925b4b..fa220a3533 100644 --- a/requirements/edx/development.txt +++ b/requirements/edx/development.txt @@ -118,7 +118,7 @@ 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 diff --git a/requirements/edx/testing.txt b/requirements/edx/testing.txt index 524624d5c2..32742b6de4 100644 --- a/requirements/edx/testing.txt +++ b/requirements/edx/testing.txt @@ -115,7 +115,7 @@ 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 From b3b8e811484ae3c4f06c7b4c0eb46a6c2185bc68 Mon Sep 17 00:00:00 2001 From: Aarif Date: Fri, 5 Feb 2021 23:54:11 +0500 Subject: [PATCH 15/24] replaced unittest assertions pytest assertions (#26267) --- .../api_admin/api/v1/tests/test_views.py | 8 +-- .../tests/test_create_api_access_request.py | 24 +++---- .../djangoapps/api_admin/tests/test_forms.py | 6 +- .../djangoapps/api_admin/tests/test_models.py | 57 +++++++-------- .../djangoapps/api_admin/tests/test_views.py | 69 +++++++++---------- 5 files changed, 74 insertions(+), 90 deletions(-) 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} From d86550e1a339f80debd0578a3a0dc17c3a979d1a Mon Sep 17 00:00:00 2001 From: uzairr Date: Sat, 6 Feb 2021 05:13:02 +0500 Subject: [PATCH 16/24] reset-password-success-email --- openedx/core/djangoapps/user_authn/views/password_reset.py | 2 +- .../djangoapps/user_authn/views/tests/test_reset_password.py | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) 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() From c658a4719b017ad13231267dbb1e9cd2b10c4f3c Mon Sep 17 00:00:00 2001 From: JayRam Nai Date: Sat, 6 Feb 2021 21:18:10 +0530 Subject: [PATCH 17/24] docs: Adds annotations for HIDE_DASHBOARD_COURSES_UNTIL_ACTIVATED feature flag (#26403) --- lms/envs/common.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/lms/envs/common.py b/lms/envs/common.py index ac7c0803e3..7a24a11aff 100644 --- a/lms/envs/common.py +++ b/lms/envs/common.py @@ -248,8 +248,14 @@ 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, # .. toggle_name: FEATURES['ENABLE_STUDENT_HISTORY_VIEW'] From f5ba226c71b859ac546b0da0488c0883895f0833 Mon Sep 17 00:00:00 2001 From: JayRam Nai Date: Sat, 6 Feb 2021 21:34:22 +0530 Subject: [PATCH 18/24] docs: Add annotations for ENABLE_DJANGO_ADMIN_SITE feature flag (#26388) --- lms/envs/common.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/lms/envs/common.py b/lms/envs/common.py index 7a24a11aff..dfdc047c6e 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'] From cdeb430f68674b5edfa7e98e0ef27acad13bc49a Mon Sep 17 00:00:00 2001 From: edX requirements bot <49161187+edx-requirements-bot@users.noreply.github.com> Date: Mon, 8 Feb 2021 02:19:01 -0500 Subject: [PATCH 19/24] Updating Python Requirements (#26418) --- requirements/edx-sandbox/py35.txt | 2 +- requirements/edx/base.txt | 4 ++-- requirements/edx/coverage.txt | 2 +- requirements/edx/development.txt | 8 ++++---- requirements/edx/testing.txt | 8 ++++---- 5 files changed, 12 insertions(+), 12 deletions(-) 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 e9198c5a23..0fff98c767 100644 --- a/requirements/edx/base.txt +++ b/requirements/edx/base.txt @@ -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 fa220a3533..bc0a6cd76b 100644 --- a/requirements/edx/development.txt +++ b/requirements/edx/development.txt @@ -113,7 +113,7 @@ edx-drf-extensions==6.4.0 # via -r requirements/edx/testing.txt, edx-completion 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 @@ -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 diff --git a/requirements/edx/testing.txt b/requirements/edx/testing.txt index 32742b6de4..f77625ead8 100644 --- a/requirements/edx/testing.txt +++ b/requirements/edx/testing.txt @@ -110,7 +110,7 @@ edx-drf-extensions==6.4.0 # via -r requirements/edx/base.txt, edx-completion, e 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 @@ -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 From 3db1a2126393e32a363adf17530c0b117bf7605d Mon Sep 17 00:00:00 2001 From: "M. Zulqarnain" Date: Mon, 8 Feb 2021 12:42:05 +0500 Subject: [PATCH 20/24] BOM-2247 : Upgrade pip-tools (#26192) * Upgrade pip-tools * Updating Python Requirements (#26191) Co-authored-by: edX requirements bot <49161187+edx-requirements-bot@users.noreply.github.com> --- requirements/constraints.txt | 2 +- requirements/edx/development.txt | 3 ++- requirements/edx/pip-tools.txt | 5 ++++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/requirements/constraints.txt b/requirements/constraints.txt index 3f9573690a..0effbf1f29 100644 --- a/requirements/constraints.txt +++ b/requirements/constraints.txt @@ -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/development.txt b/requirements/edx/development.txt index bc0a6cd76b..76a041be8d 100644 --- a/requirements/edx/development.txt +++ b/requirements/edx/development.txt @@ -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 From 7bbde8f0f5b514ae4d04bd08aa57c379d3f4dbe2 Mon Sep 17 00:00:00 2001 From: usamasadiq Date: Tue, 2 Feb 2021 14:54:00 +0500 Subject: [PATCH 21/24] Applied pylint-amnesty --- cms/djangoapps/api/__init__.py | 2 +- .../api/v1/serializers/course_runs.py | 28 +++++++-------- .../test_serializers/test_course_runs.py | 4 +-- .../v1/tests/test_views/test_course_runs.py | 14 ++++---- cms/djangoapps/api/v1/tests/utils.py | 1 + cms/djangoapps/api/v1/views/course_runs.py | 14 ++++---- cms/djangoapps/cms_user_tasks/tests.py | 10 +++--- .../contentstore/api/views/course_import.py | 2 +- .../contentstore/api/views/course_quality.py | 19 ++++++----- .../api/views/course_validation.py | 11 +++--- .../contentstore/course_group_config.py | 8 ++--- .../contentstore/courseware_index.py | 10 +++--- .../contentstore/debug_file_uploader.py | 4 +-- .../contentstore/git_export_utils.py | 18 +++++----- .../management/commands/cleanup_assets.py | 4 +-- .../management/commands/create_course.py | 4 +-- .../management/commands/delete_course.py | 4 +-- .../management/commands/delete_orphans.py | 2 +- .../management/commands/edit_course_tabs.py | 5 +-- .../management/commands/export.py | 2 +- .../commands/export_content_library.py | 4 +-- .../management/commands/export_olx.py | 4 +-- .../management/commands/force_publish.py | 2 +- .../management/commands/generate_courses.py | 22 ++++++------ .../management/commands/git_export.py | 4 +-- .../commands/import_content_library.py | 4 +-- .../management/commands/migrate_to_split.py | 8 ++--- .../management/commands/reindex_course.py | 7 ++-- .../management/commands/sync_courses.py | 4 +-- .../commands/tests/test_cleanup_assets.py | 8 ++--- .../commands/tests/test_create_course.py | 4 +-- .../management/commands/tests/test_export.py | 2 +- .../commands/tests/test_export_all_courses.py | 4 +-- .../commands/tests/test_force_publish.py | 2 +- .../commands/tests/test_git_export.py | 2 +- .../management/commands/tests/test_import.py | 4 +-- .../commands/tests/test_migrate_to_split.py | 18 +++++----- .../commands/tests/test_reindex_courses.py | 4 +-- .../commands/tests/test_reindex_library.py | 2 +- .../commands/tests/test_sync_courses.py | 6 ++-- .../contentstore/management/commands/utils.py | 2 +- cms/djangoapps/contentstore/proctoring.py | 2 +- .../contentstore/signals/handlers.py | 2 +- cms/djangoapps/contentstore/storage.py | 2 +- cms/djangoapps/contentstore/tasks.py | 4 +-- .../contentstore/tests/test_clone_course.py | 4 +-- .../contentstore/tests/test_contentstore.py | 26 +++++++------- .../tests/test_course_create_rerun.py | 2 +- .../contentstore/tests/test_course_listing.py | 2 +- .../tests/test_course_settings.py | 10 +++--- .../tests/test_courseware_index.py | 18 +++++----- .../contentstore/tests/test_export_git.py | 2 +- .../contentstore/tests/test_gating.py | 2 +- .../contentstore/tests/test_i18n.py | 12 +++---- .../contentstore/tests/test_import.py | 6 ++-- .../tests/test_import_draft_order.py | 2 +- .../contentstore/tests/test_libraries.py | 10 +++--- .../contentstore/tests/test_permissions.py | 8 ++--- .../contentstore/tests/test_proctoring.py | 2 +- .../contentstore/tests/test_signals.py | 2 +- .../contentstore/tests/test_tasks.py | 4 +-- .../tests/test_transcripts_utils.py | 16 ++++----- .../tests/test_users_default_role.py | 4 +-- .../contentstore/tests/test_utils.py | 8 ++--- .../contentstore/tests/test_video_utils.py | 4 +-- cms/djangoapps/contentstore/tests/tests.py | 6 ++-- cms/djangoapps/contentstore/tests/utils.py | 8 ++--- cms/djangoapps/contentstore/utils.py | 4 +-- cms/djangoapps/contentstore/video_utils.py | 2 +- cms/djangoapps/contentstore/views/__init__.py | 2 +- cms/djangoapps/contentstore/views/assets.py | 12 +++---- .../contentstore/views/certificates.py | 6 ++-- .../contentstore/views/checklists.py | 1 + .../contentstore/views/component.py | 10 +++--- cms/djangoapps/contentstore/views/course.py | 34 +++++++++---------- .../contentstore/views/entrance_exam.py | 6 ++-- cms/djangoapps/contentstore/views/error.py | 7 ++-- .../contentstore/views/exception.py | 4 +-- cms/djangoapps/contentstore/views/helpers.py | 2 +- .../contentstore/views/import_export.py | 10 +++--- cms/djangoapps/contentstore/views/item.py | 8 ++--- .../contentstore/views/organization.py | 4 +-- cms/djangoapps/contentstore/views/preview.py | 10 +++--- .../contentstore/views/session_kv_store.py | 2 +- cms/djangoapps/contentstore/views/tabs.py | 2 +- .../contentstore/views/tests/test_access.py | 4 +-- .../contentstore/views/tests/test_assets.py | 8 ++--- .../views/tests/test_certificates.py | 6 ++-- .../views/tests/test_container_page.py | 2 +- .../views/tests/test_course_index.py | 10 +++--- .../views/tests/test_course_updates.py | 10 +++--- .../views/tests/test_credit_eligibility.py | 2 +- .../views/tests/test_entrance_exam.py | 4 +-- .../views/tests/test_exam_settings_view.py | 2 +- .../contentstore/views/tests/test_gating.py | 2 +- .../views/tests/test_group_configurations.py | 4 +-- .../views/tests/test_header_menu.py | 2 +- .../views/tests/test_import_export.py | 30 ++++++++-------- .../contentstore/views/tests/test_item.py | 32 ++++++++--------- .../contentstore/views/tests/test_library.py | 2 +- .../views/tests/test_organizations.py | 2 +- .../contentstore/views/tests/test_preview.py | 4 +-- .../contentstore/views/tests/test_tabs.py | 2 +- .../views/tests/test_textbooks.py | 8 ++--- .../views/tests/test_transcript_settings.py | 4 +-- .../views/tests/test_transcripts.py | 10 +++--- .../views/tests/test_unit_page.py | 4 +-- .../contentstore/views/tests/test_user.py | 6 ++-- .../contentstore/views/tests/test_videos.py | 14 ++++---- .../contentstore/views/tests/utils.py | 2 +- .../contentstore/views/transcript_settings.py | 2 +- .../contentstore/views/transcripts_ajax.py | 6 ++-- cms/djangoapps/contentstore/views/user.py | 2 +- cms/djangoapps/contentstore/views/videos.py | 2 +- common/lib/symmath/symmath/__init__.py | 1 + common/lib/symmath/symmath/formula.py | 20 +++++------ common/lib/symmath/symmath/symmath_check.py | 34 +++++++++---------- common/lib/symmath/symmath/test_formula.py | 4 +-- .../lib/symmath/symmath/test_symmath_check.py | 8 ++--- common/lib/xmodule/xmodule/graders.py | 2 +- lms/djangoapps/courseware/masquerade.py | 2 +- lms/djangoapps/courseware/model_data.py | 2 +- lms/djangoapps/instructor/views/__init__.py | 2 +- lms/djangoapps/instructor/views/api.py | 30 ++++++++-------- .../instructor/views/gradebook_api.py | 2 +- .../instructor/views/instructor_dashboard.py | 4 +-- .../core/djangoapps/profile_images/urls.py | 1 - .../djangoapps/site_configuration/helpers.py | 2 +- openedx/core/djangoapps/user_authn/utils.py | 2 +- 129 files changed, 443 insertions(+), 438 deletions(-) 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 34eb146913..7654f78a06 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): 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/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/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/lms/djangoapps/courseware/masquerade.py b/lms/djangoapps/courseware/masquerade.py index 521098a8fe..bfb35f671c 100644 --- a/lms/djangoapps/courseware/masquerade.py +++ b/lms/djangoapps/courseware/masquerade.py @@ -412,7 +412,7 @@ class MasqueradingKeyValueStore(KeyValueStore): This `KeyValueStore` wraps an underlying `KeyValueStore`. Reads are forwarded to the underlying store, but writes go to a Django session (or other dictionary-like object). """ - def __init__(self, kvs, session): + def __init__(self, kvs, session): # lint-amnesty, pylint: disable=super-init-not-called """ Arguments: kvs: The KeyValueStore to wrap. 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/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/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/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): From 047a5f5f19db29a67c4626f3116dd01e6569e77a Mon Sep 17 00:00:00 2001 From: "M. Zulqarnain" Date: Mon, 8 Feb 2021 15:51:22 +0500 Subject: [PATCH 22/24] BOM-2319 : Pylint amnesty in openedx content apps (#26347) * pylint amnesty in openedx content apps Co-authored-by: Jawayria --- .../content/block_structure/admin.py | 2 +- .../content/block_structure/apps.py | 2 +- .../block_structure/block_structure.py | 20 +++---- .../content/block_structure/exceptions.py | 10 ++-- .../tests/test_generate_course_blocks.py | 2 +- .../content/block_structure/manager.py | 2 +- .../content/block_structure/models.py | 14 ++--- .../content/block_structure/store.py | 4 +- .../content/block_structure/tests/helpers.py | 8 +-- .../block_structure/tests/test_factory.py | 2 +- .../block_structure/tests/test_manager.py | 2 +- .../block_structure/tests/test_models.py | 6 +- .../block_structure/tests/test_signals.py | 2 +- .../block_structure/tests/test_store.py | 2 +- .../tests/test_transformer_registry.py | 8 +-- .../tests/test_transformers.py | 4 +- .../content/block_structure/transformer.py | 2 +- .../content/block_structure/transformers.py | 4 +- .../content/course_overviews/apps.py | 2 +- .../commands/generate_course_overview.py | 2 +- .../management/commands/simulate_publish.py | 14 ++--- .../tests/test_generate_course_overview.py | 2 +- .../commands/tests/test_simulate_publish.py | 4 +- .../content/course_overviews/models.py | 10 ++-- .../content/course_overviews/serializers.py | 2 +- .../content/course_overviews/signals.py | 2 +- .../content/course_overviews/tasks.py | 6 +- .../course_overviews/tests/factories.py | 4 +- .../course_overviews/tests/test_api.py | 2 +- .../tests/test_course_overviews.py | 2 +- .../tests/test_serializers.py | 2 +- .../course_overviews/tests/test_signals.py | 4 +- .../course_overviews/tests/test_tasks.py | 6 +- .../learning_sequences/api/__init__.py | 1 + .../learning_sequences/api/outlines.py | 12 ++-- .../learning_sequences/api/processors/base.py | 8 +-- .../api/processors/content_gating.py | 1 + .../api/processors/milestones.py | 3 +- .../api/processors/schedule.py | 7 ++- .../api/processors/special_exams.py | 2 +- .../learning_sequences/api/tests/test_data.py | 3 +- .../api/tests/test_outlines.py | 60 +++++++++---------- .../content/learning_sequences/apps.py | 3 +- .../content/learning_sequences/data.py | 8 +-- .../content/learning_sequences/models.py | 2 +- .../learning_sequences/tests/test_views.py | 8 +-- .../content/learning_sequences/urls.py | 1 + .../content/learning_sequences/views.py | 14 ++--- .../core/djangoapps/content_libraries/api.py | 6 +- .../content_libraries/library_bundle.py | 2 +- .../content_libraries/library_context.py | 4 +- .../commands/reindex_content_library.py | 2 +- .../djangoapps/content_libraries/models.py | 6 +- .../content_libraries/permissions.py | 2 +- .../content_libraries/serializers.py | 2 +- .../tests/test_content_libraries.py | 2 +- .../content_libraries/tests/test_runtime.py | 4 +- .../djangoapps/content_libraries/views.py | 32 +++++----- .../core/djangoapps/contentserver/__init__.py | 2 +- .../djangoapps/contentserver/middleware.py | 6 +- .../contentserver/test/test_contentserver.py | 14 ++--- .../djangoapps/cors_csrf/authentication.py | 2 +- .../core/djangoapps/cors_csrf/middleware.py | 6 +- .../cors_csrf/tests/test_authentication.py | 2 +- .../cors_csrf/tests/test_decorators.py | 2 +- .../cors_csrf/tests/test_middleware.py | 6 +- .../djangoapps/cors_csrf/tests/test_views.py | 2 +- 67 files changed, 202 insertions(+), 195 deletions(-) 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/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 61eb0cd3b9..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), @@ -592,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..0516078923 100644 --- a/openedx/core/djangoapps/content/course_overviews/tasks.py +++ b/openedx/core/djangoapps/content/course_overviews/tasks.py @@ -1,4 +1,4 @@ - +# lint-amnesty, pylint: disable=missing-module-docstring import logging @@ -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, 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: From 16cc57dc7da7041a5fb3dc0bebe143bda7505bde Mon Sep 17 00:00:00 2001 From: JayRam Nai Date: Mon, 8 Feb 2021 18:26:48 +0530 Subject: [PATCH 23/24] docs: Add annotations for EDITABLE_SHORT_DESCRIPTION feature flag (#26401) --- cms/envs/common.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) 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 From 17cde562da882a309c7fff59c82dcc8330619c09 Mon Sep 17 00:00:00 2001 From: JayRam Nai Date: Mon, 8 Feb 2021 18:28:09 +0530 Subject: [PATCH 24/24] docs: Add annotations for ENABLE_FOOTER_MOBILE_APP_LINKS feature flag (#26389) docs: update warning for ENABLE_FOOTER_MOBILE_APP_LINKS features toggle --- lms/envs/common.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/lms/envs/common.py b/lms/envs/common.py index dfdc047c6e..c2fa5e5935 100644 --- a/lms/envs/common.py +++ b/lms/envs/common.py @@ -486,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