wlav / cppyy

Other
401 stars 41 forks source link

[Question] Why does the automatic overloading fails here? #34

Closed Tillsten closed 2 years ago

Tillsten commented 2 years ago

I have an object of type <cppyy.gbl.BLArrayView<BLPoint> object at 0x000002C9302F2440>. The following call with the object as the argument fails to my surprise (see below), since the fourth signature should work. It does work when I choose it manually via 'const BLArrayView<BLPoint>& poly, BLGeometryDirection dir = BL_GEOMETRY_DIRECTION_CW'. Casting the obj does not, it seems to be a non-op (as expected). Any hints?

 >>> p.addPolyline(obj)

TypeError: none of the 8 overloaded methods succeeded. Full details:
  unsigned int BLPath::addPolyline(const BLArrayView<BLPoint>& poly, const BLMatrix2D& m, BLGeometryDirection dir) =>
    TypeError: takes at least 3 arguments (2 given)
  unsigned int BLPath::addPolyline(const BLArrayView<BLPointI>& poly, BLGeometryDirection dir = BL_GEOMETRY_DIRECTION_CW) =>
    TypeError: could not convert argument 1
  unsigned int BLPath::addPolyline(const BLArrayView<BLPointI>& poly, const BLMatrix2D& m, BLGeometryDirection dir = BL_GEOMETRY_DIRECTION_CW) =>
    TypeError: could not convert argument 1
  unsigned int BLPath::addPolyline(const BLArrayView<BLPoint>& poly, BLGeometryDirection dir = BL_GEOMETRY_DIRECTION_CW) =>
    TypeError: could not convert argument 1
  unsigned int BLPath::addPolyline(const BLPoint* poly, size_t n, const BLMatrix2D& m, BLGeometryDirection dir) =>
    TypeError: takes at least 4 arguments (2 given)
  unsigned int BLPath::addPolyline(const BLPointI* poly, size_t n, BLGeometryDirection dir = BL_GEOMETRY_DIRECTION_CW) =>
    TypeError: could not convert argument 1
  unsigned int BLPath::addPolyline(const BLPointI* poly, size_t n, const BLMatrix2D& m, BLGeometryDirection dir = BL_GEOMETRY_DIRECTION_CW) =>
    TypeError: takes at least 3 arguments (2 given)
  unsigned int BLPath::addPolyline(const BLPoint* poly, size_t n, BLGeometryDirection dir = BL_GEOMETRY_DIRECTION_CW) =>
    TypeError: could not convert argument 1
wlav commented 2 years ago

Any chance of a standalone reproducer? As described, indeed the 4th one:

unsigned int BLPath::addPolyline(const BLArrayView<BLPoint>& poly, BLGeometryDirection dir = BL_GEOMETRY_DIRECTION_CW) =>
    TypeError: could not convert argument 1

should have worked. The error isn't particularly helpful; I wonder whether it's hiding a different error (happens sometimes when there are multiple ways of resolution; in this case, it being a const-ref, an implicit conversion is allowed and may have been tried, but it should not go down that road).

With manual selection, you mean the use of __overload__? Underneath it's all the same thing, so maybe the issue is a conversion error that from a previous overload (the first time around, they are all tried in order) that's not cleared. Here, too, I'm not sure how that could happen. Are any of the BLArrayView<> classes inherited from each other?

Tillsten commented 2 years ago

I am using cppyy to interface with Blend2d. So the cppyy side boils down to:

import cppyy
import cppyy.gbl as g

cppyy.include('blend2d.h')
cppyy.load_library('bin/blend2d.dll')
triangle = g.BLPoint(-5, -5), g.BLPoint(5, -5), g.BLPoint(0, 5)
points = g.BLArray[g.BLPoint]()
for t in triangles:
    points.append(t)
view = points.view()
print(f"{view=}")
p = g.BLPath()

#p.addPolyline(view) # dont work
p.addPolyline.__overload__('const BLArrayView<BLPoint>& poly, BLGeometryDirection dir = BL_GEOMETRY_DIRECTION_CW')(view) # works

As far as I can tell the array classes have a commen base class, but my cpp knowledge is quite limited. The header file containing the array implemention can be found at https://github.com/blend2d/blend2d/blob/master/src/blend2d/array.h.

Tillsten commented 2 years ago

Just as an additional check I ran the following without issues.

cppyy.cppexec(
    r"""
    auto points = BLArray<BLPoint>();
    for (int i = 0; i < 3; i++) {points.append(BLPoint(i, i));}
    auto p = BLPath();
    p.addPolyline(points.view());
    """)
Tillsten commented 2 years ago

The same issues also raises in other methods, e.g. the following does not work without the explict overload

    circle_path = Path()
    circle_path.addCircle.__overload__('const BLCircle& circle, BLGeometryDirection dir = BL_GEOMETRY_DIRECTION_CW')(g.BLCircle(0, 0, .5))
wlav commented 2 years ago

Based on this line: cppyy.load_library('bin/blend2d.dll') I presume this is on Windows?

(I just installed Blend2D on Linux and there the code runs fine.)

Tillsten commented 2 years ago

Yes. And thanks for going through the hoops to help

Tillsten commented 2 years ago

Somehow after compiler updates the problem did disappered? Will close it for now until I can get a better grip, thanks for the support.