mirror of https://github.com/python/cpython
gh-93202: Always use %zd printf formatter (#93201)
Python now always use the ``%zu`` and ``%zd`` printf formats to format a size_t or Py_ssize_t number. Building Python 3.12 requires a C11 compiler, so these printf formats are now always supported. * PyObject_Print() and _PyObject_Dump() now use the printf %zd format to display an object reference count. * Update PY_FORMAT_SIZE_T comment. * Remove outdated notes about the %zd format in PyBytes_FromFormat() and PyUnicode_FromFormat() documentations. * configure no longer checks for the %zd format and no longer defines PY_FORMAT_SIZE_T macro in pyconfig.h. * pymacconfig.h no longer undefines PY_FORMAT_SIZE_T: macOS 10.4 is no longer supported. Python 3.12 now requires macOS 10.6 (Snow Leopard) or newer.
This commit is contained in:
parent
9485a0dbdd
commit
71d8775fee
|
@ -58,9 +58,6 @@ called with a non-bytes parameter.
|
||||||
|
|
||||||
.. % XXX: This should be exactly the same as the table in PyErr_Format.
|
.. % XXX: This should be exactly the same as the table in PyErr_Format.
|
||||||
.. % One should just refer to the other.
|
.. % One should just refer to the other.
|
||||||
.. % XXX: The descriptions for %zd and %zu are wrong, but the truth is complicated
|
|
||||||
.. % because not all compilers support the %z width modifier -- we fake it
|
|
||||||
.. % when necessary via interpolating PY_FORMAT_SIZE_T.
|
|
||||||
|
|
||||||
.. tabularcolumns:: |l|l|L|
|
.. tabularcolumns:: |l|l|L|
|
||||||
|
|
||||||
|
|
|
@ -397,10 +397,6 @@ APIs:
|
||||||
ASCII-encoded string. The following format characters are allowed:
|
ASCII-encoded string. The following format characters are allowed:
|
||||||
|
|
||||||
.. % This should be exactly the same as the table in PyErr_Format.
|
.. % This should be exactly the same as the table in PyErr_Format.
|
||||||
.. % The descriptions for %zd and %zu are wrong, but the truth is complicated
|
|
||||||
.. % because not all compilers support the %z width modifier -- we fake it
|
|
||||||
.. % when necessary via interpolating PY_FORMAT_SIZE_T.
|
|
||||||
.. % Similar comments apply to the %ll width modifier and
|
|
||||||
|
|
||||||
.. tabularcolumns:: |l|l|L|
|
.. tabularcolumns:: |l|l|L|
|
||||||
|
|
||||||
|
|
|
@ -84,18 +84,6 @@
|
||||||
# define HAVE_GCC_ASM_FOR_X87
|
# define HAVE_GCC_ASM_FOR_X87
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
|
||||||
* The definition in pyconfig.h is only valid on the OS release
|
|
||||||
* where configure ran on and not necessarily for all systems where
|
|
||||||
* the executable can be used on.
|
|
||||||
*
|
|
||||||
* Specifically: OSX 10.4 has limited supported for '%zd', while
|
|
||||||
* 10.5 has full support for '%zd'. A binary built on 10.5 won't
|
|
||||||
* work properly on 10.4 unless we suppress the definition
|
|
||||||
* of PY_FORMAT_SIZE_T
|
|
||||||
*/
|
|
||||||
#undef PY_FORMAT_SIZE_T
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* defined(_APPLE__) */
|
#endif /* defined(_APPLE__) */
|
||||||
|
|
||||||
|
|
|
@ -186,32 +186,10 @@ typedef Py_ssize_t Py_ssize_clean_t;
|
||||||
/* Largest possible value of size_t. */
|
/* Largest possible value of size_t. */
|
||||||
#define PY_SIZE_MAX SIZE_MAX
|
#define PY_SIZE_MAX SIZE_MAX
|
||||||
|
|
||||||
/* Macro kept for backward compatibility: use "z" in new code.
|
/* Macro kept for backward compatibility: use directly "z" in new code.
|
||||||
*
|
*
|
||||||
* PY_FORMAT_SIZE_T is a platform-specific modifier for use in a printf
|
* PY_FORMAT_SIZE_T is a modifier for use in a printf format to convert an
|
||||||
* format to convert an argument with the width of a size_t or Py_ssize_t.
|
* argument with the width of a size_t or Py_ssize_t: "z" (C99).
|
||||||
* C99 introduced "z" for this purpose, but old MSVCs had not supported it.
|
|
||||||
* Since MSVC supports "z" since (at least) 2015, we can just use "z"
|
|
||||||
* for new code.
|
|
||||||
*
|
|
||||||
* These "high level" Python format functions interpret "z" correctly on
|
|
||||||
* all platforms (Python interprets the format string itself, and does whatever
|
|
||||||
* the platform C requires to convert a size_t/Py_ssize_t argument):
|
|
||||||
*
|
|
||||||
* PyBytes_FromFormat
|
|
||||||
* PyErr_Format
|
|
||||||
* PyBytes_FromFormatV
|
|
||||||
* PyUnicode_FromFormatV
|
|
||||||
*
|
|
||||||
* Lower-level uses require that you interpolate the correct format modifier
|
|
||||||
* yourself (e.g., calling printf, fprintf, sprintf, PyOS_snprintf); for
|
|
||||||
* example,
|
|
||||||
*
|
|
||||||
* Py_ssize_t index;
|
|
||||||
* fprintf(stderr, "index %" PY_FORMAT_SIZE_T "d sucks\n", index);
|
|
||||||
*
|
|
||||||
* That will expand to %zd or to something else correct for a Py_ssize_t on
|
|
||||||
* the platform.
|
|
||||||
*/
|
*/
|
||||||
#ifndef PY_FORMAT_SIZE_T
|
#ifndef PY_FORMAT_SIZE_T
|
||||||
# define PY_FORMAT_SIZE_T "z"
|
# define PY_FORMAT_SIZE_T "z"
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
Python now always use the ``%zu`` and ``%zd`` printf formats to format a
|
||||||
|
``size_t`` or ``Py_ssize_t`` number. Building Python 3.12 requires a C11
|
||||||
|
compiler, so these printf formats are now always supported. Patch by Victor
|
||||||
|
Stinner.
|
|
@ -396,9 +396,9 @@ _ctypes_alloc_format_string_with_shape(int ndim, const Py_ssize_t *shape,
|
||||||
strcat(new_prefix, "(");
|
strcat(new_prefix, "(");
|
||||||
for (k = 0; k < ndim; ++k) {
|
for (k = 0; k < ndim; ++k) {
|
||||||
if (k < ndim-1) {
|
if (k < ndim-1) {
|
||||||
sprintf(buf, "%"PY_FORMAT_SIZE_T"d,", shape[k]);
|
sprintf(buf, "%zd,", shape[k]);
|
||||||
} else {
|
} else {
|
||||||
sprintf(buf, "%"PY_FORMAT_SIZE_T"d)", shape[k]);
|
sprintf(buf, "%zd)", shape[k]);
|
||||||
}
|
}
|
||||||
strcat(new_prefix, buf);
|
strcat(new_prefix, buf);
|
||||||
}
|
}
|
||||||
|
|
|
@ -274,11 +274,8 @@ PyObject_Print(PyObject *op, FILE *fp, int flags)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (Py_REFCNT(op) <= 0) {
|
if (Py_REFCNT(op) <= 0) {
|
||||||
/* XXX(twouters) cast refcount to long until %zd is
|
|
||||||
universally available */
|
|
||||||
Py_BEGIN_ALLOW_THREADS
|
Py_BEGIN_ALLOW_THREADS
|
||||||
fprintf(fp, "<refcnt %ld at %p>",
|
fprintf(fp, "<refcnt %zd at %p>", Py_REFCNT(op), (void *)op);
|
||||||
(long)Py_REFCNT(op), (void *)op);
|
|
||||||
Py_END_ALLOW_THREADS
|
Py_END_ALLOW_THREADS
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -371,9 +368,7 @@ _PyObject_Dump(PyObject* op)
|
||||||
|
|
||||||
/* first, write fields which are the least likely to crash */
|
/* first, write fields which are the least likely to crash */
|
||||||
fprintf(stderr, "object address : %p\n", (void *)op);
|
fprintf(stderr, "object address : %p\n", (void *)op);
|
||||||
/* XXX(twouters) cast refcount to long until %zd is
|
fprintf(stderr, "object refcount : %zd\n", Py_REFCNT(op));
|
||||||
universally available */
|
|
||||||
fprintf(stderr, "object refcount : %ld\n", (long)Py_REFCNT(op));
|
|
||||||
fflush(stderr);
|
fflush(stderr);
|
||||||
|
|
||||||
PyTypeObject *type = Py_TYPE(op);
|
PyTypeObject *type = Py_TYPE(op);
|
||||||
|
|
|
@ -21150,72 +21150,6 @@ then
|
||||||
LIBS="$LIBS -framework CoreFoundation"
|
LIBS="$LIBS -framework CoreFoundation"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for %zd printf() format support" >&5
|
|
||||||
$as_echo_n "checking for %zd printf() format support... " >&6; }
|
|
||||||
if ${ac_cv_have_size_t_format+:} false; then :
|
|
||||||
$as_echo_n "(cached) " >&6
|
|
||||||
else
|
|
||||||
if test "$cross_compiling" = yes; then :
|
|
||||||
ac_cv_have_size_t_format="cross -- assuming yes"
|
|
||||||
|
|
||||||
else
|
|
||||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
|
||||||
/* end confdefs.h. */
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#ifdef HAVE_SYS_TYPES_H
|
|
||||||
#include <sys/types.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_SSIZE_T
|
|
||||||
typedef ssize_t Py_ssize_t;
|
|
||||||
#elif SIZEOF_VOID_P == SIZEOF_LONG
|
|
||||||
typedef long Py_ssize_t;
|
|
||||||
#else
|
|
||||||
typedef int Py_ssize_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
char buffer[256];
|
|
||||||
|
|
||||||
if(sprintf(buffer, "%zd", (size_t)123) < 0)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
if (strcmp(buffer, "123"))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
if (sprintf(buffer, "%zd", (Py_ssize_t)-123) < 0)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
if (strcmp(buffer, "-123"))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
_ACEOF
|
|
||||||
if ac_fn_c_try_run "$LINENO"; then :
|
|
||||||
ac_cv_have_size_t_format=yes
|
|
||||||
else
|
|
||||||
ac_cv_have_size_t_format=no
|
|
||||||
fi
|
|
||||||
rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
|
|
||||||
conftest.$ac_objext conftest.beam conftest.$ac_ext
|
|
||||||
fi
|
|
||||||
|
|
||||||
fi
|
|
||||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_size_t_format" >&5
|
|
||||||
$as_echo "$ac_cv_have_size_t_format" >&6; }
|
|
||||||
if test "$ac_cv_have_size_t_format" != no ; then
|
|
||||||
|
|
||||||
$as_echo "#define PY_FORMAT_SIZE_T \"z\"" >>confdefs.h
|
|
||||||
|
|
||||||
fi
|
|
||||||
|
|
||||||
ac_fn_c_check_type "$LINENO" "socklen_t" "ac_cv_type_socklen_t" "
|
ac_fn_c_check_type "$LINENO" "socklen_t" "ac_cv_type_socklen_t" "
|
||||||
#ifdef HAVE_SYS_TYPES_H
|
#ifdef HAVE_SYS_TYPES_H
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
46
configure.ac
46
configure.ac
|
@ -6004,52 +6004,6 @@ then
|
||||||
LIBS="$LIBS -framework CoreFoundation"
|
LIBS="$LIBS -framework CoreFoundation"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
AC_CACHE_CHECK([for %zd printf() format support], ac_cv_have_size_t_format, [dnl
|
|
||||||
AC_RUN_IFELSE([AC_LANG_SOURCE([[
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#ifdef HAVE_SYS_TYPES_H
|
|
||||||
#include <sys/types.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_SSIZE_T
|
|
||||||
typedef ssize_t Py_ssize_t;
|
|
||||||
#elif SIZEOF_VOID_P == SIZEOF_LONG
|
|
||||||
typedef long Py_ssize_t;
|
|
||||||
#else
|
|
||||||
typedef int Py_ssize_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
char buffer[256];
|
|
||||||
|
|
||||||
if(sprintf(buffer, "%zd", (size_t)123) < 0)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
if (strcmp(buffer, "123"))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
if (sprintf(buffer, "%zd", (Py_ssize_t)-123) < 0)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
if (strcmp(buffer, "-123"))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
]])],
|
|
||||||
[ac_cv_have_size_t_format=yes],
|
|
||||||
[ac_cv_have_size_t_format=no],
|
|
||||||
[ac_cv_have_size_t_format="cross -- assuming yes"
|
|
||||||
])])
|
|
||||||
if test "$ac_cv_have_size_t_format" != no ; then
|
|
||||||
AC_DEFINE(PY_FORMAT_SIZE_T, "z",
|
|
||||||
[Define to printf format modifier for Py_ssize_t])
|
|
||||||
fi
|
|
||||||
|
|
||||||
AC_CHECK_TYPE(socklen_t,,
|
AC_CHECK_TYPE(socklen_t,,
|
||||||
AC_DEFINE(socklen_t,int,
|
AC_DEFINE(socklen_t,int,
|
||||||
[Define to `int' if <sys/socket.h> does not define.]),[
|
[Define to `int' if <sys/socket.h> does not define.]),[
|
||||||
|
|
|
@ -1506,9 +1506,6 @@
|
||||||
/* Define if you want to coerce the C locale to a UTF-8 based locale */
|
/* Define if you want to coerce the C locale to a UTF-8 based locale */
|
||||||
#undef PY_COERCE_C_LOCALE
|
#undef PY_COERCE_C_LOCALE
|
||||||
|
|
||||||
/* Define to printf format modifier for Py_ssize_t */
|
|
||||||
#undef PY_FORMAT_SIZE_T
|
|
||||||
|
|
||||||
/* Define to 1 to build the sqlite module with loadable extensions support. */
|
/* Define to 1 to build the sqlite module with loadable extensions support. */
|
||||||
#undef PY_SQLITE_ENABLE_LOAD_EXTENSION
|
#undef PY_SQLITE_ENABLE_LOAD_EXTENSION
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue