diff --git a/lms/djangoapps/instructor/tests/test_api.py b/lms/djangoapps/instructor/tests/test_api.py index 00b0fc56b05f..0cb7e009454e 100644 --- a/lms/djangoapps/instructor/tests/test_api.py +++ b/lms/djangoapps/instructor/tests/test_api.py @@ -713,7 +713,7 @@ def test_bad_file_upload_type(self): """ Try uploading some non-CSV file and verify that it is rejected """ - uploaded_file = SimpleUploadedFile("temp.csv", io.BytesIO(b"some initial binary data: \x00\x01").read()) + uploaded_file = SimpleUploadedFile("temp.csv", io.BytesIO(b"some initial binary data: \xC3\x01").read()) response = self.client.post(self.url, {'students_list': uploaded_file}) assert response.status_code == 200 data = json.loads(response.content.decode('utf-8')) @@ -920,15 +920,16 @@ def test_users_created_and_enrolled_successfully_if_others_fail(self): manual_enrollments = ManualEnrollmentAudit.objects.all() assert manual_enrollments.count() == 2 - @patch('lms.djangoapps.instructor.views.api', 'generate_random_string', - Mock(side_effect=['first', 'first', 'second'])) def test_generate_unique_password_no_reuse(self): """ generate_unique_password should generate a unique password string that hasn't been generated before. """ - generated_password = ['first'] - password = generate_unique_password(generated_password, 12) - assert password != 'first' + with patch('lms.djangoapps.instructor.views.api.generate_random_string') as mock: + mock.side_effect = ['first', 'first', 'second'] + + generated_password = ['first'] + password = generate_unique_password(generated_password, 12) + assert password != 'first' @patch.dict(settings.FEATURES, {'ALLOW_AUTOMATED_SIGNUPS': False}) def test_allow_automated_signups_flag_not_set(self): diff --git a/lms/djangoapps/instructor/tests/test_certificates.py b/lms/djangoapps/instructor/tests/test_certificates.py index 9921ae6d6831..ce3433f312d8 100644 --- a/lms/djangoapps/instructor/tests/test_certificates.py +++ b/lms/djangoapps/instructor/tests/test_certificates.py @@ -888,7 +888,7 @@ def test_bad_file_upload_type(self): """ Try uploading CSV file with invalid binary data and verify that it is rejected """ - uploaded_file = SimpleUploadedFile("temp.csv", io.BytesIO(b"some initial binary data: \x00\x01").read()) + uploaded_file = SimpleUploadedFile("temp.csv", io.BytesIO(b"some initial binary data: \xC3\x01").read()) response = self.client.post(self.url, {'students_list': uploaded_file}) assert response.status_code == 200 data = json.loads(response.content.decode('utf-8')) diff --git a/openedx/core/lib/cache_utils.py b/openedx/core/lib/cache_utils.py index 1b3b65f378a4..c379ab2d961a 100644 --- a/openedx/core/lib/cache_utils.py +++ b/openedx/core/lib/cache_utils.py @@ -126,7 +126,7 @@ def __init__(self, func): self.cache = {} def __call__(self, *args): - if not isinstance(args, collections.Hashable): + if not isinstance(args, collections.abc.Hashable): # uncacheable. a list, for instance. # better to not cache than blow up. return self.func(*args) @@ -147,7 +147,10 @@ def __get__(self, obj, objtype): """ Support instance methods. """ - return functools.partial(self.__call__, obj) + partial = functools.partial(self.__call__, obj) + # Make the cache accessible on the wrapped object so it can be cleared if needed. + partial.cache = self.cache + return partial class CacheInvalidationManager: diff --git a/xmodule/library_content_block.py b/xmodule/library_content_block.py index 4edcca5f00b6..6c8965186d51 100644 --- a/xmodule/library_content_block.py +++ b/xmodule/library_content_block.py @@ -221,7 +221,7 @@ def make_selection(cls, selected, children, max_count, mode): overlimit_block_keys = set() if len(selected_keys) > max_count: num_to_remove = len(selected_keys) - max_count - overlimit_block_keys = set(rand.sample(selected_keys, num_to_remove)) + overlimit_block_keys = set(rand.sample(list(selected_keys), num_to_remove)) selected_keys -= overlimit_block_keys # Do we have enough blocks now? @@ -233,7 +233,7 @@ def make_selection(cls, selected, children, max_count, mode): pool = valid_block_keys - selected_keys if mode == "random": num_to_add = min(len(pool), num_to_add) - added_block_keys = set(rand.sample(pool, num_to_add)) + added_block_keys = set(rand.sample(list(pool), num_to_add)) # We now have the correct n random children to show for this user. else: raise NotImplementedError("Unsupported mode.") diff --git a/xmodule/tests/xml/factories.py b/xmodule/tests/xml/factories.py index 23a57898b6dc..a62f7b3f49bb 100644 --- a/xmodule/tests/xml/factories.py +++ b/xmodule/tests/xml/factories.py @@ -57,7 +57,7 @@ def __repr__(self): # Extract all argument names used to construct XmlImportData objects, # so that the factory doesn't treat them as XML attributes -XML_IMPORT_ARGS = inspect.getargspec(XmlImportData.__init__).args # lint-amnesty, pylint: disable=deprecated-method +XML_IMPORT_ARGS = inspect.getfullargspec(XmlImportData.__init__).args class XmlImportFactory(Factory):