ionelmc/python-lazy-object-proxy

The function is called on assignment if the assignment is done in an interactive shell

KOLANICH opened this issue · 9 comments

When I set the variable created with lazy_object_proxy it triggers the function.

def a():
    print("a")
from lazy_object_proxy import Proxy
b=Proxy(a)
b=None # a

It is not good for some use cases, like lazy importing modules (making importing non-idempotent), and is not good at all, since this is not how python works. It would be nice if you provided a way to disable this behavior.

The investigation had showed that in an interactive shell Proxy_get_class is called multiple times.

Maybe you do a implicit .__str__() call on it (and thus the factory is called) by printing it by accident? Nothing should call a in that example.

I have done some experiments and found out that the function is invoked on the last line only if I paste the code into an interactive shell (either ipython or plain python), if I paste the code into a file, save it and run it by passing its name as a cli argument, everything works as expected.

That's strange.

The investigation had showed that in an interactive shell Proxy_get_class is called multiple times.

So your interactive shell does something with the object that triggers the evaluation?

So your interactive shell

It's not mine interactive shell. As I have said, it works in all vanilla python shell, IPython one and Jupyter notebook. I guess it may be something about python itself. I have no idea why does it do so since the result is not displayed anyhow, just assigned to a variable.

It may be a bug in python.

Or we may want to examine stack in that call, detect this situation and skip the evaluation.

Just do a traceback.print_stack() in the factory and you'll know for sure

traceback.print_stack()

It was the first thing I have done and anything checking the class have not been shown, it seems like it is done in C++.

Ok. So what I propose is that you use one of the pure python implementations (slots or simple) to see exactly what triggers the factory.

I'm sorry, I have mixed 2 separate issues with the similar sympthoms.

1 IPython uses isinstance somehow
2 import machinery (python interpreter itself) uses getattr