akssria day ago
This doesn't work the moment the module you're importing something imports something else that you've changed.
Worse, you can't redine methods, because the classes get "redefined". This means that you need to first redefine classes, then "reload" (hoping it doesn't break for to silly implementation limitations mentioned above), then initialize objects, then retest.
Obviously this is quite painful which is why I use this decorator to mimic Lisp's defmethod to patch methods on "live" objects without class redefinition,
https://gist.github.com/akssri/431f2dfe037bbdbb3c8668872edfd...
aidenn0a day ago
That's a really neat decorator.
smackea day ago
Pickling + unpickling the object is a neat trick to update objects to point to the new methods, but it's even more straightforward to just patch `obj.__class__ = reloaded_module.NewClass`. This is what ipython's autoreload extension used to do (and still does in some circumstances, along with other tricks to patch up old references), though nowadays it's had some improvements over this approach: https://github.com/ipython/ipython/pull/14500
apwheeleop21 hours ago
Oh nice, thank you for that tip. I was doing the opposite, `new_obj = mod.Class(...)` and then assigning the dicts from the old object (which was when I realized the pickle save/load was easier).
westurner16 hours ago
Pytest has a number of tools for monkeypatching in tests; rpytest.monkeypatch.setattr, setitem: https://docs.pytest.org/en/stable/how-to/monkeypatch.html
Pickles aren't signed and pickle is basically eval().
kissgyorgya day ago
What I did recently when developing a TUI was that I put the state in a dict, start the app in an infinite loop and whenever it quit, reload module, keep the state and instantiate the class with that state again. Something like this:
import tui
state = {"current_step_index": 0, "variables": None}
while True:
app = tui.App(state)
tui.run()
state = app.get_state()
importlib.reload(tui)