7
7
// https://github.com/python/pythoncapi_compat
8
8
//
9
9
// Latest version:
10
- // https://raw.githubusercontent.com/python/pythoncapi_compat/master /pythoncapi_compat.h
10
+ // https://raw.githubusercontent.com/python/pythoncapi-compat/main /pythoncapi_compat.h
11
11
//
12
12
// SPDX-License-Identifier: 0BSD
13
13
@@ -24,6 +24,9 @@ extern "C" {
24
24
#if PY_VERSION_HEX < 0x030b00B4 && !defined(PYPY_VERSION)
25
25
# include " frameobject.h" // PyFrameObject, PyFrame_GetBack()
26
26
#endif
27
+ #if PY_VERSION_HEX < 0x030C00A3
28
+ # include < structmember.h> // T_SHORT, READONLY
29
+ #endif
27
30
28
31
29
32
#ifndef _Py_CAST
@@ -287,7 +290,7 @@ PyFrame_GetVarString(PyFrameObject *frame, const char *name)
287
290
288
291
289
292
// bpo-39947 added PyThreadState_GetInterpreter() to Python 3.9.0a5
290
- #if PY_VERSION_HEX < 0x030900A5 || defined(PYPY_VERSION)
293
+ #if PY_VERSION_HEX < 0x030900A5 || ( defined(PYPY_VERSION) && PY_VERSION_HEX < 0x030B0000 )
291
294
static inline PyInterpreterState *
292
295
PyThreadState_GetInterpreter (PyThreadState *tstate)
293
296
{
@@ -918,7 +921,7 @@ static inline int
918
921
PyObject_VisitManagedDict (PyObject *obj, visitproc visit, void *arg)
919
922
{
920
923
PyObject **dict = _PyObject_GetDictPtr (obj);
921
- if (*dict == NULL ) {
924
+ if (dict == NULL || *dict == NULL ) {
922
925
return -1 ;
923
926
}
924
927
Py_VISIT (*dict);
@@ -929,7 +932,7 @@ static inline void
929
932
PyObject_ClearManagedDict (PyObject *obj)
930
933
{
931
934
PyObject **dict = _PyObject_GetDictPtr (obj);
932
- if (*dict == NULL ) {
935
+ if (dict == NULL || *dict == NULL ) {
933
936
return ;
934
937
}
935
938
Py_CLEAR (*dict);
@@ -1204,11 +1207,11 @@ static inline int PyTime_PerfCounter(PyTime_t *result)
1204
1207
#endif
1205
1208
1206
1209
// gh-111389 added hash constants to Python 3.13.0a5. These constants were
1207
- // added first as private macros to Python 3.4.0b1 and PyPy 7.3.9 .
1210
+ // added first as private macros to Python 3.4.0b1 and PyPy 7.3.8 .
1208
1211
#if (!defined(PyHASH_BITS) \
1209
1212
&& ((!defined(PYPY_VERSION) && PY_VERSION_HEX >= 0x030400B1 ) \
1210
1213
|| (defined(PYPY_VERSION) && PY_VERSION_HEX >= 0x03070000 \
1211
- && PYPY_VERSION_NUM >= 0x07090000 )))
1214
+ && PYPY_VERSION_NUM >= 0x07030800 )))
1212
1215
# define PyHASH_BITS _PyHASH_BITS
1213
1216
# define PyHASH_MODULUS _PyHASH_MODULUS
1214
1217
# define PyHASH_INF _PyHASH_INF
@@ -1520,6 +1523,36 @@ static inline int PyLong_GetSign(PyObject *obj, int *sign)
1520
1523
}
1521
1524
#endif
1522
1525
1526
+ // gh-126061 added PyLong_IsPositive/Negative/Zero() to Python in 3.14.0a2
1527
+ #if PY_VERSION_HEX < 0x030E00A2
1528
+ static inline int PyLong_IsPositive (PyObject *obj)
1529
+ {
1530
+ if (!PyLong_Check (obj)) {
1531
+ PyErr_Format (PyExc_TypeError, " expected int, got %s" , Py_TYPE (obj)->tp_name );
1532
+ return -1 ;
1533
+ }
1534
+ return _PyLong_Sign (obj) == 1 ;
1535
+ }
1536
+
1537
+ static inline int PyLong_IsNegative (PyObject *obj)
1538
+ {
1539
+ if (!PyLong_Check (obj)) {
1540
+ PyErr_Format (PyExc_TypeError, " expected int, got %s" , Py_TYPE (obj)->tp_name );
1541
+ return -1 ;
1542
+ }
1543
+ return _PyLong_Sign (obj) == -1 ;
1544
+ }
1545
+
1546
+ static inline int PyLong_IsZero (PyObject *obj)
1547
+ {
1548
+ if (!PyLong_Check (obj)) {
1549
+ PyErr_Format (PyExc_TypeError, " expected int, got %s" , Py_TYPE (obj)->tp_name );
1550
+ return -1 ;
1551
+ }
1552
+ return _PyLong_Sign (obj) == 0 ;
1553
+ }
1554
+ #endif
1555
+
1523
1556
1524
1557
// gh-124502 added PyUnicode_Equal() to Python 3.14.0a0
1525
1558
#if PY_VERSION_HEX < 0x030E00A0
@@ -1690,6 +1723,216 @@ static inline int PyLong_AsUInt64(PyObject *obj, uint64_t *pvalue)
1690
1723
#endif
1691
1724
1692
1725
1726
+ // gh-102471 added import and export API for integers to 3.14.0a2.
1727
+ #if PY_VERSION_HEX < 0x030E00A2 && PY_VERSION_HEX >= 0x03000000 && !defined(PYPY_VERSION)
1728
+ // Helpers to access PyLongObject internals.
1729
+ static inline void
1730
+ _PyLong_SetSignAndDigitCount (PyLongObject *op, int sign, Py_ssize_t size)
1731
+ {
1732
+ #if PY_VERSION_HEX >= 0x030C0000
1733
+ op->long_value .lv_tag = (uintptr_t )(1 - sign) | ((uintptr_t )(size) << 3 );
1734
+ #elif PY_VERSION_HEX >= 0x030900A4
1735
+ Py_SET_SIZE (op, sign * size);
1736
+ #else
1737
+ Py_SIZE (op) = sign * size;
1738
+ #endif
1739
+ }
1740
+
1741
+ static inline Py_ssize_t
1742
+ _PyLong_DigitCount (const PyLongObject *op)
1743
+ {
1744
+ #if PY_VERSION_HEX >= 0x030C0000
1745
+ return (Py_ssize_t)(op->long_value .lv_tag >> 3 );
1746
+ #else
1747
+ return _PyLong_Sign ((PyObject*)op) < 0 ? -Py_SIZE (op) : Py_SIZE (op);
1748
+ #endif
1749
+ }
1750
+
1751
+ static inline digit*
1752
+ _PyLong_GetDigits (const PyLongObject *op)
1753
+ {
1754
+ #if PY_VERSION_HEX >= 0x030C0000
1755
+ return (digit*)(op->long_value .ob_digit );
1756
+ #else
1757
+ return (digit*)(op->ob_digit );
1758
+ #endif
1759
+ }
1760
+
1761
+ typedef struct PyLongLayout {
1762
+ uint8_t bits_per_digit;
1763
+ uint8_t digit_size;
1764
+ int8_t digits_order;
1765
+ int8_t digit_endianness;
1766
+ } PyLongLayout;
1767
+
1768
+ typedef struct PyLongExport {
1769
+ int64_t value;
1770
+ uint8_t negative;
1771
+ Py_ssize_t ndigits;
1772
+ const void *digits;
1773
+ Py_uintptr_t _reserved;
1774
+ } PyLongExport;
1775
+
1776
+ typedef struct PyLongWriter PyLongWriter;
1777
+
1778
+ static inline const PyLongLayout*
1779
+ PyLong_GetNativeLayout (void )
1780
+ {
1781
+ static const PyLongLayout PyLong_LAYOUT = {
1782
+ PyLong_SHIFT,
1783
+ sizeof (digit),
1784
+ -1 , // least significant first
1785
+ PY_LITTLE_ENDIAN ? -1 : 1 ,
1786
+ };
1787
+
1788
+ return &PyLong_LAYOUT;
1789
+ }
1790
+
1791
+ static inline int
1792
+ PyLong_Export (PyObject *obj, PyLongExport *export_long)
1793
+ {
1794
+ if (!PyLong_Check (obj)) {
1795
+ memset (export_long, 0 , sizeof (*export_long));
1796
+ PyErr_Format (PyExc_TypeError, " expected int, got %s" ,
1797
+ Py_TYPE (obj)->tp_name );
1798
+ return -1 ;
1799
+ }
1800
+
1801
+ // Fast-path: try to convert to a int64_t
1802
+ PyLongObject *self = (PyLongObject*)obj;
1803
+ int overflow;
1804
+ #if SIZEOF_LONG == 8
1805
+ long value = PyLong_AsLongAndOverflow (obj, &overflow);
1806
+ #else
1807
+ // Windows has 32-bit long, so use 64-bit long long instead
1808
+ long long value = PyLong_AsLongLongAndOverflow (obj, &overflow);
1809
+ #endif
1810
+ Py_BUILD_ASSERT (sizeof (value) == sizeof (int64_t ));
1811
+ // the function cannot fail since obj is a PyLongObject
1812
+ assert (!(value == -1 && PyErr_Occurred ()));
1813
+
1814
+ if (!overflow) {
1815
+ export_long->value = value;
1816
+ export_long->negative = 0 ;
1817
+ export_long->ndigits = 0 ;
1818
+ export_long->digits = 0 ;
1819
+ export_long->_reserved = 0 ;
1820
+ }
1821
+ else {
1822
+ export_long->value = 0 ;
1823
+ export_long->negative = _PyLong_Sign (obj) < 0 ;
1824
+ export_long->ndigits = _PyLong_DigitCount (self);
1825
+ if (export_long->ndigits == 0 ) {
1826
+ export_long->ndigits = 1 ;
1827
+ }
1828
+ export_long->digits = _PyLong_GetDigits (self);
1829
+ export_long->_reserved = (Py_uintptr_t)Py_NewRef (obj);
1830
+ }
1831
+ return 0 ;
1832
+ }
1833
+
1834
+ static inline void
1835
+ PyLong_FreeExport (PyLongExport *export_long)
1836
+ {
1837
+ PyObject *obj = (PyObject*)export_long->_reserved ;
1838
+
1839
+ if (obj) {
1840
+ export_long->_reserved = 0 ;
1841
+ Py_DECREF (obj);
1842
+ }
1843
+ }
1844
+
1845
+ static inline PyLongWriter*
1846
+ PyLongWriter_Create (int negative, Py_ssize_t ndigits, void **digits)
1847
+ {
1848
+ if (ndigits <= 0 ) {
1849
+ PyErr_SetString (PyExc_ValueError, " ndigits must be positive" );
1850
+ return NULL ;
1851
+ }
1852
+ assert (digits != NULL );
1853
+
1854
+ PyLongObject *obj = _PyLong_New (ndigits);
1855
+ if (obj == NULL ) {
1856
+ return NULL ;
1857
+ }
1858
+ _PyLong_SetSignAndDigitCount (obj, negative?-1 :1 , ndigits);
1859
+
1860
+ *digits = _PyLong_GetDigits (obj);
1861
+ return (PyLongWriter*)obj;
1862
+ }
1863
+
1864
+ static inline void
1865
+ PyLongWriter_Discard (PyLongWriter *writer)
1866
+ {
1867
+ PyLongObject *obj = (PyLongObject *)writer;
1868
+
1869
+ assert (Py_REFCNT (obj) == 1 );
1870
+ Py_DECREF (obj);
1871
+ }
1872
+
1873
+ static inline PyObject*
1874
+ PyLongWriter_Finish (PyLongWriter *writer)
1875
+ {
1876
+ PyObject *obj = (PyObject *)writer;
1877
+ PyLongObject *self = (PyLongObject*)obj;
1878
+ Py_ssize_t j = _PyLong_DigitCount (self);
1879
+ Py_ssize_t i = j;
1880
+ int sign = _PyLong_Sign (obj);
1881
+
1882
+ assert (Py_REFCNT (obj) == 1 );
1883
+
1884
+ // Normalize and get singleton if possible
1885
+ while (i > 0 && _PyLong_GetDigits (self)[i-1 ] == 0 ) {
1886
+ --i;
1887
+ }
1888
+ if (i != j) {
1889
+ if (i == 0 ) {
1890
+ sign = 0 ;
1891
+ }
1892
+ _PyLong_SetSignAndDigitCount (self, sign, i);
1893
+ }
1894
+ if (i <= 1 ) {
1895
+ long val = sign * (long )(_PyLong_GetDigits (self)[0 ]);
1896
+ Py_DECREF (obj);
1897
+ return PyLong_FromLong (val);
1898
+ }
1899
+
1900
+ return obj;
1901
+ }
1902
+ #endif
1903
+
1904
+
1905
+ #if PY_VERSION_HEX < 0x030C00A3
1906
+ # define Py_T_SHORT T_SHORT
1907
+ # define Py_T_INT T_INT
1908
+ # define Py_T_LONG T_LONG
1909
+ # define Py_T_FLOAT T_FLOAT
1910
+ # define Py_T_DOUBLE T_DOUBLE
1911
+ # define Py_T_STRING T_STRING
1912
+ # define _Py_T_OBJECT T_OBJECT
1913
+ # define Py_T_CHAR T_CHAR
1914
+ # define Py_T_BYTE T_BYTE
1915
+ # define Py_T_UBYTE T_UBYTE
1916
+ # define Py_T_USHORT T_USHORT
1917
+ # define Py_T_UINT T_UINT
1918
+ # define Py_T_ULONG T_ULONG
1919
+ # define Py_T_STRING_INPLACE T_STRING_INPLACE
1920
+ # define Py_T_BOOL T_BOOL
1921
+ # define Py_T_OBJECT_EX T_OBJECT_EX
1922
+ # define Py_T_LONGLONG T_LONGLONG
1923
+ # define Py_T_ULONGLONG T_ULONGLONG
1924
+ # define Py_T_PYSSIZET T_PYSSIZET
1925
+
1926
+ # if PY_VERSION_HEX >= 0x03000000 && !defined(PYPY_VERSION)
1927
+ # define _Py_T_NONE T_NONE
1928
+ # endif
1929
+
1930
+ # define Py_READONLY READONLY
1931
+ # define Py_AUDIT_READ READ_RESTRICTED
1932
+ # define _Py_WRITE_RESTRICTED PY_WRITE_RESTRICTED
1933
+ #endif
1934
+
1935
+
1693
1936
#ifdef __cplusplus
1694
1937
}
1695
1938
#endif
0 commit comments