{"id":5164,"library":"cppy","title":"Cppy (Python C++ Extension Headers)","description":"Cppy is a small C++ header library designed to simplify the creation of Python extension modules. Its core feature is a `PyObject` smart pointer, which automates Python's reference counting mechanism and provides convenient methods for common object operations. The current version is 1.3.1. As a C++ header library, its release cadence is typically driven by CPython API changes or new convenience features rather than a fixed schedule.","status":"active","version":"1.3.1","language":"en","source_language":"en","source_url":"https://github.com/nucleic/cppy","tags":["c++","python-extensions","c-api","reference-counting","build-tool"],"install":[{"cmd":"pip install cppy","lang":"bash","label":"Install stable version"},{"cmd":"pip install git+https://github.com/nucleic/cppy","lang":"bash","label":"Install development version"}],"dependencies":[{"reason":"Required as a build dependency for Python extensions using cppy.","package":"setuptools","optional":false},{"reason":"Commonly used alongside setuptools for building Python wheels.","package":"wheel","optional":false}],"imports":[{"note":"This is a C++ header inclusion, not a Python import. Cppy provides its functionalities within the 'cppy' C++ namespace.","symbol":"cppy/cppy.h","correct":"#include <cppy/cppy.h>"},{"note":"This Python import is used in a 'setup.py' script for building C++ extensions with setuptools, ensuring C++11 and access to cppy headers.","symbol":"CppyBuildExt","correct":"from cppy import CppyBuildExt"}],"quickstart":{"code":"import os\nfrom setuptools import setup, Extension\nfrom setuptools.command.build_ext import build_ext\n\n# A minimal C++ source file that includes cppy\n# In a real project, this would be in a separate .cpp file\ncpp_source = '''\n#include <Python.h>\n#include <cppy/cppy.h>\n\nstatic PyObject* greet_method(PyObject* self, PyObject* args) {\n    const char* name;\n    if (!PyArg_ParseTuple(args, \"s\", &name)) {\n        return NULL;\n    }\n    std::string greeting = \"Hello, \" + std::string(name) + \"!\";\n    cppy::ptr result_ptr(PyUnicode_FromString(greeting.c_str()));\n    return result_ptr.release(); // release ownership to Python\n}\n\nstatic PyMethodDef methods[] = {\n    {\"greet\", greet_method, METH_VARARGS, \"Greet a person.\"},\n    {NULL, NULL, 0, NULL}\n};\n\nstatic struct PyModuleDef mymodule = {\n    PyModuleDef_HEAD_INIT,\n    \"_my_extension\", // Name of the module\n    NULL,            // Module documentation\n    -1,              // Size of per-interpreter state of the module\n    methods\n};\n\nPyMODINIT_FUNC PyInit__my_extension(void) {\n    return PyModule_Create(&mymodule);\n}\n'''\n\n# Write the C++ code to a temporary file for demonstration\nwith open('my_extension_module.cpp', 'w') as f:\n    f.write(cpp_source)\n\nclass CustomBuildExt(build_ext):\n    def build_extension(self, ext):\n        # Example of setting C++ standard if not using CppyBuildExt directly\n        # For cppy, C++11 is typically required.\n        if self.compiler.compiler_type == 'msvc':\n            ext.extra_compile_args = ['/std:c++11']\n        else:\n            ext.extra_compile_args = ['-std=c++11']\n        super().build_extension(ext)\n\nsetup(\n    name='my-cpp-extension',\n    version='0.1.0',\n    description='A simple C++ extension using cppy',\n    ext_modules=[\n        Extension(\n            '_my_extension',\n            sources=['my_extension_module.cpp'],\n            include_dirs=[os.path.join(os.environ.get('VIRTUAL_ENV', '/usr/local'), 'include')], # Adjust if cppy headers not found\n            language='c++'\n        )\n    ],\n    # For real projects, you might use CppyBuildExt directly:\n    # cmdclass={'build_ext': CppyBuildExt},\n    # Or ensure cppy is in build-system.requires in pyproject.toml\n    # and then 'from cppy import CppyBuildExt' in setup.py\n    cmdclass={'build_ext': CustomBuildExt},\n    setup_requires=['cppy'], # Ensure cppy is available during setup\n    install_requires=[]\n)\n\n# To demonstrate usage after hypothetical build and installation:\n# import _my_extension\n# print(_my_extension.greet(\"World\"))\n","lang":"python","description":"To use Cppy, you write C++ code for your Python extension module and include the `cppy/cppy.h` header. This example shows a `setup.py` that would build a simple C++ extension. Cppy handles Python object reference counting through its `cppy::ptr` smart pointer. For a more direct integration with `setuptools`, you can import `CppyBuildExt` from the `cppy` package in your `setup.py` to automatically enforce C++11 and include the necessary headers. Alternatively, specify `cppy` as a build requirement in `pyproject.toml`."},"warnings":[{"fix":"Understand that `pip install cppy` makes the C++ headers available for your C++ compiler. Python-side, you might import `CppyBuildExt` in your `setup.py` or declare `cppy` as a build-system requirement in `pyproject.toml`.","message":"Cppy is a C++ header library, not a Python module for direct runtime import. Its primary use is during the compilation of Python C++ extension modules. The Python 'cppy' package provides build-time integration components like `CppyBuildExt` for `setup.py`.","severity":"gotcha","affected_versions":"All"},{"fix":"Ensure your C++ compiler is configured to use C++11 (e.g., `-std=c++11` for GCC/Clang or `/std:c++11` for MSVC). `CppyBuildExt` aims to enforce this automatically when used.","message":"Cppy requires C++11 or a later standard for compilation. Older C++ compilers or build configurations not explicitly setting C++11 (or newer) will fail to compile extensions using Cppy.","severity":"breaking","affected_versions":"All"},{"fix":"Always wrap raw `PyObject*` pointers obtained from Python API calls (that give a new reference) or those you intend to return to Python (after acquiring a new reference) in `cppy::ptr` to ensure correct reference counting, especially when returning an object to Python using `cppy::ptr::release()`.","message":"Properly managing reference counts in Python C extensions is a common source of bugs. Cppy's `cppy::ptr` smart pointer is designed to alleviate this by automatically handling `Py_INCREF` and `Py_DECREF`.","severity":"gotcha","affected_versions":"All"},{"fix":"Set the environment variable `CPPY_DISABLE_FH4=1` during the build process to disable FH4 Exception Handling and avoid this dependency if it's causing issues. This should be done before running your build command (e.g., `set CPPY_DISABLE_FH4=1 && python setup.py install`).","message":"On Windows, when compiling, you might encounter issues related to FH4 Exception Handling, potentially requiring `VCRUNTIME140_1.dll`. This can be disabled if not needed.","severity":"gotcha","affected_versions":"All"},{"fix":"Include `cppy>=1.2` (or your desired version) in the `[build-system] requires` section of your `pyproject.toml` file (e.g., `requires = [\"setuptools>=42\", \"wheel\", \"cppy>=1.2\"]`).","message":"When using `setuptools` with a PEP 517 compatible build system (i.e., `pyproject.toml`), `cppy` must be listed as a build-time requirement to be available during the `setup.py` execution.","severity":"gotcha","affected_versions":"All"}],"env_vars":null,"last_verified":"2026-04-13T00:00:00.000Z","next_check":"2026-07-12T00:00:00.000Z"}