Skip to content

Commit b4606d8

Browse files
committed
Give binary extensions their own section
1 parent f866b7c commit b4606d8

File tree

3 files changed

+238
-191
lines changed

3 files changed

+238
-191
lines changed

source/additional.rst

Lines changed: 1 addition & 191 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ Additional Topics
33
=================
44

55
:Page Status: Incomplete
6-
:Last Reviewed: 2013-12-01
6+
:Last Reviewed: 2013-12-08
77

88

99
.. _`pip vs easy_install`:
@@ -202,196 +202,6 @@ Dependency Resolution
202202
- conflicts with what's already installed
203203

204204

205-
.. _`Binary Extensions`:
206-
207-
Binary Extensions
208-
=================
209-
210-
One of the features of the CPython reference interpreter is that, in
211-
addition to allowing the execution of Python code, it also exposes a rich
212-
C API for use by other software. One of the most common uses of this C API
213-
is to create importable C extensions that allow things which aren't
214-
always easy to achieve in pure Python code.
215-
216-
217-
Use cases for binary extensions
218-
-------------------------------
219-
220-
The typical use cases for binary extensions break down into just three
221-
conventional categories:
222-
223-
* accelerator modules: these modules are completely self-contained, and
224-
are created solely to run faster than the equivalent pure Python code
225-
runs in CPython. Ideally, accelerator modules will always have a pure
226-
Python equivalent to use as a fallback if the accelerated version isn't
227-
available on a given system. The CPython standard library makes extensive
228-
use of accelerator modules.
229-
230-
* wrapper modules: these modules are created to expose existing C interfaces
231-
to Python code. They may either expose the underlying C interface directly,
232-
or else expose a more "Pythonic" API that makes use of Python language
233-
features to make the API easier to use. The CPython standard library makes
234-
extensive use of accelerator modules.
235-
236-
* low level system access: these modules are created to access lower level
237-
features of the CPython runtime, the operating system, or the underlying
238-
hardware. Through platform specific code, extension modules may achieve
239-
things that aren't possible in pure Python code. A number of CPython
240-
standard library modules are written in C in order to access interpreter
241-
internals that aren't exposed at the language level.
242-
243-
One particularly notable feature of C extensions is that, when they don't
244-
need to call back into the interpreter runtime, they can release CPython's
245-
global interpreter lock around long-running operations (regardling of
246-
whether those operations are CPU or IO bound).
247-
248-
Not all extension modules will fit neatly into the above categories. The
249-
extension modules included with NumPy, for example, span all three use cases
250-
- they moves inner loops to C for speed reasons, wrap external libraries
251-
written in C, FORTRAN and other languages, and uses low level system
252-
interfaces for both CPython and the underlying operation system to support
253-
concurrent execution of vectorised operations and to tightly control the
254-
exact memory layout of created objects.
255-
256-
257-
Disadvantages of using binary extensions
258-
----------------------------------------
259-
260-
The main disadvantage of using binary extensions is the fact that it makes
261-
subsequent distribution of the software more difficult. One of the
262-
advantages of using Python is that it is largely cross platform, and the
263-
languages used to write extension modules (typically C or C++, but really
264-
any language that can bind to the CPython C API) typically require that
265-
custom binaries be created for different platforms.
266-
267-
This means that binary extensions:
268-
269-
* require that end users be able to either build them from source, or else
270-
that someone publish pre-built binaries for common platforms
271-
272-
* may not be compatible with different builds of the CPython reference
273-
interpreter
274-
275-
* often will not work correctly with alternative interpreters such as PyPy,
276-
IronPython or Jython
277-
278-
* if handcoded, make maintenance more difficult by requiring that
279-
maintainers be familiar not only with Python, but also with the language
280-
used to create the binary extension, as well as with the details of the
281-
CPython C API.
282-
283-
* if a pure Python fallback implementation is provided, make maintenance
284-
more difficult by requiring that changes be implemented in two places,
285-
and introducing additional complexity in the test suite to ensure both
286-
versions are always executed.
287-
288-
289-
Alternatives to handcoded accelerator modules
290-
---------------------------------------------
291-
292-
When extension modules are just being used to make code run faster (after
293-
profiling has identified the code where the speed increase is worth
294-
additional maintenance effort), a number of other alternatives should
295-
also be considered:
296-
297-
* look for existing optimised alternatives. The CPython standard libary
298-
includes a number of optimised data structures and algorithms (especially
299-
in the builtins and the ``collections`` and ``itertools`` modules). The
300-
Python Package Index also offers additional alternatives. Sometimes, the
301-
appropriate choice of standard library or third party module can avoid the
302-
need to create your own accelerator module.
303-
304-
* for long running applications, the JIT compiled `PyPy interpreter
305-
<http://pypy.org/>`__ may offer a suitable alternative to the standard
306-
CPython runtime. The main barrier to adopting PyPy is typically reliance
307-
on other binary extension modules - while PyPy does emulate the CPython
308-
C API, modules that rely on that cause problems for the PyPy JIT, and the
309-
emulation layer can often expose latent defects in extension modules that
310-
CPython currently tolerates (frequently around reference counting errors -
311-
an object having one live reference instead of two often won't break
312-
anything, but no references instead of one is a major problem).
313-
314-
* `Cython <http://cython.org/>`__ is a mature static compiler that can
315-
compile most Python code to C extension modules. The initial compilation
316-
provides some speed increases (by bypassing the CPython interpreter layer),
317-
and Cython's optional static typing features can offer additional
318-
opportunities for speed increases. Using Cython still has the disadvantage
319-
of increasing the complexity of distributing the resulting application,
320-
but has the benefit of having a reduced barrier to entry for Python
321-
programmers (relative to other languages like C or C++).
322-
323-
* `Numba <http://numba.pydata.org/>`__ is a newer tool, created by members
324-
of the scientific Python community, that aims to leverage LLVM to allow
325-
selective compilation of pieces of a Python application to native
326-
machine code at runtime. It requires that LLVM be available on the
327-
system where the code is running, but can provide significant speed
328-
increases, especially for operations that are amenable to vectorisation.
329-
330-
331-
Alternatives to handcoded wrapper modules
332-
-----------------------------------------
333-
334-
The C ABI (Application Binary Interface) is a common standard for sharing
335-
functionality between multiple applications. One of the strengths of the
336-
CPython C API (Application Programming Interface) is allowing Python users
337-
to tap into that functionality. However, wrapping modules by hand is quite
338-
tedious, so a number of other alternative approaches should be considered.
339-
340-
The approaches described below don't simplify the distribution case at all,
341-
but they *can* significantly reduce the maintenance burden of keeping
342-
wrapper modules up to date.
343-
344-
* In addition to being useful for the creation of accelerator modules,
345-
`Cython <http://cython.org/>`__ is also useful for creating wrapper
346-
modules. It still involves wrapping the interfaces by hand, however, so
347-
may not be a good choice for wrapping large APIs.
348-
349-
* `cffi <cffi.readthedocs.org/>`__ is a project created by some of the PyPy
350-
developers to make it straightforward for developers that already know
351-
both Python and C to expose their C modules to Python applications. It
352-
also makes it relatively straightforward to wrap a C module based on its
353-
header files, even if you don't know C yourself.
354-
355-
One of the key advantages of ``cffi`` is that it is compatible with the
356-
PyPy JIT, allowing CFFI wrapper modules to participate fully in PyPy's
357-
tracing JIT optimisations.
358-
359-
* `SWIG <http://www.swig.org/>`__ is a wrapper interface generator that
360-
allows a variety of programming languages, including Python, to interface
361-
with C *and C++* code.
362-
363-
* The standard library's ``ctypes`` module, while useful for getting access
364-
to C level interfaces when header information isn't available, suffers
365-
from the fact that it operates solely at the C ABI level, and thus has
366-
no automatic consistency checking between the interface actually being
367-
exported by the library and the one declared in the Python code. By
368-
contrast, the above alternatives are all able to operate at the C *API*
369-
level, using C header files to ensure consistency between the interface
370-
exported by the library being wrapped and the one expected by the Python
371-
wrapper module. While ``cffi`` *can* operate directly at the C ABI level,
372-
it suffers from the same interface inconsistency problems as ``ctypes``
373-
when it is used that way.
374-
375-
376-
Alternatives for low level system access
377-
----------------------------------------
378-
379-
For applications that need low level system access (regardless of the
380-
reason), a binary extension module often *is* the best way to go about it.
381-
This is particularly true for low level access to the CPython runtime
382-
itself, since some operations (like releasing the Global Interpreter Lock)
383-
are simply invalid when the interpreter is running code, even if a module
384-
like ``ctypes`` or ``cffi`` is used to obtain access to the relevant C
385-
API interfaces.
386-
387-
For cases where the extension module is manipulating the underlying
388-
operating system or hardware (rather than the CPython runtime), it may
389-
sometimes be better to just write an ordinary C library (or a library in
390-
another systems programming language like C++ or Rust that can export a C
391-
compatible ABI), and then use one of the wrapping techniques described
392-
above to make the interface available as an importable Python module.
393-
394-
395205
.. _`NumPy and the Science Stack`:
396206

397207
Installing Scientific Packages

0 commit comments

Comments
 (0)