-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
162 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
#include <c2py/c2py.hpp> | ||
#include <c2py/converters/stl/any.hpp> | ||
#include <complex> | ||
|
||
struct opaque { | ||
int c = 17; // not exposed | ||
int *non_convertible = 0; | ||
int f(int x) { return x + 1; }; // not exposed | ||
}; | ||
|
||
// The convertion to Py is done as a PyCapsule of std::any | ||
template <> struct c2py::py_converter<opaque> : c2py::py_converter_as_any<opaque> {}; | ||
|
||
// maker | ||
opaque make_opaque() { return {}; } | ||
|
||
// passing the object back from Python | ||
int take_opaque(opaque const &x) { return x.c; } | ||
|
||
// we can modify the object passed from Python | ||
int inc_opaque(opaque &x) { return ++(x.c); } | ||
|
||
// Should not be needed. | ||
// If a class alaready has a converter, it is automatically rejected | ||
// from the list of classes to wrap. | ||
//namespace c2py_module { | ||
// constexpr auto reject_names = "opaque"; | ||
//} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
|
||
// C.f. https://numpy.org/doc/1.21/reference/c-api/array.html#importing-the-api | ||
#define PY_ARRAY_UNIQUE_SYMBOL _cpp2py_ARRAY_API | ||
#ifdef __clang__ | ||
// #pragma clang diagnostic ignored "-W#warnings" | ||
#endif | ||
#ifdef __GNUC__ | ||
#pragma GCC diagnostic ignored "-Wmissing-field-initializers" | ||
#pragma GCC diagnostic ignored "-Wcast-function-type" | ||
#pragma GCC diagnostic ignored "-Wcpp" | ||
#endif | ||
|
||
#define C2PY_VERSION_MAJOR 0 | ||
#define C2PY_VERSION_MINOR 1 | ||
|
||
#include "c2py/c2py.hpp" | ||
#include "any.cpp" | ||
|
||
using c2py::operator"" _a; | ||
|
||
// ==================== Wrapped classes ===================== | ||
|
||
#ifndef C2PY_HXX_DECLARATION_any_GUARDS | ||
#define C2PY_HXX_DECLARATION_any_GUARDS | ||
|
||
#endif | ||
|
||
// ==================== enums ===================== | ||
|
||
// ==================== module classes ===================== | ||
|
||
template <> struct c2py::py_converter<opaque> : c2py::py_converter_as_any<opaque> {}; | ||
template <> struct c2py::py_converter<opaque2> : c2py::py_converter_as_any<opaque2> {}; | ||
|
||
// ==================== module functions ==================== | ||
|
||
// inc_opaque | ||
static auto const fun_0 = c2py::dispatcher_f_kw_t{c2py::cfun(c2py::cast<opaque &>(&inc_opaque), "x")}; | ||
|
||
// inc_opaque2 | ||
static auto const fun_1 = c2py::dispatcher_f_kw_t{c2py::cfun(c2py::cast<opaque2 &>(&NN::inc_opaque2), "x")}; | ||
|
||
// make_opaque | ||
static auto const fun_2 = c2py::dispatcher_f_kw_t{c2py::cfun(c2py::cast<>(&make_opaque))}; | ||
|
||
// make_opaque2 | ||
static auto const fun_3 = c2py::dispatcher_f_kw_t{c2py::cfun(c2py::cast<>(&NN::make_opaque2))}; | ||
|
||
// take_opaque | ||
static auto const fun_4 = c2py::dispatcher_f_kw_t{c2py::cfun(c2py::cast<const opaque &>(&take_opaque), "x")}; | ||
|
||
// take_opaque2 | ||
static auto const fun_5 = c2py::dispatcher_f_kw_t{c2py::cfun(c2py::cast<const opaque2 &>(&NN::take_opaque2), "x")}; | ||
|
||
static const auto doc_d_0 = fun_0.doc({R"DOC( )DOC"}); | ||
static const auto doc_d_1 = fun_1.doc({R"DOC( )DOC"}); | ||
static const auto doc_d_2 = fun_2.doc({R"DOC( )DOC"}); | ||
static const auto doc_d_3 = fun_3.doc({R"DOC( )DOC"}); | ||
static const auto doc_d_4 = fun_4.doc({R"DOC( )DOC"}); | ||
static const auto doc_d_5 = fun_5.doc({R"DOC( )DOC"}); | ||
//--------------------- module function table ----------------------------- | ||
|
||
static PyMethodDef module_methods[] = { | ||
{"inc_opaque", (PyCFunction)c2py::pyfkw<fun_0>, METH_VARARGS | METH_KEYWORDS, doc_d_0.c_str()}, | ||
{"inc_opaque2", (PyCFunction)c2py::pyfkw<fun_1>, METH_VARARGS | METH_KEYWORDS, doc_d_1.c_str()}, | ||
{"make_opaque", (PyCFunction)c2py::pyfkw<fun_2>, METH_VARARGS | METH_KEYWORDS, doc_d_2.c_str()}, | ||
{"make_opaque2", (PyCFunction)c2py::pyfkw<fun_3>, METH_VARARGS | METH_KEYWORDS, doc_d_3.c_str()}, | ||
{"take_opaque", (PyCFunction)c2py::pyfkw<fun_4>, METH_VARARGS | METH_KEYWORDS, doc_d_4.c_str()}, | ||
{"take_opaque2", (PyCFunction)c2py::pyfkw<fun_5>, METH_VARARGS | METH_KEYWORDS, doc_d_5.c_str()}, | ||
{nullptr, nullptr, 0, nullptr} // Sentinel | ||
}; | ||
|
||
//--------------------- module struct & init error definition ------------ | ||
|
||
//// module doc directly in the code or "" if not present... | ||
/// Or mandatory ? | ||
static struct PyModuleDef module_def = {PyModuleDef_HEAD_INIT, | ||
"any", /* name of module */ | ||
R"RAWDOC()RAWDOC", /* module documentation, may be NULL */ | ||
-1, /* size of per-interpreter state of the module, or -1 if the module keeps state in global variables. */ | ||
module_methods, | ||
NULL, | ||
NULL, | ||
NULL, | ||
NULL}; | ||
|
||
//--------------------- module init function ----------------------------- | ||
|
||
extern "C" __attribute__((visibility("default"))) PyObject *PyInit_any() { | ||
|
||
if (not c2py::check_python_version("any")) return NULL; | ||
|
||
// import numpy iff 'numpy/arrayobject.h' included | ||
#ifdef Py_ARRAYOBJECT_H | ||
import_array(); | ||
#endif | ||
|
||
PyObject *m; | ||
|
||
if (PyType_Ready(&c2py::wrap_pytype<c2py::py_range>) < 0) return NULL; | ||
|
||
m = PyModule_Create(&module_def); | ||
if (m == NULL) return NULL; | ||
|
||
auto &conv_table = *c2py::conv_table_sptr.get(); | ||
|
||
conv_table[std::type_index(typeid(c2py::py_range)).name()] = &c2py::wrap_pytype<c2py::py_range>; | ||
|
||
return m; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import unittest | ||
import numpy as np | ||
import any as A | ||
|
||
def is_capsule(o): | ||
t = type(o) | ||
return t.__module__ == 'builtins' and t.__name__ == 'PyCapsule' | ||
|
||
class TestIterable(unittest.TestCase): | ||
|
||
def test_opaque(self): | ||
a = A.make_opaque() | ||
self.assertTrue(is_capsule(a)) | ||
self.assertEqual(A.take_opaque(a), 17) | ||
self.assertEqual(A.inc_opaque(a), 18) | ||
self.assertEqual(A.inc_opaque(a), 19) | ||
self.assertEqual(A.take_opaque(a), 19) | ||
|
||
if __name__ == '__main__': | ||
unittest.main() | ||
|
||
|
||
|