11PEP: 737
2- Title: Unify type name formatting
2+ Title: C API to format a type fully qualified name
33Author: Victor Stinner <vstinner@python.org>
44Discussions-To: https://discuss.python.org/t/pep-737-unify-type-name-formatting/39872
55Status: Draft
@@ -12,17 +12,12 @@ Post-History: `29-Nov-2023 <https://discuss.python.org/t/pep-737-unify-type-name
1212Abstract
1313========
1414
15- Add new convenient APIs to format type names the same way in Python and
16- in C. No longer format type names differently depending on how types are
17- implemented.
15+ Add new convenient C APIs to format a type fully qualified name. No longer
16+ format type names differently depending on how types are implemented.
1817
1918Recommend using the type fully qualified name in error messages and in
20- ``__repr__() `` methods in new code. Recommend not truncating type names
21- in new code.
22-
23- Add ``N `` and ``#N `` formats to ``type.__format__() `` to format a type
24- fully qualified name. For example, ``f"{type(obj):N}" `` formats the
25- fully qualified name of an object *obj *.
19+ ``__repr__() `` methods in new C code. Recommend not truncating type
20+ names in new C code.
2621
2722Add ``%T ``, ``%#T ``, ``%N `` and ``%#N `` formats to
2823``PyUnicode_FromFormat() `` to format the fully qualified, respectively,
@@ -180,65 +175,58 @@ limit of 500 bytes is outdated
180175Specification
181176=============
182177
183- * Add ``type.__fully_qualified_name__ `` attribute.
184- * Add ``type.__format__() `` method.
185- * Add formats to ``PyUnicode_FromFormat() ``.
186- * Add ``PyType_GetModuleName() `` function.
187178* Add ``PyType_GetFullyQualifiedName() `` function.
179+ * Add ``PyType_GetModuleName() `` function.
180+ * Add formats to ``PyUnicode_FromFormat() ``.
188181* Recommend using the type fully qualified name in error messages and
189- in ``__repr__() `` methods in new code.
190- * Recommend not truncating type names in new code.
182+ in ``__repr__() `` methods in new C code.
183+ * Recommend not truncating type names in new C code.
191184
192185
193- Add type.__fully_qualified_name__ attribute
186+ Add PyType_GetFullyQualifiedName() function
194187-------------------------------------------
195188
196- Add `` type.__fully_qualified_name__ `` read-only attribute, the fully
189+ Add the `` PyType_GetFullyQualifiedName() `` function to get the fully
197190qualified name of a type: similar to
198- ``f"{type.__module__}.{type.__qualname__}" ``, or ``type.__qualname__ `` if
199- ``type.__module__ `` is not a string or is equal to ``"builtins" `` or is
200- equal to ``"__main__" ``.
191+ ``f"{type.__module__}.{type.__qualname__}" ``, or ``type.__qualname__ ``
192+ if ``type.__module__ `` is not a string or is equal to ``"builtins" `` or
193+ is equal to ``"__main__" ``.
201194
202- The ``type.__repr__() `` is left unchanged, it only omits the module if
203- the module is equal to ``"builtins" ``.
195+ API:
204196
197+ .. code-block :: c
205198
206- Add type.__format__() method
207- ----------------------------
199+ PyObject* PyType_GetFullyQualifiedName(PyTypeObject *type)
208200
209- Add ``type.__format__() `` method with the following formats:
201+ On success, return a new reference to the string. On error, raise an
202+ exception and return ``NULL ``.
210203
211- * ``N `` formats the type **fully qualified name **
212- (``type.__fully_qualified_name__ ``);
213- ``N `` stands for **N **\ ame.
214- * ``#N `` (alternative form) formats the type **fully qualified name **
215- using the **colon ** (``: ``) separator, instead of the dot separator
216- (``. ``), between the module name and the qualified name.
217204
218- Examples using f-string::
205+ Add PyType_GetModuleName() function
206+ -----------------------------------
219207
220- >>> import datetime
221- >>> f"{datetime.timedelta:N}" # fully qualified name
222- 'datetime.timedelta'
223- >>> f"{datetime.timedelta:#N}" # fully qualified name, colon separator
224- 'datetime:timedelta'
208+ Add the ``PyType_GetModuleName() `` function to get the module name of a
209+ type (``type.__module__ `` string). API:
225210
226- The colon (``: ``) separator used by the ``#N `` format eliminates
227- guesswork when you want to import the name, see
228- ``pkgutil.resolve_name() ``, ``python -m inspect `` command line
229- interface, and ``setuptools `` entry points.
211+ .. code-block :: c
212+
213+ PyObject* PyType_GetModuleName(PyTypeObject *type)
214+
215+ On success, return a new reference to the string. On error, raise an
216+ exception and return ``NULL ``.
230217
231218
232219Add formats to PyUnicode_FromFormat()
233220-------------------------------------
234221
235222Add the following formats to ``PyUnicode_FromFormat() ``:
236223
237- * ``%N `` formats the **fully qualified name ** of a **type **
238- (``type.__fully_qualified_name__ ``); **N ** stands for type **N **\ ame.
239- * ``%T `` formats the type **fully qualified name ** of an **object **
240- (``type(obj).__fully_qualified_name__ ``); **T ** stands for object
241- **T **\ ype.
224+ * ``%N `` formats the **fully qualified name ** of a **type **,
225+ similar to ``PyType_GetFullyQualifiedName(type) ``;
226+ **N ** stands for type **N **\ ame.
227+ * ``%T `` formats the type **fully qualified name ** of an **object **,
228+ similar to ``PyType_GetFullyQualifiedName(Py_TYPE(obj)) ``;
229+ **T ** stands for object **T **\ ype.
242230* ``%#N `` and ``%#T ``: the alternative form uses the **colon ** separator
243231 (``: ``), instead of the dot separator (``. ``), between the module name
244232 and the qualified name.
@@ -263,9 +251,6 @@ Advantages of the updated code:
263251* Safer C code: avoid ``Py_TYPE() `` which returns a borrowed reference.
264252* The ``PyTypeObject.tp_name `` member is no longer read explicitly: the
265253 code becomes compatible with the limited C API.
266- * The ``PyTypeObject.tp_name `` bytes string no longer has to be decoded
267- from UTF-8 at each ``PyErr_Format() `` call, since
268- ``type.__fully_qualified_name__ `` is already a Unicode string.
269254* The formatted type name no longer depends on the type implementation.
270255* The type name is no longer truncated.
271256
@@ -281,50 +266,19 @@ Formats Summary
281266
282267 * - C object
283268 - C type
284- - Python
285269 - Format
286270 * - ``%T ``
287271 - ``%N ``
288- - ``:N ``
289272 - Type **fully qualified ** name.
290273 * - ``%#T ``
291274 - ``%#N ``
292- - ``:#N ``
293275 - Type **fully qualified ** name, **colon ** separator.
294276
295- Add PyType_GetModuleName() function
296- -----------------------------------
297-
298- Add the ``PyType_GetModuleName() `` function to get the module name of a
299- type (``type.__module__ ``). API:
300-
301- .. code-block :: c
302-
303- PyObject* PyType_GetModuleName(PyTypeObject *type)
304-
305- On success, return a new reference to the string. On error, raise an
306- exception and return ``NULL ``.
307-
308-
309- Add PyType_GetFullyQualifiedName() function
310- -------------------------------------------
311-
312- Add the ``PyType_GetFullyQualifiedName() `` function to get the fully
313- qualified name of a type (``type.__fully_qualified_name__ ``). API:
314-
315- .. code-block :: c
316-
317- PyObject* PyType_GetFullyQualifiedName(PyTypeObject *type)
318-
319- On success, return a new reference to the string. On error, raise an
320- exception and return ``NULL ``.
321-
322-
323277Recommend using the type fully qualified name
324278---------------------------------------------
325279
326280The type fully qualified name is recommended in error messages and in
327- ``__repr__() `` methods in new code.
281+ ``__repr__() `` methods in new C code.
328282
329283In non-trivial applications, it is likely to have two types with the
330284same short name defined in two different modules, especially with
@@ -335,7 +289,7 @@ in an unambiguous way.
335289Recommend not truncating type names
336290-----------------------------------
337291
338- Type names should not be truncated in new code. For example, the
292+ Type names should not be truncated in new C code. For example, the
339293``%.100s `` format should be avoided: use the ``%s `` format instead (or
340294``%T `` format in C).
341295
@@ -352,18 +306,76 @@ Backwards Compatibility
352306
353307Changes proposed in this PEP are backward compatible.
354308
355- Adding new APIs has no effect on the backward compatibility. Existing
356- APIs are left unchanged.
309+ Adding new C APIs has no effect on the backward compatibility. Existing
310+ C APIs are left unchanged. No Python API is changed .
357311
358312Replacing the type short name with the type fully qualified name is only
359- recommended in new code. No longer truncating type names is only
360- recommended in new code. Existing code should be left unchanged and so
361- remains backward compatible.
313+ recommended in new C code. No longer truncating type names is only
314+ recommended in new C code. Existing code should be left unchanged and so
315+ remains backward compatible. There is no recommendation for Python code.
362316
363317
364318Rejected Ideas
365319==============
366320
321+ Add type.__fully_qualified_name__ attribute
322+ -------------------------------------------
323+
324+ Add ``type.__fully_qualified_name__ `` read-only attribute, the fully
325+ qualified name of a type: similar to
326+ ``f"{type.__module__}.{type.__qualname__}" ``, or ``type.__qualname__ `` if
327+ ``type.__module__ `` is not a string or is equal to ``"builtins" `` or is
328+ equal to ``"__main__" ``.
329+
330+ The ``type.__repr__() `` is left unchanged, it only omits the module if
331+ the module is equal to ``"builtins" ``.
332+
333+ This change was `rejected by the Steering Council
334+ <https://discuss.python.org/t/pep-737-unify-type-name-formatting/39872/51> `__:
335+
336+ We can see the usefulness of the C API changes proposed by the PEP
337+ and would likely accept those changes as is.
338+
339+ We see less justification for the Python level changes. We
340+ especially question the need for ``__fully_qualified_name__ ``.
341+
342+ Thomas Wouters added:
343+
344+ If there really is a desire for formatting types the exact same way
345+ the C API does it, a utility function would make more sense to me,
346+ personally, than ``type.__format__ ``, but I think the SC could be
347+ persuaded given some concrete use-cases.
348+
349+
350+ Add type.__format__() method
351+ ----------------------------
352+
353+ Add ``type.__format__() `` method with the following formats:
354+
355+ * ``N `` formats the type **fully qualified name **
356+ (``type.__fully_qualified_name__ ``);
357+ ``N `` stands for **N **\ ame.
358+ * ``#N `` (alternative form) formats the type **fully qualified name **
359+ using the **colon ** (``: ``) separator, instead of the dot separator
360+ (``. ``), between the module name and the qualified name.
361+
362+ Examples using f-string::
363+
364+ >>> import datetime
365+ >>> f"{datetime.timedelta:N}" # fully qualified name
366+ 'datetime.timedelta'
367+ >>> f"{datetime.timedelta:#N}" # fully qualified name, colon separator
368+ 'datetime:timedelta'
369+
370+ The colon (``: ``) separator used by the ``#N `` format eliminates
371+ guesswork when you want to import the name, see
372+ ``pkgutil.resolve_name() ``, ``python -m inspect `` command line
373+ interface, and ``setuptools `` entry points.
374+
375+ This change was `rejected by the Steering Council
376+ <https://discuss.python.org/t/pep-737-unify-type-name-formatting/39872/52> `__.
377+
378+
367379Change str(type)
368380----------------
369381
@@ -386,7 +398,7 @@ Add !t formatter to get an object type
386398Use ``f"{obj!t:T}" `` to format ``type(obj).__fully_qualified_name__ ``,
387399similar to ``f"{type(obj):T}" ``.
388400
389- When the ``!t `` formatter was proposed in 2018, `Eric Smith was stronly
401+ When the ``!t `` formatter was proposed in 2018, `Eric Smith was strongly
390402opposed to this
391403<https://mail.python.org/archives/list/python-dev@python.org/message/BMIW3FEB77OS7OB3YYUUDUBITPWLRG3U/> `_;
392404Eric is the author of the f-string :pep: `498 ` "Literal String Interpolation".
0 commit comments