-
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.
Implementation details for clair change (fix 4) and any
- Loading branch information
Showing
9 changed files
with
196 additions
and
42 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
#pragma once | ||
#include <any> | ||
#include <cmath> | ||
#include "./common.hpp" | ||
|
||
namespace c2py { | ||
|
||
template <> struct py_converter<std::any> { | ||
|
||
static void capsule_destructor(PyObject *capsule) { | ||
void *p = PyCapsule_GetPointer(capsule, "std::any"); | ||
assert(p); | ||
auto *a_ptr = static_cast<std::any *>(p); | ||
delete a_ptr; //NOLINT | ||
} | ||
|
||
template <typename U> static PyObject *c2py(U &&u) { | ||
auto *p = new std::any{std::forward<U>(u)}; //NOLINT | ||
return PyCapsule_New(p, "std::any", capsule_destructor); | ||
} | ||
|
||
// -------------------------------------- | ||
|
||
static bool is_convertible(PyObject *ob, bool raise_exception) { | ||
bool ok = (PyCapsule_CheckExact(ob) and (std::string_view{PyCapsule_GetName(ob)} == "std::any")); | ||
if (!ok and raise_exception) { PyErr_SetString(PyExc_TypeError, ("Cannot convert "s + to_string(ob) + " to std::any"s).c_str()); } | ||
return ok; | ||
} | ||
|
||
// -------------------------------------- | ||
|
||
static std::any &py2c(PyObject *ob) { | ||
void *p = PyCapsule_GetPointer(ob, "std::any"); | ||
assert(p); | ||
return *static_cast<std::any *>(p); | ||
} | ||
}; | ||
|
||
// ------------------------------------------------------- | ||
|
||
template <typename T> struct py_converter_as_any : py_converter<std::any> { | ||
|
||
using base_t = py_converter<std::any>; | ||
|
||
static bool is_convertible(PyObject *ob, bool raise_exception) { | ||
if (!base_t::is_convertible(ob, raise_exception)) return false; | ||
return base_t::py2c(ob).type() == std::type_index(typeid(T)); | ||
} | ||
|
||
static T &py2c(PyObject *ob) { return std::any_cast<T &>(base_t::py2c(ob)); } | ||
}; | ||
} // namespace c2py |
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
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
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,46 @@ | ||
#include <c2py/c2py.hpp> | ||
#include <c2py/converters/stl/any.hpp> | ||
#include <complex> | ||
|
||
struct C2PY_OPAQUE opaque { | ||
int c = 17; // not exposed | ||
int *non_convertible = 0; | ||
int f(int x) { return x + 1; }; // not exposed | ||
}; | ||
|
||
// 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); } | ||
|
||
// ------------------------------------- | ||
/// Same test again, with the regex | ||
|
||
struct opaque2 { | ||
int c = 17; // not exposed | ||
int *non_convertible = 0; | ||
int f(int x) { return x + 1; }; // not exposed | ||
}; | ||
|
||
namespace NN { | ||
// maker | ||
opaque2 make_opaque2() { return {}; } | ||
|
||
// passing the object back from Python | ||
int take_opaque2(opaque2 const &x) { return x.c; } | ||
|
||
// we can modify the object passed from Python | ||
int inc_opaque2(opaque2 &x) { return ++(x.c); } | ||
} // namespace NN | ||
// ------------------------------------------------- | ||
|
||
namespace c2py_module { | ||
#pragma clang diagnostic ignored "-Wunused-const-variable" | ||
|
||
constexpr auto opaque_match_names = ".*opaque2"; | ||
|
||
} // namespace c2py_module |
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,33 @@ | ||
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) | ||
|
||
|
||
def test_opaque2(self): | ||
a = A.make_opaque2() | ||
self.assertTrue(is_capsule(a)) | ||
self.assertEqual(A.take_opaque2(a), 17) | ||
self.assertEqual(A.inc_opaque2(a), 18) | ||
self.assertEqual(A.inc_opaque2(a), 19) | ||
self.assertEqual(A.take_opaque2(a), 19) | ||
|
||
|
||
if __name__ == '__main__': | ||
unittest.main() | ||
|
||
|
||
|
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 @@ | ||
#ifdef __GNUC__ | ||
#pragma GCC diagnostic ignored "-Wunused-parameter" | ||
#endif | ||
|
||
#include <vector> | ||
#include <iostream> | ||
#include <c2py/c2py.hpp> | ||
|
||
struct a_struct { | ||
int a; | ||
C2PY_IGNORE int b = 1; | ||
double x_ignore_me = 0; // should be ignored by the regex | ||
|
||
C2PY_IGNORE int bad_method() { return 0; } | ||
int method_ignore_me() { return 1; } | ||
}; | ||
// =============== Declare module =========================== | ||
|
||
namespace c2py_module { | ||
|
||
constexpr auto reject_names = ".*ignore_me"; | ||
|
||
} // namespace c2py_module |
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,38 @@ | ||
import unittest | ||
import numpy as np | ||
import pickle | ||
|
||
import ignore as M | ||
A = M.AStruct | ||
|
||
class TestIterable(unittest.TestCase): | ||
|
||
def test_ignore(self): | ||
a = A(a = 10) | ||
print(a.a) # ok | ||
|
||
def f(): | ||
A(a= 10, b =2) | ||
self.assertRaises(RuntimeError, f) | ||
|
||
def f(x): | ||
print(x.b) | ||
self.assertRaises(AttributeError, f, a) | ||
|
||
def f(x): | ||
print(x.x_ignore_me) | ||
self.assertRaises(AttributeError, f, a) | ||
|
||
def f(x): | ||
x.bad_method(1) | ||
self.assertRaises(AttributeError, f, a) | ||
|
||
def f(x): | ||
x.method_ignore_me(1) | ||
self.assertRaises(AttributeError, f, a) | ||
|
||
|
||
if __name__ == '__main__': | ||
unittest.main() | ||
|
||
|