summaryrefslogtreecommitdiffstats
path: root/Objects
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@python.org>2024-03-14 22:23:00 (GMT)
committerGitHub <noreply@github.com>2024-03-14 22:23:00 (GMT)
commit7bbb9b57e67057d5ca3b7e3a434527fb3fcf5a2b (patch)
tree5f09547613d22804329cac09199b629f3182b4db /Objects
parent5f52d20a93908196f74271db8437cc1ba7e1e262 (diff)
downloadcpython-7bbb9b57e67057d5ca3b7e3a434527fb3fcf5a2b.zip
cpython-7bbb9b57e67057d5ca3b7e3a434527fb3fcf5a2b.tar.gz
cpython-7bbb9b57e67057d5ca3b7e3a434527fb3fcf5a2b.tar.bz2
gh-111696, PEP 737: Add %T and %N to PyUnicode_FromFormat() (#116839)
Diffstat (limited to 'Objects')
-rw-r--r--Objects/typeobject.c10
-rw-r--r--Objects/unicodeobject.c58
2 files changed, 66 insertions, 2 deletions
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index 1c5729c..b73dfba 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -1208,7 +1208,7 @@ type_set_module(PyTypeObject *type, PyObject *value, void *context)
PyObject *
-PyType_GetFullyQualifiedName(PyTypeObject *type)
+_PyType_GetFullyQualifiedName(PyTypeObject *type, char sep)
{
if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) {
return PyUnicode_FromString(type->tp_name);
@@ -1230,7 +1230,7 @@ PyType_GetFullyQualifiedName(PyTypeObject *type)
&& !_PyUnicode_Equal(module, &_Py_ID(builtins))
&& !_PyUnicode_Equal(module, &_Py_ID(__main__)))
{
- result = PyUnicode_FromFormat("%U.%U", module, qualname);
+ result = PyUnicode_FromFormat("%U%c%U", module, sep, qualname);
}
else {
result = Py_NewRef(qualname);
@@ -1240,6 +1240,12 @@ PyType_GetFullyQualifiedName(PyTypeObject *type)
return result;
}
+PyObject *
+PyType_GetFullyQualifiedName(PyTypeObject *type)
+{
+ return _PyType_GetFullyQualifiedName(type, '.');
+}
+
static PyObject *
type_abstractmethods(PyTypeObject *type, void *context)
diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c
index 0a569a9..c8f647a 100644
--- a/Objects/unicodeobject.c
+++ b/Objects/unicodeobject.c
@@ -2791,6 +2791,64 @@ unicode_fromformat_arg(_PyUnicodeWriter *writer,
break;
}
+ case 'T':
+ {
+ PyObject *obj = va_arg(*vargs, PyObject *);
+ PyTypeObject *type = (PyTypeObject *)Py_NewRef(Py_TYPE(obj));
+
+ PyObject *type_name;
+ if (f[1] == '#') {
+ type_name = _PyType_GetFullyQualifiedName(type, ':');
+ f++;
+ }
+ else {
+ type_name = PyType_GetFullyQualifiedName(type);
+ }
+ Py_DECREF(type);
+ if (!type_name) {
+ return NULL;
+ }
+
+ if (unicode_fromformat_write_str(writer, type_name,
+ width, precision, flags) == -1) {
+ Py_DECREF(type_name);
+ return NULL;
+ }
+ Py_DECREF(type_name);
+ break;
+ }
+
+ case 'N':
+ {
+ PyObject *type_raw = va_arg(*vargs, PyObject *);
+ assert(type_raw != NULL);
+
+ if (!PyType_Check(type_raw)) {
+ PyErr_SetString(PyExc_TypeError, "%N argument must be a type");
+ return NULL;
+ }
+ PyTypeObject *type = (PyTypeObject*)type_raw;
+
+ PyObject *type_name;
+ if (f[1] == '#') {
+ type_name = _PyType_GetFullyQualifiedName(type, ':');
+ f++;
+ }
+ else {
+ type_name = PyType_GetFullyQualifiedName(type);
+ }
+ if (!type_name) {
+ return NULL;
+ }
+ if (unicode_fromformat_write_str(writer, type_name,
+ width, precision, flags) == -1) {
+ Py_DECREF(type_name);
+ return NULL;
+ }
+ Py_DECREF(type_name);
+ break;
+ }
+
default:
invalid_format:
PyErr_Format(PyExc_SystemError, "invalid format string: %s", p);