I'm trying to extract all the "runnable" code given a function in a module. Right now I'm only able to extract the functions in any imported module that are called inside the starting function. However, some modules have "outside" expressions (i.e. some variables defined globally in the module, or functions called in the same level).
With inspect and dis I did the work to extract the functions, but, is there any way of extracting the "non-function" of a module?
If anybody wonders what am I doing, is a packer for python. What I want to achieve is that this tools only packs the required code given a starting function.
Also, if is there something already out there that does what I'm trying to achieve, I'd like to know.
importing a module as a code object
You can use importlib's get_code() method which returns the code object of the module and then you can modify or create a new code object extracting the required parts. exec method can be used for executing code object.
Alternatively, using the built-in compile function, you can directly compile source code into byte code then follow the same procedure as mentioned above.
References:
Modifying python bytecode
assembling-python-module-on-fly-dynamic-import
Related
I need to understand the code base of a relatively big Python library. The code being too convoluted, I thought it would be a good start to know which methods call which other methods when I execute an imported function that I need to use.
Is it possible to do something along the lines of:
from library import function
get_traceback(function)
And get a list of all the functions being called in the background by the library?
I am trying to modify the source code for the eval() function, in my own file, so I need the source code.
I have tried writing eval with an error, but that just says error in . I tried using the inspect function, but that said "TypeError: is a built-in class
".
This is what I did for inspect:
import inspect
print(inspect.getsource(eval))
Can you tell me how to find it, or even just give me a link to github file?
Even though some python functions are written in python, most core functions are actually implemented in C.
Here is the source code for the eval() function.
In Python C API, I already know how to import a module via PyImport_ImportModule, as described in Python Documentation: Importing Modules. I also know that there is a lot of ways to create or allocate or initialize a module and some functions for operating a module, as described in Python Documentation: Module Objects.
But how can I get a function from a module (and call it), or, get a type/class from a module (and instantiate it), or, get an object from a module (and operate on it), or get anything from a module and do anything I want to do?
I think this can be a fool question but I really cannot find any tutorial or documentation. The only way I think that I can achieve this is use PyModule_GetDict to get the __dict__ property of the module and fetch what I want, as described in the latter documentation I mentioned. But the documentation also recommend that one should not use this function to operate the module.
So any "official way" or best practice for getting something from a module?
According to the documentation for PyModule_GetDict:
It is recommended extensions use other PyModule_*() and PyObject_*() functions rather than directly manipulate a module’s __dict__.
The functions you need are generic object functions (PyObject_*) rather than module functions (PyModule_*), and I suspect this is where you were looking in the wrong place.
You want to use PyObject_GetAttr or PyObject_GetAttrString.
I'm wondering, if Python offers something similar to the package keyword in Perl. This keyword in effect creates a labeled namespace just anywhere in the code.
As far as I know, similar namespacing in Python is only possible by putting that code into a file and import it. But what if I have the code in a variable (e.g. read from some configuration file of my script)?
So in other words: Is there a way to eval Python code within an arbitrary namespace? In Perl I would just add
package my_pack;
at the beginning of that code and then eval it (within a namespace called my_pack)
Thanks for any help.
No, Perl's and Python's module systems work very differently. It is not possible to explicitly declare a specific Python module.
For a Python eval() or exec() that should execute the code within the context of a particular module, consider which aspects define this module for your purposes – the important aspect is likely that module's global variables. You can provide these explicitly, and capture the current environment via the globals() function. The environment is just a dict, which you can copy if you want to avoid modifications of the module's environment.
From the c-api, I would like to call a python function by name. I would then be calling the function with a list of python objects as arguments.
It is not clear to me in the Python documentation how I would get a "Callable" object from the main python interpreter.
Any help appreciated in:
Getting the address from the function
Calling the function with my PythonObject's as arguments.
I'm using Python 2.x series for my development.
Basically, you use the Python C API to get the module the function is contained in, then query the module dictionary for the function. That's more or less the same what the Python runtime does internally when your Python code invokes a function from somewhere.
Relevant functions from the API to look at are PyImport_ImportModule, PyModule_GetDict, PyDict_GetItem and the PyObject_CallXXX family of functions.