1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
|
# autoreloading launcher
# stolen a lot from Ian Bicking's WSGIKit (www.wsgikit.org)
import os
import sys
import time
import thread
RUN_RELOADER = True
reloadFiles = []
def reloader_thread(freq):
mtimes = {}
def fileattr(m):
if hasattr(m, "__loader__"):
if hasattr(m.__loader__, "archive"):
return m.__loader__.archive
return getattr(m, "__file__", None)
while RUN_RELOADER:
for filename in map(fileattr, sys.modules.values()) + reloadFiles:
if filename:
if filename.endswith(".pyc"):
filename = filename[:-1]
try:
mtime = os.stat(filename).st_mtime
except OSError:
sys.exit(3) # force reload
if filename not in mtimes:
mtimes[filename] = mtime
continue
if mtime > mtimes[filename]:
sys.exit(3) # force reload
time.sleep(freq)
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 main(main_func, args=None, kwargs=None, freq=1):
if os.environ.get("RUN_MAIN") == "true":
if args is None:
args = ()
if kwargs is None:
kwargs = {}
thread.start_new_thread(main_func, args, kwargs)
# If KeyboardInterrupt is raised within reloader_thread,
# let it propagate out to the caller.
reloader_thread(freq)
else:
# If KeyboardInterrupt is raised within restart_with_reloader,
# let it propagate out to the caller.
sys.exit(restart_with_reloader())
|