5 ms·
i wrote something similar a while ago, and it gave rise to a pretty head-scratching bug... my code was doing something like if type(x) is Foo: and mysteriou
by uryga 7y ago
i wrote something similar a while ago, and it gave rise to a pretty head-scratching bug... my code was doing something like
if type(x) is Foo:
and mysteriously failed for some data around the reload. turns out that Foo objects from before the reload were using a different class object than Foo objects after the reload (which makes sense in hindsight, as Foo was redefined). fun times debugging that!
- julvo 7y agoThat's a pain to debug. A similar thing happened to me with reload from Python's importlib. In the case of the reloading loop I think this will only happen when redefining the type within the loop, either through a class definition or an importlib reload.
- uryga 7y agoyeah, importlib.reload caused mine as well! i'm wondering if there's a way to avoid that... maybe a @reloadable class decorator that saves a reference to each object you instantiate and switches out their .__class__ upon reload? obv not great for performance, but could be useful during development (which is where i'd mostly use hot reloading anyway)
- orf 7y agoI did a talk on this recently at EuroPython. Hot reloaders are really, really really hard to implement in Python in the general case (I.e not an IPython shell). You run into corner cases like this, and it basically comes down to reloading the whole app anyway.
- znpy 7y agolink plz?
- orf 7y agohttps://youtu.be/IghyoR6ld60 https://youtu.be/IghyoR6ld60 I didn't go into as much detail as I would have liked about hot reloaders, but the tl;dr is that if you have a _single_ reference to something, then hot reloading it is somewhat simple. The problem comes when you want to hot reload a single module inside a large program. Hot reloading a loop like this is super cool, but it only works if you're just changing constants and not defining anything. The moment you want to change the definitions of an object in the loop and hot reload it then you're in a lot of pain. Here's the source code for IPythons autoreload magic command: https://github.com/ipython/ipython/blob/cd54f15544eee69449cc5b3e926665bda5afb9fa/IPython/extensions/autoreload.py https://github.com/ipython/ipython/blob/cd54f15544eee69449cc.... Take note of the Caveats section.
- nerdponx 7y agoWould this still fail if you used the preferred idiom of isinstance(x, Foo)
- uryga 7y agohad to check to make sure isinstance wasn't doing some magic, but yes. the whole issue is that as far as python is concerned, the pre- and post-reload Foo classes aren't related in any way except by name and module, which aren't checked by either of these methods (aside: i know that `isinstance` is the official way, but i just don't like the way it reads – "x is an instance of y" is an infix construct and looks weird in a prefix position. i don't really use inheritance so `type(x) is y` is good enough, and it reads very naturally)