@@ -46,6 +46,21 @@ def _file_changed(f):
4646def _all_file_changes (filepaths ):
4747 return {path : _file_changed (path ) for path in filepaths }
4848
49+ def _changed_modules (new_changed , last_changed ):
50+ list = []
51+ if last_changed is None :
52+ return list
53+ modules = {}
54+ for module in sys .modules .copy ().values ():
55+ file = getattr (module , '__file__' , None )
56+ if file is not None :
57+ modules [file ] = module
58+ for path in new_changed :
59+ if new_changed [path ] != last_changed [path ]:
60+ module = modules .get (path , None )
61+ if module is not None :
62+ list .append (module )
63+ return list
4964
5065def listfiles (folder , ext = "" ):
5166 fs = list ()
@@ -135,6 +150,13 @@ class ClearTerminal(Runnable):
135150 def run (self ):
136151 os .system ("cls" if os .name == "nt" else "clear" )
137152
153+ class ReloadModules (Runnable ):
154+ def __init__ (self , module ):
155+ self .main_module = module
156+ def run (self , modules ):
157+ for module in modules :
158+ if module != self .main_module :
159+ _reload_module (module )
138160
139161def hotload (watch , steps , waittime_ms = 1.0 / 144 ):
140162 """Hotload that code!"""
@@ -148,18 +170,25 @@ def hotload(watch, steps, waittime_ms=1.0 / 144):
148170 # Take note of when files were last changed before we start reloading
149171 last_changed = None
150172
173+ is_module_reloader = lambda step : type (step ).__name__ == "ReloadModules"
174+ do_reload_modules = bool (list (filter (is_module_reloader , steps )))
175+
151176 # Begin the loop! Each Runner is responsible for handling its own exceptions.
152177 while True :
153178 new_changed = _all_file_changes (watchfiles )
154179 if last_changed == new_changed :
155180 time .sleep (waittime_ms )
156181 else :
157182 reload_begin_ms = time .time () * 1000
183+ changed_modules = _changed_modules (new_changed , last_changed ) if do_reload_modules else []
158184 last_changed = new_changed
159185 try :
160186 for step in steps :
161187 try :
162- step .run ()
188+ if is_module_reloader (step ):
189+ step .run (changed_modules )
190+ else :
191+ step .run ()
163192 except KeyboardInterrupt :
164193 raise
165194 except :
@@ -210,7 +239,7 @@ def main():
210239 print ()
211240 print (" ls *py | hotload hello.py" )
212241
213- watchfiles = [f .strip () for f in sys .stdin .readlines ()]
242+ watchfiles = [os . path . normpath ( os . path . join ( os . getcwd (), f .strip ()) ) for f in sys .stdin .readlines ()]
214243
215244 if not watchfiles :
216245 print ("Error: no watch files specified." )
@@ -227,7 +256,7 @@ def main():
227256
228257 conf = {
229258 "watch" : [watchfiles ],
230- "steps" : [ClearTerminal (), reloaded_module ],
259+ "steps" : [ClearTerminal (), ReloadModules ( reloaded_module . module ), reloaded_module ],
231260 }
232261
233262 hotload (** conf )
@@ -237,3 +266,4 @@ def main():
237266
238267if __name__ == "__main__" :
239268 main ()
269+
0 commit comments