
Embedding PyPy in a C application - thedjinn
http://codelle.com/blog/2016/5/embedding-pypy-in-a-c-application/
======
jamesdutc
There's interesting overlap between tools like `cffi` and `cython`.

This is one of the approaches I am pursuing to polish off something I put
together recently: rapid prototyping of LD_PRELOADs in Python.

I presented an early approach at PyData London last week using LD_AUDIT and
`cython`:
[https://www.youtube.com/watch?v=L3j2qw9XZCc](https://www.youtube.com/watch?v=L3j2qw9XZCc)

It doesn't seem that amazing to be able to write:

    
    
        @preload
        def open(pathname: 'const char*', flags: 'int') -> 'int':
            return __open__(pathname, flags)
    

After all, this is only slightly more convenient syntax than in C. However,
imagine how much functionality you could quickly develop with access to the
Python standard library.

Even using my clumsy `cython` and `LD_AUDIT` approach, I was able to rapidly
develop libraries that interpose file-handling library calls and implement:

    
    
        # `less` is used as an example of a libc programme with no concept of Python, git, &c.
    
        $ COMMIT_HASH=abc123 gitit less test # interact with files as-of some commit in a git repo via pygit (libgit2)
    
        $ runit less test.py # redirect read() so that the contents of the file appears to be the results emitted of having run the file
    
        $ zipit less test.gz # redirect read()/write() to transparently handle gzip files
    

Each one of these took about half an hour to throw together, which is
substantially faster than I could reliably develop them in pure-C (not to
mention how much code I avoid having to write myself by relying on Python's
rich stdlib & ecosystem.)

~~~
bartbes
That was a really interesting talk, thanks for sharing!

------
kensai
"With only a few lines of code we have written a C program that fires up a
PyPy interpreter and runs our Python code as if it was a native C function. Of
course I've only shown you the basics here, but the technology is really
powerful."

So, C speed with Python semantics?

~~~
guipsp
Scripting apis are a possible use too.

~~~
thedjinn
Yes indeed, and using this approach you can also write Python plugins for
other applications if they don't have Python scripting support already.

~~~
noahdesu
In the article, after the pypy plugin.py step that produced the C library, one
could presumably dlopen the library to accomplish a dynamic plugin feature. Is
there a way to invoke pypy to JIT this code to avoid invoking pypy and a
compiler?

~~~
thedjinn
The way I understand it is that on first invocation of a function exported in
the library this function will spin up a regular PyPy interpreter, which does
JIT in exactly the same way as a normal invocation of PyPy would.

------
azag0
I used cffi recently to embed CPython into a fairly rigid Fortran program to
support dynamic scripting. Was a piece of cake.

~~~
mattip
Can you share the code?

------
curiousgal
Noob question, isn't Python already based on C?

~~~
timClicks
The reference Python interpreter is implemented in C, but that doesn't mean
that Python equals C.

Implementing programming language interpreters is a bigger topic than a HN
topic... but in general when things are easier from the programmer's
perspective, then the machine needs to do significantly more work to get
things right.

This is especially true in Python, where 1 + 1 doesn't necessarily mean "add
one to one" because the integer literals (1) and the addition operator (+) can
be overloaded to mean different things. Even at runtime, it's possible to have
the same written code and different semantics.

C's semantics are much closer to how the hardware operates. In order to code
effectively and efficiently in C, you need to understand much more nitty
gritty details about how computers operate.

~~~
azag0
I know what you wanted to say, but you didn't give the best example. "1 + 1 ==
2" will be always true in any Python code since all those symbols are either
operators or literals. I believe you cannot change dynamically how the
interpreter interprets operators (that is, "+" always calls __add__ and
__radd__) or literals.

------
solidsnack9000
Does PyPy embedding get around the GIL?

~~~
BuckRogers
No, but if you embed PyPy-STM[0] you get around the GIL.

[0][http://doc.pypy.org/en/latest/stm.html](http://doc.pypy.org/en/latest/stm.html)

