Open frdfsnlght opened 4 years ago
Strange. The locals
argument in exec()
is supposed to accept a mapping object and as far as I know, DotMap
is one. But maybe I'm wrong about that.
In the meanwhile, a usable, if slightly cumbersome, workaround is
from dotmap import DotMap
code = 'print("hello")'
g = {}
l = DotMap()
exec(code, g, l.toDict())
That's about where I've arrived as well. However, I don't think it will work for my use case. Correct me if I'm wrong, but changes made the dictionary (in the code being exec'ed) that result from l.toDict() won't propagate back to the DotMap? Maybe I could just create a new DotMap from the changed dictionary, but I get worried about all the conversions back and forth taking up "too much time". I don't know what "too much time" means for my situation, but I'm trying to keep the part of the code that needs to do the exec as fast as possible.
You're findings on the requirements of the local parameter to the exec function are also what I found and caused me to scratch my head. Looking at the DotMap code (and since it inherits from dict) it looks like it satisfies the requirements. I don't understand what's going on. Maybe the python source needs to be consulted?
Yes, if you need the code
in the exec
call to update the values in the locals
DotMap
, then the toDict
solution won't work.
Checking the exec
source code is probably the next step, though not one that I personally have the bandwidth to explore.
Well, I just spent some time looking at the python source for exec and following it to the best of my abilities and I'm no closer to understanding what's wrong.
Adding DotMap to my project was just a nice feature to have but unnecessary. I'll probably have to drop it unless I can think of some other clever solution. I have a bunch more development to do anyway.
Thanks.
Just encountered the same problem. Any new insights on this issue ? Thanks a lot.
No new insights. Full disclosure, I support DotMap as much as I can in my spare time using my past experience in Python and general programming and algorithms knowledge. But I don't even use Python for active development anymore, let alone DotMap
specifically. So involved Python-specific debugging like this is way out of scope for my personal attention.
This code
from dotmap import DotMap
#x = {}
x = DotMap()
exec("print(42)", {}, x)
fails with the DotMap with the Error:
TypeError: 'DotMap' object is not callable
Other instructions, like
from dotmap import DotMap
#x = {}
x = DotMap()
exec("a=42", {}, x)
work fine. The problem is the function call to print. In fact, this is true for any other function call, like:
exec("list([])", {}, x)
DotMap seems to try to generate "list" or "print" as an entry to the dictionary.
Edit:
Using DotMap(_dynamic=False)
makes the code work again.
I think this should be fine for my current usecase, maybe it helps others, and maybe it helps to identify where the bug is ?
Here's some sample code:
And it's output (using python 3.7.3 on Raspbian):
Any idea why I can't use a DotMap as the "locals" parameter? Using a standard dictionary works, of course. I can't seem to find any obvious answer, but maybe I'm missing something.