{"library":"types-cffi","title":"Typing Stubs for cffi","description":"types-cffi is a type stub package providing external type annotations for the popular `cffi` library, which allows Python to call C code. It enables static type checkers like MyPy and PyRight to analyze code that uses `cffi` for improved development experience and bug detection. This package is part of the broader typeshed project and is regularly updated, with releases potentially occurring daily, to maintain compatibility with `cffi` itself.","status":"active","version":"2.0.0.20260402","language":"en","source_language":"en","source_url":"https://github.com/python/typeshed","tags":["typing","stubs","cffi","typeshed","static analysis","ffi"],"install":[{"cmd":"pip install types-cffi","lang":"bash","label":"Install types-cffi"},{"cmd":"pip install cffi","lang":"bash","label":"Install cffi runtime (required)"}],"dependencies":[{"reason":"types-cffi provides type hints for the cffi runtime library; cffi itself must be installed separately to execute code.","package":"cffi","optional":false}],"imports":[{"note":"types-cffi provides stubs for the 'cffi' library; you do not directly import from 'types-cffi'.","symbol":"FFI","correct":"from cffi import FFI"},{"note":"types-cffi provides stubs for the 'cffi' library; you do not directly import from 'types-cffi'.","symbol":"lib","correct":"from cffi import lib"}],"quickstart":{"code":"import os\nfrom cffi import FFI\n\n# Initialize FFI\nffi = FFI()\n\n# Declare C functions (e.g., from the standard C library)\nffi.cdef(\"\"\"int puts(const char* s);\"\"\")\n\n# Load the C library (None on Unix-like systems typically opens libc)\ntry:\n    libc = ffi.dlopen(None) # type: ignore\nexcept OSError:\n    print(\"Could not load libc. This example might not run on all systems.\\n\"\\\n          \"Ensure a C standard library is available and discoverable.\")\n    exit(1)\n\n# Call a C function with type checking (implicitly using types-cffi)\nmessage = ffi.new(\"char[]\", b\"Hello from C via CFFI and types-cffi!\")\nreturn_code = libc.puts(message)\n\nprint(f\"C puts() returned: {return_code}\")\n\n# Example of type checking at development time:\n# If you misspelled 'puts' or passed an int instead of bytes, \n# a type checker (like MyPy) would flag it due to types-cffi.","lang":"python","description":"This quickstart demonstrates a basic usage of `cffi` to call a C standard library function, `puts`. When `types-cffi` is installed, a static type checker will provide type hints for `ffi`, `lib`, and other `cffi` objects, helping to catch type-related errors at development time. The example intentionally avoids platform-specific library loading to be more general, using `ffi.dlopen(None)` for Unix-like systems to access the standard C library."},"warnings":[{"fix":"Ensure both `pip install types-cffi` and `pip install cffi` are executed.","message":"Installing `types-cffi` does not install the `cffi` runtime library. `types-cffi` only provides type annotations. You must install `cffi` separately (e.g., `pip install cffi`) for your code to run.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Keep `types-cffi` and `cffi` versions in sync, ideally pinning both to compatible major/minor versions. Refer to typeshed documentation for specific compatibility.","message":"`types-cffi` versions are aligned with `cffi` runtime versions. For example, `types-cffi==2.0.x.YYYYMMDD` provides stubs for `cffi==2.0.*`. Using significantly mismatched versions (e.g., `types-cffi` for `cffi` 2.0 with a `cffi` 1.x runtime) can lead to incorrect type checking results or missed errors.","severity":"breaking","affected_versions":"All versions"},{"fix":"Always ensure the Python object returned by `ffi.new_handle()` is kept alive for as long as the C `void *` value might be used. Review code for explicit handle management.","message":"The behavior of `ffi.new_handle()` changed in `cffi` v1.3.1 to guarantee unique `void *` values, even when called on the same object multiple times. Code relying on previous CPython behavior (where it might return two `cdata` objects with the same `void *` value) could break if not keeping the result of `ffi.new_handle()` alive explicitly.","severity":"deprecated","affected_versions":"<1.3.1 (for reliance on old behavior)"},{"fix":"Add `setuptools` to your project's `install_requires` if you build `cffi` extensions that previously relied on `distutils` functionality with Python 3.12 or newer.","message":"For `cffi` projects targeting Python 3.12 and newer, if they utilize `cffi` features that historically depended on `distutils` (which was removed in Python 3.12), they must explicitly add `setuptools` as a dependency. `cffi` itself does not add this runtime dependency to avoid unnecessary installs for projects that don't need it.","severity":"breaking","affected_versions":"cffi <1.16.0 (if targeting Python 3.12+ and using distutils-dependent features)"},{"fix":"Consider pinning `types-cffi` to a known good version in your `requirements.txt` (e.g., `types-cffi==2.0.0.20260402`) and update it periodically, or use version ranges that align with `cffi`'s compatibility.","message":"While typeshed aims to minimize breaking changes in stubs, any update to `types-cffi` (or any `types-*` package) can introduce changes that might cause your code to fail type checking, even if the runtime behavior of `cffi` hasn't changed. This is inherent to the evolving nature of type annotations.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-05T00:00:00.000Z","next_check":"2026-07-04T00:00:00.000Z"}