Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork32.4k
DO-NOT-MERGE: bpo-34595: Add %t format to PyUnicode_FromFormatV()#9122
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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Uh oh!
There was an error while loading.Please reload this page.
Changes fromall commits
File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading.Please reload this page.
Jump to
Uh oh!
There was an error while loading.Please reload this page.
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -519,8 +519,12 @@ APIs: | ||
| :attr:`%R` | PyObject\* | The result of calling | | ||
| | | :c:func:`PyObject_Repr`. | | ||
+-------------------+---------------------+--------------------------------+ | ||
| :attr:`%T` | PyObject\* | The object type name, | | ||
| | | equivalent to: | | ||
| | | ``type(op).__name__``. | | ||
+-------------------+---------------------+--------------------------------+ | ||
| :attr:`%T` | PyObject\* | The object type fully | | ||
| | | qualified name [2]_. | | ||
+-------------------+---------------------+--------------------------------+ | ||
An unrecognized format character causes all the rest of the format string to be | ||
@@ -536,6 +540,9 @@ APIs: | ||
.. [1] For integer specifiers (d, u, ld, li, lu, lld, lli, llu, zd, zi, | ||
zu, i, x): the 0-conversion flag has effect even when a precision is given. | ||
.. [2] The object type fully qualified name is equivalent to: | ||
``f"{type(obj).__module__}.{type(obj).__qualname__}"``. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Except that the module name is omitted for types in the builtins module (and for non-heap extension types that don't specify the module, but this can be considered as a bug). | ||
.. versionchanged:: 3.2 | ||
Support for ``"%lld"`` and ``"%llu"`` added. | ||
@@ -547,7 +554,8 @@ APIs: | ||
``"%V"``, ``"%S"``, ``"%R"`` added. | ||
.. versionchanged:: 3.7 | ||
Support for ``"%t"`` (object type name) and ``"%T"`` (object type fully | ||
qualified name) added. | ||
.. c:function:: PyObject* PyUnicode_FromFormatV(const char *format, va_list vargs) | ||
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
:c:func:`PyUnicode_FromFormatV`: add ``%t`` and ``%T``formats to | ||
:c:func:`PyUnicode_FromFormatV`, and so to :c:func:`PyUnicode_FromFormat` | ||
and :c:func:`PyErr_Format`, to format an object type name. ``%t`` is equivalent to | ||
``type(obj).__name__`` and ``%T`` is equivalent to | ||
``f"{type(obj).__module__}.{type(obj).__qualname__}"``. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -768,7 +768,7 @@ ensure_unicode(PyObject *obj) | ||
{ | ||
if (!PyUnicode_Check(obj)) { | ||
PyErr_Format(PyExc_TypeError, | ||
"must be str, not %t", obj); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. What was used instead of %t/%T before? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Python 3.7 code:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Thus it was closer to %T. In error messages it is better to use fully qualified names. | ||
return -1; | ||
} | ||
return PyUnicode_READY(obj); | ||
@@ -2826,17 +2826,33 @@ unicode_fromformat_arg(_PyUnicodeWriter *writer, | ||
break; | ||
} | ||
case 't': | ||
{ | ||
/* Object type name: type(obj).__name__ */ | ||
PyObject *obj = va_arg(*vargs, PyObject *); | ||
PyTypeObject *type = Py_TYPE(obj); | ||
const char *type_name =_PyType_Name(type); | ||
if (unicode_fromformat_write_utf8(writer, type_name, -1, -1) < 0) { | ||
return NULL; | ||
} | ||
break; | ||
} | ||
case 'T': | ||
{ | ||
/* Object type fully qualified name: | ||
f"{type(obj).__module__}.{type(obj).__qualname__}". */ | ||
PyObject *obj = va_arg(*vargs, PyObject *); | ||
PyTypeObject *type = Py_TYPE(obj); | ||
PyObject *name = _PyType_FullName(type); | ||
if (_PyUnicodeWriter_WriteStr(writer, name) < 0) { | ||
Py_DECREF(name); | ||
return NULL; | ||
} | ||
Py_DECREF(name); | ||
break; | ||
} | ||
case '%': | ||
if (_PyUnicodeWriter_WriteCharInline(writer, '%') < 0) | ||
return NULL; | ||
@@ -3034,7 +3050,7 @@ PyUnicode_FromObject(PyObject *obj) | ||
return _PyUnicode_Copy(obj); | ||
} | ||
PyErr_Format(PyExc_TypeError, | ||
"Can't convert '%t' object to str implicitly", obj); | ||
return NULL; | ||
} | ||
@@ -3070,7 +3086,7 @@ PyUnicode_FromEncodedObject(PyObject *obj, | ||
/* Retrieve a bytes buffer view through the PEP 3118 buffer interface */ | ||
if (PyObject_GetBuffer(obj, &buffer, PyBUF_SIMPLE) < 0) { | ||
PyErr_Format(PyExc_TypeError, | ||
"decoding to str: need a bytes-like object, %t found", | ||
obj); | ||
return NULL; | ||
} | ||
@@ -3201,7 +3217,7 @@ PyUnicode_Decode(const char *s, | ||
goto onError; | ||
if (!PyUnicode_Check(unicode)) { | ||
PyErr_Format(PyExc_TypeError, | ||
"'%.400s' decoder returned '%t' instead of 'str'; " | ||
"use codecs.decode() to decode to arbitrary types", | ||
encoding, unicode); | ||
Py_DECREF(unicode); | ||
@@ -3263,7 +3279,7 @@ PyUnicode_AsDecodedUnicode(PyObject *unicode, | ||
goto onError; | ||
if (!PyUnicode_Check(v)) { | ||
PyErr_Format(PyExc_TypeError, | ||
"'%.400s' decoder returned '%t' instead of 'str'; " | ||
"use codecs.decode() to decode to arbitrary types", | ||
encoding, unicode); | ||
Py_DECREF(v); | ||
@@ -3496,7 +3512,7 @@ PyUnicode_AsEncodedString(PyObject *unicode, | ||
} | ||
PyErr_Format(PyExc_TypeError, | ||
"'%.400s' encoder returned '%t' instead of 'bytes'; " | ||
"use codecs.encode() to encode to arbitrary types", | ||
encoding, v); | ||
Py_DECREF(v); | ||
@@ -3529,7 +3545,7 @@ PyUnicode_AsEncodedUnicode(PyObject *unicode, | ||
goto onError; | ||
if (!PyUnicode_Check(v)) { | ||
PyErr_Format(PyExc_TypeError, | ||
"'%.400s' encoder returned '%t' instead of 'str'; " | ||
"use codecs.encode() to encode to arbitrary types", | ||
encoding, v); | ||
Py_DECREF(v); | ||
@@ -3704,7 +3720,7 @@ PyUnicode_FSDecoder(PyObject* arg, void* addr) | ||
if (!PyBytes_Check(path) && | ||
PyErr_WarnFormat(PyExc_DeprecationWarning, 1, | ||
"path should be string, bytes, " | ||
"or os.PathLike, not %t", | ||
arg)) | ||
{ | ||
Py_DECREF(path); | ||
@@ -3724,7 +3740,7 @@ PyUnicode_FSDecoder(PyObject* arg, void* addr) | ||
} | ||
else { | ||
PyErr_Format(PyExc_TypeError, | ||
"path should be string, bytes, or os.PathLike, not %t", | ||
arg); | ||
Py_DECREF(path); | ||
return 0; | ||
@@ -9893,7 +9909,7 @@ _PyUnicode_JoinArray(PyObject *separator, PyObject *const *items, Py_ssize_t seq | ||
else { | ||
if (!PyUnicode_Check(separator)) { | ||
PyErr_Format(PyExc_TypeError, | ||
"separator: expected str instance, %t found", | ||
separator); | ||
goto onError; | ||
} | ||
@@ -9925,7 +9941,7 @@ _PyUnicode_JoinArray(PyObject *separator, PyObject *const *items, Py_ssize_t seq | ||
item = items[i]; | ||
if (!PyUnicode_Check(item)) { | ||
PyErr_Format(PyExc_TypeError, | ||
"sequence item %zd: expected str instance, %t found", | ||
i, item); | ||
goto onError; | ||
} | ||
@@ -10741,7 +10757,7 @@ convert_uc(PyObject *obj, void *addr) | ||
if (!PyUnicode_Check(obj)) { | ||
PyErr_Format(PyExc_TypeError, | ||
"The fill character must be a unicode character, " | ||
"not %t", obj); | ||
return 0; | ||
} | ||
if (PyUnicode_READY(obj) < 0) | ||
@@ -11147,7 +11163,7 @@ PyUnicode_Contains(PyObject *str, PyObject *substr) | ||
if (!PyUnicode_Check(substr)) { | ||
PyErr_Format(PyExc_TypeError, | ||
"'in <string>' requires string as left operand, not %t", | ||
substr); | ||
return -1; | ||
} | ||
@@ -12853,7 +12869,7 @@ unicode_split_impl(PyObject *self, PyObject *sep, Py_ssize_t maxsplit) | ||
if (PyUnicode_Check(sep)) | ||
return split(self, sep, maxsplit); | ||
PyErr_Format(PyExc_TypeError, "must be str or None, not %t", sep); | ||
return NULL; | ||
} | ||
@@ -13039,7 +13055,7 @@ unicode_rsplit_impl(PyObject *self, PyObject *sep, Py_ssize_t maxsplit) | ||
if (PyUnicode_Check(sep)) | ||
return rsplit(self, sep, maxsplit); | ||
PyErr_Format(PyExc_TypeError, "must be str or None, not %t", sep); | ||
return NULL; | ||
} | ||
@@ -13334,7 +13350,7 @@ unicode_startswith(PyObject *self, | ||
if (!PyUnicode_Check(substring)) { | ||
PyErr_Format(PyExc_TypeError, | ||
"tuple for startswith must only contain str, " | ||
"not %t", | ||
substring); | ||
return NULL; | ||
} | ||
@@ -13351,7 +13367,7 @@ unicode_startswith(PyObject *self, | ||
if (!PyUnicode_Check(subobj)) { | ||
PyErr_Format(PyExc_TypeError, | ||
"startswith first arg must be str or " | ||
"a tuple of str, not %t", subobj); | ||
return NULL; | ||
} | ||
result = tailmatch(self, subobj, start, end, -1); | ||
@@ -13388,7 +13404,7 @@ unicode_endswith(PyObject *self, | ||
if (!PyUnicode_Check(substring)) { | ||
PyErr_Format(PyExc_TypeError, | ||
"tuple for endswith must only contain str, " | ||
"not %t", | ||
substring); | ||
return NULL; | ||
} | ||
@@ -13404,7 +13420,7 @@ unicode_endswith(PyObject *self, | ||
if (!PyUnicode_Check(subobj)) { | ||
PyErr_Format(PyExc_TypeError, | ||
"endswith first arg must be str or " | ||
"a tuple of str, not %t", subobj); | ||
return NULL; | ||
} | ||
result = tailmatch(self, subobj, start, end, +1); | ||
@@ -14314,12 +14330,12 @@ mainformatlong(PyObject *v, | ||
case 'x': | ||
case 'X': | ||
PyErr_Format(PyExc_TypeError, | ||
"%%%c format: an integer is required, not %t", | ||
type, v); | ||
break; | ||
default: | ||
PyErr_Format(PyExc_TypeError, | ||
"%%%c format: a number is required, not %t", | ||
type, v); | ||
break; | ||
} | ||