Generate Swig input files from annotated header files
Project description
PySwig
Simple wrapper integration (Python × SWIG):
integration matrix
(updated after a green pipeline on master; preview on develop — see
pages-domain.md).
SWIG is a great tool to generate wrappers very easily in various scripting languages of C/C++ libraries. But if you develop a C/C++ library and its wrapper at the same time, it has a significant flow: the necessity to create input files distinct from the source code of your library. The more extensive the library is, the biggest issue is to have to maintain virtually two sets of header files.
With PySwig, the source header files are annotated, allowing the automatic generation of the input files needed by Swig. With those input files, Swig can then create the sources of the wrapper. In this way, the maintenance effort is reduced to its minimum, since only one set of header files is needed.
Furthermore, PySwig can also take care of calling Swig to generate the wrapper. The result is a Python script, importing PySwig, and defining the operations to carry out. In the end, one just has to call this Python script to generate the Swig input files and call Swig to create the wrapper source files in one step.
Installation
Requires Python 3.9+ and SWIG on your PATH (or SWIG / ESYS_SWIG
environment variables).
pip install pyswig
pyswig --help
For wrapper development (Swig provisioning, multi-Python test runs, environment setup):
pip install pyswig-dev
pyswig-dev setup
pyswig-dev test-all
The pyswig-dev package depends on pyswig (same version on PyPI). See
docs/guides/packaging.md.
The pyswig CLI accepts optional header paths for single-file runs; full wrapper
generation still requires a script with FileConfig (see Quick start below).
Useful flags: --version, -q/--quiet, --run-swig, -l/--language,
--copy-shadow.
For PySwig contributors working from a git clone:
pip install -e "packages/pyswig[contributor]" -e packages/pyswig-dev
pyswig-dev setup
Documentation
- Hosted docs: pyswig.org
- Site roadmap (Sphinx → Docusaurus): docs/guides/docs-site-roadmap.md
- API reference: Sphinx under
docs/source/ - Contributing: CONTRIBUTING.md
Quick start
Configure header files with FileConfig, drive generation with PySwig, then run SWIG:
import pyswig
file_config = pyswig.FileConfig()
file_config.set_input_dir("../include/simple")
file_config.set_base_inc_dir("simple")
file_config.set_source_files(["version.h", "object.h"])
pyswig_obj = pyswig.PySwig(parse_cli=False)
pyswig_obj.add_file_config(file_config)
pyswig_obj.set_module_name("simple")
pyswig_obj.set_src_output_dir("./pysimple")
pyswig_obj.set_inc_output_dir("../include/pysimplewrap") # optional wrapper include
pyswig_obj.generate()
pyswig_obj.set_all_warnings()
pyswig_obj.set_process_cpp()
pyswig_obj.set_language("python")
pyswig_obj.run_swig()
See the full example in src/pysimple.py. Generated Swig files
land in src/pysimple/ and include/pysimple/simple_inc.h; run
python pysimple.py from src/ to refresh them (they are not committed).
Development
Supported test Python versions are listed in pyproject.toml under
[tool.pyswig] test-python-versions. Simple wrapper integration tests use the pinned SWIG
versions in [tool.pyswig] integration-swig-versions; missing binaries are downloaded to
.cache/swig (Windows: portable swigwin zip, Linux/macOS: built from source when needed).
# One-time setup: finds uv, installs test Pythons, .venv, dev deps, pre-commit hooks
python scripts/setup_dev.py
# Run tests on every configured Python version (coverage on 3.11 only)
python scripts/test_all.py --write-badges
# Default venv only
.venv/bin/python -m pytest # Linux/macOS
.venv\Scripts\python -m pytest # Windows
# End-to-end simple wrapper tests (downloads/builds SWIG versions from pyproject.toml)
python -m pytest -q -m integration tests/test_integration_simple_wrapper.py
# Full integration matrix (same as CI; reads pyproject.toml)
python scripts/ci_integration_matrix.py
Commit messages and code style are enforced with pre-commit (ruff + gitlint). See docs/guides/commit-messages.md.
Annotations
The basic principle is to add XML-like annotations in comments to various effects: to comment out a line, or a block of code; to include some lines in the input files used by Swig; to add automatically include files.
Add source include file
//<swig_inc/>
Automatically add the include file to the Swig input file. As an example of usage of this annotation, the result in the Swig input file would be:
//<swig_inc>
%{
#include "simple/object.h"
%}
//</swig_inc>
Comment out one line
//<swig_out/>
This annotation is to comment out one line of source code in the Swig input file. See the line below as an example one line in a header file of a library.
std::string &get_name(); //<swig_out/> In C#, string are immutable
This same line will be transformed to the following line in the Swig input file:
// std::string &get_name(); //<swig_out/> In C#, string are immutable
Commenting out a block of code
Often a block of code needs to be commented out. It can be done in this way.
//<swig_out>
int m_value = 0;
…
//</swig_out>
The result in the Swig input file is:
/* //<swig_out>
int m_value = 0;
…
//</swig_out> */
Add code specific to Swig
Often, it’s required to add code specific to Swig to handle templates, typemaps, director, etc. It can be done as follow:
/*<swig>
%apply std::string &OUTPUT …
//</swig>*/
It will result in the following line in a Swig input file:
//<swig>
%apply std::string &OUTPUT …
//</swig>
To add only one line, a simpler form is also possible:
//<swig/> %apply std::string &OUTPUT …
In the Swig input file, the line will look like the following:
%apply std::string &OUTPUT …
Build script
As mentioned earlier, PySwig can also be used to automate the creation of the wrapper by directly calling Swig. The simplest is to look at one of the examples provided in the git repo for the wrapper of the c++ library simple.
There are two Python classes to be aware of:
FileConfig— configuration for a set of annotated source headers (input dir, output dir, source list, include base path).PySwig— orchestrates parsing annotations, writing Swig.hhinterface files, and optionally invoking Swig. UsePySwig(parse_cli=False)when configuring everything from a script; omit that when driving generation from the command line.
The example script:
- Creates one or more
FileConfiginstances and registers them onPySwig. - Sets module name, output directories, typemaps, and includes.
- Calls
generate()to write Swig input files from annotated headers. - Configures and calls
run_swig()to produce the wrapper sources.
The lower-level Swig class locates the Swig executable and runs it with language and warning
options. ProcessSrcFile parses annotations in a single header; you rarely instantiate it
directly.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pyswig-0.2.0.tar.gz.
File metadata
- Download URL: pyswig-0.2.0.tar.gz
- Upload date:
- Size: 19.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
114cafa3e56b7179802342703e1f85c0620657701bd54da17dd3c3ecfc832b37
|
|
| MD5 |
908d4e0860a33de1dda42d8c4d778da6
|
|
| BLAKE2b-256 |
4ff5a4883fbe8b4215340e8b9d5b24919347c708bece785aa52fcc31ace63147
|
File details
Details for the file pyswig-0.2.0-py3-none-any.whl.
File metadata
- Download URL: pyswig-0.2.0-py3-none-any.whl
- Upload date:
- Size: 20.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6f266d6f8da12c188662d2d0a9479b41f72b6612994f381fb02390f816bb1e98
|
|
| MD5 |
296649b5c4a61550fb97e82fa8dce6ea
|
|
| BLAKE2b-256 |
f5567a3f1a980d61c1dd900cbc82f12fec42da6a4f0e4ca7bbd1922e5153eca3
|