summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRamiro Morales <cramm0@gmail.com>2012-12-12 00:33:03 -0300
committerRamiro Morales <cramm0@gmail.com>2012-12-15 10:17:25 -0300
commitc2a6b2a43fb8f32cff078c823054e2e65f325464 (patch)
tree9dbc8325e2bd53d3b88774efaa86881887db4429
parentb052e6cc959b540e4d1de8a747689c25c6aeace9 (diff)
Fixed #9589 -- Made development web server more robust in the presence of a wider variety of code errors.
Thanks goes to contributor with Trac user 'berto' for the patch.
-rw-r--r--AUTHORS1
-rw-r--r--django/utils/autoreload.py35
2 files changed, 33 insertions, 3 deletions
diff --git a/AUTHORS b/AUTHORS
index 6496005082..0f793cc5f4 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -91,6 +91,7 @@ answer newbie questions, and generally made Django that much better:
James Bennett
Danilo Bargen
Shai Berger <shai@platonix.com>
+ berto
Julian Bez
Arvis Bickovskis <viestards.lists@gmail.com>
Natalia Bidart <nataliabidart@gmail.com>
diff --git a/django/utils/autoreload.py b/django/utils/autoreload.py
index 2daafedd85..f600f0611c 100644
--- a/django/utils/autoreload.py
+++ b/django/utils/autoreload.py
@@ -28,7 +28,7 @@
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-import os, sys, time, signal
+import os, sys, time, signal, traceback
try:
from django.utils.six.moves import _thread as thread
@@ -52,10 +52,12 @@ RUN_RELOADER = True
_mtimes = {}
_win = (sys.platform == "win32")
+_error_files = []
+
def code_changed():
global _mtimes, _win
filenames = [getattr(m, "__file__", None) for m in sys.modules.values()]
- for filename in filter(None, filenames):
+ for filename in filter(None, filenames) + _error_files:
if filename.endswith(".pyc") or filename.endswith(".pyo"):
filename = filename[:-1]
if filename.endswith("$py.class"):
@@ -71,9 +73,34 @@ def code_changed():
continue
if mtime != _mtimes[filename]:
_mtimes = {}
+ try:
+ del _error_files[_error_files.index(filename)]
+ except ValueError:
+ pass
return True
return False
+def check_errors(fn):
+ def wrapper(*args, **kwargs):
+ try:
+ fn(*args, **kwargs)
+ except (ImportError, IndentationError, NameError, SyntaxError,
+ TypeError, AttributeError):
+ et, ev, tb = sys.exc_info()
+
+ if getattr(ev, 'filename', None) is None:
+ # get the filename from the last item in the stack
+ filename = traceback.extract_tb(tb)[-1][0]
+ else:
+ filename = ev.filename
+
+ if filename not in _error_files:
+ _error_files.append(filename)
+
+ raise
+
+ return wrapper
+
def ensure_echo_on():
if termios:
fd = sys.stdin
@@ -142,5 +169,7 @@ def main(main_func, args=None, kwargs=None):
reloader = jython_reloader
else:
reloader = python_reloader
- reloader(main_func, args, kwargs)
+
+ wrapped_main_func = check_errors(main_func)
+ reloader(wrapped_main_func, args, kwargs)