Download Install Tutorial Docs FAQ Tools WikiLicense Team IRC Planet Involvement Shop Book

root/branches/cherrypy-2.x/cherrypy/lib/autoreload.py

Revision 1566 (checked in by fumanchu, 2 years ago)

2.x backport of [1220] (Fix for #438 (autoreload.py: Server fails to start if a .pyc is imported with no corresponding .py)) and [1337] (New engine.autoreload.match attribute for filtering autoreload to a single package.)

  • Property svn:eol-style set to native
Line 
1 # autoreloading launcher
2 # stolen a lot from Ian Bicking's WSGIKit (www.wsgikit.org)
3
4 import errno
5 import os
6 import re
7 import sys
8 import time
9 import thread
10
11 RUN_RELOADER = True
12 reloadFiles = []
13 ignoreFiles = ['<string>']
14 match = ".*"
15
16
17 def reloader_thread(freq):
18     mtimes = {}
19    
20     while RUN_RELOADER:
21         sysfiles = []
22         for k, m in sys.modules.items():
23             if re.match(match, k):
24                 if hasattr(m, "__loader__"):
25                     if hasattr(m.__loader__, "archive"):
26                         k = m.__loader__.archive
27                 k = getattr(m, "__file__", None)
28                 sysfiles.append(k)
29        
30         for filename in sysfiles + reloadFiles:
31             if filename and filename not in ignoreFiles:
32                
33                 orig = filename
34                 if filename.endswith(".pyc"):
35                     filename = filename[:-1]
36                
37                 # Get the last-modified time of the source file.
38                 try:
39                     mtime = os.stat(filename).st_mtime
40                 except OSError, e:
41                     if orig.endswith('.pyc') and e[0] == errno.ENOENT:
42                         # This prevents us from endlessly restarting if
43                         # there is an old .pyc lying around after a .py
44                         # file has been deleted. Note that TG's solution
45                         # actually deletes the .pyc, but we just ignore it.
46                         # See http://www.cherrypy.org/ticket/438.
47                         continue
48                     sys.exit(3) # force reload
49                
50                 if filename not in mtimes:
51                     mtimes[filename] = mtime
52                     continue
53                
54                 if mtime > mtimes[filename]:
55                     sys.exit(3) # force reload
56         time.sleep(freq)
57
58 def restart_with_reloader():
59     while True:
60         args = [sys.executable] + sys.argv
61         if sys.platform == "win32":
62             args = ['"%s"' % arg for arg in args]
63         new_environ = os.environ.copy()
64         new_environ["RUN_MAIN"] = 'true'
65         exit_code = os.spawnve(os.P_WAIT, sys.executable, args, new_environ)
66         if exit_code != 3:
67             return exit_code
68
69 def main(main_func, args=None, kwargs=None, freq=1):
70     if os.environ.get("RUN_MAIN") == "true":
71        
72         if args is None:
73             args = ()
74         if kwargs is None:
75             kwargs = {}
76         thread.start_new_thread(main_func, args, kwargs)
77        
78         # If KeyboardInterrupt is raised within reloader_thread,
79         # let it propagate out to the caller.
80         reloader_thread(freq)
81     else:
82         # If KeyboardInterrupt is raised within restart_with_reloader,
83         # let it propagate out to the caller.
84         sys.exit(restart_with_reloader())
Note: See TracBrowser for help on using the browser.

Hosted by WebFaction

Log in as guest/cpguest to create tickets