Outdated macros
---------------
-The following macros have been used to features that have been standardized
-in C11.
+The following :term:`soft deprecated` macros have been used to features that
+have been standardized in C11 (or previous standards).
.. c:macro:: Py_ALIGNED(num)
- Specify alignment to *num* bytes on compilers that support it.
+ On some GCC-like compilers, specify alignment to *num* bytes.
+ This does nothing on other compilers.
- Consider using the C11 standard ``_Alignas`` specifier over this macro.
+ Use the standard ``alignas`` specifier rather than this macro.
+
+ .. deprecated:: next
+ The macro is :term:`soft deprecated`.
+
+.. c:macro:: PY_FORMAT_SIZE_T
+
+ The :c:func:`printf` formatting modifier for :c:type:`size_t`.
+ Use ``"z"`` directly instead.
+
+ .. deprecated:: next
+ The macro is :term:`soft deprecated`.
.. c:macro:: Py_LL(number)
Py_ULL(number)
Consider using the C99 standard suffixes ``LL`` and ``LLU`` directly.
+ .. deprecated:: next
+ The macro is :term:`soft deprecated`.
+
+.. c:macro:: PY_LONG_LONG
+ PY_INT32_T
+ PY_UINT32_T
+ PY_INT64_T
+ PY_UINT64_T
+
+ Aliases for the types :c:type:`!long long`, :c:type:`!int32_t`,
+ :c:type:`!uint32_t`. :c:type:`!int64_t` and :c:type:`!uint64_t`,
+ respectively.
+ Historically, these types needed compiler-specific extensions.
+
+ .. deprecated:: next
+ These macros are :term:`soft deprecated`.
+
+.. c:macro:: PY_LLONG_MIN
+ PY_LLONG_MAX
+ PY_ULLONG_MAX
+ PY_SIZE_MAX
+
+ Aliases for the values :c:macro:`!LLONG_MIN`, :c:macro:`!LLONG_MAX`,
+ :c:macro:`!ULLONG_MAX`, and :c:macro:`!SIZE_MAX`, respectively.
+ Use these standard names instead.
+
+ The required header, ``<limits.h>``,
+ :ref:`is included <capi-system-includes>` in ``Python.h``.
+
+ .. deprecated:: next
+ These macros are :term:`soft deprecated`.
+
.. c:macro:: Py_MEMCPY(dest, src, n)
This is a :term:`soft deprecated` alias to :c:func:`!memcpy`.
.. deprecated:: 3.14
The macro is :term:`soft deprecated`.
+.. c:macro:: Py_UNICODE_SIZE
+
+ Size of the :c:type:`!wchar_t` type.
+ Use ``sizeof(wchar_t)`` or ``WCHAR_WIDTH/8`` instead.
+
+ The required header for the latter, ``<limits.h>``,
+ :ref:`is included <capi-system-includes>` in ``Python.h``.
+
+ .. deprecated:: next
+ The macro is :term:`soft deprecated`.
+
+.. c:macro:: Py_UNICODE_WIDE
+
+ Defined if ``wchar_t`` can hold a Unicode character (UCS-4).
+ Use ``sizeof(wchar_t) >= 4`` instead
+
+ .. deprecated:: next
+ The macro is :term:`soft deprecated`.
+
.. c:macro:: Py_VA_COPY
This is a :term:`soft deprecated` alias to the C99-standard ``va_copy``
.. versionchanged:: 3.6
This is now an alias to ``va_copy``.
+ .. deprecated:: next
+ The macro is :term:`soft deprecated`.
+
.. _api-objects:
Use :c:func:`PyWeakref_GetRef` instead. The `pythoncapi-compat project
<https://github.com/python/pythoncapi-compat/>`__ can be used to get
:c:func:`PyWeakref_GetRef` on Python 3.12 and older.
-* :c:type:`Py_UNICODE` type and the :c:macro:`!Py_UNICODE_WIDE` macro:
- Use :c:type:`wchar_t` instead.
* :c:func:`!PyUnicode_AsDecodedObject`:
Use :c:func:`PyCodec_Decode` instead.
* :c:func:`!PyUnicode_AsDecodedUnicode`:
use the C11 standard ``<math.h>`` :c:macro:`!INFINITY` instead.
(Contributed by Sergey B Kirpichev in :gh:`141004`.)
+* The following macros are :term:`soft deprecated`:
+
+ - :c:macro:`Py_ALIGNED`: Prefer ``alignas`` instead.
+ - :c:macro:`PY_FORMAT_SIZE_T`: Use ``"z"`` directly.
+ - :c:macro:`Py_LL` & :c:macro:`Py_ULL`:
+ Use standard suffixes, ``LL`` & ``ULL``.
+ - :c:macro:`PY_LONG_LONG`, :c:macro:`PY_LLONG_MIN`, :c:macro:`PY_LLONG_MAX`,
+ :c:macro:`PY_ULLONG_MAX`, :c:macro:`PY_INT32_T`, :c:macro:`PY_UINT32_T`,
+ :c:macro:`PY_INT64_T`, :c:macro:`PY_UINT64_T`, :c:macro:`PY_SIZE_MAX`:
+ Use C99 types/limits.
+ - :c:macro:`Py_UNICODE_SIZE`: Use ``sizeof(wchar_t)`` directly.
+ - :c:macro:`Py_VA_COPY`: Use ``va_copy`` directly.
+
+ The macro :c:macro:`Py_UNICODE_WIDE`, which was scheduled for removal,
+ is :term:`soft deprecated` instead.
+
+ (Contributed by Petr Viktorin in :gh:`146175`.)
+
* :c:macro:`!Py_MATH_El` and :c:macro:`!Py_MATH_PIl` are deprecated
since 3.15 and will be removed in 3.20.
(Contributed by Sergey B Kirpichev in :gh:`141004`.)
new_refcnt = _Py_IMMORTAL_INITIAL_REFCNT;
}
# if SIZEOF_VOID_P > 4
- op->ob_refcnt = (PY_UINT32_T)new_refcnt;
+ op->ob_refcnt = (uint32_t)new_refcnt;
# else
op->ob_refcnt = new_refcnt;
# endif
struct _object {
_Py_ANONYMOUS union {
#if SIZEOF_VOID_P > 4
- PY_INT64_T ob_refcnt_full; /* This field is needed for efficient initialization with Clang on ARM */
+ int64_t ob_refcnt_full; /* This field is needed for efficient initialization with Clang on ARM */
struct {
# if PY_BIG_ENDIAN
uint16_t ob_flags;
/*
* Specify alignment on compilers that support it.
*/
-#if defined(__GNUC__) && __GNUC__ >= 3
+#ifdef Py_BUILD_CORE
+// always use _Py_ALIGNED_DEF instead
+#elif defined(__GNUC__) && __GNUC__ >= 3
#define Py_ALIGNED(x) __attribute__((aligned(x)))
#else
#define Py_ALIGNED(x)
return (_Py_atomic_load_uint32_relaxed(&op->ob_ref_local) ==
_Py_IMMORTAL_REFCNT_LOCAL);
#elif SIZEOF_VOID_P > 4
- return _Py_CAST(PY_INT32_T, op->ob_refcnt) < 0;
+ return _Py_CAST(int32_t, op->ob_refcnt) < 0;
#else
return op->ob_refcnt >= _Py_IMMORTAL_MINIMUM_REFCNT;
#endif
}
#ifndef Py_GIL_DISABLED
#if SIZEOF_VOID_P > 4
- ob->ob_refcnt = (PY_UINT32_T)refcnt;
+ ob->ob_refcnt = (uint32_t)refcnt;
#else
ob->ob_refcnt = refcnt;
#endif
_Py_atomic_add_ssize(&op->ob_ref_shared, (1 << _Py_REF_SHARED_SHIFT));
}
#elif SIZEOF_VOID_P > 4
- PY_UINT32_T cur_refcnt = op->ob_refcnt;
+ uint32_t cur_refcnt = op->ob_refcnt;
if (cur_refcnt >= _Py_IMMORTAL_INITIAL_REFCNT) {
// the object is immortal
_Py_INCREF_IMMORTAL_STAT_INC();
#if SIZEOF_VOID_P > 4
/* If an object has been freed, it will have a negative full refcnt
* If it has not it been freed, will have a very large refcnt */
- if (op->ob_refcnt_full <= 0 || op->ob_refcnt > (((PY_UINT32_T)-1) - (1<<20))) {
+ if (op->ob_refcnt_full <= 0 || op->ob_refcnt > (((uint32_t)-1) - (1<<20))) {
#else
if (op->ob_refcnt <= 0) {
#endif
#error Must define SIZEOF_WCHAR_T
#endif
+/* Soft-deprecated defines */
#define Py_UNICODE_SIZE SIZEOF_WCHAR_T
-
-/* If wchar_t can be used for UCS-4 storage, set Py_UNICODE_WIDE.
- Otherwise, Unicode strings are stored as UCS-2 (with limited support
- for UTF-16) */
-
-#if Py_UNICODE_SIZE >= 4
+#if SIZEOF_WCHAR_T >= 4
#define Py_UNICODE_WIDE
#endif
--- /dev/null
+The following macros are :term:`soft deprecated`:
+:c:macro:`Py_ALIGNED`,
+:c:macro:`PY_FORMAT_SIZE_T`,
+:c:macro:`Py_LL`, :c:macro:`Py_ULL`,
+:c:macro:`PY_LONG_LONG`, :c:macro:`PY_LLONG_MIN`, :c:macro:`PY_LLONG_MAX`,
+:c:macro:`PY_ULLONG_MAX`, :c:macro:`PY_INT32_T`, :c:macro:`PY_UINT32_T`,
+:c:macro:`PY_INT64_T`, :c:macro:`PY_UINT64_T`, :c:macro:`PY_SIZE_MAX`,
+:c:macro:`Py_UNICODE_SIZE`,
+:c:macro:`Py_VA_COPY`.
+
+The macro :c:macro:`Py_UNICODE_WIDE`, which was scheduled for removal, is
+:term:`soft deprecated` instead.
alloc = size + 1;
}
- if (alloc > PY_SIZE_MAX / sizeof(Py_UCS4))
+ if (alloc > SIZE_MAX / sizeof(Py_UCS4))
goto overflow;
new_buf = (Py_UCS4 *)PyMem_Realloc(self->buf, alloc * sizeof(Py_UCS4));
if (new_buf == NULL) {
}
+static PyObject*
+test_soft_deprecated_macros(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(args))
+{
+ // Test soft-deprecated macros
+ Py_ALIGNED(64) char buf[4];
+ #ifdef __GNUC__
+ // Py_ALIGNED must compile everywhere, but only does something
+ // on "supported" compilers, i.e. GCC
+ Py_BUILD_ASSERT(__extension__ __alignof__(buf) >= 64);
+ #endif
+ assert(strcmp(PY_FORMAT_SIZE_T, "z") == 0);
+ Py_BUILD_ASSERT(Py_LL(123) == 123LL);
+ Py_BUILD_ASSERT(sizeof(Py_LL(123)) == sizeof(long long));
+ Py_BUILD_ASSERT(sizeof(Py_ULL(123)) == sizeof(unsigned long long));
+ Py_BUILD_ASSERT(sizeof(PY_LONG_LONG) == sizeof(long long));
+ Py_BUILD_ASSERT(sizeof(PY_INT32_T) == sizeof(int32_t));
+ Py_BUILD_ASSERT(sizeof(PY_UINT32_T) == sizeof(uint32_t));
+ Py_BUILD_ASSERT(sizeof(PY_INT64_T) == sizeof(int64_t));
+ Py_BUILD_ASSERT(sizeof(PY_UINT64_T) == sizeof(uint64_t));
+ Py_BUILD_ASSERT(PY_LLONG_MIN == LLONG_MIN);
+ Py_BUILD_ASSERT(PY_LLONG_MAX == LLONG_MAX);
+ Py_BUILD_ASSERT(PY_ULLONG_MAX == ULLONG_MAX);
+ Py_BUILD_ASSERT(PY_SIZE_MAX == SIZE_MAX);
+ Py_BUILD_ASSERT(PY_LLONG_MIN == LLONG_MIN);
+ Py_MEMCPY(buf, "abc", 4);
+ assert(strcmp(buf, "abc") == 0);
+ Py_BUILD_ASSERT(Py_UNICODE_SIZE == sizeof(wchar_t));
+ #ifdef Py_UNICODE_WIDE
+ Py_BUILD_ASSERT(sizeof(wchar_t) >= 4);
+ #else
+ Py_BUILD_ASSERT(sizeof(wchar_t) < 4);
+ #endif
+ Py_RETURN_NONE;
+}
+
static PyMethodDef TestMethods[] = {
{"set_errno", set_errno, METH_VARARGS},
{"test_config", test_config, METH_NOARGS},
{"toggle_reftrace_printer", toggle_reftrace_printer, METH_O},
{"create_managed_weakref_nogc_type",
create_managed_weakref_nogc_type, METH_NOARGS},
+ {"test_soft_deprecated_macros", test_soft_deprecated_macros, METH_NOARGS},
{NULL, NULL} /* sentinel */
};
view->internal = NULL;
if ((flags & PyBUF_FORMAT) == PyBUF_FORMAT) {
view->format = (char *)self->ob_descr->formats;
-#ifdef Py_UNICODE_WIDE
- if (self->ob_descr->typecode == 'u') {
+ if (sizeof(wchar_t) >= 4 && self->ob_descr->typecode == 'u') {
view->format = "w";
}
-#endif
}
self->ob_exports++;
/* Align to 64 bytes for L1 cache line friendliness */
-static const unsigned char table_a2b_base64[] Py_ALIGNED(64) = {
+static const _Py_ALIGNED_DEF(64, unsigned char) table_a2b_base64[] = {
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63,
*/
/* Align to 64 bytes for L1 cache line friendliness */
-static const unsigned char table_b2a_base64[] Py_ALIGNED(64) =
+static const _Py_ALIGNED_DEF(64, unsigned char) table_b2a_base64[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
/* Encode 3 bytes into 4 base64 characters. */
}
-static const unsigned char table_a2b_base85[] Py_ALIGNED(64) = {
+static const _Py_ALIGNED_DEF(64, unsigned char) table_a2b_base85[] = {
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
-1,62,-1,63, 64,65,66,-1, 67,68,69,70, -1,71,-1,-1,
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
};
-static const unsigned char table_a2b_base85_a85[] Py_ALIGNED(64) = {
+static const _Py_ALIGNED_DEF(64, unsigned char) table_a2b_base85_a85[] = {
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14,
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
};
-static const unsigned char table_b2a_base85[] Py_ALIGNED(64) =
+static const _Py_ALIGNED_DEF(64, unsigned char) table_b2a_base85[] =
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" \
"abcdefghijklmnopqrstuvwxyz!#$%&()*+-;<=>?@^_`{|}~";
-static const unsigned char table_b2a_base85_a85[] Py_ALIGNED(64) =
+static const _Py_ALIGNED_DEF(64, unsigned char) table_b2a_base85_a85[] =
"!\"#$%&\'()*+,-./0123456789:;<=>?@" \
"ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstu";
#define BASE85_A85_Y 0x20202020
-static const unsigned char table_a2b_base32[] Py_ALIGNED(64) = {
+static const _Py_ALIGNED_DEF(64, unsigned char) table_a2b_base32[] = {
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
};
-static const unsigned char table_b2a_base32[] Py_ALIGNED(64) =
+static const _Py_ALIGNED_DEF(64, unsigned char) table_b2a_base32[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
#define BASE32_PAD '='
gethostbyaddr_r is 8-byte aligned, which at least llvm-gcc
does not ensure. The attribute below instructs the compiler
to maintain this alignment. */
- char buf[16384] Py_ALIGNED(8);
+ _Py_ALIGNED_DEF(8, char) buf[16384];
int buf_len = (sizeof buf) - 1;
int errnop;
#endif
Py_ssize_t ch_pos = i;
Py_UCS4 ch = text[i];
i++;
-#if Py_UNICODE_SIZE == 2
- if (Py_UNICODE_IS_HIGH_SURROGATE(ch)
+ if (sizeof(wchar_t) == 2
+ && Py_UNICODE_IS_HIGH_SURROGATE(ch)
&& i < len
&& Py_UNICODE_IS_LOW_SURROGATE(text[i]))
{
ch = Py_UNICODE_JOIN_SURROGATES(ch, text[i]);
i++;
}
-#endif
if (ch < 0x80) {
/* Encode ASCII */
# pyport.h
PYLONG_BITS_IN_DIGIT
PY_DWORD_MAX
-PY_FORMAT_SIZE_T
-PY_INT32_T
-PY_INT64_T
-PY_LLONG_MAX
-PY_LLONG_MIN
-PY_LONG_LONG
-PY_SIZE_MAX
-PY_UINT32_T
-PY_UINT64_T
-PY_ULLONG_MAX
PY_BIG_ENDIAN
-# unicodeobject.h
-Py_UNICODE_SIZE
# cpython/methodobject.h
PyCFunction_GET_CLASS
# cpython/compile.h