app/django/utils/autoreload.py
changeset 323 ff1a9aa48cfd
parent 54 03e267d67478
equal deleted inserted replaced
322:6641e941ef1e 323:ff1a9aa48cfd
    43     pass
    43     pass
    44 
    44 
    45 
    45 
    46 RUN_RELOADER = True
    46 RUN_RELOADER = True
    47 
    47 
       
    48 _mtimes = {}
       
    49 _win = (sys.platform == "win32")
       
    50 
       
    51 def code_changed():
       
    52     global _mtimes, _win
       
    53     for filename in filter(lambda v: v, map(lambda m: getattr(m, "__file__", None), sys.modules.values())):
       
    54         if filename.endswith(".pyc") or filename.endswith(".pyo"):
       
    55             filename = filename[:-1]
       
    56         if not os.path.exists(filename):
       
    57             continue # File might be in an egg, so it can't be reloaded.
       
    58         stat = os.stat(filename)
       
    59         mtime = stat.st_mtime
       
    60         if _win:
       
    61             mtime -= stat.st_ctime
       
    62         if filename not in _mtimes:
       
    63             _mtimes[filename] = mtime
       
    64             continue
       
    65         if mtime != _mtimes[filename]:
       
    66             _mtimes = {}
       
    67             return True
       
    68     return False
       
    69 
    48 def reloader_thread():
    70 def reloader_thread():
    49     mtimes = {}
       
    50     win = (sys.platform == "win32")
       
    51     while RUN_RELOADER:
    71     while RUN_RELOADER:
    52         for filename in filter(lambda v: v, map(lambda m: getattr(m, "__file__", None), sys.modules.values())):
    72         if code_changed():
    53             if filename.endswith(".pyc") or filename.endswith("*.pyo"):
    73             sys.exit(3) # force reload
    54                 filename = filename[:-1]
       
    55             if not os.path.exists(filename):
       
    56                 continue # File might be in an egg, so it can't be reloaded.
       
    57             stat = os.stat(filename)
       
    58             mtime = stat.st_mtime
       
    59             if win:
       
    60                 mtime -= stat.st_ctime
       
    61             if filename not in mtimes:
       
    62                 mtimes[filename] = mtime
       
    63                 continue
       
    64             if mtime != mtimes[filename]:
       
    65                 sys.exit(3) # force reload
       
    66         time.sleep(1)
    74         time.sleep(1)
    67 
    75 
    68 def restart_with_reloader():
    76 def restart_with_reloader():
    69     while True:
    77     while True:
    70         args = [sys.executable] + sys.argv
    78         args = [sys.executable] + sys.argv
    74         new_environ["RUN_MAIN"] = 'true'
    82         new_environ["RUN_MAIN"] = 'true'
    75         exit_code = os.spawnve(os.P_WAIT, sys.executable, args, new_environ)
    83         exit_code = os.spawnve(os.P_WAIT, sys.executable, args, new_environ)
    76         if exit_code != 3:
    84         if exit_code != 3:
    77             return exit_code
    85             return exit_code
    78 
    86 
    79 def main(main_func, args=None, kwargs=None):
    87 def python_reloader(main_func, args, kwargs):
    80     if os.environ.get("RUN_MAIN") == "true":
    88     if os.environ.get("RUN_MAIN") == "true":
    81         if args is None:
       
    82             args = ()
       
    83         if kwargs is None:
       
    84             kwargs = {}
       
    85         thread.start_new_thread(main_func, args, kwargs)
    89         thread.start_new_thread(main_func, args, kwargs)
    86         try:
    90         try:
    87             reloader_thread()
    91             reloader_thread()
    88         except KeyboardInterrupt:
    92         except KeyboardInterrupt:
    89             pass
    93             pass
    90     else:
    94     else:
    91         try:
    95         try:
    92             sys.exit(restart_with_reloader())
    96             sys.exit(restart_with_reloader())
    93         except KeyboardInterrupt:
    97         except KeyboardInterrupt:
    94             pass
    98             pass
       
    99 
       
   100 def jython_reloader(main_func, args, kwargs):
       
   101     from _systemrestart import SystemRestart
       
   102     thread.start_new_thread(main_func, args)
       
   103     while True:
       
   104         if code_changed():
       
   105             raise SystemRestart
       
   106         time.sleep(1)
       
   107 
       
   108 
       
   109 def main(main_func, args=None, kwargs=None):
       
   110     if args is None:
       
   111         args = ()
       
   112     if kwargs is None:
       
   113         kwargs = {}
       
   114     if sys.platform.startswith('java'):
       
   115         reloader = jython_reloader
       
   116     else:
       
   117         reloader = python_reloader
       
   118     reloader(main_func, args, kwargs)
       
   119