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
user32882
  • 5,094
  • 5
  • 43
  • 82
  • 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? – MisterMiyagi Mar 22 '20 at 08:42
  • 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. – user32882 Mar 22 '20 at 08:43
  • The search term for this is "decompile" - if the function's source code is not available then you must decompile its bytecode. – kaya3 Mar 22 '20 at 08:50
  • Where's `decompile`? I can't find it anywhere?? Could you give an example? – user32882 Mar 22 '20 at 08:52
  • `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? – AKS Mar 22 '20 at 11:58
  • 1
    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? – user32882 Mar 22 '20 at 12:02
  • 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](https://riptutorial.com/python/example/23814/display-the-source-code-of-an-object#undefined) and [python bug](https://bugs.python.org/issue12920) – AKS Mar 22 '20 at 12:58
  • `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? – user32882 Mar 22 '20 at 13:17
  • 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](https://imgur.com/a/l08S9Cj). – AKS Mar 22 '20 at 15:03
  • The interpreter destroys the AST as soon as it uses it to generate the bytecode. Your request, as stated, is impossible. – Davis Herring Mar 22 '20 at 20:07
  • Why not just ask the user to provide a string with the source code, instead of the actual function object? – Karl Knechtel Apr 01 '23 at 05:07

0 Answers0