-
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
Vote on PEP 757 – C API to import-export Python integers #45
Comments
I'd prefer being able to deprecate |
I address d.p.o comment also here:
Probably, this concern also could be resolved with a new Edit: lets look closer on the structure typedef struct PyLongExport {
int64_t value;
uint8_t negative;
Py_ssize_t ndigits;
const void *digits;
// Member used internally, must not be used for other purpose.
Py_uintptr_t _reserved;
} PyLongExport; Most public fields (negative/ndigits/digits) are required, else the whole API doesn't make sense. So, we left with one field: typedef struct PyLongExport2 {
uint8_t is_compact;
union {
struct {
uint8_t version;
int64_t value;
} compact_value;
struct {
uint8_t negative;
Py_ssize_t ndigits;
const void *digits;
// _reserved could be actually here.
} digit_array;
};
// Member used internally, must not be used for other purpose.
Py_uintptr_t _reserved;
} PyLongExport2; Or we could use just reserve enough room for struct {
int64_t value[2];
} compact_value; |
As long as we can support it, but it shouldn't be forced to live forever :)
Sure, but AFAIK there's no expectation of that being a zero-copy mechanism, and it is in a library that's expected to provide conversions between arbitrary formats. It seems that adding a But, not being able to fail with
Oh, right -- a version field would be better on No version anywhere means that if/when
Examples are 2's complement, or a 64-bit compact value with a separate sign bit. But the ability to deprecate functions is mainly useful for unknown unknowns. I can't see decades ahead. |
Not all. Only if this representation can't fit in 64-bit
Then I'm lost :( The It's used to describe "asymptotic" representation of CPython integers as "digit array". (Maybe PEP isn't clear enough here?) Which else field we might want to add to this structure?
I'm assuming you meant 2's complement for "compact" values, not for representation of big integers. Then both variants could be solved as described above:
If this complication is required - I'm slightly biased to (1). |
I dislike anonymous union, it caused us some troubles in the past.
I dislike having two numbers, you have to define the order. I don't think that it's needed. I suggest to revisit the API once Python will need 128-bit. For now, it only needs 60-bit. |
We can make a small change to PEP 757:
It doubles the capacity of |
What would be the point though? How likely is it that CPython switches to an uncommon "uint64 + sign bit" representation? @markshannon what do you think? |
It may simplify the code using this API: https://peps.python.org/pep-0757/#export-pylong-export-with-gmpy2 Currently, this code is needed: mpz_import(z, 1, -1, sizeof(int64_t), 0, 0, &value);
if (value < 0) {
mpz_t tmp;
mpz_init(tmp);
mpz_ui_pow_ui(tmp, 2, 64);
mpz_sub(z, z, tmp);
mpz_clear(tmp);
} I expect that it can be simplified to the following code which should be more efficient: mpz_import(z, 1, -1, sizeof(uint64_t), 0, 0, &value);
if (long_export.negative) {
mpz_neg(z, z);
} Note: currently, only Windows uses this code path, since Windows only has 32-bit C long for |
I should never have mentioned any examples. A |
I wrote python/peps#4025 to allow PyLong_Export() to fail. |
The goal of this API is not to simplify consumer code, it's to make the export as efficient as possible. To make the export as efficient as possible, it must be as close as possible to CPython's internal representation. CPython is much more likely to adopt a int64 representation internally, than a "uint64 + sign bit" representation. The latter simply doesn't make sense, because it can't fit in a machine register. Thus the export API should favor int64 over "uint64 + sign bit". |
Was it before or after adding the C11 compiler requirement? With union, the structure will be also smaller (both in the current variant & with version field).
Native. Something like that does make sense for me with hypothetical 128-bit machine int's. Using e.g. uint64_t + sign doesn't look as a possible future for CPython integers.
What about version field? |
In short, the Python C API only requires C99, not C11: see the long discussion. |
I don't think that we should add a |
The union doesn't need to be anonymous, let's just name it. How about:
(edit: the union should be last so the struct can grow) Maybe this discussion should be on Discourse, not here... |
Which problem are you trying to address with this different structure? |
Compared to @skirpichev's earlier proposal:
|
I'm not sure if anonymous unions are banned from public API. (The long discussion seems to be unfinished.) But the rest clearly does make sense. This even more closer to the original proposal by Antoine. |
Vote on PEP 757 – C API to import-export Python integers.
Since I co-authored PEP 757, I abstain from voting on my own PEP :-)
I closed the previous issue since it had a long history and the API changed multiple times.
The text was updated successfully, but these errors were encountered: