-
-
Notifications
You must be signed in to change notification settings - Fork 32.1k
gh-110628: Add tests for PyLong C API #110629
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
gh-110628: Add tests for PyLong C API #110629
Conversation
|
||
PyObject *result = PyLong_FromString(str, &end, base); | ||
if (result == NULL) { | ||
// XXX 'end' is not always set. |
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.
What does XXX
imply? Is it a FIXME or TODO comment? If it has no special meaning, I think it should be removed. If it has a special meaning, it should be expressed clearly.
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.
It means that that we cannot add assert(end != UNINITIALIZED_PTR)
here. end
is not set if base
is incorrect, and maybe in case of memory allocation error. I am not sure what to do with this. It is not correct to set end = str
, because the first character can be valid. Maybe set it to NULL? This is a different issue, and I am going to think about this later.
XXX means "Look! Something not good here."
|
||
PyObject *result = PyLong_FromString(str, &end, base); | ||
if (result == NULL) { | ||
// XXX 'end' is not always set. |
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.
not good :-( can it be fixed?
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.
Not in this issue. And it is not clear what fix may look like.
} | ||
Py_RETURN_NONE; | ||
} | ||
return Py_NewRef((PyObject *)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.
Wait, is it an object? It's just a raw pointer, no?
Maybe return PyLong_FromVoidPtr(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.
Yes, it is a raw pointer. But Python does not have pointers. So these tests only test pointers to Python objects (and NULL). With PyLong_FromVoidPtr() and
PyLong_AsVoidPtr()` we can round trip object -> int -> object.
float_max = sys.float_info.max | ||
for value in (5.0, 5.1, 5.9, -5.1, -5.9, 0.0, -0.0, float_max, -float_max): | ||
with self.subTest(value=value): | ||
self.assertEqual(fromdouble(value), int(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.
This test is now suspicious. What if int() executes exactly the same code path, PyLong_FromDouble()?
I would prefer to hardcode the expected result:
for value, expected in (
(5.0, 5),
...
(float_max, int(float_max)),
):
...
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.
Right, it is the purpose. PyLong_FromDouble()
works exactly as int()
with float argument.
How does int()
with float argument work is tested in other tests.
Thanks @serhiy-storchaka for the PR 🌮🎉.. I'm working now to backport this PR to: 3.12. |
Sorry, @serhiy-storchaka, I could not cleanly backport this to
|
(cherry picked from commit 9d40ebf) Co-authored-by: Serhiy Storchaka <[email protected]>
GH-110854 is a backport of this pull request to the 3.12 branch. |
Uh oh!
There was an error while loading. Please reload this page.