web/lib/django/utils/autoreload.py
changeset 0 0d40e90630ef
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/lib/django/utils/autoreload.py	Wed Jan 20 00:34:04 2010 +0100
@@ -0,0 +1,119 @@
+# Autoreloading launcher.
+# Borrowed from Peter Hunt and the CherryPy project (http://www.cherrypy.org).
+# Some taken from Ian Bicking's Paste (http://pythonpaste.org/).
+#
+# Portions copyright (c) 2004, CherryPy Team (team@cherrypy.org)
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without modification,
+# are permitted provided that the following conditions are met:
+#
+#     * Redistributions of source code must retain the above copyright notice,
+#       this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright notice,
+#       this list of conditions and the following disclaimer in the documentation
+#       and/or other materials provided with the distribution.
+#     * Neither the name of the CherryPy Team nor the names of its contributors
+#       may be used to endorse or promote products derived from this software
+#       without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# 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
+
+try:
+    import thread
+except ImportError:
+    import dummy_thread as thread
+
+# This import does nothing, but it's necessary to avoid some race conditions
+# in the threading module. See http://code.djangoproject.com/ticket/2330 .
+try:
+    import threading
+except ImportError:
+    pass
+
+
+RUN_RELOADER = True
+
+_mtimes = {}
+_win = (sys.platform == "win32")
+
+def code_changed():
+    global _mtimes, _win
+    for filename in filter(lambda v: v, map(lambda m: getattr(m, "__file__", None), sys.modules.values())):
+        if filename.endswith(".pyc") or filename.endswith(".pyo"):
+            filename = filename[:-1]
+        if not os.path.exists(filename):
+            continue # File might be in an egg, so it can't be reloaded.
+        stat = os.stat(filename)
+        mtime = stat.st_mtime
+        if _win:
+            mtime -= stat.st_ctime
+        if filename not in _mtimes:
+            _mtimes[filename] = mtime
+            continue
+        if mtime != _mtimes[filename]:
+            _mtimes = {}
+            return True
+    return False
+
+def reloader_thread():
+    while RUN_RELOADER:
+        if code_changed():
+            sys.exit(3) # force reload
+        time.sleep(1)
+
+def restart_with_reloader():
+    while True:
+        args = [sys.executable] + sys.argv
+        if sys.platform == "win32":
+            args = ['"%s"' % arg for arg in args]
+        new_environ = os.environ.copy()
+        new_environ["RUN_MAIN"] = 'true'
+        exit_code = os.spawnve(os.P_WAIT, sys.executable, args, new_environ)
+        if exit_code != 3:
+            return exit_code
+
+def python_reloader(main_func, args, kwargs):
+    if os.environ.get("RUN_MAIN") == "true":
+        thread.start_new_thread(main_func, args, kwargs)
+        try:
+            reloader_thread()
+        except KeyboardInterrupt:
+            pass
+    else:
+        try:
+            sys.exit(restart_with_reloader())
+        except KeyboardInterrupt:
+            pass
+
+def jython_reloader(main_func, args, kwargs):
+    from _systemrestart import SystemRestart
+    thread.start_new_thread(main_func, args)
+    while True:
+        if code_changed():
+            raise SystemRestart
+        time.sleep(1)
+
+
+def main(main_func, args=None, kwargs=None):
+    if args is None:
+        args = ()
+    if kwargs is None:
+        kwargs = {}
+    if sys.platform.startswith('java'):
+        reloader = jython_reloader
+    else:
+        reloader = python_reloader
+    reloader(main_func, args, kwargs)
+