Skip to content
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

PEP 757: Use union #4111

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 42 additions & 26 deletions peps/pep-0757.rst
Original file line number Diff line number Diff line change
Expand Up @@ -107,37 +107,51 @@ Export API

Export of a Python :class:`int` object.

There are two cases:
.. c:member:: int8_t kind

* If :c:member:`digits` is ``NULL``, only use the :c:member:`value` member.
Calling :c:func:`PyLong_FreeExport` is optional in this case.
* If :c:member:`digits` is not ``NULL``, use :c:member:`negative`,
:c:member:`ndigits` and :c:member:`digits` members.
Calling :c:func:`PyLong_FreeExport` is mandatory in this case.
There are two cases:

.. c:member:: int64_t value
* If :c:member:`kind` is :c:macro:`PyLongExport_VALUE_KIND`, use
:c:member:`data.value`. Calling :c:func:`PyLong_FreeExport` is
optional in this case.
* If :c:member:`kind` is :c:macro:`PyLongExport_ARRAY_KIND`, use
:c:member:`data.array`. Calling :c:func:`PyLong_FreeExport` is
mandatory in this case.

The native integer value of the exported :class:`int` object.
Only valid if :c:member:`digits` is ``NULL``.
.. c:namespace:: NULL

.. c:member:: uint8_t negative
======================================== =====
Kind Value
======================================== =====
.. c:macro:: PyLongExport_VALUE_KIND ``1``
.. c:macro:: PyLongExport_ARRAY_KIND ``2``
Comment on lines +126 to +127
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we expose these details? Lets just keep symbolic constants.

======================================== =====

1 if the number is negative, 0 otherwise.
Only valid if :c:member:`digits` is not ``NULL``.
.. c:union:: data

.. c:member:: Py_ssize_t ndigits
.. c:member:: int64_t value

Number of digits in :c:member:`digits` array.
Only valid if :c:member:`digits` is not ``NULL``.
The native integer value of the exported :class:`int` object.

.. c:member:: const void *digits
.. c:struct:: array

Read-only array of unsigned digits. Can be ``NULL``.
.. c:member:: uint8_t negative

If :c:member:`digits` not ``NULL``, a private field of the
:c:struct:`PyLongExport` structure stores a strong reference to the Python
:class:`int` object to make sure that that structure remains valid until
:c:func:`PyLong_FreeExport()` is called.
1 if the number is negative, 0 otherwise.

.. c:member:: Py_ssize_t ndigits

Number of digits in :c:member:`digits` array.

.. c:member:: const void *digits

Read-only array of unsigned digits. Can be ``NULL``.

If :c:member:`kind` is :c:macro:`PyLongExport_ARRAY_KIND`, a private
field of the :c:struct:`PyLongExport` structure stores a strong
reference to the Python :class:`int` object to make sure that that
structure remains valid until :c:func:`PyLong_FreeExport()` is
called.


.. c:function:: int PyLong_Export(PyObject *obj, PyLongExport *export_long)
Expand Down Expand Up @@ -270,16 +284,18 @@ Code::
return -1;
}

if (long_export.digits) {
mpz_import(z, long_export.ndigits, int_digits_order, int_digit_size,
int_endianness, int_nails, long_export.digits);
if (long_export.negative) {
if (long_export.kind == PyLongExport_ARRAY_KIND) {
mpz_import(z, long_export.data.array.ndigits,
int_digits_order, int_digit_size, int_endianness,
int_nails, long_export.data.array.digits);
if (long_export.data.array.negative) {
skirpichev marked this conversation as resolved.
Show resolved Hide resolved
mpz_neg(z, z);
}
PyLong_FreeExport(&long_export);
}
else {
const int64_t value = long_export.value;
assert(long_export.kind == PyLongExport_VALUE_KIND);
const int64_t value = long_export.data.value;

if (LONG_MIN <= value && value <= LONG_MAX) {
mpz_set_si(z, value);
Expand Down
Loading