File: getting_started.rst

package info (click to toggle)
mypy 1.19.1-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 22,412 kB
  • sloc: python: 114,754; ansic: 13,343; cpp: 11,380; makefile: 257; sh: 28
file content (240 lines) | stat: -rw-r--r-- 6,740 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
Getting started
===============

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

Prerequisites
-------------

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

macOS
*****

Install Xcode command line tools:

.. code-block::

    $ xcode-select --install

Linux
*****

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:

.. code-block::

    $ sudo apt install python3-dev

Windows
*******

From `Build Tools for Visual Studio 2022 <https://www.visualstudio.com/downloads/#build-tools-for-visual-studio-2022>`_, install MSVC C++ build tools for your architecture and a Windows SDK. (latest versions recommended)

Installation
------------

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

.. code-block::

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

On some systems you need to use this instead:

.. code-block::

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

Example program
---------------

Let's start with a classic micro-benchmark, recursive fibonacci. Save
this file as ``fib.py``:

.. code-block:: python

   import time

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

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

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

.. note::

   `Mypy documentation
   <https://mypy.readthedocs.io/en/stable/index.html>`_ 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 ``fib.py`` as a regular, interpreted program using CPython:

.. code-block:: console

    $ python3 fib.py
    0.4125328063964844

It took about 0.41s to run on my computer.

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

.. code-block:: console

    $ mypyc fib.py

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 ``fib.cpython-37m-x86_64-linux-gnu.so``.

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

.. code-block:: console

    $ python3 -c "import fib"
    0.04097270965576172

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

.. note::

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

You can also pass most
`mypy command line options <https://mypy.readthedocs.io/en/stable/command_line.html>`_
to ``mypyc``.

Deleting compiled binary
------------------------

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

.. code-block::

    $ rm fib.*.so

Using setup.py
--------------

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

    from setuptools import setup

    from mypyc.build import mypycify

    setup(
        name='mylib',
        packages=['mylib'],
        ext_modules=mypycify([
            'mylib/__init__.py',
            'mylib/mod.py',
        ]),
    )

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

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

    python3 setup.py 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 setup.py build_ext --inplace

You can include most `mypy command line options
<https://mypy.readthedocs.io/en/stable/command_line.html>`_ 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::

    ...
    setup(
        name='frobnicate',
        packages=['frobnicate'],
        ext_modules=mypycify([
            '--disallow-untyped-defs',  # Pass a mypy flag
            'frobnicate.py',
        ]),
    )

.. note:

   You may be tempted to use `--check-untyped-defs
   <https://mypy.readthedocs.io/en/stable/command_line.html#cmdoption-mypy-check-untyped-defs>`_
   to type check functions without type annotations. Note that this
   may reduce performance, due to many transitions between type-checked and unchecked
   code.

Recommended workflow
--------------------

A simple way to use mypyc is to always compile your code after any
code changes, but this can get tedious, especially if you have a lot
of code. Instead, you can do most development in interpreted mode.
This development workflow has worked smoothly for developing mypy and
mypyc (often we forget that we aren't working on a vanilla Python
project):

1. During development, use interpreted mode. This gives you a fast
   edit-run cycle.

2. Use type annotations liberally and use mypy to type check your code
   during development. Mypy and tests can find most errors that would
   break your compiled code, if you have good type annotation
   coverage. (Running mypy is pretty quick.)

3. After you've implemented a feature or a fix, compile your project
   and run tests again, now in compiled mode. Usually nothing will
   break here, assuming your type annotation coverage is good. This
   can happen locally or in a Continuous Integration (CI) job. If you
   have CI, compiling locally may be rarely needed.

4. Release or deploy a compiled version. Optionally, include a
   fallback interpreted version for platforms that mypyc doesn't
   support.

This mypyc workflow only involves minor tweaks to a typical Python
workflow. Most of development, testing and debugging happens in
interpreted mode. Incremental mypy runs, especially when using the
mypy daemon, are very quick (often a few hundred milliseconds).

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:

* :ref:`using-type-annotations`
* :ref:`native-classes`
* :ref:`differences-from-python`
* :ref:`performance-tips`