-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Regression in transforms: raises exception when applied to single point #3866
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -419,24 +419,30 @@ const char *Py_affine_transform__doc__ = "affine_transform(points, trans)"; | |
|
||
static PyObject *Py_affine_transform(PyObject *self, PyObject *args, PyObject *kwds) | ||
{ | ||
numpy::array_view<const double, 2> vertices; | ||
PyObject *vertices_obj; | ||
agg::trans_affine trans; | ||
|
||
if (!PyArg_ParseTuple(args, | ||
"O&O&:affine_transform", | ||
&vertices.converter, | ||
&vertices, | ||
"OO&:affine_transform", | ||
&vertices_obj, | ||
&convert_trans_affine, | ||
&trans)) { | ||
return NULL; | ||
} | ||
|
||
npy_intp dims[] = { vertices.dim(0), 2 }; | ||
numpy::array_view<double, 2> result(dims); | ||
|
||
CALL_CPP("affine_transform", (affine_transform(vertices, trans, result))); | ||
|
||
return result.pyobj(); | ||
try { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Try catch, or just test the dimensionality of the object? Is there a preferred paradigm? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good point, I had the same thought when I read it. Testing for dimensionality seems slightly clearer to me personally because it doesn't treat the 1d case as "effectively wrong, but ok let's support it anyway". I don't have any strong opinions on this, though. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was trying to avoid the 4-5 lines of complex code, involving reference counting, just to convert to an array to check its dimensionality, when that's neatly encapsulated in the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Again, no strong opinions from my side. It was just my first thought when I read the code, but with your explanation I'm happy to leave it this way. One question though, since I'm not really familiar with the C++ side of things: is it safe to catch a generic exception, or is there a way to specifically catch the ValueError that is triggered if the array is not 2d? I can't see much of a problem here, I'm just asking because I've been bitten by generic "catch" statements quite a few times in the past (but this was always on a much higher Python level with more potential for other exceptions to be triggered by the same piece of code, which doesn't seem to be the case here). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think in this specific instance, the generic catch is fine -- and we don't actually have much choice: All Python exceptions "thrown" as |
||
numpy::array_view<double, 2> vertices(vertices_obj); | ||
npy_intp dims[] = { vertices.dim(0), 2 }; | ||
numpy::array_view<double, 2> result(dims); | ||
CALL_CPP("affine_transform", (affine_transform_2d(vertices, trans, result))); | ||
return result.pyobj(); | ||
} catch (py::exception) { | ||
numpy::array_view<double, 1> vertices(vertices_obj); | ||
npy_intp dims[] = { vertices.dim(0) }; | ||
numpy::array_view<double, 1> result(dims); | ||
CALL_CPP("affine_transform", (affine_transform_1d(vertices, trans, result))); | ||
return result.pyobj(); | ||
} | ||
} | ||
|
||
const char *Py_count_bboxes_overlapping_bbox__doc__ = "count_bboxes_overlapping_bbox(bbox, bboxes)"; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again, things I may not really want to know, but will ask anyway, what is
O&O&
vsOO&
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
https://docs.python.org/3/c-api/arg.html#other-objects
The
O
means dump the object in a C pointer (vertices_obj
); theO&
means use a converter function (convert_trans_affine
) to convert the object before dumping the result in a C pointer (trans
). This is the as-modified version; in the previous version, each of the two arguments was processed by a converter.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Exactly. In order to support the fact that the vertices array can be either 1-d or 2-d, I needed to do the conversion manually below rather than using a converter function.