From 73c9e65b75cd956410ae71f39fb2f6a9b7b45b42 Mon Sep 17 00:00:00 2001 From: Aymeric Augustin Date: Wed, 18 Dec 2013 10:34:20 +0100 Subject: [PATCH] Added a context manager to hold the import lock. --- django/core/apps/cache.py | 8 ++------ django/utils/module_loading.py | 13 +++++++++++++ 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/django/core/apps/cache.py b/django/core/apps/cache.py index b076fc1968..d07c3bbe34 100644 --- a/django/core/apps/cache.py +++ b/django/core/apps/cache.py @@ -1,7 +1,6 @@ "Utilities for loading models and the modules that contain them." from collections import OrderedDict -import imp from importlib import import_module import os import sys @@ -9,7 +8,7 @@ import warnings from django.conf import settings from django.core.exceptions import ImproperlyConfigured -from django.utils.module_loading import module_has_submodule +from django.utils.module_loading import import_lock, module_has_submodule from django.utils._os import upath from django.utils import six @@ -74,8 +73,7 @@ class AppCache(object): # without holding the importer lock and another thread then tries to # import something which also launches the app loading. For details of # this situation see #18251. - imp.acquire_lock() - try: + with import_lock(): if self.loaded: return for app_name in settings.INSTALLED_APPS: @@ -86,8 +84,6 @@ class AppCache(object): for app_name in self.postponed: self.load_app(app_name) self.loaded = True - finally: - imp.release_lock() def load_app(self, app_name, can_postpone=False): """ diff --git a/django/utils/module_loading.py b/django/utils/module_loading.py index 8868a2d3ab..0c6bad2a7b 100644 --- a/django/utils/module_loading.py +++ b/django/utils/module_loading.py @@ -1,5 +1,6 @@ from __future__ import absolute_import # Avoid importing `importlib` from this package. +from contextlib import contextmanager import copy import imp from importlib import import_module @@ -35,6 +36,18 @@ def import_by_path(dotted_path, error_prefix=''): return attr +@contextmanager +def import_lock(): + """ + Context manager that aquires the import lock. + """ + imp.acquire_lock() + try: + yield + finally: + imp.release_lock() + + def autodiscover_modules(*args, **kwargs): """ Auto-discover INSTALLED_APPS modules and fail silently when