@@ -653,3 +653,177 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate.
653653
654654 .. versionadded:: 3.12
655655
656+
657+ Export API
658+ ^^^^^^^^^^
659+
660+ .. versionadded:: 3.14
661+
662+ .. c:struct:: PyLongLayout
663+
664+ Layout of an array of "digits" ("limbs" in the GMP terminology), used to
665+ represent absolute value for arbitrary precision integers.
666+
667+ Use :c:func:`PyLong_GetNativeLayout` to get the native layout of Python
668+ :class:`int` objects, used internally for integers with "big enough"
669+ absolute value.
670+
671+ See also :data:`sys.int_info` which exposes similar information in Python.
672+
673+ .. c:member:: uint8_t bits_per_digit
674+
675+ Bits per digit. For example, a 15 bit digit means that bits 0-14 contain
676+ meaningful information.
677+
678+ .. c:member:: uint8_t digit_size
679+
680+ Digit size in bytes. For example, a 15 bit digit will require at least 2
681+ bytes.
682+
683+ .. c:member:: int8_t digits_order
684+
685+ Digits order:
686+
687+ - ``1`` for most significant digit first
688+ - ``-1`` for least significant digit first
689+
690+ .. c:member:: int8_t digit_endianness
691+
692+ Digit endianness:
693+
694+ - ``1`` for most significant byte first (big endian)
695+ - ``-1`` for least significant byte first (little endian)
696+
697+
698+ .. c:function:: const PyLongLayout* PyLong_GetNativeLayout(void)
699+
700+ Get the native layout of Python :class:`int` objects.
701+
702+ See the :c:struct:`PyLongLayout` structure.
703+
704+ The function must not be called before Python initialization nor after
705+ Python finalization. The returned layout is valid until Python is
706+ finalized. The layout is the same for all Python sub-interpreters
707+ in a process, and so it can be cached.
708+
709+
710+ .. c:struct:: PyLongExport
711+
712+ Export of a Python :class:`int` object.
713+
714+ There are two cases:
715+
716+ * If :c:member:`digits` is ``NULL``, only use the :c:member:`value` member.
717+ * If :c:member:`digits` is not ``NULL``, use :c:member:`negative`,
718+ :c:member:`ndigits` and :c:member:`digits` members.
719+
720+ .. c:member:: int64_t value
721+
722+ The native integer value of the exported :class:`int` object.
723+ Only valid if :c:member:`digits` is ``NULL``.
724+
725+ .. c:member:: uint8_t negative
726+
727+ ``1`` if the number is negative, ``0`` otherwise.
728+ Only valid if :c:member:`digits` is not ``NULL``.
729+
730+ .. c:member:: Py_ssize_t ndigits
731+
732+ Number of digits in :c:member:`digits` array.
733+ Only valid if :c:member:`digits` is not ``NULL``.
734+
735+ .. c:member:: const void *digits
736+
737+ Read-only array of unsigned digits. Can be ``NULL``.
738+
739+
740+ .. c:function:: int PyLong_Export(PyObject *obj, PyLongExport *export_long)
741+
742+ Export a Python :class: `int ` object.
743+
744+ *export_long * must point to a :c:struct: `PyLongExport ` structure allocated
745+ by the caller. It must not be ``NULL ``.
746+
747+ On success, fill in *\* export_long * and return ``0 ``.
748+ On error, set an exception and return ``-1 ``.
749+
750+ :c:func: `PyLong_FreeExport ` must be called when the export is no longer
751+ needed.
752+
753+ .. impl-detail ::
754+ This function always succeeds if *obj * is a Python :class: `int ` object
755+ or a subclass.
756+
757+
758+ .. c :function :: void PyLong_FreeExport (PyLongExport *export_long)
759+
760+ Release the export *export_long * created by :c:func: `PyLong_Export `.
761+
762+ .. impl-detail ::
763+ Calling :c:func: `PyLong_FreeExport ` is optional if *export_long->digits *
764+ is ``NULL ``.
765+
766+
767+ PyLongWriter API
768+ ^^^^^^^^^^^^^^^^
769+
770+ The :c:type: `PyLongWriter ` API can be used to import an integer.
771+
772+ .. versionadded :: 3.14
773+
774+ .. c :struct :: PyLongWriter
775+
776+ A Python :class: `int ` writer instance.
777+
778+ The instance must be destroyed by :c:func: `PyLongWriter_Finish ` or
779+ :c:func: `PyLongWriter_Discard `.
780+
781+
782+ .. c :function :: PyLongWriter* PyLongWriter_Create (int negative, Py_ssize_t ndigits, void **digits)
783+
784+ Create a :c:type: `PyLongWriter `.
785+
786+ On success, allocate *\* digits * and return a writer.
787+ On error, set an exception and return ``NULL ``.
788+
789+ *negative * is ``1 `` if the number is negative, or ``0 `` otherwise.
790+
791+ *ndigits * is the number of digits in the *digits * array. It must be
792+ greater than 0.
793+
794+ *digits * must not be NULL.
795+
796+ After a successful call to this function, the caller should fill in the
797+ array of digits *digits * and then call :c:func: `PyLongWriter_Finish ` to get
798+ a Python :class: `int `.
799+ The layout of *digits * is described by :c:func: `PyLong_GetNativeLayout `.
800+
801+ Digits must be in the range [``0 ``; ``(1 << bits_per_digit) - 1 ``]
802+ (where the :c:struct: `~PyLongLayout.bits_per_digit ` is the number of bits
803+ per digit).
804+ Any unused most significant digits must be set to ``0``.
805+
806+ Alternately, call :c:func:`PyLongWriter_Discard` to destroy the writer
807+ instance without creating an :class:`~int` object.
808+
809+
810+ .. c:function:: PyObject* PyLongWriter_Finish(PyLongWriter *writer)
811+
812+ Finish a :c:type: `PyLongWriter ` created by :c:func: `PyLongWriter_Create `.
813+
814+ On success, return a Python :class: `int ` object.
815+ On error, set an exception and return ``NULL ``.
816+
817+ The function takes care of normalizing the digits and converts the object
818+ to a compact integer if needed.
819+
820+ The writer instance and the *digits * array are invalid after the call.
821+
822+
823+ .. c :function :: void PyLongWriter_Discard (PyLongWriter *writer)
824+
825+ Discard a :c:type: `PyLongWriter ` created by :c:func: `PyLongWriter_Create `.
826+
827+ *writer * must not be ``NULL ``.
828+
829+ The writer instance and the *digits * array are invalid after the call.
0 commit comments