get ast from python object in interpreter
Asked Answered
G

0

2

I am building an application for which I would like a naive user to define a simple function. I would then like to take this function and convert it into an abstract syntax tree. This should also work during an interactive session (i.e using the interpreter). Here's what I have tried so far in the interpreter:

  • dill.source.getsource method
  • inspect.getsourcemethod
  • accessing the function object's __code__ attribute

The first two methods are problematic since they need for the function object to be written in a physical file somewhere in the system. The third one only gave me a byte code version of the code, not useable in ast.parse method.

I am also open to converting a python object directly to abstract syntax but this seems to go against how ast's are supposed to work.

I really need to be able to get an ast from my python object in a regular (not ipython) interpreter. How can I do this?

EDIT

Heres how my "naive user" would interact with my custom library through the interpreter:

>>> import MyLib
>>> def f(x): return x**2
>>> f = MyLib.FunctionAST(f) #FunctionAST will handld the conversion to abstract syntax
Godless answered 22/3, 2020 at 8:37 Comment(11)
Do users give you a function object or source code? If it's the former, how do they do this without you being able to access the source?Cromorne
users write out the function and instantiate a class I am creating by passing in the function object. Please see edit to original question for an example.Godless
The search term for this is "decompile" - if the function's source code is not available then you must decompile its bytecode.Spire
Where's decompile? I can't find it anywhere?? Could you give an example?Godless
ast.dump(ast.parse(inspect.getsource(f))) does work when using ipython. It doesn't work in normal python shell because linecache.cache is empty there. If you expect the user to interact in a shell, doesn't it make more sense to use an interactive one?Nodal
I'd like to make this as flexible as possible... I prefer not to force the user to use any particular shell, but have this work in any python shell. Is there a clean way to force use of ipython?Godless
I tried dill.source.getsource in a python shell, and it works as expected: ast.dump(ast.parse(dill.source.getsource(f))). Apparently, inspect.getsource doesn't work for objects which are defined interactively. Reference and python bugNodal
dill.source.getsource does not work for me and returns OSError: could not extract source code. Are you sure you're not using ipython? What version of dill are you using?Godless
I am using python 3.6.8 and dill==0.3.1.1. And, yes I am sure that I am in python shell because I tested it again. Check here.Nodal
The interpreter destroys the AST as soon as it uses it to generate the bytecode. Your request, as stated, is impossible.Lombardy
Why not just ask the user to provide a string with the source code, instead of the actual function object?Boneblack

© 2022 - 2024 — McMap. All rights reserved.