3 ms·
And the reason Jurigged breaks on changes to toplevel is it's re-running the top level in its own thread... including the infinite loop that is your application
by adinisom 6y ago
And the reason Jurigged breaks on changes to toplevel is it's re-running the top level in its own thread... including the infinite loop that is your application.
This makes sense: it has to re-run the module's code. As long as you don't touch the module that kicks off your application it'll work fine. How can we make it work in the same module that runs the app?
One approach that seems to work is to use the: if __name__ == "__main__" guard on your app code, then modify Jurigged to change __name__ to something else upon reloading. I'm not familiar enough with Python internals to tell if changing __name__ is kosher.
Another possibility is to examine the stack and stop executing code when reaching the root of the current stack... although there's no guarantee the code has been running long enough to reach the program's infinite loop such as when the file was modified a split second after the program started.
- breuleux 6y agoI mean, if you watch the example gif in the README, it shows the toplevel module being changed (you can see the if __name__ guard on the screen). It should work. Basically, Jurigged only re-runs the diff: if you don't change the `if __name__ ...`, it shouldn't run it again. If you change a function in the toplevel module (outside of the guard) it should figure that out by comparing the old AST to the new one and only re-execute that specific function. Can I see the code you're using for your tests? There might be some other issue.
- adinisom 6y agoHere's the test code: https://pastebin.com/Ye8qecgW https://pastebin.com/Ye8qecgW The original issue I had is that under Windows sometimes Watchdog picks up the entire file as being Deleted/Added. Seems to be a race condition of some sort because adding "print" statements after picking up a change makes that less likely. That causes the part guarded by __name__=="__main__" to be re-run under the Jurigged thread: https://pastebin.com/p68NBxmE https://pastebin.com/p68NBxmE Or to get the same results without the Watchdog issue I can change time.sleep(1) to some other number. It makes sense that if you change the program top-level Jurigged will try to re-run it but at the same time it never makes sense to re-run infinite loops. I've tested changing __name__ when re-running and that works although requires a guard and I also think it might be helpful not to re-run module code that is already running as determined by the thread's call stack. --- (edited since can't reply) --- Good call on de-bouncing. I tested with both "notepad" and "notepad++" and get the same behavior. The Delete/Run happens within a millisecond so 0.1s filtering should work. Perhaps that would also allow you to monitor for file Delete/Add to work with editors that use atomic replacement. With that fixed, avoiding re-executing the main loop isn't as important but I think it's worth doing for robustness. Detecting this also gives you the option of restarting the process instead.
- breuleux 6y agoOh, I see. Jurigged doesn't watch for add/delete of files, just modifications (which means it'll miss changes from certain editors like vi that use a move instead of modifying an existing file). I think the write's not atomic so the file's flashing empty. It might depend on the editor? Either way it's a problem. What's the time gap between the deletes and adds? I think debouncing the event so it only executes after e.g. 0.1s with no changes might fix it. I suppose I could also just flat out ignore empty files but that wouldn't be as robust.
- breuleux 6y agoI made an issue to track this so I don't forget and where it can be discussed further if needed: https://github.com/breuleux/jurigged/issues/2 https://github.com/breuleux/jurigged/issues/2 Explicitly detecting changes to if __name__ == "__main__" is a good idea as well, I think. It's an easy pitfall and I can't really think of any situation where it would work, so I might as well warn the user. Thanks for the useful feedback :D