Code for a Python function

Dear all, for my current task I have a Python interpreter embedded in a C++ program. There are several ways through which the user can interact with this interpreter, typing code into it, and possibly also def-fining functions. I need to be able to look into all defined functions, find one given its name and (here comes the hard part) read whatever code it currently contains. I looked into the API and there is a PyCodeObject class, but it is subject to change at any time and I do not want to start using code that might just change the next time the user upgrades Python. Is there any documented and portable-across-versions way to read the code into a Python function just given its name?
Thanks for any help you'll be willing to provide on this
Enrico Granata ✆ 408.974.5572 | ✉ egranata@.com

Enrico Granata, 16.07.2011 02:44:
for my current task I have a Python interpreter embedded in a C++ program. There are several ways through which the user can interact with this interpreter, typing code into it, and possibly also def-fining functions. I need to be able to look into all defined functions, find one given its name and (here comes the hard part) read whatever code it currently contains. I looked into the API and there is a PyCodeObject class, but it is subject to change at any time and I do not want to start using code that might just change the next time the user upgrades Python. Is there any documented and portable-across-versions way to read the code into a Python function just given its name?
Hi,
as this question refers to Python's introspection capabilities in general, this isn't the perfect place to ask. The general Python list would be a better place.
That being said, PyCodeObject doesn't actually contain the source code but the compiled byte code. You didn't state what you wanted to do with the code, so this may or may not be what you want. In fact, you didn't state your actual goals at all, so it's not obvious to me that you will really need the source code for what you are trying to achieve.
The code object also contains references to the place the source code originated from (file path and source lines). However, given that you expect users to "type code into the interpreter", instead of loading code from files, this will not allow you to get at the source code when the function originated in the interpreter.
Stefan

On Jul 15, 2011, at 9:54 PM, Stefan Behnel <python_capi@behnel.de> wrote:
Enrico Granata, 16.07.2011 02:44:
for my current task I have a Python interpreter embedded in a C++ program. There are several ways through which the user can interact with this interpreter, typing code into it, and possibly also def-fining functions. I need to be able to look into all defined functions, find one given its name and (here comes the hard part) read whatever code it currently contains. I looked into the API and there is a PyCodeObject class, but it is subject to change at any time and I do not want to start using code that might just change the next time the user upgrades Python. Is there any documented and portable-across-versions way to read the code into a Python function just given its name?
Hi,
as this question refers to Python's introspection capabilities in general, this isn't the perfect place to ask. The general Python list would be a better place.
Sorry for the mistake. I will try and redirect my question to the appropriate place.
That being said, PyCodeObject doesn't actually contain the source code but the compiled byte code. You didn't state what you wanted to do with the code, so this may or may not be what you want. In fact, you didn't state your actual goals at all, so it's not obvious to me that you will really need the source code for what you are trying to achieve.
Having the source code into a char* or std::string ready for display is good enough for my usage scenario. I cannot really delve into the details unfortunately.
The code object also contains references to the place the source code originated from (file path and source lines). However, given that you expect users to "type code into the interpreter", instead of loading code from files, this will not allow you to get at the source code when the function originated in the interpreter.
Stefan
Thanks, Enrico

Hi Enrico, Officially, I think what you want to do isn't really supported by python.
- What if the python function is loaded from a pyc with no source code?
- What if the function is defined in a string which is executed but does not correspond to a valid __file__ you can open and inspect.
In practice you can probably manage it if make a few assumptions.
You can access these attributes (or their C values directly): myfunc.__code__.co_filename myfunc.__code__.co_firstlineno
Personally I'd not worry about the PyCodeObject changing (though without more details on what you do its hard to say).
Or you could import the 'inspect' module via the C api and call its getsource() function, however 'inspect' just makes a guess too and isn't guaranteed to give the correct result, this at least gets around changes in PyCodeObject but assumes a full python installation.
participants (3)
-
Campbell Barton
-
Enrico Granata
-
Stefan Behnel