Mailing List Archive

gh-117642: Fix PEP 737 implementation (GH-117643)
https://github.com/python/cpython/commit/24a2bd048115efae799b0a9c5dd9fbb7a0806978
commit: 24a2bd048115efae799b0a9c5dd9fbb7a0806978
branch: main
author: Serhiy Storchaka <storchaka@gmail.com>
committer: serhiy-storchaka <storchaka@gmail.com>
date: 2024-04-08T16:27:25Z
summary:

gh-117642: Fix PEP 737 implementation (GH-117643)

* Fix implementation of %#T and %#N (they were implemented as %T# and
%N#).
* Restore tests removed in gh-116417.

files:
A Misc/NEWS.d/next/C API/2024-04-08-18-53-33.gh-issue-117642._-tYH_.rst
M Doc/c-api/unicode.rst
M Doc/whatsnew/3.13.rst
M Lib/test/test_capi/test_unicode.py
M Objects/unicodeobject.c

diff --git a/Doc/c-api/unicode.rst b/Doc/c-api/unicode.rst
index 78eec14e3a24d6..7320d035bab513 100644
--- a/Doc/c-api/unicode.rst
+++ b/Doc/c-api/unicode.rst
@@ -523,7 +523,7 @@ APIs:
- Get the fully qualified name of an object type;
call :c:func:`PyType_GetFullyQualifiedName`.

- * - ``T#``
+ * - ``#T``
- :c:expr:`PyObject*`
- Similar to ``T`` format, but use a colon (``:``) as separator between
the module name and the qualified name.
@@ -533,7 +533,7 @@ APIs:
- Get the fully qualified name of a type;
call :c:func:`PyType_GetFullyQualifiedName`.

- * - ``N#``
+ * - ``#N``
- :c:expr:`PyTypeObject*`
- Similar to ``N`` format, but use a colon (``:``) as separator between
the module name and the qualified name.
@@ -574,7 +574,7 @@ APIs:
copied as-is to the result string, and any extra arguments discarded.

.. versionchanged:: 3.13
- Support for ``%T``, ``%T#``, ``%N`` and ``%N#`` formats added.
+ Support for ``%T``, ``%#T``, ``%N`` and ``%#N`` formats added.


.. c:function:: PyObject* PyUnicode_FromFormatV(const char *format, va_list vargs)
diff --git a/Doc/whatsnew/3.13.rst b/Doc/whatsnew/3.13.rst
index 0fe2dafbfd6f02..72b3a4c951eda6 100644
--- a/Doc/whatsnew/3.13.rst
+++ b/Doc/whatsnew/3.13.rst
@@ -1775,7 +1775,7 @@ New Features
Equivalent to getting the ``type.__module__`` attribute.
(Contributed by Eric Snow and Victor Stinner in :gh:`111696`.)

-* Add support for ``%T``, ``%T#``, ``%N`` and ``%N#`` formats to
+* Add support for ``%T``, ``%#T``, ``%N`` and ``%#N`` formats to
:c:func:`PyUnicode_FromFormat`: format the fully qualified name of an object
type and of a type: call :c:func:`PyType_GetModuleName`. See :pep:`737` for
more information.
diff --git a/Lib/test/test_capi/test_unicode.py b/Lib/test/test_capi/test_unicode.py
index a64c75c415c3fe..a69f817c515ba7 100644
--- a/Lib/test/test_capi/test_unicode.py
+++ b/Lib/test/test_capi/test_unicode.py
@@ -650,6 +650,40 @@ def check_format(expected, format, *args):
check_format('\U0001f4bb+' if sizeof(c_wchar) > 2 else '\U0001f4bb',
b'%.2lV', None, c_wchar_p('\U0001f4bb+\U0001f40d'))

+ # test %T
+ check_format('type: str',
+ b'type: %T', py_object("abc"))
+ check_format(f'type: st',
+ b'type: %.2T', py_object("abc"))
+ check_format(f'type: str',
+ b'type: %10T', py_object("abc"))
+
+ class LocalType:
+ pass
+ obj = LocalType()
+ fullname = f'{__name__}.{LocalType.__qualname__}'
+ check_format(f'type: {fullname}',
+ b'type: %T', py_object(obj))
+ fullname_alt = f'{__name__}:{LocalType.__qualname__}'
+ check_format(f'type: {fullname_alt}',
+ b'type: %#T', py_object(obj))
+
+ # test %N
+ check_format('type: str',
+ b'type: %N', py_object(str))
+ check_format(f'type: st',
+ b'type: %.2N', py_object(str))
+ check_format(f'type: str',
+ b'type: %10N', py_object(str))
+
+ check_format(f'type: {fullname}',
+ b'type: %N', py_object(type(obj)))
+ check_format(f'type: {fullname_alt}',
+ b'type: %#N', py_object(type(obj)))
+ with self.assertRaisesRegex(TypeError, "%N argument must be a type"):
+ check_format('type: str',
+ b'type: %N', py_object("abc"))
+
# test variable width and precision
check_format(' abc', b'%*s', c_int(5), b'abc')
check_format('ab', b'%.*s', c_int(2), b'abc')
diff --git a/Misc/NEWS.d/next/C API/2024-04-08-18-53-33.gh-issue-117642._-tYH_.rst b/Misc/NEWS.d/next/C API/2024-04-08-18-53-33.gh-issue-117642._-tYH_.rst
new file mode 100644
index 00000000000000..edef2777717014
--- /dev/null
+++ b/Misc/NEWS.d/next/C API/2024-04-08-18-53-33.gh-issue-117642._-tYH_.rst
@@ -0,0 +1 @@
+Fix :pep:`737` implementation for ``%#T`` and ``%#N``.
diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c
index 59b350f0a609a6..5f15071d7d54ef 100644
--- a/Objects/unicodeobject.c
+++ b/Objects/unicodeobject.c
@@ -2468,6 +2468,7 @@ unicode_fromformat_arg(_PyUnicodeWriter *writer,
switch (*f++) {
case '-': flags |= F_LJUST; continue;
case '0': flags |= F_ZERO; continue;
+ case '#': flags |= F_ALT; continue;
}
f--;
break;
@@ -2797,9 +2798,8 @@ unicode_fromformat_arg(_PyUnicodeWriter *writer,
PyTypeObject *type = (PyTypeObject *)Py_NewRef(Py_TYPE(obj));

PyObject *type_name;
- if (f[1] == '#') {
+ if (flags & F_ALT) {
type_name = _PyType_GetFullyQualifiedName(type, ':');
- f++;
}
else {
type_name = PyType_GetFullyQualifiedName(type);
@@ -2830,9 +2830,8 @@ unicode_fromformat_arg(_PyUnicodeWriter *writer,
PyTypeObject *type = (PyTypeObject*)type_raw;

PyObject *type_name;
- if (f[1] == '#') {
+ if (flags & F_ALT) {
type_name = _PyType_GetFullyQualifiedName(type, ':');
- f++;
}
else {
type_name = PyType_GetFullyQualifiedName(type);

_______________________________________________
Python-checkins mailing list -- python-checkins@python.org
To unsubscribe send an email to python-checkins-leave@python.org
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: list-python-checkins@lists.gossamer-threads.com