Package wtf :: Module autoreload
[hide private]
[frames] | no frames]

Source Code for Module wtf.autoreload

  1  # -*- coding: ascii -*- 
  2  # 
  3  # Copyright 2007-2012 
  4  # Andr\xe9 Malo or his licensors, as applicable 
  5  # 
  6  # Licensed under the Apache License, Version 2.0 (the "License"); 
  7  # you may not use this file except in compliance with the License. 
  8  # You may obtain a copy of the License at 
  9  # 
 10  #     http://www.apache.org/licenses/LICENSE-2.0 
 11  # 
 12  # Unless required by applicable law or agreed to in writing, software 
 13  # distributed under the License is distributed on an "AS IS" BASIS, 
 14  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
 15  # See the License for the specific language governing permissions and 
 16  # limitations under the License. 
 17  """ 
 18  Autoreload of python code 
 19  ========================= 
 20   
 21  This module provides logic to implemented the autoreload mechanism. This is 
 22  implemented by forking early, remembering the module's mtimes and dealing 
 23  with changed mtimes by going back right before the fork point. 
 24  """ 
 25  __author__ = u"Andr\xe9 Malo" 
 26  __docformat__ = "restructuredtext en" 
 27   
 28  import os as _os 
 29  import sys as _sys 
 30  import time as _time 
 31   
 32   
33 -class ReloadRequested(SystemExit):
34 """ 35 Reload requested exception 36 37 :CVariables: 38 - `CODE`: Exit code for the child process 39 40 :Types: 41 - `CODE`: ``int`` 42 """ 43 CODE = 9 44
45 - def __init__(self):
46 """ Initialization """ 47 SystemExit.__init__(self, self.CODE)
48 49
50 -class Autoreload(object):
51 """ Autoreload logic container """ 52 _check_mtime, _before = None, None 53
54 - def __init__(self, config, opts, args):
55 """ 56 Initialization 57 58 :Parameters: 59 - `config`: Configuration 60 - `opts`: Command line options 61 - `args`: Positioned command line arguments 62 63 :Types: 64 - `config`: `wtf.config.Config` 65 - `opts`: ``optparse.OptionContainer`` 66 - `args`: ``list`` 67 """ 68 autoreload = config.wtf('autoreload', False) 69 if autoreload: 70 self._check_mtime = _time.time() 71 self._before = set(_sys.modules.iterkeys()) 72 self.check = self._check 73 else: 74 self.check = lambda: ()
75
76 - def _check(self):
77 """ 78 Check the need of reloading in case autoreload has been turned on 79 80 This method takes a snapshot of the current sys.modules, mtimes 81 are compared with an older snapshot and on differences true is 82 returned. False otherwise. 83 84 :return: Names of the changed modules (empty if nothing's changed) 85 :rtype: ``iterable`` 86 """ 87 check_mtime, changed = _time.time(), [] 88 for name, mod in _sys.modules.items(): 89 if mod is None or name in self._before: 90 continue 91 mtime = self._mtime(mod) 92 if mtime is None: 93 continue 94 if mtime > self._check_mtime: 95 changed.append(name) 96 self._check_mtime = check_mtime 97 return changed
98
99 - def _mtime(self, mod):
100 """ 101 Determine the mtime of a module 102 103 :Parameters: 104 - `mod`: The module to inspect 105 106 :Types: 107 - `mod`: ``module`` 108 109 :return: The mtime or ``None`` if it couldn't be determined (``float`` 110 or ``int``, depending on the ``os.stat_float_times`` setting) 111 :rtype: number 112 """ 113 filename = getattr(mod, '__file__', None) 114 if filename is not None: 115 try: 116 if filename.endswith('.pyo') or filename.endswith('.pyc'): 117 newname = filename[:-1] 118 return _os.stat(newname).st_mtime 119 raise OSError() 120 except OSError: 121 try: 122 return _os.stat(filename).st_mtime 123 except OSError: 124 pass 125 return None
126