Registry / serialization / cffi

cffi

JSON →
library2.0.0pypypi✓ verified 35d ago

CFFI (C Foreign Function Interface) lets Python code call C libraries by declaring C-like function signatures and types that can often be copy-pasted directly from header files. It supports four modes: ABI/API level each with inline or out-of-line (pre-compiled) preparation. The current stable release is 2.0.0 (released September 2025), requiring Python >=3.9. It is the recommended way to interface with C on PyPy and is used as a foundation by cryptography, bcrypt, and many other major Python packages.

serialization
Install & Compatibility
Where this runs
tested against v2.0.0 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
py 3.103.925 runs
installs and imports cleanly · install 0.0s · import 0.008s · 19.2MB
glibc
py 3.103.925 runs
installs and imports cleanly · install 1.8s · import 0.002s · 20MB
18MB installed
● package 18MB
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

Both forms work, but 'from cffi import FFI' is the canonical pattern used throughout the official docs. Using cffi.FFI() directly after a bare import is verbose but not broken.

from cffi import FFI

In out-of-line API mode the compiled extension exports its own 'ffi' (CompiledFFI) and 'lib' objects; do not re-instantiate FFI() at runtime.

from _my_compiled_module import ffi, lib

Inline ABI mode: declare a C function signature and call it via dlopen. No C compiler needed, but prefer out-of-line API mode for production.

from cffi import FFI ffi = FFI() # Declare the C function signature (copy-paste from man page / header) ffi.cdef(""" size_t strlen(const char *s); """) # ABI mode: open the C standard library C = ffi.dlopen(None) # None = current process / libc on POSIX # On Windows use ffi.dlopen('msvcrt') instead # char* arguments must be bytes, not str result = C.strlen(b"hello, cffi") print(result) # 11 # Allocate a C buffer buf = ffi.new("char[]", b"world") print(ffi.string(buf)) # b'world'
Debug
Known footguns
breakingIn 2.0.0, reading a C '_Bool'/'bool' field whose underlying byte is not exactly 0 or 1 now raises an exception instead of returning the raw integer. Previously undefined-behavior values were silently returned.
breakingPython 2.7, 3.6, and 3.7 support was dropped. The minimum supported version is now Python 3.9 (as of 2.0.0 PyPI metadata).
breakingffi.string() no longer works on bool[] arrays. It previously returned raw bytes up to the first zero byte, which was rarely meaningful.
gotchachar* in C corresponds to bytes in Python 3, not str. Passing a Python str to any char* argument raises TypeError or produces garbage. Always encode strings explicitly: s.encode('utf-8').
gotchaABI mode (ffi.dlopen) is error-prone: wrong type declarations cause silent data corruption or crashes rather than compile-time errors. API mode (ffi.set_source + ffi.compile) is verified by a real C compiler.
gotchaOn Python 3.12+ any code path that calls ffi.compile() or uses cffi_modules= in setup.py requires setuptools at runtime because distutils was removed. CFFI does not declare this dependency automatically.
gotchaffi.dlopen(None) does not work on Python 3 on Windows. It raises OSError or returns an unusable handle.
Upgrade
Version history

Breaking-change detection hasn't run for this library yet.

Audit
Security & dependencies

CVE tracking and dependency tree are planned for a later release.

Agent activity
34 hits · last 30 days
bytedance
11
claudebot
5
gptbot
4
ahrefsbot
4
amazonbot
4
chatgpt-user
1
Resources