Open edcjones00 opened 2 years ago
Unfortunately, global overloads are difficult to handle (since they can be defined completely independently from the arguments they operate on), so their whole lookup is internal on the C++ side in CPyCppyy in order to be lazy but efficient after first lookup, and not easily available through reflection on the Python side.
However, the reason that this is happening, is that there is a method:
inline
Gmpq
operator+(const Gmpq &x, const Gmpq &y)
{
Gmpq Res;
mpq_add(Res.mpq(), x.mpq(), y.mpq());
return Res;
}
in CGAL/GMP/Gmpq_type.h
, which can take Gmpz
arguments through implicit conversion, but the Gmpz
equivalent is in C++ taken from the templated provided by the BOOST_BINARY_OPERATOR_COMMUTATIVE
macro and is declared as a friend
, which Cling doesn't consider in it's lookup for methods (this is a known, open, bug).
Until then, best I can offer is a workaround using a pythonizor, for example:
#! /usr/bin/env python
import cppyy
cppyy.load_library('libgmp')
cppyy.include('CGAL/Gmpz.h')
def CGAL_pythonizer(klass, name):
if name == 'Gmpz':
cppyy.cppdef("""\
CGAL::Gmpz fixadd(const CGAL::Gmpz& x, const CGAL::Gmpz& y) { return x+y; }"""
)
klass.__add__ = cppyy.gbl.fixadd
cppyy.py.add_pythonization(CGAL_pythonizer, "CGAL")
# Add two bigints, get a big rational:
three = cppyy.gbl.CGAL.Gmpz(3)
print(three, type(three))
seven = cppyy.gbl.CGAL.Gmpz(7)
print(seven, type(seven))
s = three + seven
print(s, type(s))
#cppyy.gbl.tryit()
# "+=" behaves correctly.
sum = cppyy.gbl.CGAL.Gmpz(0)
sum += three
sum += seven
print(sum, type(sum))
I have a Debian 11 system on a PC. I created a miniconda environment with Python 3.8.12, CGAL 5.0.1, cppyy 2.2.0, and gmp 6.2.1.
"CGAL" is The Computational Geometry Algorithms Library. It is written in C++. It contains wrappers for the Gnu multi-precision library. Class
Gmpz
does bigints and classGmpq
does big-rationals.When I add two
Gmpz
objects, I get aGmpq
object. Assuming that I am not experienced with cppyy, how do I find out exactly what is happening?