Getting started

Here you will learn some basic things you need to know to get started with mypyc.


You need a Python C extension development environment. The way to set this up depends on your operating system.


Install Xcode command line tools:

$ xcode-select --install


You need a C compiler and CPython headers and libraries. The specifics of how to install these varies by distribution. Here are instructions for Ubuntu 18.04, for example:

$ sudo apt install python3-dev


From Build Tools for Visual Studio 2022, install MSVC C++ build tools for your architecture and a Windows SDK. (latest versions recommended)


Mypyc is shipped as part of the mypy distribution. Install mypy like this (you need Python 3.8 or later):

$ python3 -m pip install -U 'mypy[mypyc]'

On some systems you need to use this instead:

$ python -m pip install -U 'mypy[mypyc]'

Example program

Let’s start with a classic micro-benchmark, recursive fibonacci. Save this file as

import time

def fib(n: int) -> int:
    if n <= 1:
        return n
        return fib(n - 2) + fib(n - 1)

t0 = time.time()
print(time.time() - t0)

Note that we gave the fib function a type annotation. Without it, performance won’t be as impressive after compilation.


Mypy documentation is a good introduction if you are new to type annotations or mypy. Mypyc uses mypy to perform type checking and type inference, so some familiarity with mypy is very useful.

Compiling and running

We can run as a regular, interpreted program using CPython:

$ python3

It took about 0.41s to run on my computer.

Run mypyc to compile the program to a binary C extension:

$ mypyc

This will generate a C extension for fib in the current working directory. For example, on a Linux system the generated file may be called

Since C extensions can’t be run as programs, use python3 -c to run the compiled module as a program:

$ python3 -c "import fib"

After compilation, the program is about 10x faster. Nice!


__name__ in would now be "fib", not "__main__".

You can also pass most mypy command line options to mypyc.

Deleting compiled binary

You can manually delete the C extension to get back to an interpreted version (this example works on Linux):

$ rm fib.*.so


You can also use to compile modules using mypyc. Here is an example file:

from setuptools import setup

from import mypycify


We used mypycify(...) to specify which files to compile using mypyc. Your can include additional Python files outside mypycify(...) that won’t be compiled.

Now you can build a wheel (.whl) file for the package:

python3 bdist_wheel

The wheel is created under dist/.

You can also compile the C extensions in-place, in the current directory (similar to using mypyc to compile modules):

python3 build_ext --inplace

You can include most mypy command line options in the list of arguments passed to mypycify(). For example, here we use the --disallow-untyped-defs flag to require that all functions have type annotations:

        '--disallow-untyped-defs',  # Pass a mypy flag

Next steps

You can sometimes get good results by just annotating your code and compiling it. If this isn’t providing meaningful performance gains, if you have trouble getting your code to work under mypyc, or if you want to optimize your code for maximum performance, you should read the rest of the documentation in some detail.

Here are some specific recommendations, or you can just read the documentation in order: