Skip to content

Commit 71d8775

Browse files
authored
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.
1 parent 9485a0d commit 71d8775

File tree

10 files changed

+11
-168
lines changed

10 files changed

+11
-168
lines changed

Doc/c-api/bytes.rst

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,6 @@ called with a non-bytes parameter.
5858
5959
.. % XXX: This should be exactly the same as the table in PyErr_Format.
6060
.. % One should just refer to the other.
61-
.. % XXX: The descriptions for %zd and %zu are wrong, but the truth is complicated
62-
.. % because not all compilers support the %z width modifier -- we fake it
63-
.. % when necessary via interpolating PY_FORMAT_SIZE_T.
6461
6562
.. tabularcolumns:: |l|l|L|
6663

Doc/c-api/unicode.rst

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -397,10 +397,6 @@ APIs:
397397
ASCII-encoded string. The following format characters are allowed:
398398
399399
.. % This should be exactly the same as the table in PyErr_Format.
400-
.. % The descriptions for %zd and %zu are wrong, but the truth is complicated
401-
.. % because not all compilers support the %z width modifier -- we fake it
402-
.. % when necessary via interpolating PY_FORMAT_SIZE_T.
403-
.. % Similar comments apply to the %ll width modifier and
404400
405401
.. tabularcolumns:: |l|l|L|
406402

Include/pymacconfig.h

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -84,18 +84,6 @@
8484
# define HAVE_GCC_ASM_FOR_X87
8585
#endif
8686

87-
/*
88-
* The definition in pyconfig.h is only valid on the OS release
89-
* where configure ran on and not necessarily for all systems where
90-
* the executable can be used on.
91-
*
92-
* Specifically: OSX 10.4 has limited supported for '%zd', while
93-
* 10.5 has full support for '%zd'. A binary built on 10.5 won't
94-
* work properly on 10.4 unless we suppress the definition
95-
* of PY_FORMAT_SIZE_T
96-
*/
97-
#undef PY_FORMAT_SIZE_T
98-
9987

10088
#endif /* defined(_APPLE__) */
10189

Include/pyport.h

Lines changed: 3 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -186,32 +186,10 @@ typedef Py_ssize_t Py_ssize_clean_t;
186186
/* Largest possible value of size_t. */
187187
#define PY_SIZE_MAX SIZE_MAX
188188

189-
/* Macro kept for backward compatibility: use "z" in new code.
189+
/* Macro kept for backward compatibility: use directly "z" in new code.
190190
*
191-
* PY_FORMAT_SIZE_T is a platform-specific modifier for use in a printf
192-
* format to convert an argument with the width of a size_t or Py_ssize_t.
193-
* C99 introduced "z" for this purpose, but old MSVCs had not supported it.
194-
* Since MSVC supports "z" since (at least) 2015, we can just use "z"
195-
* for new code.
196-
*
197-
* These "high level" Python format functions interpret "z" correctly on
198-
* all platforms (Python interprets the format string itself, and does whatever
199-
* the platform C requires to convert a size_t/Py_ssize_t argument):
200-
*
201-
* PyBytes_FromFormat
202-
* PyErr_Format
203-
* PyBytes_FromFormatV
204-
* PyUnicode_FromFormatV
205-
*
206-
* Lower-level uses require that you interpolate the correct format modifier
207-
* yourself (e.g., calling printf, fprintf, sprintf, PyOS_snprintf); for
208-
* example,
209-
*
210-
* Py_ssize_t index;
211-
* fprintf(stderr, "index %" PY_FORMAT_SIZE_T "d sucks\n", index);
212-
*
213-
* That will expand to %zd or to something else correct for a Py_ssize_t on
214-
* the platform.
191+
* PY_FORMAT_SIZE_T is a modifier for use in a printf format to convert an
192+
* argument with the width of a size_t or Py_ssize_t: "z" (C99).
215193
*/
216194
#ifndef PY_FORMAT_SIZE_T
217195
# define PY_FORMAT_SIZE_T "z"
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Python now always use the ``%zu`` and ``%zd`` printf formats to format a
2+
``size_t`` or ``Py_ssize_t`` number. Building Python 3.12 requires a C11
3+
compiler, so these printf formats are now always supported. Patch by Victor
4+
Stinner.

Modules/_ctypes/_ctypes.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -396,9 +396,9 @@ _ctypes_alloc_format_string_with_shape(int ndim, const Py_ssize_t *shape,
396396
strcat(new_prefix, "(");
397397
for (k = 0; k < ndim; ++k) {
398398
if (k < ndim-1) {
399-
sprintf(buf, "%"PY_FORMAT_SIZE_T"d,", shape[k]);
399+
sprintf(buf, "%zd,", shape[k]);
400400
} else {
401-
sprintf(buf, "%"PY_FORMAT_SIZE_T"d)", shape[k]);
401+
sprintf(buf, "%zd)", shape[k]);
402402
}
403403
strcat(new_prefix, buf);
404404
}

Objects/object.c

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -274,11 +274,8 @@ PyObject_Print(PyObject *op, FILE *fp, int flags)
274274
}
275275
else {
276276
if (Py_REFCNT(op) <= 0) {
277-
/* XXX(twouters) cast refcount to long until %zd is
278-
universally available */
279277
Py_BEGIN_ALLOW_THREADS
280-
fprintf(fp, "<refcnt %ld at %p>",
281-
(long)Py_REFCNT(op), (void *)op);
278+
fprintf(fp, "<refcnt %zd at %p>", Py_REFCNT(op), (void *)op);
282279
Py_END_ALLOW_THREADS
283280
}
284281
else {
@@ -371,9 +368,7 @@ _PyObject_Dump(PyObject* op)
371368

372369
/* first, write fields which are the least likely to crash */
373370
fprintf(stderr, "object address : %p\n", (void *)op);
374-
/* XXX(twouters) cast refcount to long until %zd is
375-
universally available */
376-
fprintf(stderr, "object refcount : %ld\n", (long)Py_REFCNT(op));
371+
fprintf(stderr, "object refcount : %zd\n", Py_REFCNT(op));
377372
fflush(stderr);
378373

379374
PyTypeObject *type = Py_TYPE(op);

configure

Lines changed: 0 additions & 66 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

configure.ac

Lines changed: 0 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -6004,52 +6004,6 @@ then
60046004
LIBS="$LIBS -framework CoreFoundation"
60056005
fi
60066006

6007-
AC_CACHE_CHECK([for %zd printf() format support], ac_cv_have_size_t_format, [dnl
6008-
AC_RUN_IFELSE([AC_LANG_SOURCE([[
6009-
#include <stdio.h>
6010-
#include <stddef.h>
6011-
#include <string.h>
6012-
6013-
#ifdef HAVE_SYS_TYPES_H
6014-
#include <sys/types.h>
6015-
#endif
6016-
6017-
#ifdef HAVE_SSIZE_T
6018-
typedef ssize_t Py_ssize_t;
6019-
#elif SIZEOF_VOID_P == SIZEOF_LONG
6020-
typedef long Py_ssize_t;
6021-
#else
6022-
typedef int Py_ssize_t;
6023-
#endif
6024-
6025-
int main()
6026-
{
6027-
char buffer[256];
6028-
6029-
if(sprintf(buffer, "%zd", (size_t)123) < 0)
6030-
return 1;
6031-
6032-
if (strcmp(buffer, "123"))
6033-
return 1;
6034-
6035-
if (sprintf(buffer, "%zd", (Py_ssize_t)-123) < 0)
6036-
return 1;
6037-
6038-
if (strcmp(buffer, "-123"))
6039-
return 1;
6040-
6041-
return 0;
6042-
}
6043-
]])],
6044-
[ac_cv_have_size_t_format=yes],
6045-
[ac_cv_have_size_t_format=no],
6046-
[ac_cv_have_size_t_format="cross -- assuming yes"
6047-
])])
6048-
if test "$ac_cv_have_size_t_format" != no ; then
6049-
AC_DEFINE(PY_FORMAT_SIZE_T, "z",
6050-
[Define to printf format modifier for Py_ssize_t])
6051-
fi
6052-
60536007
AC_CHECK_TYPE(socklen_t,,
60546008
AC_DEFINE(socklen_t,int,
60556009
[Define to `int' if <sys/socket.h> does not define.]),[

pyconfig.h.in

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1506,9 +1506,6 @@
15061506
/* Define if you want to coerce the C locale to a UTF-8 based locale */
15071507
#undef PY_COERCE_C_LOCALE
15081508

1509-
/* Define to printf format modifier for Py_ssize_t */
1510-
#undef PY_FORMAT_SIZE_T
1511-
15121509
/* Define to 1 to build the sqlite module with loadable extensions support. */
15131510
#undef PY_SQLITE_ENABLE_LOAD_EXTENSION
15141511

0 commit comments

Comments
 (0)