Newer
Older
<!DOCTYPE html>
<html>
<head>
<title>PyPy - Python compatibility</title>
<meta http-equiv="content-language" content="en" />
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<meta name="author" content="PyPy Team" />
<meta name="description" content="PyPy" />
<meta name="copyright" content="MIT" />
<meta name="document-rating" content="general" />
<link rel="stylesheet" type="text/css" media="screen" title="default" href="css/site.css" />
<link rel="alternate" type="application/rss+xml" title="RSS Feed for PyPy" href="http://feeds.feedburner.com/PyPyStatusBlog" />
<link rel="stylesheet" type="text/css" href="css/jquery-ui-1.8.14.custom.css" />
<script type="text/javascript" src="https://use.typekit.com/hdt8sni.js"></script>
<script type="text/javascript">try{Typekit.load();}catch(e){}</script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type="text/javascript" src="js/jquery-ui-1.8.14.custom.min.js"></script>
<script type="text/javascript" src="js/script2.js?bust=1"></script>
</head>
<body>
<script type="text/javascript">
var _gaq = [['_setAccount', 'UA-7778406-3'], ['_trackPageview']];
if (document.location.protocol !== 'file:') {
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(ga);
})();
}
</script>
<div id="body-outer"><div id="body-inner"><div id="body" class="clearfix">
<div id="header">
<div id="menu-follow">
<div><a href="https://bitbucket.org/pypy/pypy"><img src="https://www.selenic.com/hg-logo/logo-droplets-25.png" width="14px" height="14px" /></a></div>
<div><a href="http://feeds.feedburner.com/PyPyStatusBlog" title="Subscribe to the RSS Feed"><img src="https://feedburner.google.com/fb/lib/images/icons/feed-icon-12x12-orange.gif" alt="Subscribe to the RSS Feed" width="14px" height="14px" /></a></div>
<div id="logo"><a href="http://pypy.org"><img src="image/pypy-logo.png" alt="PyPy" height="110px" /></a></div>
<hr class="clear-left" />
<div id="menu-sub">
<a href="index.html">Home</a>
<span class="menu-sub-sep"> | </span>
<a href="features.html">What is PyPy?</a>
<span class="menu-sub-sep"> | </span>
<a href="download.html">Download</a>
<span class="menu-sub-sep"> | </span>
<a href="compat.html">Compatibility</a>
<span class="menu-sub-sep"> | </span>
<a href="performance.html">Performance</a>
<span class="menu-sub-sep"> | </span>
<a href="http://doc.pypy.org">Dev Documentation</a>
<span class="menu-sub-sep"> | </span>
<a href="http://morepypy.blogspot.com">Blog</a>
<span class="menu-sub-sep"> | </span>
<a href="people.html">People</a>
<span class="menu-sub-sep"> | </span>
<a href="contact.html">Contact</a>
<br />
</div>
<hr class="clear" />
</div>
<div id="content">
<div>
<div id="main">
<h1 class="title">Python compatibility</h1>
<p>PyPy implements the Python language version 2.7.13. It supports all of the core
language, passing Python test suite (with minor modifications that were
already accepted in the main python in newer versions). It supports most
of the commonly used Python <a class="reference external" href="http://docs.python.org/library/">standard library modules</a>; details below.</p>
<p>PyPy3 implements the Python language version 3.5.3. It has been released,
but Python is a large language and it is quite possible that a few things are missing.</p>
<p class="download-menu"><a class="reference external" href="http://packages.pypy.org">List of installable top 1000 PyPI packages</a></p>
<p>PyPy has support for the <a class="reference external" href="http://docs.python.org/c-api/">CPython C API</a>, however there are constructs
that are <cite>not compatible</cite>. We strongly advise use of <a class="reference external" href="http://cffi.readthedocs.org/">CFFI</a>
a bit of effort to work, but there are known success stories. Check out
PyPy blog for updates, as well as the <a class="reference external" href="https://bitbucket.org/pypy/compatibility/wiki/Home">Compatibility Wiki</a>.</p>
<p>C extensions need to be recompiled for PyPy in order to work. Depending on
your build system, it might work out of the box or will be slightly harder.</p>
<p>Standard library modules supported by PyPy. Note that large parts of python
library are implemented in pure python, so they don't have to be listed
there. Please just check if it imports. If it imports, it should work.</p>
<ul class="simple">
<li><tt class="docutils literal">__builtin__, __pypy__, _ast, _cffi_backend, _codecs, _collections, _continuation, _csv, _file, _hashlib, _io, _locale, _lsprof, _md5, _minimal_curses, _multibytecodec, _multiprocessing, _numpypy, _pickle_support, _pypyjson, _random, _rawffi, _sha, _socket, _sre, _ssl, _struct, _testing, _warnings, _weakref, array, binascii, bz2, cStringIO, cmath, cppyy, cpyext, crypt, errno, exceptions, fcntl, gc, imp, itertools, marshal, math, mmap, operator, parser, posix, pwd, pyexpat, pypyjit, select, signal, symbol, sys, termios, thread, time, token, unicodedata, zipimport, zlib</tt></li>
<ul class="simple">
<li><tt class="docutils literal">cPickle, ctypes, datetime, dbm, _functools, grp, readline, resource, sqlite3, syslog</tt></li>
</ul>
<p>All modules that are pure python in CPython of course work.</p>
<p>Python libraries known to work under PyPy (the list is not exhaustive).
A <a class="reference external" href="http://packages.pypy.org">fuller list</a> is available.</p>
<ul class="simple">
<li>ctypes</li>
<li>django</li>
<li>sqlalchemy</li>
<li>flask</li>
<li>pylons</li>
<li>divmod's nevow</li>
<li>pyglet</li>
<li>Pillow (the PIL fork)</li>
<li><a class="reference external" href="https://github.com/amauryfa/lxml/tree/cffi/">lxml</a></li>
<li>NumPy</li>
<p>The main difference that is not going to be fixed is that PyPy does
not support refcounting semantics. The following code won't fill the
file immediately, but only after a certain period of time, when the GC
does a collection:</p>
<div class="syntax python"><pre><span></span><span class="nb">open</span><span class="p">(</span><span class="s2">"filename"</span><span class="p">,</span> <span class="s2">"w"</span><span class="p">)</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s2">"stuff"</span><span class="p">)</span><br/></pre></div>
<div class="syntax python"><pre><span></span><span class="n">f</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="s2">"filename"</span><span class="p">,</span> <span class="s2">"w"</span><span class="p">)</span><br/><span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s2">"stuff"</span><span class="p">)</span><br/><span class="n">f</span><span class="o">.</span><span class="n">close</span><span class="p">()</span><br/></pre></div>
<p>or using the <tt class="docutils literal">with</tt> keyword</p>
<div class="syntax python"><pre><span></span><span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="s2">"filename"</span><span class="p">,</span> <span class="s2">"w"</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span><br/> <span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s2">"stuff"</span><span class="p">)</span><br/></pre></div>
<p>The same problem–not closing your files–can also show up if your
program opens a large number of files without closing them explicitly.
In that case, you can easily hit the system limit on the number of file
descriptors that are allowed to be opened at the same time.</p>
<p>Since release 5.4, PyPy can be run with the command-line option <tt class="docutils literal"><span class="pre">-X</span>
<span class="pre">track-resources</span></tt> (as in, <tt class="docutils literal">pypy <span class="pre">-X</span> <span class="pre">track-resources</span> myprogram.py</tt>).
This produces a ResourceWarning when the GC closes a non-closed file or
socket. The traceback for the place where the file or socket was
allocated is given as well, which aids finding places where <tt class="docutils literal">close()</tt>
is missing.</p>
<p>Similarly, remember that you must <tt class="docutils literal">close()</tt> a non-exhausted
generator in order to have its pending <tt class="docutils literal">finally</tt> or <tt class="docutils literal">with</tt>
clauses executed immediately:</p>
<div class="syntax python"><pre><span></span><span class="k">def</span> <span class="nf">mygen</span><span class="p">():</span><br/> <span class="k">with</span> <span class="n">foo</span><span class="p">:</span><br/> <span class="k">yield</span> <span class="mi">42</span><br/><br/><span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">mygen</span><span class="p">():</span><br/> <span class="k">if</span> <span class="n">x</span> <span class="o">==</span> <span class="mi">42</span><span class="p">:</span><br/> <span class="k">break</span> <span class="c1"># foo.__exit__ is not run immediately!</span><br/><br/><span class="c1"># fixed version:</span><br/><span class="n">gen</span> <span class="o">=</span> <span class="n">mygen</span><span class="p">()</span><br/><span class="k">try</span><span class="p">:</span><br/> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">gen</span><span class="p">:</span><br/> <span class="k">if</span> <span class="n">x</span> <span class="o">==</span> <span class="mi">42</span><span class="p">:</span><br/> <span class="k">break</span><br/><span class="k">finally</span><span class="p">:</span><br/> <span class="n">gen</span><span class="o">.</span><span class="n">close</span><span class="p">()</span><br/></pre></div>
<p>More generally, <tt class="docutils literal">__del__()</tt> methods are not executed as predictively
as on CPython: they run “some time later” in PyPy (or not at all if
the program finishes running in the meantime). See <a class="reference external" href="http://pypy.readthedocs.org/en/latest/cpython_differences.html#differences-related-to-garbage-collection-strategies">more details
here</a>.</p>
<p>Note that PyPy returns unused memory to the operating system if there
is a madvise() system call (at least Linux, OS X, BSD) or on Windows. It is
important to realize that you may not see this in <tt class="docutils literal">top</tt>. The unused
pages are marked with <tt class="docutils literal">MADV_FREE</tt>, which tells the system “if you
need more memory at some point, grab this page”. As long as memory is
plentiful, the <tt class="docutils literal">RES</tt> column in <tt class="docutils literal">top</tt> might remains high. (Exceptions to
this rule are systems with no <tt class="docutils literal">MADV_FREE</tt>, where we use
<tt class="docutils literal">MADV_DONTNEED</tt>, which forcefully lowers the <tt class="docutils literal">RES</tt>. This includes
Linux <= 4.4.)</p>
<p>A more complete list of known differences is available at <a class="reference external" href="http://pypy.readthedocs.org/en/latest/cpython_differences.html">our dev site</a>.</p>
</div>
<div id="sidebar">
</div>
</div>
</div>
</div></div></div>
</body>