def test_clear_template_tag_caches(self): """Testing clear_template_tag_caches""" def _check_state(enabled): if enabled: if get_templatetags_modules is not None: self.assertIn(templatetags_module_name, get_templatetags_modules()) self.assertEqual( Template(template_str).render(Context({})), 'Hello, world!') else: if get_templatetags_modules is not None: self.assertNotIn(templatetags_module_name, get_templatetags_modules()) with self.assertRaisesRegexp(TemplateSyntaxError, 'is not a (valid|registered) tag ' 'library'): Template(template_str).render(Context({})) templatetags_module_name = 'djblets.template.tests.templatetags' template_str = ( '{% load template_tests %}' '{% my_test_template_tag %}' ) # Sanity-check that the template tag module isn't registered. _check_state(enabled=False) # Enable a new template tag library. old_installed_apps = settings.INSTALLED_APPS settings.INSTALLED_APPS = list(old_installed_apps) + [ 'djblets.template.tests', ] if apps: apps.set_installed_apps(settings.INSTALLED_APPS) try: clear_template_tag_caches() _check_state(enabled=True) finally: settings.INSTALLED_APPS = old_installed_apps if apps: apps.unset_installed_apps() clear_template_tag_caches() _check_state(enabled=False) # Other libraries should still work. Template('{% load djblets_js djblets_extensions %}').render( Context({}))
def test_clear_template_tag_caches(self): """Testing clear_template_tag_caches""" def _check_state(enabled): if enabled: if get_templatetags_modules is not None: self.assertIn(templatetags_module_name, get_templatetags_modules()) self.assertEqual( Template(template_str).render(Context({})), 'Hello, world!') else: if get_templatetags_modules is not None: self.assertNotIn(templatetags_module_name, get_templatetags_modules()) with self.assertRaisesRegexp( TemplateSyntaxError, 'is not a (valid|registered) tag ' 'library'): Template(template_str).render(Context({})) templatetags_module_name = 'djblets.template.tests.templatetags' template_str = ('{% load template_tests %}' '{% my_test_template_tag %}') # Sanity-check that the template tag module isn't registered. _check_state(enabled=False) # Enable a new template tag library. old_installed_apps = settings.INSTALLED_APPS settings.INSTALLED_APPS = list(old_installed_apps) + [ 'djblets.template.tests', ] if apps: apps.set_installed_apps(settings.INSTALLED_APPS) try: clear_template_tag_caches() _check_state(enabled=True) finally: settings.INSTALLED_APPS = old_installed_apps if apps: apps.unset_installed_apps() clear_template_tag_caches() _check_state(enabled=False) # Other libraries should still work. Template('{% load djblets_js djblets_extensions %}').render(Context( {}))
def revert(self, migrate=True): for k, v in self._original_settings.items(): if v == NO_SETTING: delattr(settings, k) else: setattr(settings, k, v) if 'INSTALLED_APPS' in self._original_settings: apps.unset_installed_apps() if migrate: self.migrate() self._original_settings = {}
def unregister_app(app_label): """Unregister an app in the registry. This must be balanced with a :py:func:`register_app` call. Args: app_label (str): The label of the app to register. """ if apps: # Django >= 1.7 # # We need to balance the ``set_installed_apps`` from # :py:func:`register_app` here. apps.unset_installed_apps() all_models[app_label].clear() clear_app_cache()
def _remove_from_installed_apps(self, extension): """Remove an extension's apps from the list of installed apps. This will unregister each app with Django and clear any caches storing the apps' models. Args: extension (djblets.extensions.extension.Extension): The extension whose apps are being removed. """ # Remove the extension's apps from INSTALLED_APPS. removed_apps = self._installed_apps_setting.remove_list( extension.apps or [extension.info.app_name]) # Now clear the apps and their modules from any caches. if apps: apps.unset_installed_apps() else: for app_name in removed_apps: # In Django 1.6, the only apps that are registered are those # with models. If this particular app does not have models, we # don't want to clear any caches below. There might be another # app with the same label that actually does have models, and # we'd be clearing those away. An example would be # reviewboard.hostingsvcs (which has models) and # rbpowerpack.hostingsvcs (which does not). # # Django 1.6 doesn't technically allow multiple apps with the # same label to have models (other craziness will happen), so # we don't have to worry about that. It's not our problem. try: app_mod = import_module('%s.models' % app_name) except ImportError: # Something went very wrong. Maybe this module didn't # exist anymore. Ignore it. continue # Fetch the models before we make any changes to the cache. model_modules = {app_mod} model_modules.update( import_module(model.__module__) for model in loading.get_models(app_mod) ) # Start pruning this app from the caches. # # We are going to keep this in loading.cache.app_models. # If we don't, we'll never get those modules again without # some potentially dangerous manipulation of sys.modules and # possibly other state. get_models() will default to ignoring # anything in that list if the app label isn't present in # loading.cache.app_labels, which we'll remove, so the model # will appear as "uninstalled." app_label = app_name.rpartition('.')[2] loading.cache.app_labels.pop(app_label, None) for module in model_modules: loading.cache.app_store.pop(module, None) # Force get_models() to recompute models for lookups, so that # now-unregistered models aren't returned. loading.cache._get_models_cache.clear()
def _remove_from_installed_apps(self, extension): """Remove an extension's apps from the list of installed apps. This will unregister each app with Django and clear any caches storing the apps' models. Args: extension (djblets.extensions.extension.Extension): The extension whose apps are being removed. """ # Remove the extension's apps from INSTALLED_APPS. removed_apps = self._installed_apps_setting.remove_list( extension.apps or [extension.info.app_name]) # Now clear the apps and their modules from any caches. if apps: apps.unset_installed_apps() else: for app_name in removed_apps: # In Django 1.6, the only apps that are registered are those # with models. If this particular app does not have models, we # don't want to clear any caches below. There might be another # app with the same label that actually does have models, and # we'd be clearing those away. An example would be # reviewboard.hostingsvcs (which has models) and # rbpowerpack.hostingsvcs (which does not). # # Django 1.6 doesn't technically allow multiple apps with the # same label to have models (other craziness will happen), so # we don't have to worry about that. It's not our problem. try: app_mod = import_module('%s.models' % app_name) except ImportError: # Something went very wrong. Maybe this module didn't # exist anymore. Ignore it. continue # Fetch the models before we make any changes to the cache. model_modules = {app_mod} model_modules.update( import_module(model.__module__) for model in loading.get_models(app_mod)) # Start pruning this app from the caches. # # We are going to keep this in loading.cache.app_models. # If we don't, we'll never get those modules again without # some potentially dangerous manipulation of sys.modules and # possibly other state. get_models() will default to ignoring # anything in that list if the app label isn't present in # loading.cache.app_labels, which we'll remove, so the model # will appear as "uninstalled." app_label = app_name.rpartition('.')[2] loading.cache.app_labels.pop(app_label, None) for module in model_modules: loading.cache.app_store.pop(module, None) # Force get_models() to recompute models for lookups, so that # now-unregistered models aren't returned. loading.cache._get_models_cache.clear()