Added auto-reload to standalone server! Fixes #113. Thanks very much to Jason Huggins for the patch.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@266 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Adrian Holovaty 2005-07-21 04:08:54 +00:00
parent c21f6ecee2
commit 9566a61a22
2 changed files with 72 additions and 19 deletions

View File

@ -419,27 +419,30 @@ def runserver(port):
"Starts a lightweight Web server for development."
from django.core.servers.basehttp import run, WSGIServerException
from django.core.handlers.wsgi import AdminMediaHandler, WSGIHandler
from django.conf.settings import SETTINGS_MODULE
if not port.isdigit():
sys.stderr.write("Error: %r is not a valid port number.\n" % port)
sys.exit(1)
print "Starting server on port %s with settings module %r." % (port, SETTINGS_MODULE)
print "Go to http://127.0.0.1:%s/ for Django." % port
print "Quit the server with CONTROL-C (Unix) or CTRL-BREAK (Windows)."
try:
run(int(port), AdminMediaHandler(WSGIHandler()))
except WSGIServerException, e:
# Use helpful error messages instead of ugly tracebacks.
ERRORS = {
13: "You don't have permission to access that port.",
98: "That port is already in use.",
}
def inner_run():
from django.conf.settings import SETTINGS_MODULE
print "Starting server on port %s with settings module %r." % (port, SETTINGS_MODULE)
print "Go to http://127.0.0.1:%s/ for Django." % port
print "Quit the server with CONTROL-C (Unix) or CTRL-BREAK (Windows)."
try:
error_text = ERRORS[e.args[0].args[0]]
except (AttributeError, KeyError):
error_text = str(e)
sys.stderr.write("Error: %s\n" % error_text)
sys.exit(1)
except KeyboardInterrupt:
sys.exit(0)
run(int(port), AdminMediaHandler(WSGIHandler()))
except WSGIServerException, e:
# Use helpful error messages instead of ugly tracebacks.
ERRORS = {
13: "You don't have permission to access that port.",
98: "That port is already in use.",
}
try:
error_text = ERRORS[e.args[0].args[0]]
except (AttributeError, KeyError):
error_text = str(e)
sys.stderr.write("Error: %s\n" % error_text)
sys.exit(1)
except KeyboardInterrupt:
sys.exit(0)
from django.utils import autoreload
autoreload.main(inner_run)
runserver.args = '[optional port number]'

View File

@ -0,0 +1,50 @@
# Autoreloading launcher.
# Borrowed from Peter Hunt and the CherryPy project (http://www.cherrypy.org).
# Some taken from Ian Bicking's Paste (http://pythonpaste.org/).
import os, sys, thread, time
RUN_RELOADER = True
reloadFiles = []
def reloader_thread():
mtimes = {}
while RUN_RELOADER:
for filename in filter(lambda v: v, map(lambda m: getattr(m, "__file__", None), sys.modules.values())) + reloadFiles:
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]:
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 main(main_func, args=None, kwargs=None):
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)
try:
reloader_thread()
except KeyboardInterrupt:
pass
else:
try:
sys.exit(restart_with_reloader())
except KeyboardInterrupt:
pass