diff examples/trac/trac/util/autoreload.py @ 39:93b4dcbafd7b trunk

Copy Trac to main branch.
author cmlenz
date Mon, 03 Jul 2006 18:53:27 +0000
parents
children
line wrap: on
line diff
new file mode 100644
--- /dev/null
+++ b/examples/trac/trac/util/autoreload.py
@@ -0,0 +1,82 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2006 Edgewall Software
+# All rights reserved.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at http://trac.edgewall.com/license.html.
+#
+# This software consists of voluntary contributions made by many
+# individuals. For the exact contribution history, see the revision
+# history and logs, available at http://projects.edgewall.com/trac/.
+
+import os
+import sys
+import time
+import thread
+
+_SLEEP_TIME = 1
+
+def _reloader_thread(modification_callback):
+    """When this function is run from the main thread, it will force other
+    threads to exit when any modules currently loaded change.
+    @param modification_callback: Function taking a single argument, the
+    modified file, and is called after a modification is detected."""
+    mtimes = {}
+    while True:
+        for filename in filter(None, [getattr(module, "__file__", None)
+                                      for module in sys.modules.values()]):
+            while not os.path.isfile(filename): # Probably in an egg or zip file
+                filename = os.path.dirname(filename)
+                if not filename:
+                    break
+            if not filename: # Couldn't map to physical file, so just ignore
+                continue
+
+            if filename.endswith(".pyc"):
+                filename = filename[:-1]
+
+            mtime = os.stat(filename).st_mtime
+            if filename not in mtimes:
+                mtimes[filename] = mtime
+                continue
+            if mtime > mtimes[filename]:
+                modification_callback(filename)
+                sys.exit(3)
+        time.sleep(_SLEEP_TIME)
+
+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'
+
+        # This call reinvokes ourself and goes into the other branch of main as
+        # a new process.
+        exit_code = os.spawnve(os.P_WAIT, sys.executable,
+                               args, new_environ)
+        if exit_code != 3:
+            return exit_code
+
+def main(main_func, modification_callback):
+    """Run `main_func` and restart any time modules are changed."""
+
+    if os.environ.get("RUN_MAIN"):
+        # Lanch the actual program as a child thread
+        thread.start_new_thread(main_func, ())
+
+        try:
+            # Now wait for a file modification and quit
+            _reloader_thread(modification_callback)
+        except KeyboardInterrupt:
+            pass
+
+    else:
+        # Initial invocation just waits around restarting this executable
+        try:
+            sys.exit(_restart_with_reloader())
+        except KeyboardInterrupt:
+            pass
Copyright (C) 2012-2017 Edgewall Software