Inception
Christian Gollwitzer
auriocus at gmx.de
Thu Mar 3 03:09:59 EST 2016
Hi Denis,
Am 03.03.16 um 06:01 schrieb Denis Akhiyarov:
> Is it possible to embed CPython in CPython, e.g. using ctypes, cffi, or cython?
>
since you titled your question with a famous movie title, I take it more
as a "philosophical" question (musing about the CPython world) than an
actual demand. Technically, I think it cannot work with the current
state of CPython. Embedding CPython into another application requires
you to load libpython3.5.so (or similar depending on OS and version) and
to call the functino sfrom within there. When a Python program runs in
the standalone interpreter, then this DLL is already loaded, obviously,
so the question is if the Python C API functions can be called from a
Python script.
Possibly ctypes or cffi can do that for you, but you would end up with
the same interpreter that executes your main script. A DLL is loaded by
the OS only once, which makes it possible to create plugin interfaces
etc. using shared symbols in C.
Now, the CPython interpreter saves its state in global variables.
Therefore only one interpreter can exist in a single process, and this
is also the reason that multithreading is complicated and does not
really work (GIL &c).
How useful could it be to have more than a single interpreter? For
instance, Tcl does it in a different way. All of the interpreter state
is stored within a Tcl_Interp struct which is passed around to every API
function. You can create more than a single interpreter, and that even
works from the script level using the "interp create" command. This is
useful to shield user script evaluation from the main script. Such
interpreters can be made "safe", i.e. to not allow file operations, or
to limit the CPU time for script evaluation, which has its primary use
case in things like web browser plugins or simple servers. A pythonized
version of the API would look like this:
from pyembedding import Interp
i=Interp()
i2=Interp(safe=True)
i.eval('print("Hello world")')
# prints Hello world
i2.eval('print("Hello world")')
# raises a SafeInterpException
# I/O is unsafe and disabled here
def greetme():
print("Hello world")
i2.alias(greet=greetme)
i2.eval('greet')
# calls back to greetme in main interpreter
This mechanism would also allow true multithreading. If you run another
interpreter in the second thread, it will have it's own GIL.
I'm not familiar with the internals of other Python implementation, but
I can imagine that maybe in Jython such an extension could be written.
Christian
More information about the Python-list
mailing list