pypy / pypy / doc / getting-started-dev.rst

Getting Started with the Translation Toolchain and Development Process

Trying out the translator


To start the interactive translator shell do:

cd pypy
python bin/


>>> t.view()

After that, the graph viewer pops up, that lets you interactively inspect the flow graph. To move around, click on something that you want to inspect. To get help about how to use it, press 'H'. To close it again, press 'Q'.

Trying out the type annotator


>>> t.annotate()
>>> t.view()


Translating the flow graph to C code

The graph can be turned into C code:

>>> t.rtype()
>>> lib = t.compile_c()


>>> from ctypes import CDLL
>>> f = CDLL(lib)
>>> f(5)
>>> f(6)

Translating the flow graph to CLI or JVM code

PyPy also contains a CLI backend and JVM backend which can translate flow graphs into .NET executables or a JVM jar file respectively. Both are able to translate the entire interpreter. You can try out the CLI and JVM backends from the interactive translator shells as follows:

>>> def myfunc(a, b): return a+b
>>> t = Translation(myfunc, [int, int])
>>> t.annotate()
>>> f = t.compile_cli() # or compile_jvm()
>>> f(4, 5)

The object returned by compile_cli or compile_jvm is a wrapper around the real executable: the parameters are passed as command line arguments, and the returned value is read from the standard output.

Once you have compiled the snippet, you can also try to launch the executable directly from the shell. You will find the executable in one of the /tmp/usession-* directories:

# For CLI:
$ mono /tmp/usession-trunk-<username>/main.exe 4 5

# For JVM:
$ java -cp /tmp/usession-trunk-<username>/pypy pypy.Main 4 5

To translate and run for the CLI you must have the SDK installed: Windows users need the .NET Framework SDK, while Linux and Mac users can use Mono. To translate and run for the JVM you must have a JDK installed (at least version 6) and java/javac on your path.

A slightly larger example


cd demo
../rpython/translator/goal/ --view --annotate

This causes to display itself as a call graph and class hierarchy. Clicking on functions shows the flow graph of the particular function. Clicking on a class shows the attributes of its instances. All this information (call graph, local variables' types, attributes of instances) is computed by the annotator.



Translating Full Programs

To translate full RPython programs, there is the script in rpython/translator/goal. Examples for this are a slightly changed version of Pystone:

cd rpython/translator/goal
python targetrpystonedalone

This will produce the executable "targetrpystonedalone-c".


Where to start reading the sources


Running PyPy's unit tests



python -h

This is usually equivalent to using an installed version:

py.test -h



py.test pypy/interpreter/test/

# or for running tests of a whole subdirectory
py.test pypy/interpreter/


Beware trying to run "all" pypy tests by pointing to the root directory or even the top level subdirectory pypy. It takes hours and uses huge amounts of RAM and is not recommended.


py.test lib-python/2.7/test/

This will usually take a long time because this will run the PyPy Python interpreter on top of CPython. On the plus side, it's usually still faster than doing a full translation and running the regression test with the translated PyPy Python interpreter.

Special Introspection Features of the Untranslated Python Interpreter


Interpreter-level console

If you start an untranslated Python interpreter via:

python pypy/bin/


>>>> a = 123
>>>> <Ctrl-C>
*** Entering interpreter-level console ***
>>> w_a


>>> <Ctrl-D>
*** Leaving interpreter-level console ***

>>>> l
[1, 'abc']

Note that the prompt of the interpreter-level console is only '>>>' since it runs on CPython level. If you want to return to PyPy, press <Ctrl-D> (under Linux) or <Ctrl-Z>, <Enter> (under Windows).


Tracing bytecode and operations on objects

You can use the trace object space to monitor the interpretation of bytecodes in connection with object space operations. To enable it, set __pytrace__=1 on the interactive PyPy console:

>>>> __pytrace__ = 1
Tracing enabled
>>>> a = 1 + 2
|- <<<< enter <inline>a = 1 + 2 @ 1 >>>>
|- 0    LOAD_CONST    0 (W_IntObject(1))
|- 3    LOAD_CONST    1 (W_IntObject(2))
|- 6    BINARY_ADD
  |-    add(W_IntObject(1), W_IntObject(2))   -> W_IntObject(3)
|- 7    STORE_NAME    0 (a)
  |-    hash(W_StringObject('a'))   -> W_IntObject(-468864544)
  |-    int_w(W_IntObject(-468864544))   -> -468864544
|-10    LOAD_CONST    2 (<W_NoneObject()>)
|- <<<< leave <inline>a = 1 + 2 @ 1 >>>>


The `demo/`_ directory contains examples of various aspects of PyPy, ranging from running regular Python programs (that we used as compliance goals) over experimental distribution mechanisms to examples translating sufficiently static programs into low level code.

Additional Tools for running (and hacking) PyPy


py.test and the py lib

The py.test testing tool drives all our testing needs.


You don't necessarily need to install these two libraries because we also ship them inlined in the PyPy source tree.

Getting involved

PyPy employs an open development process. You are invited to join our pypy-dev mailing list or look at the other contact possibilities. Usually we give out commit rights fairly liberally, so if you want to do something with PyPy, you can become a committer. We are also doing coding Sprints which are separately announced and often happen around Python conferences such as EuroPython or Pycon. Upcoming events are usually announced on the blog.

Tip: Use camelCasing e.g. ProjME to search for