diff options
| author | Ramiro Morales <cramm0@gmail.com> | 2012-12-12 00:33:03 -0300 |
|---|---|---|
| committer | Ramiro Morales <cramm0@gmail.com> | 2012-12-15 10:17:25 -0300 |
| commit | c2a6b2a43fb8f32cff078c823054e2e65f325464 (patch) | |
| tree | 9dbc8325e2bd53d3b88774efaa86881887db4429 | |
| parent | b052e6cc959b540e4d1de8a747689c25c6aeace9 (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-- | AUTHORS | 1 | ||||
| -rw-r--r-- | django/utils/autoreload.py | 35 |
2 files changed, 33 insertions, 3 deletions
@@ -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) |
