diff --git a/cms/djangoapps/xblock_config/tests/test_models.py b/cms/djangoapps/xblock_config/tests/test_models.py index 3ce81a51f1..fbd379c584 100644 --- a/cms/djangoapps/xblock_config/tests/test_models.py +++ b/cms/djangoapps/xblock_config/tests/test_models.py @@ -5,9 +5,9 @@ from contextlib import contextmanager import ddt from django.test import TestCase +from edx_django_utils.cache import RequestCache from opaque_keys.edx.locator import CourseLocator -from openedx.core.djangoapps.request_cache.middleware import RequestCache from xblock_config.models import CourseEditLTIFieldsEnabledFlag @@ -20,7 +20,7 @@ def lti_consumer_fields_editing_flag(course_id, enabled_for_course=False): course_id (CourseLocator): course locator to control this feature for. enabled_for_course (bool): whether feature is enabled for 'course_id' """ - RequestCache.clear_request_cache() + RequestCache.clear_all_namespaces() CourseEditLTIFieldsEnabledFlag.objects.create(course_id=course_id, enabled=enabled_for_course) yield diff --git a/cms/envs/common.py b/cms/envs/common.py index 0d9f7d643f..74605df72f 100644 --- a/cms/envs/common.py +++ b/cms/envs/common.py @@ -472,9 +472,6 @@ XQUEUE_INTERFACE = { MIDDLEWARE_CLASSES = [ 'crum.CurrentRequestUserMiddleware', - # Deprecated, but well entrenched RequestCache - 'openedx.core.djangoapps.request_cache.middleware.RequestCache', - # A newer and safer request cache. 'edx_django_utils.cache.middleware.RequestCacheMiddleware', 'edx_django_utils.monitoring.middleware.MonitoringMemoryMiddleware', diff --git a/common/djangoapps/course_modes/models.py b/common/djangoapps/course_modes/models.py index 7a03b4c196..3361d23c65 100644 --- a/common/djangoapps/course_modes/models.py +++ b/common/djangoapps/course_modes/models.py @@ -13,11 +13,12 @@ from django.db.models import Q from django.dispatch import receiver from django.utils.timezone import now from django.utils.translation import ugettext_lazy as _ +from edx_django_utils.cache import RequestCache from opaque_keys.edx.keys import CourseKey from opaque_keys.edx.django.models import CourseKeyField from openedx.core.djangoapps.content.course_overviews.models import CourseOverview -from openedx.core.djangoapps.request_cache.middleware import RequestCache, ns_request_cached +from openedx.core.djangoapps.request_cache.middleware import ns_request_cached Mode = namedtuple('Mode', [ @@ -727,7 +728,7 @@ class CourseMode(models.Model): @receiver(models.signals.post_delete, sender=CourseMode) def invalidate_course_mode_cache(sender, **kwargs): # pylint: disable=unused-argument """Invalidate the cache of course modes. """ - RequestCache.clear_request_cache(name=CourseMode.CACHE_NAMESPACE) + RequestCache(namespace=CourseMode.CACHE_NAMESPACE).clear() def get_cosmetic_verified_display_price(course): diff --git a/common/djangoapps/edxmako/tests.py b/common/djangoapps/edxmako/tests.py index 23e3065705..4f96e680e2 100644 --- a/common/djangoapps/edxmako/tests.py +++ b/common/djangoapps/edxmako/tests.py @@ -7,12 +7,12 @@ from django.http import HttpResponse from django.test import TestCase from django.test.client import RequestFactory from django.test.utils import override_settings +from edx_django_utils.cache import RequestCache from mock import Mock, patch from edxmako import LOOKUP, add_lookup from edxmako.request_context import get_template_request_context from edxmako.shortcuts import is_any_marketing_link_set, is_marketing_link_set, marketing_link, render_to_string -from openedx.core.djangoapps.request_cache.middleware import RequestCache from student.tests.factories import UserFactory from util.testing import UrlResetMixin @@ -89,7 +89,7 @@ class MakoRequestContextTest(TestCase): self.request.user = self.user self.response = Mock(spec=HttpResponse) - self.addCleanup(RequestCache.clear_request_cache) + self.addCleanup(RequestCache.clear_all_namespaces) def test_with_current_request(self): """ @@ -128,7 +128,7 @@ class MakoRequestContextTest(TestCase): self.assertIsNotNone(get_template_request_context()) mock_get_current_request.assert_not_called() - RequestCache.clear_request_cache() + RequestCache.clear_all_namespaces() with patch('edxmako.request_context.get_current_request', return_value=None): # requestcontext should be None, because the cache isn't filled diff --git a/common/lib/xmodule/xmodule/modulestore/django.py b/common/lib/xmodule/xmodule/modulestore/django.py index 5fb1f9921f..0013cac544 100644 --- a/common/lib/xmodule/xmodule/modulestore/django.py +++ b/common/lib/xmodule/xmodule/modulestore/django.py @@ -23,8 +23,8 @@ from django.core.cache import caches, InvalidCacheBackendError import django.dispatch import django.utils from django.utils.translation import get_language, to_locale +from edx_django_utils.cache import DEFAULT_REQUEST_CACHE -from openedx.core.djangoapps.request_cache.middleware import RequestCache from xmodule.contentstore.django import contentstore from xmodule.modulestore.draft_and_published import BranchSettingMixin from xmodule.modulestore.mixed import MixedModuleStore @@ -249,7 +249,7 @@ def create_modulestore_instance( if key in _options and isinstance(_options[key], basestring): _options[key] = load_function(_options[key]) - request_cache = RequestCache.get_request_cache() + request_cache = DEFAULT_REQUEST_CACHE try: metadata_inheritance_cache = caches['mongo_metadata_inheritance'] @@ -278,14 +278,9 @@ def create_modulestore_instance( if disabled_xblocks is None: return [] - if request_cache: - if 'disabled_xblock_types' not in request_cache.data: - request_cache.data['disabled_xblock_types'] = [block.name for block in disabled_xblocks()] - return request_cache.data['disabled_xblock_types'] - else: - disabled_xblock_types = [block.name for block in disabled_xblocks()] - - return disabled_xblock_types + if 'disabled_xblock_types' not in request_cache.data: + request_cache.data['disabled_xblock_types'] = [block.name for block in disabled_xblocks()] + return request_cache.data['disabled_xblock_types'] return class_( contentstore=content_store, diff --git a/lms/djangoapps/ccx/tests/test_field_override_performance.py b/lms/djangoapps/ccx/tests/test_field_override_performance.py index f40192b1d0..3588600594 100644 --- a/lms/djangoapps/ccx/tests/test_field_override_performance.py +++ b/lms/djangoapps/ccx/tests/test_field_override_performance.py @@ -16,10 +16,10 @@ from django.conf import settings from django.core.cache import caches from django.test.client import RequestFactory from django.test.utils import override_settings +from edx_django_utils.cache import RequestCache from lms.djangoapps.ccx.tests.factories import CcxFactory from opaque_keys.edx.keys import CourseKey from openedx.core.djangoapps.content.block_structure.api import get_course_in_cache -from openedx.core.djangoapps.request_cache.middleware import RequestCache from openedx.core.djangoapps.waffle_utils.testutils import WAFFLE_TABLES from pytz import UTC from student.models import CourseEnrollment @@ -176,7 +176,7 @@ class FieldOverridePerformanceTestCase(FieldOverrideTestMixin, ProceduralCourseT get_course_in_cache(course_key) # We clear the request cache to simulate a new request in the LMS. - RequestCache.clear_request_cache() + RequestCache.clear_all_namespaces() # Reset the list of provider classes, so that our django settings changes # can actually take affect. diff --git a/lms/djangoapps/ccx/tests/test_overrides.py b/lms/djangoapps/ccx/tests/test_overrides.py index 536f26fc97..1665fef9f0 100644 --- a/lms/djangoapps/ccx/tests/test_overrides.py +++ b/lms/djangoapps/ccx/tests/test_overrides.py @@ -8,6 +8,7 @@ import mock import pytz from ccx_keys.locator import CCXLocator from django.test.utils import override_settings +from edx_django_utils.cache import RequestCache from courseware.courses import get_course_by_id from courseware.field_overrides import OverrideFieldData @@ -16,7 +17,6 @@ from lms.djangoapps.ccx.models import CustomCourseForEdX from lms.djangoapps.ccx.overrides import override_field_for_ccx from lms.djangoapps.ccx.tests.utils import flatten, iter_blocks from lms.djangoapps.courseware.tests.test_field_overrides import inject_field_overrides -from openedx.core.djangoapps.request_cache.middleware import RequestCache from student.tests.factories import AdminFactory from xmodule.modulestore.tests.django_utils import TEST_DATA_SPLIT_MODULESTORE, SharedModuleStoreTestCase from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory @@ -74,7 +74,7 @@ class TestFieldOverrides(FieldOverrideTestMixin, SharedModuleStoreTestCase): get_ccx.return_value = ccx self.addCleanup(patch.stop) - self.addCleanup(RequestCache.clear_request_cache) + self.addCleanup(RequestCache.clear_all_namespaces) inject_field_overrides(iter_blocks(ccx.course), self.course, AdminFactory.create()) diff --git a/lms/djangoapps/ccx/tests/test_views.py b/lms/djangoapps/ccx/tests/test_views.py index 1ab1b829a9..ef2a7efe1d 100644 --- a/lms/djangoapps/ccx/tests/test_views.py +++ b/lms/djangoapps/ccx/tests/test_views.py @@ -26,6 +26,7 @@ from courseware.testutils import FieldOverrideTestMixin from django_comment_client.utils import has_forum_access from django_comment_common.models import FORUM_ROLE_ADMINISTRATOR from django_comment_common.utils import are_permissions_roles_seeded +from edx_django_utils.cache import RequestCache from edxmako.shortcuts import render_to_response from lms.djangoapps.ccx.models import CustomCourseForEdX from lms.djangoapps.ccx.overrides import get_override_for_ccx, override_field_for_ccx @@ -36,7 +37,6 @@ from lms.djangoapps.ccx.views import get_date from lms.djangoapps.grades.tasks import compute_all_grades_for_course from lms.djangoapps.instructor.access import allow_access, list_with_level from openedx.core.djangoapps.content.course_overviews.models import CourseOverview -from openedx.core.djangoapps.request_cache.middleware import RequestCache from openedx.core.lib.tests import attr from student.models import CourseEnrollment, CourseEnrollmentAllowed from student.roles import CourseCcxCoachRole, CourseInstructorRole, CourseStaffRole @@ -1051,7 +1051,7 @@ class TestCCXGrades(FieldOverrideTestMixin, SharedModuleStoreTestCase, LoginEnro CourseOverview.load_from_module_store(self.course.id) setup_students_and_grades(self) self.client.login(username=coach.username, password="test") - self.addCleanup(RequestCache.clear_request_cache) + self.addCleanup(RequestCache.clear_all_namespaces) from xmodule.modulestore.django import SignalHandler # using CCX object as sender here. @@ -1064,7 +1064,7 @@ class TestCCXGrades(FieldOverrideTestMixin, SharedModuleStoreTestCase, LoginEnro @patch('lms.djangoapps.instructor.views.gradebook_api.MAX_STUDENTS_PER_PAGE_GRADE_BOOK', 1) def test_gradebook(self): self.course.enable_ccx = True - RequestCache.clear_request_cache() + RequestCache.clear_all_namespaces() url = reverse( 'ccx_gradebook', @@ -1081,7 +1081,7 @@ class TestCCXGrades(FieldOverrideTestMixin, SharedModuleStoreTestCase, LoginEnro def test_grades_csv(self): self.course.enable_ccx = True - RequestCache.clear_request_cache() + RequestCache.clear_all_namespaces() url = reverse( 'ccx_grades_csv', diff --git a/lms/djangoapps/commerce/signals.py b/lms/djangoapps/commerce/signals.py index 54e3134053..a6b53adb28 100644 --- a/lms/djangoapps/commerce/signals.py +++ b/lms/djangoapps/commerce/signals.py @@ -5,11 +5,11 @@ from __future__ import unicode_literals import logging +from crum import get_current_request from django.contrib.auth.models import AnonymousUser from django.dispatch import receiver from openedx.core.djangoapps.commerce.utils import is_commerce_service_configured -from openedx.core.djangoapps.request_cache.middleware import RequestCache from student.signals import REFUND_ORDER from .utils import refund_seat @@ -56,5 +56,5 @@ def get_request_user(): If the requester of an unenrollment is not the same person as the student being unenrolled, we authenticate to the commerce service as the requester. """ - request = RequestCache.get_current_request() + request = get_current_request() return getattr(request, 'user', None) diff --git a/lms/djangoapps/course_goals/api.py b/lms/djangoapps/course_goals/api.py index d2f4aedbc4..55f090f88a 100644 --- a/lms/djangoapps/course_goals/api.py +++ b/lms/djangoapps/course_goals/api.py @@ -73,7 +73,7 @@ def has_course_goal_permission(request, course_id, user_access): can use this feature. """ course_key = CourseKey.from_string(course_id) - has_verified_mode = CourseMode.has_verified_mode(CourseMode.modes_for_course_dict(unicode(course_id))) + has_verified_mode = CourseMode.has_verified_mode(CourseMode.modes_for_course_dict(course_key)) return user_access['is_enrolled'] and has_verified_mode and ENABLE_COURSE_GOALS.is_enabled(course_key) \ and settings.FEATURES.get('ENABLE_COURSE_GOALS') diff --git a/lms/djangoapps/courseware/course_tools.py b/lms/djangoapps/courseware/course_tools.py index 5be900f92f..8493cbd7d3 100644 --- a/lms/djangoapps/courseware/course_tools.py +++ b/lms/djangoapps/courseware/course_tools.py @@ -4,10 +4,10 @@ Platform plugins to support a verified upgrade tool. import datetime import pytz +from crum import get_current_request from django.utils.translation import ugettext as _ from course_modes.models import CourseMode -from openedx.core.djangoapps.request_cache import get_request from openedx.features.course_experience.course_tools import CourseTool from student.models import CourseEnrollment from courseware.date_summary import verified_upgrade_deadline_link @@ -69,5 +69,5 @@ class VerifiedUpgradeTool(CourseTool): """ Returns the URL for this tool for the specified course key. """ - request = get_request() + request = get_current_request() return verified_upgrade_deadline_link(request.user, course_id=course_key) diff --git a/lms/djangoapps/courseware/field_overrides.py b/lms/djangoapps/courseware/field_overrides.py index dd57b5af6f..ae172064d6 100644 --- a/lms/djangoapps/courseware/field_overrides.py +++ b/lms/djangoapps/courseware/field_overrides.py @@ -19,9 +19,9 @@ from abc import ABCMeta, abstractmethod from contextlib import contextmanager from django.conf import settings +from edx_django_utils.cache import DEFAULT_REQUEST_CACHE from xblock.field_data import FieldData -from openedx.core.djangoapps.request_cache.middleware import RequestCache from xmodule.modulestore.inheritance import InheritanceMixin NOTSET = object() @@ -180,7 +180,7 @@ class OverrideFieldData(FieldData): Arguments: course: The course XBlock """ - request_cache = RequestCache.get_request_cache() + request_cache = DEFAULT_REQUEST_CACHE if course is None: cache_key = ENABLED_OVERRIDE_PROVIDERS_KEY.format(course_id='None') else: @@ -294,7 +294,7 @@ class OverrideModulestoreFieldData(OverrideFieldData): course_id = unicode(block.location.course_key) cache_key = ENABLED_MODULESTORE_OVERRIDE_PROVIDERS_KEY.format(course_id=course_id) - request_cache = RequestCache.get_request_cache() + request_cache = DEFAULT_REQUEST_CACHE enabled_providers = request_cache.data.get(cache_key) if enabled_providers is None: diff --git a/lms/djangoapps/courseware/tests/test_module_render.py b/lms/djangoapps/courseware/tests/test_module_render.py index 4cbd404ebe..577fdb4086 100644 --- a/lms/djangoapps/courseware/tests/test_module_render.py +++ b/lms/djangoapps/courseware/tests/test_module_render.py @@ -2414,7 +2414,7 @@ class TestDisabledXBlockTypes(ModuleStoreTestCase): self._verify_descriptor('problem', course, 'CapaDescriptorWithMixins', item_usage_id) # Now simulate a new request cache. - self.store.request_cache.data = {} + self.store.request_cache.data.clear() self._verify_descriptor('problem', course, 'RawDescriptorWithMixins', item_usage_id) def _verify_descriptor(self, category, course, descriptor, item_id=None): diff --git a/lms/djangoapps/discussion/tests/test_views.py b/lms/djangoapps/discussion/tests/test_views.py index dd29291dc3..6bc60fa237 100644 --- a/lms/djangoapps/discussion/tests/test_views.py +++ b/lms/djangoapps/discussion/tests/test_views.py @@ -8,6 +8,7 @@ from django.http import Http404 from django.test.client import Client, RequestFactory from django.test.utils import override_settings from django.utils import translation +from edx_django_utils.cache import RequestCache from mock import ANY, Mock, call, patch from six import text_type @@ -43,7 +44,6 @@ from lms.lib.comment_client.utils import CommentClientPaginatedResult from openedx.core.djangoapps.course_groups.models import CourseUserGroup from openedx.core.djangoapps.course_groups.tests.helpers import config_course_cohorts from openedx.core.djangoapps.course_groups.tests.test_views import CohortViewsTestCase -from openedx.core.djangoapps.request_cache.middleware import RequestCache from openedx.core.djangoapps.util.testing import ContentGroupTestCase from openedx.core.djangoapps.waffle_utils.testutils import WAFFLE_TABLES from openedx.features.enterprise_support.tests.mixins.enterprise import EnterpriseTestConsentRequired @@ -1968,7 +1968,7 @@ class CourseDiscussionsHandlerTestCase(DividedDiscussionsTestCase): expected_response = self.get_expected_response() self.assertEqual(response, expected_response) - RequestCache.clear_request_cache() + RequestCache.clear_all_namespaces() now = datetime.now() # inline discussion ItemFactory.create( diff --git a/lms/djangoapps/django_comment_client/permissions.py b/lms/djangoapps/django_comment_client/permissions.py index 9527182696..8dba693a2a 100644 --- a/lms/djangoapps/django_comment_client/permissions.py +++ b/lms/djangoapps/django_comment_client/permissions.py @@ -5,18 +5,19 @@ Module for checking permissions with the comment_client backend import logging from types import NoneType +from edx_django_utils.cache import DEFAULT_REQUEST_CACHE from opaque_keys.edx.keys import CourseKey from django_comment_common.models import CourseDiscussionSettings, all_permissions_for_user_in_course from django_comment_common.utils import get_course_discussion_settings from lms.djangoapps.teams.models import CourseTeam from lms.lib.comment_client import Thread -from openedx.core.djangoapps.request_cache.middleware import RequestCache, request_cached +from openedx.core.djangoapps.request_cache.middleware import request_cached def has_permission(user, permission, course_id=None): assert isinstance(course_id, (NoneType, CourseKey)) - request_cache_dict = RequestCache.get_request_cache().data + request_cache_dict = DEFAULT_REQUEST_CACHE.data cache_key = "django_comment_client.permissions.has_permission.all_permissions.{}.{}".format( user.id, course_id ) @@ -65,7 +66,7 @@ def _check_condition(user, condition, content): if not content: return False try: - request_cache_dict = RequestCache.get_request_cache().data + request_cache_dict = DEFAULT_REQUEST_CACHE.data if content["type"] == "thread": cache_key = "django_comment_client.permissions._check_condition.check_question_author.{}.{}".format( user.id, content['id'] @@ -98,7 +99,7 @@ def _check_condition(user, condition, content): return False try: commentable_id = content['commentable_id'] - request_cache_dict = RequestCache.get_request_cache().data + request_cache_dict = DEFAULT_REQUEST_CACHE.data cache_key = u"django_comment_client.check_team_member.{}.{}".format(user.id, commentable_id) if cache_key in request_cache_dict: return request_cache_dict[cache_key] diff --git a/lms/djangoapps/django_comment_client/tests/test_utils.py b/lms/djangoapps/django_comment_client/tests/test_utils.py index 0573427058..d9d126aefc 100644 --- a/lms/djangoapps/django_comment_client/tests/test_utils.py +++ b/lms/djangoapps/django_comment_client/tests/test_utils.py @@ -7,6 +7,7 @@ import mock from django.urls import reverse from django.test import RequestFactory, TestCase +from edx_django_utils.cache import RequestCache from mock import Mock, patch from pytz import UTC from six import text_type @@ -36,7 +37,6 @@ from lms.lib.comment_client.utils import CommentClientMaintenanceError, perform_ from openedx.core.djangoapps.course_groups import cohorts from openedx.core.djangoapps.course_groups.cohorts import set_course_cohorted from openedx.core.djangoapps.course_groups.tests.helpers import CohortFactory, config_course_cohorts -from openedx.core.djangoapps.request_cache.middleware import RequestCache from openedx.core.djangoapps.util.testing import ContentGroupTestCase from openedx.core.lib.tests import attr from student.roles import CourseStaffRole @@ -217,7 +217,7 @@ class CoursewareContextTestCase(ModuleStoreTestCase): self.assertEqual(len(utils.get_accessible_discussion_xblocks(course, self.user)), 1) # The above call is request cached, so we need to clear it for this test. - RequestCache.clear_request_cache() + RequestCache.clear_all_namespaces() # Add an orphan discussion xblock to that course orphan = course.id.make_usage_key('discussion', 'orphan_discussion') self.store.create_item(self.user.id, orphan.course_key, orphan.block_type, block_id=orphan.block_id) @@ -261,7 +261,7 @@ class CachedDiscussionIdMapTestCase(ModuleStoreTestCase): discussion_target='Beta Testing', visible_to_staff_only=True ) - RequestCache.clear_request_cache() # clear the cache before the last course publish + RequestCache.clear_all_namespaces() # clear the cache before the last course publish self.bad_discussion = ItemFactory.create( parent_location=self.course.location, category='discussion', @@ -1780,7 +1780,7 @@ class GroupModeratorPermissionsTestCase(ModuleStoreTestCase): 'can_vote': True, 'can_report': True }) - RequestCache.clear_request_cache() + RequestCache.clear_all_namespaces() set_discussion_division_settings(self.course.id, division_scheme=CourseDiscussionSettings.ENROLLMENT_TRACK) content = {'user_id': self.verified_user.id, 'type': 'thread', 'username': self.verified_user.username} diff --git a/lms/djangoapps/gating/tests/test_integration.py b/lms/djangoapps/gating/tests/test_integration.py index 66da7e9d07..45dfa148ae 100644 --- a/lms/djangoapps/gating/tests/test_integration.py +++ b/lms/djangoapps/gating/tests/test_integration.py @@ -4,6 +4,7 @@ Integration tests for gated content. import ddt from crum import set_current_request from completion import waffle as completion_waffle +from edx_django_utils.cache import RequestCache from milestones import api as milestones_api from milestones.tests.utils import MilestonesTestCaseMixin @@ -12,7 +13,6 @@ from lms.djangoapps.grades.course_grade_factory import CourseGradeFactory from lms.djangoapps.grades.tests.utils import answer_problem from openedx.core.djangolib.testing.utils import get_mock_request from openedx.core.lib.gating import api as gating_api -from openedx.core.djangoapps.request_cache.middleware import RequestCache from student.tests.factories import UserFactory from xmodule.modulestore.django import modulestore from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase @@ -141,7 +141,7 @@ class TestGatedContent(MilestonesTestCaseMixin, SharedModuleStoreTestCase): Verifies access to gated content for the given user is as expected. """ # clear the request cache to flush any cached access results - RequestCache.clear_request_cache() + RequestCache.clear_all_namespaces() # access to gating content (seq1) remains constant self.assertTrue(bool(has_access(user, 'load', self.seq1, self.course.id))) diff --git a/lms/djangoapps/grades/config/tests/utils.py b/lms/djangoapps/grades/config/tests/utils.py index 89a910c31b..b038eba233 100644 --- a/lms/djangoapps/grades/config/tests/utils.py +++ b/lms/djangoapps/grades/config/tests/utils.py @@ -3,9 +3,9 @@ Provides helper functions for tests that want to configure flags related to persistent grading. """ from contextlib import contextmanager +from edx_django_utils.cache import RequestCache from lms.djangoapps.grades.config.models import CoursePersistentGradesFlag, PersistentGradesEnabledFlag -from openedx.core.djangoapps.request_cache.middleware import RequestCache @contextmanager @@ -20,7 +20,7 @@ def persistent_grades_feature_flags( as they need to set the global setting and the course-specific setting for a single course. """ - RequestCache.clear_request_cache() + RequestCache.clear_all_namespaces() PersistentGradesEnabledFlag.objects.create(enabled=global_flag, enabled_for_all_courses=enabled_for_all_courses) if course_id: CoursePersistentGradesFlag.objects.create(course_id=course_id, enabled=enabled_for_course) diff --git a/lms/djangoapps/instructor_task/tests/test_tasks_helper.py b/lms/djangoapps/instructor_task/tests/test_tasks_helper.py index 403d761ba1..654d97dd28 100644 --- a/lms/djangoapps/instructor_task/tests/test_tasks_helper.py +++ b/lms/djangoapps/instructor_task/tests/test_tasks_helper.py @@ -24,6 +24,7 @@ from courseware.tests.factories import InstructorFactory from django.conf import settings from django.urls import reverse from django.test.utils import override_settings +from edx_django_utils.cache import RequestCache from freezegun import freeze_time from instructor_analytics.basic import UNAVAILABLE, list_problem_responses from mock import MagicMock, Mock, patch, ANY @@ -85,7 +86,6 @@ from lms.djangoapps.verify_student.tests.factories import SoftwareSecurePhotoVer from openedx.core.djangoapps.course_groups.models import CohortMembership, CourseUserGroupPartitionGroup from openedx.core.djangoapps.course_groups.tests.helpers import CohortFactory from openedx.core.djangoapps.credit.tests.factories import CreditCourseFactory -from openedx.core.djangoapps.request_cache.middleware import RequestCache from openedx.core.djangoapps.user_api.partition_schemes import RandomUserPartitionScheme from openedx.core.djangoapps.util.testing import ContentGroupTestCase, TestConditionalContent from ..models import ReportStore @@ -411,7 +411,7 @@ class TestInstructorGradeReport(InstructorGradeReportTestCase): CourseEnrollment.enroll(user, course.id, mode='verified') SoftwareSecurePhotoVerificationFactory.create(user=user, status='approved') - RequestCache.clear_request_cache() + RequestCache.clear_all_namespaces() expected_query_count = 43 with patch('lms.djangoapps.instructor_task.tasks_helper.runner._get_current_task'): diff --git a/lms/djangoapps/lms_xblock/runtime.py b/lms/djangoapps/lms_xblock/runtime.py index ce3b8cf221..67bc712cfb 100644 --- a/lms/djangoapps/lms_xblock/runtime.py +++ b/lms/djangoapps/lms_xblock/runtime.py @@ -4,6 +4,7 @@ Module implementing `xblock.runtime.Runtime` functionality for the LMS from completion.services import CompletionService from django.conf import settings from django.urls import reverse +from edx_django_utils.cache import DEFAULT_REQUEST_CACHE import xblock.reference.plugins from badges.service import BadgingService @@ -12,7 +13,6 @@ from lms.djangoapps.lms_xblock.models import XBlockAsidesConfig from openedx.core.djangoapps.user_api.course_tag import api as user_course_tag_api from openedx.core.lib.url_utils import quote_slashes from openedx.core.lib.xblock_utils import xblock_local_resource_url -from openedx.core.djangoapps.request_cache.middleware import RequestCache from xmodule.library_tools import LibraryToolsService from xmodule.modulestore.django import ModuleI18nService, modulestore from xmodule.partitions.partitions_service import PartitionService @@ -133,7 +133,7 @@ class LmsModuleSystem(ModuleSystem): # pylint: disable=abstract-method ModuleSystem specialized to the LMS """ def __init__(self, **kwargs): - request_cache_dict = RequestCache.get_request_cache().data + request_cache_dict = DEFAULT_REQUEST_CACHE.data store = modulestore() services = kwargs.setdefault('services', {}) diff --git a/lms/envs/common.py b/lms/envs/common.py index 4e7afd9d30..73caf09ce0 100644 --- a/lms/envs/common.py +++ b/lms/envs/common.py @@ -1216,9 +1216,6 @@ CREDIT_NOTIFICATION_CACHE_TIMEOUT = 5 * 60 * 60 MIDDLEWARE_CLASSES = [ 'crum.CurrentRequestUserMiddleware', - # Deprecated, but well entrenched RequestCache - 'openedx.core.djangoapps.request_cache.middleware.RequestCache', - # A newer and safer request cache. 'edx_django_utils.cache.middleware.RequestCacheMiddleware', 'edx_django_utils.monitoring.middleware.MonitoringCustomMetricsMiddleware', @@ -3259,8 +3256,6 @@ AUDIT_CERT_CUTOFF_DATE = None CREDENTIALS_SERVICE_USERNAME = 'credentials_service_user' CREDENTIALS_GENERATION_ROUTING_KEY = HIGH_PRIORITY_QUEUE -WIKI_REQUEST_CACHE_MIDDLEWARE_CLASS = "openedx.core.djangoapps.request_cache.middleware.RequestCache" - # Settings for Comprehensive Theming app # See https://github.com/edx/edx-django-sites-extensions for more info diff --git a/openedx/core/djangoapps/bookmarks/services.py b/openedx/core/djangoapps/bookmarks/services.py index 4560040a03..8f4bcc78b4 100644 --- a/openedx/core/djangoapps/bookmarks/services.py +++ b/openedx/core/djangoapps/bookmarks/services.py @@ -4,8 +4,8 @@ Bookmarks service. import logging from django.core.exceptions import ObjectDoesNotExist +from edx_django_utils.cache import DEFAULT_REQUEST_CACHE -from openedx.core.djangoapps.request_cache.middleware import RequestCache from xmodule.modulestore.django import modulestore from xmodule.modulestore.exceptions import ItemNotFoundError @@ -46,12 +46,12 @@ class BookmarksService(object): return [] cache_key = CACHE_KEY_TEMPLATE.format(self._user.id, course_key) - bookmarks_cache = RequestCache.get_request_cache().data.get(cache_key, None) + bookmarks_cache = DEFAULT_REQUEST_CACHE.data.get(cache_key, None) if bookmarks_cache is None and fetch is True: bookmarks_cache = api.get_bookmarks( self._user, course_key=course_key, fields=DEFAULT_FIELDS ) - RequestCache.get_request_cache().data[cache_key] = bookmarks_cache + DEFAULT_REQUEST_CACHE.data[cache_key] = bookmarks_cache return bookmarks_cache diff --git a/openedx/core/djangoapps/coursegraph/tasks.py b/openedx/core/djangoapps/coursegraph/tasks.py index 093e4ef099..834ac1d4e5 100644 --- a/openedx/core/djangoapps/coursegraph/tasks.py +++ b/openedx/core/djangoapps/coursegraph/tasks.py @@ -9,10 +9,10 @@ import logging from celery import task from django.conf import settings from django.utils import six, timezone +from edx_django_utils.cache import RequestCache from opaque_keys.edx.keys import CourseKey from py2neo import Graph, Node, Relationship, authenticate, NodeSelector from py2neo.compat import integer, string, unicode as neo4j_unicode -from openedx.core.djangoapps.request_cache.middleware import RequestCache log = logging.getLogger(__name__) @@ -348,7 +348,7 @@ class ModuleStoreSerializer(object): for index, course_key in enumerate(self.course_keys): # first, clear the request cache to prevent memory leaks - RequestCache.clear_request_cache() + RequestCache.clear_all_namespaces() log.info( "Now submitting %s for export to neo4j: course %d of %d total courses", diff --git a/openedx/core/djangoapps/credit/models.py b/openedx/core/djangoapps/credit/models.py index a9bd61fa5b..bbc7f7e4cd 100644 --- a/openedx/core/djangoapps/credit/models.py +++ b/openedx/core/djangoapps/credit/models.py @@ -19,12 +19,12 @@ from django.db import IntegrityError, models, transaction from django.dispatch import receiver from django.utils.translation import ugettext as _ from django.utils.translation import ugettext_lazy +from edx_django_utils.cache import RequestCache from jsonfield.fields import JSONField from model_utils.models import TimeStampedModel from opaque_keys.edx.django.models import CourseKeyField -from openedx.core.djangoapps.request_cache.middleware import RequestCache, ns_request_cached - +from openedx.core.djangoapps.request_cache.middleware import ns_request_cached CREDIT_PROVIDER_ID_REGEX = r"[a-z,A-Z,0-9,\-]+" log = logging.getLogger(__name__) @@ -401,7 +401,7 @@ class CreditRequirement(TimeStampedModel): @receiver(models.signals.post_delete, sender=CreditRequirement) def invalidate_credit_requirement_cache(sender, **kwargs): # pylint: disable=unused-argument """Invalidate the cache of credit requirements. """ - RequestCache.clear_request_cache(name=CreditRequirement.CACHE_NAMESPACE) + RequestCache(namespace=CreditRequirement.CACHE_NAMESPACE).clear() class CreditRequirementStatus(TimeStampedModel): diff --git a/openedx/core/djangoapps/request_cache/__init__.py b/openedx/core/djangoapps/request_cache/__init__.py index da444e521c..1e50ed5f3d 100644 --- a/openedx/core/djangoapps/request_cache/__init__.py +++ b/openedx/core/djangoapps/request_cache/__init__.py @@ -12,6 +12,7 @@ from celery.signals import task_postrun import crum from django.conf import settings from django.test.client import RequestFactory +from edx_django_utils.cache import RequestCache from openedx.core.djangoapps.request_cache import middleware @@ -26,7 +27,7 @@ def clear_request_cache(**kwargs): # pylint: disable=unused-argument prevent memory leaks. """ if getattr(settings, 'CLEAR_REQUEST_CACHE_ON_TASK_COMPLETION', True): - middleware.RequestCache.clear_request_cache() + RequestCache.clear_all_namespaces() def get_cache(name): @@ -38,7 +39,8 @@ def get_cache(name): Returns: dict """ - return middleware.RequestCache.get_request_cache(name) + assert name is not None + return RequestCache(name).data def clear_cache(name): @@ -48,16 +50,7 @@ def clear_cache(name): Arguments: name (str): The name of the request cache to clear """ - return middleware.RequestCache.clear_request_cache(name) - - -def get_request(): - """ - Return the current request. - - Deprecated: Please use crum to retrieve current requests. - """ - return crum.get_current_request() + RequestCache(name).clear() def get_request_or_stub(): diff --git a/openedx/core/djangoapps/request_cache/middleware.py b/openedx/core/djangoapps/request_cache/middleware.py index 340b33a5ca..90d5209098 100644 --- a/openedx/core/djangoapps/request_cache/middleware.py +++ b/openedx/core/djangoapps/request_cache/middleware.py @@ -1,71 +1,12 @@ """ -An implementation of a RequestCache. This cache is reset at the beginning -and end of every request. -""" -# pylint: disable=unused-argument -import threading +The middleware for the edx-platform version of the RequestCache has been +removed in favor of the RequestCache found in edx-django-utils. -import crum +TODO: This file still contains request cache related decorators that +should be moved out of this middleware file. +""" from django.utils.encoding import force_text - - -class _RequestCache(threading.local): - """ - A thread-local for storing the per-request cache. - """ - def __init__(self): - super(_RequestCache, self).__init__() - self.data = {} - - -REQUEST_CACHE = _RequestCache() - - -class RequestCache(object): - """ - DEPRECATED Request Cache Middleware. Will be removed very shortly. - """ - @classmethod - def get_request_cache(cls, name=None): - """ - This method is deprecated. Please use :func:`request_cache.get_cache`. - """ - if name is None: - return REQUEST_CACHE - else: - return REQUEST_CACHE.data.setdefault(name, {}) - - @classmethod - def get_current_request(cls): - """ - This method is deprecated. Please use :func:`request_cache.get_request`. - """ - return crum.get_current_request() - - @classmethod - def clear_request_cache(cls, name=None): - """ - Empty the request cache. - """ - if name is None: - REQUEST_CACHE.data = {} - elif REQUEST_CACHE.data.get(name): - REQUEST_CACHE.data[name] = {} - - def process_request(self, request): - self.clear_request_cache() - return None - - def process_response(self, request, response): - self.clear_request_cache() - return response - - def process_exception(self, request, exception): - """ - Clear the RequestCache after a failed request. - """ - self.clear_request_cache() - return None +from edx_django_utils.cache import RequestCache def request_cached(f): @@ -98,7 +39,8 @@ def ns_request_cached(namespace=None): Arguments: namespace (string): An optional namespace to use for the cache. Useful if the caller wants to manage - their own sub-cache by, for example, calling RequestCache.clear_request_cache for their own namespace. + their own sub-cache by, for example, calling RequestCache(namespace=NAMESPACE).clear() for their own + namespace. """ def outer_wrapper(f): """ @@ -113,22 +55,22 @@ def ns_request_cached(namespace=None): """ # Check to see if we have a result in cache. If not, invoke our wrapped # function. Cache and return the result to the caller. - rcache = RequestCache.get_request_cache(namespace) - rcache = rcache.data if namespace is None else rcache - cache_key = func_call_cache_key(f, *args, **kwargs) + request_cache = RequestCache(namespace) + cache_key = _func_call_cache_key(f, *args, **kwargs) - if cache_key in rcache: - return rcache.get(cache_key) - else: - result = f(*args, **kwargs) - rcache[cache_key] = result - return result + cached_response = request_cache.get_cached_response(cache_key) + if cached_response.is_found: + return cached_response.value + + result = f(*args, **kwargs) + request_cache.set(cache_key, result) + return result return inner_wrapper return outer_wrapper -def func_call_cache_key(func, *args, **kwargs): +def _func_call_cache_key(func, *args, **kwargs): """ Returns a cache key based on the function's module the function's name, and a stringified list of arguments diff --git a/openedx/core/djangoapps/request_cache/tests.py b/openedx/core/djangoapps/request_cache/tests.py index c0c6223b18..68fc74faa6 100644 --- a/openedx/core/djangoapps/request_cache/tests.py +++ b/openedx/core/djangoapps/request_cache/tests.py @@ -6,16 +6,17 @@ from celery.task import task from django.conf import settings from django.test import TestCase from django.test.utils import override_settings +from edx_django_utils.cache import RequestCache from mock import Mock from openedx.core.djangoapps.request_cache import get_request_or_stub -from openedx.core.djangoapps.request_cache.middleware import RequestCache, request_cached +from openedx.core.djangoapps.request_cache.middleware import request_cached from xmodule.modulestore.django import modulestore class TestRequestCache(TestCase): """ - Tests for the request cache. + Tests for request cache helpers and decorators. """ def test_get_request_or_stub(self): @@ -43,7 +44,7 @@ class TestRequestCache(TestCase): """ Ensure that after a cache miss, we fill the cache and can hit it. """ - RequestCache.clear_request_cache() + RequestCache.clear_all_namespaces() to_be_wrapped = Mock() to_be_wrapped.return_value = 42 @@ -66,7 +67,7 @@ class TestRequestCache(TestCase): """ Ensure that after caching a result, we always send it back, even if the underlying result changes. """ - RequestCache.clear_request_cache() + RequestCache.clear_all_namespaces() to_be_wrapped = Mock() to_be_wrapped.side_effect = [1, 2, 3] @@ -102,7 +103,7 @@ class TestRequestCache(TestCase): Ensure that calling a decorated function with different positional arguments will not use a cached value invoked by a previous call with different arguments. """ - RequestCache.clear_request_cache() + RequestCache.clear_all_namespaces() to_be_wrapped = Mock() to_be_wrapped.side_effect = [1, 2, 3, 4, 5, 6] @@ -143,7 +144,7 @@ class TestRequestCache(TestCase): Ensure that calling a decorated function with different keyword arguments will not use a cached value invoked by a previous call with different arguments. """ - RequestCache.clear_request_cache() + RequestCache.clear_all_namespaces() to_be_wrapped = Mock() to_be_wrapped.side_effect = [1, 2, 3, 4, 5, 6] @@ -188,7 +189,7 @@ class TestRequestCache(TestCase): """ Ensure that request_cached can work with mixed str and Unicode parameters. """ - RequestCache.clear_request_cache() + RequestCache.clear_all_namespaces() def dummy_function(arg1, arg2): """ @@ -212,7 +213,7 @@ class TestRequestCache(TestCase): properly caches the result and doesn't recall the underlying function. """ - RequestCache.clear_request_cache() + RequestCache.clear_all_namespaces() to_be_wrapped = Mock() to_be_wrapped.side_effect = [None, None, None, 1, 1] diff --git a/openedx/core/djangoapps/theming/helpers.py b/openedx/core/djangoapps/theming/helpers.py index 914c31aaec..9fcfa5bcf3 100644 --- a/openedx/core/djangoapps/theming/helpers.py +++ b/openedx/core/djangoapps/theming/helpers.py @@ -8,6 +8,7 @@ import os import re from logging import getLogger +import crum from django.conf import settings from microsite_configuration import microsite @@ -19,7 +20,7 @@ from openedx.core.djangoapps.theming.helpers_dirs import ( get_theme_dirs, get_themes_unchecked ) -from openedx.core.djangoapps.request_cache.middleware import RequestCache, request_cached +from openedx.core.djangoapps.request_cache.middleware import request_cached logger = getLogger(__name__) # pylint: disable=invalid-name @@ -165,7 +166,7 @@ def get_current_request(): Returns: (HttpRequest): returns current request """ - return RequestCache.get_current_request() + return crum.get_current_request() def get_current_site(): diff --git a/openedx/core/djangoapps/theming/tests/test_helpers.py b/openedx/core/djangoapps/theming/tests/test_helpers.py index 570cfb670a..afde716822 100644 --- a/openedx/core/djangoapps/theming/tests/test_helpers.py +++ b/openedx/core/djangoapps/theming/tests/test_helpers.py @@ -5,6 +5,7 @@ from mock import patch, Mock from django.test import TestCase, override_settings from django.conf import settings +from edx_django_utils.cache import RequestCache from openedx.core.djangoapps.theming.tests.test_util import with_comprehensive_theme from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers @@ -12,7 +13,6 @@ from openedx.core.djangoapps.theming import helpers as theming_helpers from openedx.core.djangoapps.theming.helpers import get_template_path_with_theme, strip_site_theme_templates_path, \ get_themes, Theme, get_theme_base_dir from openedx.core.djangolib.testing.utils import skip_unless_cms, skip_unless_lms -from openedx.core.djangoapps.request_cache.middleware import RequestCache class TestHelpers(TestCase): @@ -190,7 +190,7 @@ class TestHelpers(TestCase): mock_microsite_backend.get_template = Mock(return_value="/microsite/about.html") self.assertEqual(theming_helpers.get_template_path("about.html"), "about.html") - RequestCache.clear_request_cache() + RequestCache.clear_all_namespaces() # if the current site does not have associated SiteTheme then get_template_path should return microsite override with patch( diff --git a/openedx/core/djangoapps/verified_track_content/models.py b/openedx/core/djangoapps/verified_track_content/models.py index 1d4136d065..d752ca7c0e 100644 --- a/openedx/core/djangoapps/verified_track_content/models.py +++ b/openedx/core/djangoapps/verified_track_content/models.py @@ -8,6 +8,7 @@ from django.db import models from django.db.models.signals import post_save, pre_save from django.dispatch import receiver from django.utils.translation import ugettext_lazy +from edx_django_utils.cache import RequestCache from opaque_keys.edx.django.models import CourseKeyField from lms.djangoapps.courseware.courses import get_course_by_id @@ -18,7 +19,7 @@ from openedx.core.djangoapps.course_groups.cohorts import ( is_course_cohorted ) from openedx.core.djangoapps.verified_track_content.tasks import sync_cohort_with_mode -from openedx.core.djangoapps.request_cache.middleware import RequestCache, ns_request_cached +from openedx.core.djangoapps.request_cache.middleware import ns_request_cached from student.models import CourseEnrollment log = logging.getLogger(__name__) @@ -147,7 +148,7 @@ class VerifiedTrackCohortedCourse(models.Model): @receiver(models.signals.post_delete, sender=VerifiedTrackCohortedCourse) def invalidate_verified_track_cache(sender, **kwargs): # pylint: disable=unused-argument """Invalidate the cache of VerifiedTrackCohortedCourse. """ - RequestCache.clear_request_cache(name=VerifiedTrackCohortedCourse.CACHE_NAMESPACE) + RequestCache(namespace=VerifiedTrackCohortedCourse.CACHE_NAMESPACE).clear() class MigrateVerifiedTrackCohortsSetting(ConfigurationModel): diff --git a/openedx/core/djangoapps/waffle_utils/tests/test_init.py b/openedx/core/djangoapps/waffle_utils/tests/test_init.py index 3facecca2e..bcac166504 100644 --- a/openedx/core/djangoapps/waffle_utils/tests/test_init.py +++ b/openedx/core/djangoapps/waffle_utils/tests/test_init.py @@ -5,9 +5,9 @@ import crum import ddt from django.test import TestCase from django.test.client import RequestFactory +from edx_django_utils.cache import RequestCache from mock import patch from opaque_keys.edx.keys import CourseKey -from openedx.core.djangoapps.request_cache.middleware import RequestCache from waffle.testutils import override_flag from .. import CourseWaffleFlag, WaffleFlagNamespace, WaffleSwitchNamespace, WaffleSwitch @@ -34,7 +34,7 @@ class TestCourseWaffleFlag(TestCase): request = RequestFactory().request() self.addCleanup(crum.set_current_request, None) crum.set_current_request(request) - RequestCache.clear_request_cache() + RequestCache.clear_all_namespaces() @ddt.data( {'course_override': WaffleFlagCourseOverrideModel.ALL_CHOICES.on, 'waffle_enabled': False, 'result': True}, diff --git a/openedx/core/djangoapps/waffle_utils/tests/test_models.py b/openedx/core/djangoapps/waffle_utils/tests/test_models.py index 5dbfbe0859..b2aab23c82 100644 --- a/openedx/core/djangoapps/waffle_utils/tests/test_models.py +++ b/openedx/core/djangoapps/waffle_utils/tests/test_models.py @@ -3,10 +3,9 @@ Tests for waffle utils models. """ from ddt import data, ddt, unpack from django.test import TestCase +from edx_django_utils.cache import RequestCache from opaque_keys.edx.keys import CourseKey -from openedx.core.djangoapps.request_cache.middleware import RequestCache - from ..models import WaffleFlagCourseOverrideModel @@ -26,7 +25,7 @@ class WaffleFlagCourseOverrideTests(TestCase): (False, OVERRIDE_CHOICES.on, OVERRIDE_CHOICES.unset)) @unpack def test_setting_override(self, is_enabled, override_choice, expected_result): - RequestCache.clear_request_cache() + RequestCache.clear_all_namespaces() self.set_waffle_course_override(override_choice, is_enabled) override_value = WaffleFlagCourseOverrideModel.override_value( self.WAFFLE_TEST_NAME, self.TEST_COURSE_KEY @@ -34,7 +33,7 @@ class WaffleFlagCourseOverrideTests(TestCase): self.assertEqual(override_value, expected_result) def test_setting_override_multiple_times(self): - RequestCache.clear_request_cache() + RequestCache.clear_all_namespaces() self.set_waffle_course_override(self.OVERRIDE_CHOICES.on) self.set_waffle_course_override(self.OVERRIDE_CHOICES.off) override_value = WaffleFlagCourseOverrideModel.override_value( diff --git a/openedx/core/djangoapps/waffle_utils/tests/test_testutils.py b/openedx/core/djangoapps/waffle_utils/tests/test_testutils.py index 5c6f5e558d..b9da185335 100644 --- a/openedx/core/djangoapps/waffle_utils/tests/test_testutils.py +++ b/openedx/core/djangoapps/waffle_utils/tests/test_testutils.py @@ -5,9 +5,9 @@ Tests for waffle utils test utilities. import crum from django.test import TestCase from django.test.client import RequestFactory +from edx_django_utils.cache import RequestCache from opaque_keys.edx.keys import CourseKey -from openedx.core.djangoapps.request_cache.middleware import RequestCache from .. import CourseWaffleFlag, WaffleFlagNamespace from ..testutils import override_waffle_flag @@ -30,7 +30,7 @@ class OverrideWaffleFlagTests(TestCase): request = RequestFactory().request() self.addCleanup(crum.set_current_request, None) crum.set_current_request(request) - RequestCache.clear_request_cache() + RequestCache.clear_all_namespaces() @override_waffle_flag(TEST_COURSE_FLAG, True) def assert_decorator_activates_flag(self): diff --git a/openedx/core/djangolib/testing/utils.py b/openedx/core/djangolib/testing/utils.py index 077bfc1ab2..710f5a35ba 100644 --- a/openedx/core/djangolib/testing/utils.py +++ b/openedx/core/djangolib/testing/utils.py @@ -21,8 +21,6 @@ from django.test import RequestFactory, TestCase, override_settings from django.test.utils import CaptureQueriesContext from edx_django_utils.cache import RequestCache -from openedx.core.djangoapps.request_cache.middleware import RequestCache as DeprecatedRequestCache - class CacheIsolationMixin(object): """ @@ -120,7 +118,6 @@ class CacheIsolationMixin(object): # Clear that. sites.models.SITE_CACHE.clear() - DeprecatedRequestCache.clear_request_cache() RequestCache.clear_all_namespaces() diff --git a/requirements/edx/base.txt b/requirements/edx/base.txt index e758f97678..6e9b6a589b 100644 --- a/requirements/edx/base.txt +++ b/requirements/edx/base.txt @@ -115,7 +115,7 @@ edx-completion==0.1.9 edx-django-oauth2-provider==1.3.4 edx-django-release-util==0.3.1 edx-django-sites-extensions==2.3.1 -edx-django-utils==1.0.0 +edx-django-utils==1.0.1 edx-drf-extensions==1.6.2 edx-enterprise==0.73.0 edx-i18n-tools==0.4.6 diff --git a/requirements/edx/development.txt b/requirements/edx/development.txt index fdf9760582..1f679c5685 100644 --- a/requirements/edx/development.txt +++ b/requirements/edx/development.txt @@ -134,7 +134,7 @@ edx-completion==0.1.9 edx-django-oauth2-provider==1.3.4 edx-django-release-util==0.3.1 edx-django-sites-extensions==2.3.1 -edx-django-utils==1.0.0 +edx-django-utils==1.0.1 edx-drf-extensions==1.6.2 edx-enterprise==0.73.0 edx-i18n-tools==0.4.6 diff --git a/requirements/edx/testing.in b/requirements/edx/testing.in index 2e4139d900..e066bd157a 100644 --- a/requirements/edx/testing.in +++ b/requirements/edx/testing.in @@ -36,7 +36,7 @@ pyquery # jQuery-like API for retrieving fragments of HTML and pysqlite # DB-API 2.0 interface for SQLite 3.x (used as the relational database for most tests) pytest==3.6.3 # Testing framework # Pinned due to https://github.com/pytest-dev/pytest/issues/3749 pytest-attrib # Select tests based on attributes -pytest-cov # pytest plugin for measuring code coverage +pytest-cov<2.6 # pytest plugin for measuring code coverage pytest-django==3.1.2 # Django support for pytest pytest-randomly # pytest plugin to randomly order tests pytest-xdist # Parallel execution of tests on multiple CPU cores or hosts diff --git a/requirements/edx/testing.txt b/requirements/edx/testing.txt index 0a5ed937c3..4cdbebb934 100644 --- a/requirements/edx/testing.txt +++ b/requirements/edx/testing.txt @@ -129,7 +129,7 @@ edx-completion==0.1.9 edx-django-oauth2-provider==1.3.4 edx-django-release-util==0.3.1 edx-django-sites-extensions==2.3.1 -edx-django-utils==1.0.0 +edx-django-utils==1.0.1 edx-drf-extensions==1.6.2 edx-enterprise==0.73.0 edx-i18n-tools==0.4.6