-
-
Notifications
You must be signed in to change notification settings - Fork 13
ENH: Support arbitrary-length Python ints in QuadPrecision constructor #213
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
base: main
Are you sure you want to change the base?
Conversation
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.
LGTM
|
I'd like to give the C code a careful once-over later today. |
Cool, I'll do maybe 2 more PRs today (its a holiday here so xD) |
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.
I didn't spot any errors in the C code but I have some suggestions to improve code quality. In particular, it's good practice to test error cases if it's reasonable to do so and I spotted some opportunities for a refactor.
| Py_DECREF(self); | ||
| return NULL; | ||
| } | ||
| else { |
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.
both of the two if and else if blocks above return unconditionally, so you can delete this else block and put the code below in the enclosing scope. Just a teeny bit easier to read that way.
|
|
||
| if (lval == -1 && PyErr_Occurred()) { | ||
| Py_DECREF(self); | ||
| return NULL; |
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.
good catch
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.
That said, I don't think it's feasible to hit this error case in practice because for whatever reason it's not possible to subclass np.bool_:
>>> class mybool(np.bool_):
... pass
...
>>> mybool(True)
np.True_
>>> type(mybool(True))
<class 'numpy.bool'>
Still, always check for errors in C 😄
| } | ||
| } | ||
| else if (PyUnicode_CheckExact(value)) { | ||
| else if (PyUnicode_Check(value)) { |
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.
super minor nit: can you add a test passing a string subclass in to test this change?
| Py_DECREF(self); // discard the default one | ||
| return result; | ||
| } | ||
| else if (val == -1 && PyErr_Occurred()) { |
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.
This code is identical to code added above. Can you add a quad_from_py_int static helper function in this file that both call sites can use to avoid the duplication?
| else if (lval == -1 && PyErr_Occurred()) { | ||
| Py_DECREF(py_int); | ||
| Py_DECREF(self); | ||
| return NULL; |
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.
you can test this error case by defining a class with an __index__ implementation that raises.
| PyObject *str_obj = PyObject_Str(py_int); | ||
| Py_DECREF(py_int); | ||
| if (str_obj == NULL) { | ||
| Py_DECREF(self); |
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.
I think you can test this error case by subclassing e.g. np.int64 with a __str__ implementation that raises
|
Thanks @ngoldbaum mostly reviews seem to be connecting to more exhaustive testing, I'll soon add the tests to address them |
This PR is a part of work, where making
numpy_quaddtypecompatible with NumPy's longdouble testsDetails
Use
PyLong_AsLongLongAndOverflowinstead ofPyLong_AsLongLong, and handle the overflow case explicitly by reconstructing theQuadPrecisionobject via string conversion.