Skip to content

Commit

Permalink
Add the any test back, simplified
Browse files Browse the repository at this point in the history
  • Loading branch information
parcollet committed Nov 14, 2024
1 parent 958dccd commit b569f40
Show file tree
Hide file tree
Showing 4 changed files with 162 additions and 0 deletions.
1 change: 1 addition & 0 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ add_custom_command(
# ----------------------------
set(c2py_all_low_level_tests cls CACHE INTERNAL "")
set(c2py_all_full_tests
any
basicfun
cls_basic
cls_der
Expand Down
28 changes: 28 additions & 0 deletions test/any.cpp
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";
//}
110 changes: 110 additions & 0 deletions test/any.wrap.cxx
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;
}
23 changes: 23 additions & 0 deletions test/any_test.py
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()



0 comments on commit b569f40

Please sign in to comment.