Is there a way to get the argname with exec or eval
vishalvora opened this issue · 4 comments
vishalvora commented
from varname import argname
class elements:
def __init__(self):
self.app = []
def sidebar(self):
c = elements()
self.app.append(c)
return c
def button(self, name):
self.app.append({"type":"button", "name":argname("name")})
ds = elements()
exec("ds.button('test button')")
Error:
\Lib\site-packages\varname\core.py", line 451, in argname
raise VarnameRetrievingError(
varname.utils.VarnameRetrievingError: Cannot retrieve the node where the function is called.
pwwang commented
Source code is not available at runtime so the node cannot be retrieved.
See: https://github.com/pwwang/python-varname#reliability-and-limitations
and https://stackoverflow.com/a/59364138/5088165
You can trick exec
to provide source code at runtime:
In [1]: from varname import argname
...:
...: class elements:
...:
...: def __init__(self):
...: self.app = []
...:
...: def sidebar(self):
...: c = elements()
...: self.app.append(c)
...: return c
...:
...: def button(self, name):
...: self.app.append({"type":"button", "name":argname("name")})
...:
...:
...: ds = elements()
...:
...: from pathlib import Path
...: code = "ds.button('test button')"
...: sourcefile = "/tmp/mycode.py"
...: Path(sourcefile).write_text(code)
...: compiled = compile(code, sourcefile, mode="exec")
...: exec(compiled)
In [2]: ds.app
Out[2]: [{'type': 'button', 'name': "'test button'"}]
vishalvora commented
It worked! Thank you so much.
pwwang commented
Now with v0.12.2
, you can use exec_code()
instead of exec()
, so that source code is visible at runtime to varname.
In [1]: from varname import argname
...: from varname.helpers import exec_code
...:
...: class elements:
...: def __init__(self):
...: self.app = []
...: def sidebar(self):
...: c = elements()
...: self.app.append(c)
...: return c
...: def button(self, name):
...: self.app.append({"type":"button", "name":argname("name", func=self.button)})
...:
...: ds = elements()
...:
...: code = "ds.button('test button')"
...: exec_code(code)
...: ds.app
Out[1]: [{'type': 'button', 'name': "'test button'"}]
vishalvora commented
This is really great 👍