2

I want to dynamically inspect the body of a lambda that specialises another lambda at runtime. This would need to happen recursively until there are no more "parent" lambdas.

What I mean by that is the following example:

add_x_z = lambda x, z: x + z
add_x_1 = lambda x: add_x_z(x, 1)

Here add_x_1 is what I refer to as a "specialisation" of add_x_z (the "parent" lambda). The specialisation here is hardcoded (z = 1) but you can imagine cases where the fixed value comes from the runtime.

In this case, I am looking for the following string as an output:

"add_x_1 = lambda x: x + 1"

There are a lot of questions on Stack Overflow about inspecting the body of functions/lambdas, the most widely-accepted solution accross all those Q&As is the following:

add_x_z = lambda x, z: x + z
add_x_1 = lambda x: add_x_z(x, 1)

print(inspect.getsource(add_x_1))
# add_x_1 = lambda x: add_x_z(x, 1)

This doesn't do the trick for me because inspect under the hood only looks at the source files and doesn't care about the runtime. There are also various solutions floating around that suggest using packages such as uncompyle6, this also doesn't solve my issue:

import uncompyle6

add_x_z = lambda x, z: x + z
add_x_1 = lambda x: add_x_z(x, 1)

uncompyle6.deparse_code2str(add_x_1.__code__)
# return add_x_z(x, 1)

Is there any way to achieve this through Python internals and that doesn't involve writing some kind of parser?

Bonus points for an answer that doesn't make use of exec or eval

Rayan Hatout
  • 640
  • 5
  • 22

1 Answers1

1

You might try using a debugger and stopping where you need to and inspect values. Most debuggers have some sort of command that allows you to show some sort of Python expression based on existing values. In trepan and other debuggers you can go into a python shell, and then create your own code based on existing variables and this may be useful for macro expanding lambdas.

And the trepan debugger allows its own kind of scriptable macros so that you can string simple debugger commands together to assist in piecing together macro expansion based on lambda parameters.

The other tool that I can think of that may be of help here might be x-python because (for simpler Python programs) you can step to where you want and then look at evaluation stack entries. There is a "trepan" debugger for that as well, so you can use this in conjunction with writing macros.

Or in x-python you could replace Python's "lambda" so that it also macro expands it and prints in addition to running it.

Note that this might not make use of exec or eval in the answer, unless some sort of debugger print or eval is done. And it feels like, for the kind the code in question, there may be some flavor of this.

In sum though, I have to say that if what you want is something general and complicated like this, you should expect to write some code including a parser or adapt one of the existing tools mentioned here (and not mentioned here).

rocky
  • 7,226
  • 3
  • 33
  • 74