You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I got some dumb questions when I using argname. I would like to know if the following two cases can be achieved:
First, I defined a class and three variables:
def test(a=None, b=None, c=None):
return argname('b')
x = [[111]]
y = [[222]]
z = [x, y]
The first question is how to know when calling a function that one of the variables is a list.
That is, when I call it like this: test(a=x,b=z,c=y)
I expect the return result of the current function to be '[x,y]'
but the return result of the current function is 'z'
I tried to call test(a=x,b=[x,y],c=y)
but it reports an error.
498 source = argument_sources[farg_name]
499 if isinstance(source, ast.AST):
--> 500 raise ImproperUseError(
501 f"Argument {ast.dump(source)} is not a variable "
502 "or an attribute."
503 )
505 if isinstance(farg_subscript, int) and not isinstance(source, tuple):
506 raise ImproperUseError(
507 f"`{farg_name}` is not a positional argument."
508 )
ImproperUseError: Argument List(elts=[Name(id='x', ctx=Load()), Name(id='y', ctx=Load())], ctx=Load()) is not a variable or an attribute.
The second problem is that using argname and exec at the same time seems to report an error. For example, executing
test_str = 'test(a=x,b=z,c=y)'
exec(test_str)
will report an error:
439 # Only do it when func_node are available
440 if not func_node:
441 # We can do something at bytecode level, when a single positional
442 # argument passed to both functions (argname and the target function)
443 # However, it's hard to ensure that there is only a single positional
444 # arguments passed to the target function, at bytecode level.
--> 445 raise VarnameRetrievingError(
446 "Cannot retrieve the node where the function is called."
447 )
449 func_node = reconstruct_func_node(func_node)
451 if not func:
VarnameRetrievingError: Cannot retrieve the node where the function is called.
Can the above two problems be solved? Thank you for your time
The text was updated successfully, but these errors were encountered:
I have read other issues, it seems to be solved by wrapper.
from varname.helpers import Wrapper
def test(a=None, b=None, c=None):
for i in b:
print(i.name, i.value)
x = Wrapper([[111]])
y = Wrapper([[222]])
z = [x, y]
test(a=x,b=z,c=y) # x [[111]] y[[222]]
and exec can work!
test_str = 'test(a=x,b=z,c=y)'
exec(test_str) # x [[111]] y[[222]]
Remember that argname() gets what directly pass to the function. So test(a=x,b=z,c=y) is supposed to return 'z'. To get [x,y] for test(a=x,b=[x,y],c=y), you need:
exec('test(a=x,b=[x,y],c=y)') won't work because we are not able to retrieve the source/AST at runtime.
The solution you posted later does not use the source/AST when test is called (because you don't call argname inside). If you did mean argname, then test(a=x,b=z,c=y) should return z. Anyway, it is a good solution if it meets your need.
Hi Devs,
I got some dumb questions when I using argname. I would like to know if the following two cases can be achieved:
First, I defined a class and three variables:
The first question is how to know when calling a function that one of the variables is a list.
That is, when I call it like this:
test(a=x,b=z,c=y)
I expect the return result of the current function to be
'[x,y]'
but the return result of the current function is
'z'
I tried to call
test(a=x,b=[x,y],c=y)
but it reports an error.
The second problem is that using argname and exec at the same time seems to report an error. For example, executing
will report an error:
Can the above two problems be solved? Thank you for your time
The text was updated successfully, but these errors were encountered: