Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

gh-117642: Fix PEP 737 implementation #117643

Merged
merged 1 commit into from
Apr 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 3 additions & 3 deletions Doc/c-api/unicode.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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.
Expand Down Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion Doc/whatsnew/3.13.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
34 changes: 34 additions & 0 deletions Lib/test/test_capi/test_unicode.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh wait, I wrote tests, but it seems like I removed them in commit a557478 !?

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')
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix :pep:`737` implementation for ``%#T`` and ``%#N``.
7 changes: 3 additions & 4 deletions Objects/unicodeobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down