-
Notifications
You must be signed in to change notification settings - Fork 1
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
Add public functions PyLong_IsPositive(), PyLong_IsNegative() and PyLong_IsZero() #29
Comments
What are return values? Especially when the argument is not a Python int? |
They should be only used with a Python int, like |
You meant for non-int's too, right?
Then using PyLongObject seems more logical. If so, I don't see why this is better than single int PyLong_Sign(PyLongobject *obj); interface, already rejected in #19 PS: int sign;
(void)PyLong_GetSign(obj, &sign);
if (sign < 0) { Some compilers (e.g. recent gcc) also emit warning on the first line. |
New public API should take Most of the usage in CPython is in The functions quite easy to implement using |
Even excluding
They are faster and more convenient. They are used in many different files:
If you insist, we can make them returning |
PyLong already has exceptions: Maybe PyLong_IsPositive(), PyLong_IsNegative() and PyLong_IsZero() belong to the PyUnstable API instead. |
All uses outside of When we use other pointer type than |
As author of the Original idea was to offer GMP-like interface - as if (PyLong_Sign(obj) < 0) { But with With API like /* Returns 1 if the object obj is negative integer, and 0 otherwise. On failure,
return -1 with an exception set. This function always succeeds if obj is
a PyLongObject or its subtype. */
int PyLong_IsNegative(PyObject obj); most consumers could use one-liners as in the issue description and not worry about calling
That's true. But I worry that all consumers of that API will end in implementing such wrappers (or PyLong_Sign-like one). The gmpy2 project has just one place, that will call this API and this doesn't matter. But not all C API users so lucky.
To me it looks, that across the whole CPython codebase - only three calls to the |
For reference, which/how many other consumers are we talking about? I thought gmpy2 is the main user. |
CPython itself uses such functions much more than the sign function. |
If the main consumer is CPython, we can use the internal C API, no? |
CPython is just an example. Looking at the list of files where they are used you can see that they are usable in many different fields. |
As I wrote previously, if you want |
Probably, sage is. gmpy2 is much less popular project.
But for CPython sometimes For external projects, I think that Positive/Zero/Negative predicates will handle all use cases. |
Based on that link, it looks like sage uses this in combination with other private API, to import/export int data without conversion. We should add API for that whole use case, not for one part of it. |
Just as gmpy2 or everyone else.
It's not easy to do this in one shot;) #31 address other parts, perhaps all. |
I proposed a whole API to import-export Python int in #35. |
@serhiy-storchaka: You didn't reply to my previous question. Would you be ok with an unstable API with int PyUnstable_Long_IsPositive(PyLongObject *);
int PyUnstable_Long_IsNegative(PyLongObject *);
int PyUnstable_Long_IsZero(PyLongObject *); |
I would prefer a single int is_positive = (PyUnstable_Long_GetSign(obj) >= 0);
int is_zero = (PyUnstable_Long_GetSign(obj) == 0);
int is_negative = (PyUnstable_Long_GetSign(obj) < 0); |
No, I do not want
As for the |
In this case, I would require the caller to handle errors if the argument is not a Python int. Which is not the API that you are asking for.
The idea is that the caller is responsible to do the cast and so takes the responsibility of invalid casts. |
I think it's fine if we document that for ints (+subtypes) - no exceptions will be raised. |
So what we can have are these 3 functions:
So these functions always succeed if the argument is a Python @serhiy-storchaka @skirpichev: Would you be ok with such API? |
Yep, this definitely better than PyLong_GetSign() API (which should be removed). Based on above statistics, maybe PyLong_IsNegative and PyLong_IsZero - enough. |
Ok, let me open a vote on these 3 functions (API): Moreover, if we add these 3 functions, should we remove
|
I still think that projects that need these more than once or twice should implement them using |
@zooba: Would you mind to vote on these APIs? |
Done. I don't mind a soft/docs-only deprecation of |
@encukou: You're against adding these 3 functions, but other voters are in favor of the addition. Can you consider changing your vote? Same remark question for the keep or remove PyLong_GetSign() vote. |
BTW, the sentence "I still think that projects that need these more than once or twice should implement them using PyLong_GetSign, handling the four possible results in the way that's most appropriate for them." contradicts to vote for removing the |
Looks like I'm outvoted. I'll change my vote on the 3 functions, so I don't block progress. But:
Did y'all consider that |
No I didn't. If it's not been released, then yeah, just remove it. |
A PR for adding |
Then we have 3/3 votes for/against removing PyLong_GetSign(). What to do? |
I have re-set the vote, and marked Steve, Erlend & me as wanting to remove it. Does anyone want to keep |
Implementation was merged to main: python/cpython#126065 |
What's decision for PyLong_GetSign? It seems more votes down... |
I voted to remove |
They should be identical to existing private functions
_PyLong_IsPositive()
,_PyLong_IsNegative()
and_PyLong_IsZero()
, except that the argument isPyObject *
instead ofPyLongObject *
.The private functions are much more used in the CPython code than
_PyLong_Sign
(numbers are not accurate):Some of cases that use
_PyLong_Sign
could use_PyLong_IsNegative
etc instead. It is expected that they will be more used in the user code too.They are faster than
PyLong_GetSign
because they have less code.They are also more convenient, because you do not need to introduce a variable for result and can use them in expression. For example:
vs
The text was updated successfully, but these errors were encountered: