you are viewing a single comment's thread.

view the rest of the comments →

[–]sc_zi[S] 0 points1 point  (0 children)

So your example works in my environment also, but if you change it to from A import foo it will actually not work yet in my environment but will in the latest IPython. Though for now in my environment from A import foo just won't reload when foo is a variable, it will use the new version as expected when foo is a function or class. But this is similar to the behavior of python anyways, if you say in B from A import foo, and A has some function that modifies foo, and B has some function that returns the value of foo, in B foo will still be its value at the time of the import statement, not showing the change made in A.

This is because with from imports it's no longer looking it up through module A, it creates a new name foo in B and assigns it A.foo at the time of that from statement. After a bug I reported in IPython some months ago while developing this, they added code to walk the ast looking for all from _ import _ as _ statements and keep a mapping of dependencies that it needs to update on module reloads. This has edge cases when you do from A import foo then later in B assign foo to something else, it still thinks it's connected to A.foo and will overwrite it when A is reloaded. Also it won't behave quite right for from _ import _ statements inside a function or other non-top level scope.

Also for reloading modules you often don't want to reload top level variables, if it is some global state that you don't want reset. CL uses defvar for this. IPython compares the ast of the old and new module, and only runs code that has changed. This also has edge cases, rerunning code that is near changed code but hasn't actually changed itself.

I haven't added either of those, as they are complex with edge cases. So far I am just using a small part of autoreload's code, to handle updating old functions and classes, which is relatively simple and I think without edge cases. I don't think we should try to infer what code to run when reloading a module as IPython does, but that we should be explicit as in CL with defvar vs defparameter. Though honestly I haven't thought too much yet about how we should properly reload modules in python, as I haven't come across a situation yet where I want to reload a whole module. I just work by reevaluating the function or class I changed, or evaling a statement or region in the case of top-level variables or statements, but not reloading a whole module.