I'm writing some code to determine the name that an object is assigned to. This is for general debugging work and to further familiarize myself with python internals.
I have it structured as a class decorator so that all instances of that class will have their names recorded if it is possible to do. The code is fairly long so I won't post it unless asked. The general technique is as follows though
decorate the class'
__init__
method with the code to do what I wantset
caller = inspect.currentframe().f_back
and openinspect.getframeinfo(caller).filename
and send it toast.parse
. I don't do any error checking here because (1) this is just for debugging/profiling/hacking (2) this exact process was 'just' completed or the code wouldn't be running. Is there a problem with this?find the
ast.Assignment
instance that causes the currently executing__init__
method to runif
len(assignment.targets) == 1
then there is only one item on the left hand side, and I can get the name out oftargets[0].id
. In a simple form likea = Foo()
, then theassignment.value
is an instance ofast.Call
. if it's a literal (e.g. list), thenvalue
will be that list and bail because the object I'm interested in isn't being assigned to a name.
What is the best way to confirm that assignment.value.func
is in fact type(obj).__call__
of the object that I'm interested in. I'm pretty sure that I'm guaranteed that It's "in there somewhere" or the code wouldn't even be running. I just need for it to be at the top level. The obvious thing to do is walk it and make sure that it doesn't contain any interior calls. Then I'm guaranteed that I have the name. (My reasoning is correct, I'm not sure if its assumptions are). This is not ideal though because if I'm interested in Foo
, this could lead me to toss away a = Foo(Bar())
because I don't know if it's a = Bar(Foo())
.
Of course I can just check assignment.value.func.id
but then somebody could have done Foobar = Foo
or something so I don't want to rely on this too heavily
Any help would be greatly appreciated. As always, I'm interested in any other suggestions or problems that I might be overlooking.
Also, I'm really surprised that I just had to invent the 'python-internals' tag.