Welcome to Pie, a wrapper for CPython's C API in C++.
CPython's C API is really nice when writing C, but when writing C++ it leaves
much to be desired. The API passes around PyObject*
objects between functions
in an object oriented fashion. Pie wraps Python's PyObject*
with its own
object
class, it leverages C++'s operator overloading to call CPython API
functions on the PyObject*
and it automatically keeps track of the object's
reference count using constructors and destructors. Pie can also parse
certain C++ objects into Python objects, for example, vectors turn into lists,
maps turn into dictionaries, etc.
- An idiomatic C++ wrapper around
PyObject*
objects, using classes and operator overloading. - Automatic incrementing and decrementing of
PyObject*
reference counts. - Parsing of C++ types into Python objects.
- Wrapping of Python exceptions into C++ exceptions.
See the example for more
information on how to use Pie. Just link with libpie
and you should be
ready to go.
Note: Pie is not a replacement for the CPython API, it is intended to compliment it and make it easier to use in C++.
Pie's C++ type parser is very simple, it handles the following cases:
- C integers become Python integers.
- C strings (
const char *
) become Python strings. - C++ strings (
std::string
) become Python strings. - Container types with an
std::pair
value type become Python dictionaries. - Container types without an
std::pair
value type become Python lists.
Pie currently works on with Python 3 only. There are plans to port Pie to Python 2 in the future.
Pie requires the following:
- Compiler with C++17 (gcc-7 should work fine).
- Python 3 and development headers.
- CMake version 3+
To build issue the following:
git clone [email protected]:ronmrdechai/Pie.git
mkdir build
cd build
cmake ..
make
sudo make install
Building the tests clones and builds
googletest which is used to run the
tests. To build the tests pass an additional -DBUILD_TESTS=ON
to the cmake
command:
cmake .. -DBUILD_TESTS=ON
make
make test
Pie is developed and tested on macOS but should work on any platform with Python and C++17.
See tests for more detailed examples.
#include <pie/pie.h>
#include <iostream>
int main() {
pie::object os = PyImport_ImportModule("os");
pie::object os_environ = pie::getattr(os, "environ");
std::cout << "The following directories are in the PATH:" << std::endl;
for (auto dir: getattr(os_environ["PATH"], "split")(":")) {
std::cout << dir << std::endl;
}
pie::object zero = 0;
pie::object one = 1;
try {
one / zero;
} catch (pie::error& e) {
std::cout << "Caught Python exception:" << std::endl;
std::cout << e.what() << std::endl;
}
return 0;
}
This is equivalent to the following Python code:
import os
print("The following directories are in the PATH:")
for dir in os.environ["PATH"].split(":"):
print(dir)
try:
1 / 0
except BaseException as e:
print("Caught Python exception:")
print(e.__class__.__name__ + ": " + str(e))
Boost.Python, PyBind11 and SWIG are wonderful packages, but they different from Pie. These packages wrap C++ classes and functions into Python classes and functions, allowing you call them from Python. Some of them have support for calling Python code from C++, but this functionality has been added as an afterthought.
Pie has been built from the ground up to wrap Python objects into C++ objects, allowing you to easily call Python from your C++ code, and embed it in your applications.
- Provide a complete documentation for Pie
- Wrap Python builtin types with
pie::objects
.