Registry / devops / extension-helpers

extension-helpers

JSON →
library1.4.0pypypi✓ verified 25d ago

extension-helpers provides a suite of utilities designed to simplify the process of building and installing Python packages that include compiled extensions (e.g., C, C++, Fortran). It helps manage compiler flags, OpenMP support, and the Python Limited API (PEP 384) for ABI compatibility. The current version is 1.4.0, and it follows a stable release cadence with minor versions released every few months, often coinciding with Astropy-related ecosystem updates.

pip install extension-helpers
INSTALL
IMPORT
SIG · EXTENSION-HELPERS
E
extension-helpers
devopspythonv1.4.0
Install
1.8s avg
Import
750ms
Disk
20MB
Pass rate
10/ 10
Env Coverage10 / 10
glibc
3.93.13
musl
3.93.13
Install & Compatibility
Where this runs
tested against v1.4.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.95 runs
installs and imports cleanly · install 0.0s · import 0.816s · 19.2MB
glibc
py 3.103.95 runs
installs and imports cleanly · install 1.8s · import 0.684s · 20MB
20MB installed
● package 20MB
Code
Verified usage

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

get_extensions
from extension_helpers import get_extensions
add_extension_helpers_build_options
from extension_helpers import add_extension_helpers_build_options

This quickstart demonstrates how to use `add_extension_helpers_build_options` to modify a `setuptools.Extension` object. It shows how the library injects compiler flags (e.g., for OpenMP if available) and how setting the `EXTENSION_HELPERS_PY_LIMITED_API` environment variable influences the compiler arguments for PEP 384 support. This code prepares the `Extension` object, but does not perform the actual compilation, which `setuptools` would handle in a `setup.py` or `pyproject.toml` based build.

import os import shutil from setuptools import Extension # setuptools must be installed from extension_helpers import add_extension_helpers_build_options # Ensure 'src' directory exists for the dummy C file os.makedirs("src", exist_ok=True) # For demonstration, create a dummy C file dummy_c_file_path = os.path.join("src", "_dummy_ext.c") dummy_c_file_content = """ #include <Python.h> static PyObject * dummy_func(PyObject *self, PyObject *args) { Py_RETURN_NONE; } static PyMethodDef DummyMethods[] = { {"dummy_func", dummy_func, METH_NOARGS, "A dummy function."}, {NULL, NULL, 0, NULL} }; static struct PyModuleDef dummymodule = { PyModuleDef_HEAD_INIT, "_dummy_ext", /* name of module */ NULL, /* module documentation, may be NULL */ -1, /* size of per-interpreter state of the module, or -1 if the module keeps state in global variables. */ DummyMethods }; PyMODINIT_FUNC PyInit__dummy_ext(void) { return PyModule_Create(&dummymodule); } """ with open(dummy_c_file_path, "w") as f: f.write(dummy_c_file_content) # Define a single extension ext = Extension( 'my_package._dummy_ext', sources=[dummy_c_file_path], include_dirs=[], extra_compile_args=[], extra_link_args=[] ) print(f"Initial Extension: {ext.name}") print(f" Sources: {ext.sources}") print(f" Initial extra_compile_args: {ext.extra_compile_args}") # Apply extension-helpers build options (e.g., for OpenMP, limited API) # This modifies the 'ext' object in-place add_extension_helpers_build_options(ext) print(f"\nExtension after add_extension_helpers_build_options:") print(f" Updated extra_compile_args: {ext.extra_compile_args}") print(f" Updated extra_link_args: {ext.extra_link_args}") # Demonstrate the Limited API env var effect os.environ['EXTENSION_HELPERS_PY_LIMITED_API'] = 'true' print("\n--- Rerunning with EXTENSION_HELPERS_PY_LIMITED_API=true ---") ext_limited = Extension( 'my_package._dummy_ext_limited', sources=[dummy_c_file_path], include_dirs=[], extra_compile_args=[], extra_link_args=[] ) add_extension_helpers_build_options(ext_limited) print(f"Extension (Limited API enabled): {ext_limited.name}") print(f" Updated extra_compile_args (Limited API): {ext_limited.extra_compile_args}") print(f" Updated extra_link_args (Limited API): {ext_limited.extra_link_args}") del os.environ['EXTENSION_HELPERS_PY_LIMITED_API'] # Clean up the dummy C file and directory if os.path.exists(dummy_c_file_path): os.remove(dummy_c_file_path) if os.path.exists("src") and not os.listdir("src"): os.rmdir("src") elif os.path.exists("src"): print("\nNote: 'src' directory not removed as it contains other files.")
Debug
Known issues
gotchaABI Compatibility with Python Limited API (PEP 384) requires careful code review. While `EXTENSION_HELPERS_PY_LIMITED_API=true` (v1.4.0+) enables compiler flags for PEP 384, developers must ensure their C/C++ code adheres to the Limited API restrictions (e.g., avoiding private Python C API functions). Incorrect usage can lead to runtime errors or subtle bugs when the extension is used with different Python versions than it was built with.
fix
Review C/C++ source code to ensure it only uses functions available in the Python Limited API. Test the built extension against multiple Python versions if targeting ABI compatibility.
affects: >=1.4.0
gotchaextension-helpers relies on a correctly configured C/C++ compiler toolchain (e.g., GCC, Clang, MSVC) and potentially additional libraries like OpenMP. Build failures often stem from missing development tools, incorrect environment variables (e.g., `CC`, `CXX`, `LDFLAGS`), or incompatible compiler versions.
fix
Ensure a compatible C/C++ compiler is installed and accessible in your system's PATH. For specific features like OpenMP, verify the necessary libraries are also installed. Refer to your operating system's documentation for installing build tools (e.g., `build-essential` on Debian/Ubuntu, Xcode Command Line Tools on macOS, Visual C++ Build Tools on Windows).
affects: All
gotchaThe library supports configuration via `[tool.extension-helpers]` in `pyproject.toml` (since v1.1.0) or by directly calling its functions within a `setup.py`. Mixing these approaches or misunderstanding their precedence can lead to unexpected build behavior, where extensions are not discovered or configured correctly.
fix
For new projects, prefer configuring `extension-helpers` through `pyproject.toml` if possible. For complex or dynamic build logic, a `setup.py` importing `get_extensions()` or `add_extension_helpers_build_options()` directly might be necessary. Avoid redundant or conflicting configurations across `pyproject.toml` and `setup.py`.
affects: >=1.1.0
Errors
Common errors & fixes
ModuleNotFoundError: No module named 'extension_helpers'
The `extension-helpers` package is not installed in the Python environment being used, or it's not correctly declared as a build dependency in `pyproject.toml` or `setup.cfg`.
fix
Ensure `extension-helpers` is listed in your `pyproject.toml` under `[build-system] requires` or install it directly into your environment using `pip install extension-helpers`.
error: command 'gcc' failed with exit status 1
Building C/C++/Fortran extensions requires a suitable compiler (e.g., GCC on Linux/macOS, Visual C++ Build Tools on Windows) that is either missing or not correctly configured in the system's PATH.
fix
Install the appropriate C/C++ compiler toolchain for your operating system (e.g., `build-essential` on Debian/Ubuntu, Xcode Command Line Tools on macOS, or Visual Studio Build Tools with C++ desktop development on Windows) and ensure it's accessible from your command line.
ModuleNotFoundError: No module named 'setuptools.dep_util'
This error often occurs when `extension-helpers` tries to import a module from `setuptools` that is either too old, too new, or otherwise incompatible with the installed `setuptools` version in the build environment.
fix
Upgrade `setuptools` to a recent, compatible version (e.g., `pip install --upgrade setuptools`) within your build environment, or ensure your `pyproject.toml` specifies compatible versions for build dependencies.
ImportError: cannot import name 'get_extensions' from 'extension_helpers'
The `get_extensions` function, a core component of `extension-helpers`, is either being imported incorrectly or the package's `setup.py` (or equivalent build configuration) is not structured to use `extension-helpers` as intended.
fix
Verify that your `setup.py` includes `from extension_helpers import get_extensions` and passes `ext_modules=get_extensions()` to `setuptools.setup()`, and that `extension-helpers` is correctly specified as a build dependency.
Upgrade
Version history
1.4.0latest on PyPI · released Jun 9, 2025
Audit
Dependencies

No dependency data recorded yet.

Agent activity
6 hits · last 30 days
node
4
Amazon
1
Resources
extension-helpers — pip install extension-helpers · libregistry