Reloadium – Advanced hot reloading for Python
github.com
github.com
Glad jurigged works for you. Coincidentally, I was working on an update today, and I am going to present jurigged at PyCon this weekend :)
a = 1
b = a + 2
Changing a = 5 will not update b which will still be equal to 3. The same goes to relations between files. Whether it is a flaw or feature it depends on the situation and codebase I guess.
Also it seems like it is not possible to reload currently executing functions (re-entering the function is needed).
If you have a white listed set of pure operations (like the `+` operation), then you can check if the hot-reloaded code has any dependencies which could be re-executed (like the b=a+2 case). You wouldn't want to re-execute code that has a side-effect upon hot reloading imho.
For code that should be executed only once you have to add # reloadium: no_reload (blocks of code can be ignored as well, more details here https://reloadium.io/documentation/decorators)
I wouldn't say either approach is intrinsically better, in either case there are situations where it won't do what you want. I think I prefer mine because it is, in a way, a bit more predictable: if e.g. I add a print statement to some function, then the next time I call it, it will print. I know that it won't reset any global state anywhere or re-run anything expensive, regardless of what else there is in the module. Usually, that's what I want.
The develoop feature (which I am rewriting right now) sort of does the reloading of currently executing functions, in the sense that you can pick one or more focus functions that are run in a loop and aborted/restarted when the source changes. At some point I looked into changing functions during a breakpoint and continuing in the new code, but I couldn't see any way to do it in pure Python, except maybe through some ctypes voodoo.
This process migrates (and transforms) data from one system to another. To do so, it needs to load rarely-changing static data from both the source and the target, and then talks to the source and target to achieve its goals.
This loading of static data took ~30 seconds every time. Because I needed to start from scratch, I couldn't afford to be re-starting all the time, and jurigged was key to this.
The secret was to use jurigged in co-operation with cmd/cmd2 which kept the process running between the dispatch of actions. During this interval, jurigged is able to jump in and reload, avoiding the need to restart and refetch the static data, and enabling me to edit and re-dispatch in a fluid manner.
This approach avoids the mental cost of context-switching and time cost of restarting, leading to a much more flow-like state of mind.
Thank you very much!
(remember of course that Kent Beck taught us all this in Smalltalk and s-unit)
There was some interesting discussion the last (?) time the topic was posted [1] and some links to similar projects.
In general, the limitations seem to prevent me from using techniques such as this as a default.
"Reloadium will rerun current function when changed. Developers get instant feedback whether the code is working or not."
How does it know what parameters to pass? Makes them up at random? Runs the whole file as a script? Does static analysis? Runs test suite?
It basically restarts the current frame.
If you can make it crystal clear when full reloading is needed, so that users can gain an intuition about that, it would help this tool a lot.
You can go a long way without fully reloading though in many cases.
Do you have any suggestions how to describe it better? Is "Edit and continue" more descriptive (I think this is what Microsoft calls it for .net).
Or to put it another way: think about why users would be interested in it, not about how it works or what it does.
would be cool if this somehow let me know before running the python code whether I am passing in the wrong type or not.
very nice work, i dont really understand whats happening underneath the hood but any productivity boost is welcome.
It can cause a beginner considerable (a|be)musement, when a change to an imported module isn't reflected in the output as expected.
From the docs:
"In many cases extension modules are not designed to be initialized more than once, and may fail in arbitrary ways when reloaded."
and
"If a module instantiates instances of a class, reloading the module that defines the class does not affect the method definitions of the instances — they continue to use the old class definition. The same is true for derived classes."