From 9ee8df09807d6bab2ba5f4c438f15feeb9d92778 Mon Sep 17 00:00:00 2001 From: Usama Sadiq Date: Wed, 20 Oct 2021 23:00:13 +0500 Subject: [PATCH] fix: Remove pylint constraint and fix warnings (#28646) --- cms/djangoapps/contentstore/views/course.py | 1 - .../entitlements/tests/test_models.py | 2 +- .../management/commands/assigngroups.py | 2 +- common/djangoapps/third_party_auth/saml.py | 2 +- common/djangoapps/util/models.py | 4 +- .../xmodule/xmodule/assetstore/__init__.py | 2 +- .../lib/xmodule/xmodule/contentstore/mongo.py | 2 +- common/lib/xmodule/xmodule/course_module.py | 2 +- common/lib/xmodule/xmodule/graders.py | 2 +- .../xmodule/xmodule/modulestore/__init__.py | 4 +- .../xmodule/xmodule/modulestore/mongo/base.py | 2 +- .../xmodule/partitions/partitions_service.py | 2 +- common/lib/xmodule/xmodule/progress.py | 2 +- lms/djangoapps/bulk_email/tasks.py | 2 +- lms/djangoapps/course_api/tests/test_views.py | 4 +- lms/djangoapps/courseware/access_response.py | 2 +- lms/djangoapps/courseware/courses.py | 2 +- lms/djangoapps/courseware/tabs.py | 2 +- .../courseware/tests/test_date_summary.py | 4 +- lms/djangoapps/discussion/tests/test_views.py | 6 +-- .../instructor/tests/test_enrollment.py | 2 +- lms/djangoapps/instructor_task/api_helper.py | 4 +- .../program_enrollments/rest_api/v1/views.py | 2 +- openedx/core/djangoapps/ccxcon/api.py | 2 +- .../content_libraries/library_bundle.py | 2 +- openedx/core/djangoapps/discussions/models.py | 2 +- .../schedules/management/commands/__init__.py | 4 +- .../djangoapps/user_api/accounts/views.py | 2 +- .../commands/sync_hubspot_contacts.py | 2 +- .../user_authn/views/registration_form.py | 2 +- .../user_authn/views/tests/test_register.py | 10 ++--- openedx/core/djangolib/blockstore_cache.py | 2 +- openedx/core/djangolib/js_utils.py | 2 +- openedx/core/lib/blockstore_api/methods.py | 4 +- openedx/core/lib/teams_config.py | 4 +- .../course_experience/course_updates.py | 2 +- .../enterprise_support/enrollments/utils.py | 2 +- pylintrc | 44 +++++++++---------- pylintrc_tweaks | 3 ++ requirements/constraints.txt | 4 -- requirements/edx/development.txt | 12 +++-- requirements/edx/testing.txt | 15 +++++-- 42 files changed, 95 insertions(+), 84 deletions(-) diff --git a/cms/djangoapps/contentstore/views/course.py b/cms/djangoapps/contentstore/views/course.py index d9feb4301e..75a3a8b213 100644 --- a/cms/djangoapps/contentstore/views/course.py +++ b/cms/djangoapps/contentstore/views/course.py @@ -1,7 +1,6 @@ """ Views related to operations on course objects """ -# pylint: disable=filter-builtin-not-iterating import copy diff --git a/common/djangoapps/entitlements/tests/test_models.py b/common/djangoapps/entitlements/tests/test_models.py index da15c09e26..a88a7182b5 100644 --- a/common/djangoapps/entitlements/tests/test_models.py +++ b/common/djangoapps/entitlements/tests/test_models.py @@ -109,7 +109,7 @@ class TestCourseEntitlementModelHelpers(ModuleStoreTestCase): ) assert not CourseEnrollment.is_enrolled(user=self.user, course_key=new_course.id) except AttributeError as error: - self.fail(error.message) # lint-amnesty, pylint: disable=no-member, exception-message-attribute + self.fail(error.message) # lint-amnesty, pylint: disable=no-member @unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms') diff --git a/common/djangoapps/student/management/commands/assigngroups.py b/common/djangoapps/student/management/commands/assigngroups.py index 5283397456..acde7994a3 100644 --- a/common/djangoapps/student/management/commands/assigngroups.py +++ b/common/djangoapps/student/management/commands/assigngroups.py @@ -54,7 +54,7 @@ class Command(BaseCommand): # lint-amnesty, pylint: disable=missing-class-docst print("Groups", groups) # Confirm group probabilities add up to 1 - total = sum(zip(*groups)[1]) # lint-amnesty, pylint: disable=unsubscriptable-object, zip-builtin-not-iterating + total = sum(zip(*groups)[1]) # lint-amnesty, pylint: disable=unsubscriptable-object print("Total:", total) if abs(total - 1) > 0.01: print("Total not 1") diff --git a/common/djangoapps/third_party_auth/saml.py b/common/djangoapps/third_party_auth/saml.py index e0385727ac..38fa157bb4 100644 --- a/common/djangoapps/third_party_auth/saml.py +++ b/common/djangoapps/third_party_auth/saml.py @@ -94,7 +94,7 @@ class SAMLAuthBackend(SAMLAuth): # pylint: disable=abstract-method log.warning( '[THIRD_PARTY_AUTH] Error in SAML authentication flow. ' 'Provider: {idp_name}, Message: {message}'.format( - message=ex.message, # lint-amnesty, pylint: disable=no-member, exception-message-attribute + message=ex.message, # lint-amnesty, pylint: disable=no-member idp_name=response.get('idp_name') ) ) diff --git a/common/djangoapps/util/models.py b/common/djangoapps/util/models.py index 1959ac3d7c..9f55d41b8e 100644 --- a/common/djangoapps/util/models.py +++ b/common/djangoapps/util/models.py @@ -35,7 +35,7 @@ def decompress_string(value): """ try: - val = value.encode('utf').decode('base64') # pylint: disable=invalid-str-codec + val = value.encode('utf').decode('base64') zbuf = BytesIO(val) zfile = gzip.GzipFile(fileobj=zbuf) ret = zfile.read() @@ -60,7 +60,7 @@ class CompressedTextField(CreatorMixin, models.TextField): if isinstance(value, str): value = value.encode('utf8') value = compress_string(value) - value = value.encode('base64').decode('utf8') # pylint: disable=invalid-str-codec + value = value.encode('base64').decode('utf8') return value def to_python(self, value): diff --git a/common/lib/xmodule/xmodule/assetstore/__init__.py b/common/lib/xmodule/xmodule/assetstore/__init__.py index 2a102a7dc5..d18a1bd020 100644 --- a/common/lib/xmodule/xmodule/assetstore/__init__.py +++ b/common/lib/xmodule/xmodule/assetstore/__init__.py @@ -285,4 +285,4 @@ class CourseAssetsFromStorage: """ Iterates over the items of the asset dict. (Python 3 naming convention) """ - return self.iteritems() # lint-amnesty, pylint: disable=dict-iter-method + return self.iteritems() diff --git a/common/lib/xmodule/xmodule/contentstore/mongo.py b/common/lib/xmodule/xmodule/contentstore/mongo.py index b2eacb33cd..2a9848bc2a 100644 --- a/common/lib/xmodule/xmodule/contentstore/mongo.py +++ b/common/lib/xmodule/xmodule/contentstore/mongo.py @@ -324,7 +324,7 @@ class MongoContentStore(ContentStore): count = 0 assets = [] try: - result = cursor.next() # lint-amnesty, pylint: disable=next-method-called + result = cursor.next() if result: count = result['count'] assets = list(result['results']) diff --git a/common/lib/xmodule/xmodule/course_module.py b/common/lib/xmodule/xmodule/course_module.py index 7b6bcfb9ad..0a6e8a4b0a 100644 --- a/common/lib/xmodule/xmodule/course_module.py +++ b/common/lib/xmodule/xmodule/course_module.py @@ -103,7 +103,7 @@ edx_xml_parser = etree.XMLParser(dtd_validation=False, load_dtd=False, _cached_toc = {} -class Textbook: # lint-amnesty, pylint: disable=missing-class-docstring, eq-without-hash +class Textbook: # lint-amnesty, pylint: disable=missing-class-docstring def __init__(self, title, book_url): self.title = title self.book_url = book_url diff --git a/common/lib/xmodule/xmodule/graders.py b/common/lib/xmodule/xmodule/graders.py index 152676e955..399e1b3f20 100644 --- a/common/lib/xmodule/xmodule/graders.py +++ b/common/lib/xmodule/xmodule/graders.py @@ -20,7 +20,7 @@ from xmodule.util.misc import get_short_labeler log = logging.getLogger("edx.courseware") -class ScoreBase(metaclass=abc.ABCMeta): # pylint: disable=eq-without-hash +class ScoreBase(metaclass=abc.ABCMeta): """ Abstract base class for encapsulating fields of values scores. """ diff --git a/common/lib/xmodule/xmodule/modulestore/__init__.py b/common/lib/xmodule/xmodule/modulestore/__init__.py index caff9a6aa3..ff6a04bd67 100644 --- a/common/lib/xmodule/xmodule/modulestore/__init__.py +++ b/common/lib/xmodule/xmodule/modulestore/__init__.py @@ -328,7 +328,7 @@ class BulkOperationsMixin: bulk_ops_record.has_library_updated_item = False -class EditInfo: # pylint: disable=eq-without-hash +class EditInfo: """ Encapsulates the editing info of a block. """ @@ -407,7 +407,7 @@ class EditInfo: # pylint: disable=eq-without-hash return not self == edit_info -class BlockData: # pylint: disable=eq-without-hash +class BlockData: """ Wrap the block data in an object instead of using a straight Python dictionary. Allows the storing of meta-information about a structure that doesn't persist along with diff --git a/common/lib/xmodule/xmodule/modulestore/mongo/base.py b/common/lib/xmodule/xmodule/modulestore/mongo/base.py index bb4644ef74..dab3bf2fad 100644 --- a/common/lib/xmodule/xmodule/modulestore/mongo/base.py +++ b/common/lib/xmodule/xmodule/modulestore/mongo/base.py @@ -1291,7 +1291,7 @@ class MongoModuleStore(ModuleStoreDraftAndPublished, ModuleStoreWriteBase, Mongo ]) courses = self.collection.find(course_search_location, projection={'_id': True}) try: - course = courses.next() # lint-amnesty, pylint: disable=next-method-called + course = courses.next() raise DuplicateCourseError(course_id, course['_id']) except StopIteration: pass diff --git a/common/lib/xmodule/xmodule/partitions/partitions_service.py b/common/lib/xmodule/xmodule/partitions/partitions_service.py index 16c3d3549a..711fe78839 100644 --- a/common/lib/xmodule/xmodule/partitions/partitions_service.py +++ b/common/lib/xmodule/xmodule/partitions/partitions_service.py @@ -78,7 +78,7 @@ def _get_dynamic_partitions(course): Return the dynamic user partitions for this course. If none exists, returns an empty array. """ - dynamic_partition_generators = DynamicPartitionGeneratorsPluginManager.get_available_plugins().values() # lint-amnesty, pylint: disable=dict-values-not-iterating + dynamic_partition_generators = DynamicPartitionGeneratorsPluginManager.get_available_plugins().values() generated_partitions = [] for generator in dynamic_partition_generators: generated_partition = generator(course) diff --git a/common/lib/xmodule/xmodule/progress.py b/common/lib/xmodule/xmodule/progress.py index deaddd282b..014ce6369f 100644 --- a/common/lib/xmodule/xmodule/progress.py +++ b/common/lib/xmodule/xmodule/progress.py @@ -9,7 +9,7 @@ frac() and __str__(). import numbers -class Progress: # pylint: disable=eq-without-hash +class Progress: '''Represents a progress of a/b (a out of b done) a and b must be numeric, but not necessarily integer, with diff --git a/lms/djangoapps/bulk_email/tasks.py b/lms/djangoapps/bulk_email/tasks.py index e2e193810b..b49eec13c2 100644 --- a/lms/djangoapps/bulk_email/tasks.py +++ b/lms/djangoapps/bulk_email/tasks.py @@ -480,7 +480,7 @@ def _send_course_email(entry_id, email_id, to_list, global_email_context, subtas task_id, email_id ) - raise + raise exc # Exclude optouts (if not a retry): # Note that we don't have to do the optout logic at all if this is a retry, diff --git a/lms/djangoapps/course_api/tests/test_views.py b/lms/djangoapps/course_api/tests/test_views.py index e2cb2521c2..425cab611d 100644 --- a/lms/djangoapps/course_api/tests/test_views.py +++ b/lms/djangoapps/course_api/tests/test_views.py @@ -556,7 +556,7 @@ class CourseIdListViewTestCase(CourseApiTestViewMixin, ModuleStoreTestCase): class LazyPageNumberPaginationTestCase(TestCase): # lint-amnesty, pylint: disable=missing-class-docstring def test_lazy_page_number_pagination(self): - number_sequence = range(20) # lint-amnesty, pylint: disable=range-builtin-not-iterating + number_sequence = range(20) even_numbers_lazy_sequence = LazySequence( ( number for number in number_sequence @@ -585,7 +585,7 @@ class LazyPageNumberPaginationTestCase(TestCase): # lint-amnesty, pylint: disab self.assertDictEqual(expected_response, paginated_response.data) def test_not_found_error_for_invalid_page(self): - number_sequence = range(20) # lint-amnesty, pylint: disable=range-builtin-not-iterating + number_sequence = range(20) even_numbers_lazy_sequence = LazySequence( ( number for number in number_sequence diff --git a/lms/djangoapps/courseware/access_response.py b/lms/djangoapps/courseware/access_response.py index acb0f2dc95..876dfd7f7b 100644 --- a/lms/djangoapps/courseware/access_response.py +++ b/lms/djangoapps/courseware/access_response.py @@ -8,7 +8,7 @@ from django.utils.translation import ugettext as _ from xmodule.course_metadata_utils import DEFAULT_START_DATE -class AccessResponse: # pylint: disable=eq-without-hash +class AccessResponse: """Class that represents a response from a has_access permission check.""" def __init__(self, has_access, error_code=None, developer_message=None, user_message=None, additional_context_user_message=None, user_fragment=None): diff --git a/lms/djangoapps/courseware/courses.py b/lms/djangoapps/courseware/courses.py index e15566068e..b89aa85f36 100644 --- a/lms/djangoapps/courseware/courses.py +++ b/lms/djangoapps/courseware/courses.py @@ -464,7 +464,7 @@ def get_course_date_blocks(course, user, request=None, include_access=False, ] blocks.extend([cls(course, user) for cls in default_block_classes]) - blocks = filter(lambda b: b.is_allowed and b.date and (include_past_dates or b.is_enabled), blocks) # lint-amnesty, pylint: disable=filter-builtin-not-iterating + blocks = filter(lambda b: b.is_allowed and b.date and (include_past_dates or b.is_enabled), blocks) return sorted(blocks, key=date_block_key_fn) diff --git a/lms/djangoapps/courseware/tabs.py b/lms/djangoapps/courseware/tabs.py index b851e625ad..7eb8ed27f1 100644 --- a/lms/djangoapps/courseware/tabs.py +++ b/lms/djangoapps/courseware/tabs.py @@ -210,7 +210,7 @@ class HtmlTextbookTabs(TextbookTabsBase): ) -class LinkTab(CourseTab): # lint-amnesty, pylint: disable=eq-without-hash +class LinkTab(CourseTab): """ Abstract class for tabs that contain external links. """ diff --git a/lms/djangoapps/courseware/tests/test_date_summary.py b/lms/djangoapps/courseware/tests/test_date_summary.py index ec3dba5d07..64569118dd 100644 --- a/lms/djangoapps/courseware/tests/test_date_summary.py +++ b/lms/djangoapps/courseware/tests/test_date_summary.py @@ -241,7 +241,7 @@ class CourseDateSummaryTest(SharedModuleStoreTestCase): blocks = get_course_date_blocks(course, user, request, num_assignments=2) assert len(blocks) == len(expected_blocks) assert {type(b) for b in blocks} == set(expected_blocks) - assignment_blocks = filter( # pylint: disable=filter-builtin-not-iterating + assignment_blocks = filter( lambda b: isinstance(b, CourseAssignmentDate), blocks ) for assignment in assignment_blocks: @@ -267,7 +267,7 @@ class CourseDateSummaryTest(SharedModuleStoreTestCase): blocks = get_course_date_blocks(course, user, request, include_past_dates=True) assert len(blocks) == len(expected_blocks) assert {type(b) for b in blocks} == set(expected_blocks) - assignment_blocks = filter( # pylint: disable=filter-builtin-not-iterating + assignment_blocks = filter( lambda b: isinstance(b, CourseAssignmentDate), blocks ) for assignment in assignment_blocks: diff --git a/lms/djangoapps/discussion/tests/test_views.py b/lms/djangoapps/discussion/tests/test_views.py index 0cf438e231..e9923a9aa1 100644 --- a/lms/djangoapps/discussion/tests/test_views.py +++ b/lms/djangoapps/discussion/tests/test_views.py @@ -280,7 +280,7 @@ def make_mock_request_impl( # lint-amnesty, pylint: disable=missing-function-do return mock_request_impl -class StringEndsWithMatcher: # lint-amnesty, pylint: disable=missing-class-docstring,eq-without-hash +class StringEndsWithMatcher: # lint-amnesty, pylint: disable=missing-class-docstring def __init__(self, suffix): self.suffix = suffix @@ -288,7 +288,7 @@ class StringEndsWithMatcher: # lint-amnesty, pylint: disable=missing-class-docs return other.endswith(self.suffix) -class PartialDictMatcher: # lint-amnesty, pylint: disable=missing-class-docstring,eq-without-hash +class PartialDictMatcher: # lint-amnesty, pylint: disable=missing-class-docstring def __init__(self, expected_values): self.expected_values = expected_values @@ -445,7 +445,7 @@ class SingleThreadTestCase(ForumsEnableMixin, ModuleStoreTestCase): # lint-amne assert 'This is a private discussion. You do not have permissions to view this discussion' in html -class AllowPlusOrMinusOneInt(int): # pylint: disable=eq-without-hash +class AllowPlusOrMinusOneInt(int): """ A workaround for the fact that assertNumQueries doesn't let you specify a range or any tolerance. An 'int' that is 'equal to' its value, diff --git a/lms/djangoapps/instructor/tests/test_enrollment.py b/lms/djangoapps/instructor/tests/test_enrollment.py index b6ae41262f..d3f2cf018a 100644 --- a/lms/djangoapps/instructor/tests/test_enrollment.py +++ b/lms/djangoapps/instructor/tests/test_enrollment.py @@ -796,7 +796,7 @@ class EnrollmentObjects: self.cea = cea -class SettableEnrollmentState(EmailEnrollmentState): # lint-amnesty, pylint: disable=eq-without-hash +class SettableEnrollmentState(EmailEnrollmentState): """ Settable enrollment state. Used for testing state changes. diff --git a/lms/djangoapps/instructor_task/api_helper.py b/lms/djangoapps/instructor_task/api_helper.py index 6349785064..cb3dfa9c67 100644 --- a/lms/djangoapps/instructor_task/api_helper.py +++ b/lms/djangoapps/instructor_task/api_helper.py @@ -32,7 +32,7 @@ class AlreadyRunningError(Exception): def __init__(self, message=None): if not message: - message = self.message # pylint: disable=exception-message-attribute + message = self.message super().__init__(message) @@ -44,7 +44,7 @@ class QueueConnectionError(Exception): def __init__(self, message=None): if not message: - message = self.message # pylint: disable=exception-message-attribute + message = self.message super().__init__(message) diff --git a/lms/djangoapps/program_enrollments/rest_api/v1/views.py b/lms/djangoapps/program_enrollments/rest_api/v1/views.py index bf22be1195..4c80bffaf2 100644 --- a/lms/djangoapps/program_enrollments/rest_api/v1/views.py +++ b/lms/djangoapps/program_enrollments/rest_api/v1/views.py @@ -770,7 +770,7 @@ class UserProgramReadOnlyAccessView(DeveloperErrorViewMixin, PaginatedAPIView): if course_run_program and course_run_program.get('type').lower() == program_type_filter: program_dict[course_run_program['uuid']] = course_run_program - return program_dict.values() # lint-amnesty, pylint: disable=dict-values-not-iterating + return program_dict.values() class UserProgramCourseEnrollmentView( diff --git a/openedx/core/djangoapps/ccxcon/api.py b/openedx/core/djangoapps/ccxcon/api.py index 26ba5cd05c..5dab1c940f 100644 --- a/openedx/core/djangoapps/ccxcon/api.py +++ b/openedx/core/djangoapps/ccxcon/api.py @@ -152,7 +152,7 @@ def course_info_to_ccxcon(course_key): if resp.status_code >= 400: log.error("Error creating course on ccxcon. Status: %s, Content: %s", resp.status_code, resp.content) # this API performs a POST request both for POST and PATCH, but the POST returns 201 and the PATCH returns 200 - elif resp.status_code != HTTP_200_OK and resp.status_code != HTTP_201_CREATED: + elif resp.status_code not in (HTTP_200_OK, HTTP_201_CREATED): log.error('Server returned unexpected status code %s', resp.status_code) else: log.debug('Request successful. Status: %s, Content: %s', resp.status_code, resp.content) diff --git a/openedx/core/djangoapps/content_libraries/library_bundle.py b/openedx/core/djangoapps/content_libraries/library_bundle.py index 4fc1cafdfc..9db51c90f5 100644 --- a/openedx/core/djangoapps/content_libraries/library_bundle.py +++ b/openedx/core/djangoapps/content_libraries/library_bundle.py @@ -179,7 +179,7 @@ class LibraryBundle: Get the set of usage keys in this bundle that have no parent. """ own_usage_keys = self.get_all_usages() - usage_keys_with_parents = self.get_bundle_includes().keys() # lint-amnesty, pylint: disable=dict-keys-not-iterating + usage_keys_with_parents = self.get_bundle_includes().keys() return [usage_key for usage_key in own_usage_keys if usage_key not in usage_keys_with_parents] def get_bundle_includes(self): diff --git a/openedx/core/djangoapps/discussions/models.py b/openedx/core/djangoapps/discussions/models.py index a5ebccac78..50944b92ad 100644 --- a/openedx/core/djangoapps/discussions/models.py +++ b/openedx/core/djangoapps/discussions/models.py @@ -74,7 +74,7 @@ class Features(Enum): self.feature_support_type = feature_support_type @property - def value(self): + def value(self): # pylint: disable=invalid-overridden-method return self.feature_id @property diff --git a/openedx/core/djangoapps/schedules/management/commands/__init__.py b/openedx/core/djangoapps/schedules/management/commands/__init__.py index 5f01d0a5be..bd0082f533 100644 --- a/openedx/core/djangoapps/schedules/management/commands/__init__.py +++ b/openedx/core/djangoapps/schedules/management/commands/__init__.py @@ -17,7 +17,7 @@ class SendEmailBaseCommand(PrefixedDebugLoggerMixin, BaseCommand): # lint-amnes # An iterable of day offsets (e.g. -7, -14, -21, -28, ...) that defines the days for # which emails are sent out, relative to the 'date' parameter - offsets = range(-7, -77, -7) # lint-amnesty, pylint: disable=range-builtin-not-iterating + offsets = range(-7, -77, -7) def add_arguments(self, parser): parser.add_argument( @@ -42,7 +42,7 @@ class SendEmailBaseCommand(PrefixedDebugLoggerMixin, BaseCommand): # lint-amnes num_weeks = options.get('weeks') if num_weeks: num_days = (7 * num_weeks) + 1 - self.offsets = range(-7, -num_days, -7) # lint-amnesty, pylint: disable=range-builtin-not-iterating + self.offsets = range(-7, -num_days, -7) current_date = datetime.datetime( *[int(x) for x in options['date'].split('-')], diff --git a/openedx/core/djangoapps/user_api/accounts/views.py b/openedx/core/djangoapps/user_api/accounts/views.py index f5568dd76e..dad523cb9a 100644 --- a/openedx/core/djangoapps/user_api/accounts/views.py +++ b/openedx/core/djangoapps/user_api/accounts/views.py @@ -546,7 +546,7 @@ class DeactivateLogoutView(APIView): ace.send(notification) except Exception as exc: log.exception('Error sending out deletion notification email') - raise + raise exc # Log the user out. logout(request) diff --git a/openedx/core/djangoapps/user_api/management/commands/sync_hubspot_contacts.py b/openedx/core/djangoapps/user_api/management/commands/sync_hubspot_contacts.py index 9bafe607ad..4f29c4d449 100644 --- a/openedx/core/djangoapps/user_api/management/commands/sync_hubspot_contacts.py +++ b/openedx/core/djangoapps/user_api/management/commands/sync_hubspot_contacts.py @@ -145,7 +145,7 @@ class Command(BaseCommand): return len(contacts) except (HttpClientError, HttpServerError) as ex: message = 'An error occurred while syncing batch of contacts for site {domain}, {message}'.format( - domain=site_conf.site.domain, message=ex.message # lint-amnesty, pylint: disable=no-member, exception-message-attribute + domain=site_conf.site.domain, message=ex.message # lint-amnesty, pylint: disable=no-member ) self.stderr.write(message) return 0 diff --git a/openedx/core/djangoapps/user_authn/views/registration_form.py b/openedx/core/djangoapps/user_authn/views/registration_form.py index 84c6729cb1..afc7bebb81 100644 --- a/openedx/core/djangoapps/user_authn/views/registration_form.py +++ b/openedx/core/djangoapps/user_authn/views/registration_form.py @@ -423,7 +423,7 @@ class RegistrationFormFactory: FormDescription.FIELD_TYPE_MAP.get(field.__class__)) if not field_type: raise ImproperlyConfigured( - u"Field type '{}' not recognized for registration extension field '{}'.".format( + "Field type '{}' not recognized for registration extension field '{}'.".format( field_type, field_name ) diff --git a/openedx/core/djangoapps/user_authn/views/tests/test_register.py b/openedx/core/djangoapps/user_authn/views/tests/test_register.py index 944a22c7e1..0f5173f736 100644 --- a/openedx/core/djangoapps/user_authn/views/tests/test_register.py +++ b/openedx/core/djangoapps/user_authn/views/tests/test_register.py @@ -660,12 +660,12 @@ class RegistrationViewTestV1( self._assert_reg_absent_field( no_extra_fields_setting, { - "name": u"favorite_editor", - "type": u"select", + "name": "favorite_editor", + "type": "select", "required": False, - "label": u"Favorite Editor", - "placeholder": u"cat", - "defaultValue": u"vim", + "label": "Favorite Editor", + "placeholder": "cat", + "defaultValue": "vim", "errorMessages": { 'required': 'This field is required.', 'invalid_choice': 'Select a valid choice. %(value)s is not one of the available choices.', diff --git a/openedx/core/djangolib/blockstore_cache.py b/openedx/core/djangolib/blockstore_cache.py index 7d77e39485..590f6ca686 100644 --- a/openedx/core/djangolib/blockstore_cache.py +++ b/openedx/core/djangolib/blockstore_cache.py @@ -262,7 +262,7 @@ def get_bundle_draft_direct_links_cached(bundle_uuid, draft_name): cache_key = ('bundle_draft_direct_links', ) result = bundle_cache.get(cache_key) if result is None: - links = blockstore_api.get_bundle_links(bundle_uuid, use_draft=draft_name).values() # lint-amnesty, pylint: disable=dict-values-not-iterating + links = blockstore_api.get_bundle_links(bundle_uuid, use_draft=draft_name).values() result = {link.name: link.direct for link in links} bundle_cache.set(cache_key, result) return result diff --git a/openedx/core/djangolib/js_utils.py b/openedx/core/djangolib/js_utils.py index 0db46f044f..115419d1c6 100644 --- a/openedx/core/djangolib/js_utils.py +++ b/openedx/core/djangolib/js_utils.py @@ -69,7 +69,7 @@ def dump_js_escaped_json(obj, cls=EdxJSONEncoder): (string) Escaped encoded JSON. """ - obj = list(obj) if isinstance(obj, type({}.values())) else obj # lint-amnesty, pylint: disable=isinstance-second-argument-not-valid-type, dict-values-not-iterating, line-too-long + obj = list(obj) if isinstance(obj, type({}.values())) else obj # lint-amnesty, pylint: disable=isinstance-second-argument-not-valid-type, line-too-long json_string = json.dumps(obj, ensure_ascii=True, cls=cls) json_string = _escape_json_for_js(json_string) return json_string diff --git a/openedx/core/lib/blockstore_api/methods.py b/openedx/core/lib/blockstore_api/methods.py index 415894346a..0dacae8a04 100644 --- a/openedx/core/lib/blockstore_api/methods.py +++ b/openedx/core/lib/blockstore_api/methods.py @@ -201,7 +201,7 @@ def update_bundle(bundle_uuid, **fields): if "collection_uuid" in fields: data["collection_uuid"] = str(fields.pop("collection_uuid")) if fields: - raise ValueError(f"Unexpected extra fields passed " # pylint: disable=dict-keys-not-iterating + raise ValueError(f"Unexpected extra fields passed " f"to update_bundle: {fields.keys()}") result = api_request('patch', api_url('bundles', str(bundle_uuid)), json=data) return _bundle_from_response(result) @@ -323,7 +323,7 @@ def get_bundle_files(bundle_uuid, use_draft=None): """ Get an iterator over all the files in the specified bundle or draft. """ - return get_bundle_files_dict(bundle_uuid, use_draft).values() # lint-amnesty, pylint: disable=dict-values-not-iterating + return get_bundle_files_dict(bundle_uuid, use_draft).values() def get_bundle_links(bundle_uuid, use_draft=None): diff --git a/openedx/core/lib/teams_config.py b/openedx/core/lib/teams_config.py index 0e93d24fe9..ab631eb3f7 100644 --- a/openedx/core/lib/teams_config.py +++ b/openedx/core/lib/teams_config.py @@ -14,7 +14,7 @@ MANAGED_TEAM_MAX_TEAM_SIZE = 200 DEFAULT_COURSE_RUN_MAX_TEAM_SIZE = 50 -class TeamsConfig: # pylint: disable=eq-without-hash +class TeamsConfig: """ Configuration for the Course Teams feature on a course run. @@ -155,7 +155,7 @@ class TeamsConfig: # pylint: disable=eq-without-hash return self.default_max_team_size -class TeamsetConfig: # pylint: disable=eq-without-hash +class TeamsetConfig: """ Configuration for a team-set within a course run. diff --git a/openedx/features/course_experience/course_updates.py b/openedx/features/course_experience/course_updates.py index 37de393ca1..9eb1db96e8 100644 --- a/openedx/features/course_experience/course_updates.py +++ b/openedx/features/course_experience/course_updates.py @@ -93,7 +93,7 @@ def get_current_update_for_user(request, course): return None update_hash = _calculate_update_hash(updates[0]) - if update_hash in dismissed_hashes: + if update_hash in dismissed_hashes: # pylint: disable=unsupported-membership-test return None return updates[0]['content'] diff --git a/openedx/features/enterprise_support/enrollments/utils.py b/openedx/features/enterprise_support/enrollments/utils.py index 4913520390..dbc4ef6ebf 100644 --- a/openedx/features/enterprise_support/enrollments/utils.py +++ b/openedx/features/enterprise_support/enrollments/utils.py @@ -60,7 +60,7 @@ def lms_enroll_user_in_course( ) log.info('The user [%s] has been enrolled in course run [%s].', username, course_id) return response - except CourseEnrollmentExistsError as error: + except CourseEnrollmentExistsError as error: # pylint: disable=unused-variable log.warning('An enrollment already exists for user [%s] in course run [%s].', username, course_id) return None except CourseEnrollmentError as error: diff --git a/pylintrc b/pylintrc index 07faac95b6..7e608a0e97 100644 --- a/pylintrc +++ b/pylintrc @@ -72,10 +72,10 @@ persistent = yes load-plugins = edx_lint.pylint,pylint_django_settings,pylint_django,pylint_celery,pylint_pytest [MESSAGES CONTROL] -enable = +enable = blacklisted-name, line-too-long, - + abstract-class-instantiated, abstract-method, access-member-before-definition, @@ -212,7 +212,7 @@ enable = using-constant-test, yield-outside-function, zip-builtin-not-iterating, - + astroid-error, django-not-available-placeholder, django-not-available, @@ -220,20 +220,20 @@ enable = method-check-failed, parse-error, raw-checker-failed, - + empty-docstring, invalid-characters-in-docstring, missing-docstring, wrong-spelling-in-comment, wrong-spelling-in-docstring, - + unused-argument, unused-import, unused-variable, - + eval-used, exec-used, - + bad-classmethod-argument, bad-mcs-classmethod-argument, bad-mcs-method-argument, @@ -271,31 +271,31 @@ enable = unneeded-not, useless-else-on-loop, wrong-assert-type, - + deprecated-method, deprecated-module, - + too-many-boolean-expressions, too-many-nested-blocks, too-many-statements, - + wildcard-import, wrong-import-order, wrong-import-position, - + missing-final-newline, mixed-indentation, mixed-line-endings, trailing-newlines, trailing-whitespace, unexpected-line-ending-format, - + bad-inline-option, bad-option-value, deprecated-pragma, unrecognized-inline-option, useless-suppression, - + cmp-method, coerce-method, delslice-method, @@ -312,7 +312,7 @@ enable = rdiv-method, setslice-method, using-cmp-argument, -disable = +disable = bad-continuation, bad-indentation, consider-using-f-string, @@ -342,10 +342,10 @@ disable = unspecified-encoding, unused-wildcard-import, use-maxsplit-arg, - + feature-toggle-needs-doc, illegal-waffle-usage, - + apply-builtin, backtick, bad-python3-import, @@ -383,7 +383,7 @@ disable = unicode-builtin, unpacking-in-except, xrange-builtin, - + logging-fstring-interpolation, native-string, import-outside-toplevel, @@ -447,7 +447,7 @@ ignore-imports = no ignore-mixin-members = yes ignored-classes = SQLObject unsafe-load-any-extension = yes -generated-members = +generated-members = REQUEST, acl_users, aq_parent, @@ -473,7 +473,7 @@ generated-members = [VARIABLES] init-import = no dummy-variables-rgx = _|dummy|unused|.*_unused -additional-builtins = +additional-builtins = [CLASSES] defining-attr-methods = __init__,__new__,setUp @@ -494,9 +494,9 @@ max-public-methods = 20 [IMPORTS] deprecated-modules = regsub,TERMIOS,Bastion,rexec -import-graph = -ext-import-graph = -int-import-graph = +import-graph = +ext-import-graph = +int-import-graph = [EXCEPTIONS] overgeneral-exceptions = Exception diff --git a/pylintrc_tweaks b/pylintrc_tweaks index 3705fd84bf..3e5f850405 100644 --- a/pylintrc_tweaks +++ b/pylintrc_tweaks @@ -24,6 +24,9 @@ disable+ = consider-using-enumerate, no-member, consider-using-with, + unspecified-encoding, + unused-variable, + unsubscriptable-object, [BASIC] attr-rgx = [a-z_][a-z0-9_]{2,40}$ diff --git a/requirements/constraints.txt b/requirements/constraints.txt index a41dbfb172..8c15a35754 100644 --- a/requirements/constraints.txt +++ b/requirements/constraints.txt @@ -90,10 +90,6 @@ click<8.0.0 # requirements of edx-platform. Pinning temporarily until this is resolved in edx-val. edxval<2.1 -# pylint>=2.10.0 introduced a lot of new pylint warnings. -# A separate PR will be needed to remove the pin and fix all the pylint warnings -pylint<2.10.0 - # At the time of writing this comment, we do not know whether py2neo>=2022 # will support our currently-deployed Neo4j version (3.5). # Feel free to loosen this constraint if/when it is confirmed that a later diff --git a/requirements/edx/development.txt b/requirements/edx/development.txt index ab161e59ff..5cf8095d43 100644 --- a/requirements/edx/development.txt +++ b/requirements/edx/development.txt @@ -63,7 +63,7 @@ asgiref==3.4.1 # -r requirements/edx/testing.txt # django # uvicorn -astroid==2.6.6 +astroid==2.8.0 # via # -r requirements/edx/testing.txt # pylint @@ -969,6 +969,7 @@ pip-tools==6.4.0 platformdirs==2.4.0 # via # -r requirements/edx/testing.txt + # pylint # virtualenv pluggy==1.0.0 # via @@ -1039,9 +1040,8 @@ pylatexenc==2.10 # via # -r requirements/edx/testing.txt # olxcleaner -pylint==2.9.6 +pylint==2.11.1 # via - # -c requirements/edx/../constraints.txt # -r requirements/edx/testing.txt # edx-lint # pylint-celery @@ -1440,9 +1440,15 @@ typing-extensions==3.10.0.2 # via # -r requirements/edx/testing.txt # aiohttp + # astroid # gitpython # mypy # pydantic + # pylint +ua-parser==0.10.0 + # via + # -r requirements/edx/testing.txt + # django-cookies-samesite unicodecsv==0.14.1 # via # -r requirements/edx/testing.txt diff --git a/requirements/edx/testing.txt b/requirements/edx/testing.txt index ca7515c6f5..1a6863415d 100644 --- a/requirements/edx/testing.txt +++ b/requirements/edx/testing.txt @@ -59,7 +59,7 @@ asgiref==3.4.1 # -r requirements/edx/base.txt # django # uvicorn -astroid==2.6.6 +astroid==2.8.0 # via # pylint # pylint-celery @@ -909,7 +909,9 @@ pillow==8.4.0 # edx-enterprise # edx-organizations platformdirs==2.4.0 - # via virtualenv + # via + # pylint + # virtualenv pluggy==1.0.0 # via # -r requirements/edx/coverage.txt @@ -977,9 +979,8 @@ pylatexenc==2.10 # via # -r requirements/edx/base.txt # olxcleaner -pylint==2.9.6 +pylint==2.11.1 # via - # -c requirements/edx/../constraints.txt # edx-lint # pylint-celery # pylint-django @@ -1327,8 +1328,14 @@ typing-extensions==3.10.0.2 # via # -r requirements/edx/base.txt # aiohttp + # astroid # gitpython # pydantic + # pylint +ua-parser==0.10.0 + # via + # -r requirements/edx/base.txt + # django-cookies-samesite unicodecsv==0.14.1 # via # -r requirements/edx/base.txt