diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-10-26-04-00-00.gh-issue-160725.pRnT8w.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-10-26-04-00-00.gh-issue-160725.pRnT8w.rst new file mode 100644 index 00000000000000..3cd098613e5afa --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-10-26-04-00-00.gh-issue-160725.pRnT8w.rst @@ -0,0 +1,2 @@ +Speed up :func:`print` by looking up the file's :meth:`~file.write` method +once per call. diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index 10c5428159e66f..ab3381746321ec 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -2241,6 +2241,23 @@ builtin_pow_impl(PyObject *module, PyObject *base, PyObject *exp, return PyNumber_Power(base, exp, mod); } +/* Write str(obj) by calling write. */ +static int +print_write(PyObject *write, PyObject *obj) +{ + PyObject *str = PyObject_Str(obj); + if (str == NULL) { + return -1; + } + PyObject *result = PyObject_CallOneArg(write, str); + Py_DECREF(str); + if (result == NULL) { + return -1; + } + Py_DECREF(result); + return 0; +} + /*[clinic input] print as builtin_print @@ -2264,7 +2281,7 @@ builtin_print_impl(PyObject *module, PyObject * const *objects, PyObject *file, int flush) /*[clinic end generated code: output=38d8def56c837bcc input=ff35cb3d59ee8115]*/ { - int i, err; + int i; if (file == Py_None) { file = PySys_GetAttr(&_Py_ID(stdout)); @@ -2283,7 +2300,7 @@ builtin_print_impl(PyObject *module, PyObject * const *objects, } if (sep == Py_None) { - sep = NULL; + sep = _Py_LATIN1_CHR(' '); } else if (sep && !PyUnicode_Check(sep)) { PyErr_Format(PyExc_TypeError, @@ -2293,7 +2310,7 @@ builtin_print_impl(PyObject *module, PyObject * const *objects, return NULL; } if (end == Py_None) { - end = NULL; + end = _Py_LATIN1_CHR('\n'); } else if (end && !PyUnicode_Check(end)) { PyErr_Format(PyExc_TypeError, @@ -2303,36 +2320,23 @@ builtin_print_impl(PyObject *module, PyObject * const *objects, return NULL; } + PyObject *write = PyObject_GetAttr(file, &_Py_ID(write)); + if (write == NULL) { + Py_DECREF(file); + return NULL; + } for (i = 0; i < objects_length; i++) { - if (i > 0) { - if (sep == NULL) { - err = PyFile_WriteString(" ", file); - } - else { - err = PyFile_WriteObject(sep, file, Py_PRINT_RAW); - } - if (err) { - Py_DECREF(file); - return NULL; - } + if (i > 0 && print_write(write, sep) < 0) { + goto error; } - err = PyFile_WriteObject(objects[i], file, Py_PRINT_RAW); - if (err) { - Py_DECREF(file); - return NULL; + if (print_write(write, objects[i]) < 0) { + goto error; } } - - if (end == NULL) { - err = PyFile_WriteString("\n", file); - } - else { - err = PyFile_WriteObject(end, file, Py_PRINT_RAW); - } - if (err) { - Py_DECREF(file); - return NULL; + if (print_write(write, end) < 0) { + goto error; } + Py_DECREF(write); if (flush) { if (_PyFile_Flush(file) < 0) { @@ -2343,6 +2347,11 @@ builtin_print_impl(PyObject *module, PyObject * const *objects, Py_DECREF(file); Py_RETURN_NONE; + +error: + Py_DECREF(write); + Py_DECREF(file); + return NULL; }