@@ -14,10 +14,19 @@ Abstract
1414
1515Add new convenient APIs to format type names the same way in Python and
1616in C. No longer format type names differently depending on how types are
17- implemented. No longer truncate type names in the standard library.
17+ implemented.
1818
1919Recommend using the type fully qualified name in error messages and in
20- ``__repr__() `` methods in new code.
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 *.
26+
27+ Add ``%T ``, ``%#T ``, ``%N `` and ``%#N `` formats to
28+ ``PyUnicode_FromFormat() `` to format the fully qualified, respectively,
29+ of an object type and of a type.
2130
2231Make C code safer by avoiding borrowed reference which can lead to
2332crashes. The new C API is compatible with the limited C API.
@@ -172,16 +181,17 @@ Specification
172181=============
173182
174183* Add ``type.__fully_qualified_name__ `` attribute.
175- * Add ``%T ``, ``%#T ``, ``%N ``, ``%#N `` formats to
176- ``PyUnicode_FromFormat() ``.
184+ * Add ``type.__format__() `` method.
185+ * Add formats to ``PyUnicode_FromFormat() ``.
186+ * Add ``PyType_GetModuleName() `` function.
177187* Add ``PyType_GetFullyQualifiedName() `` function.
178188* Recommend using the type fully qualified name in error messages and
179189 in ``__repr__() `` methods in new code.
180- * Recommend not truncating type names.
190+ * Recommend not truncating type names in new code .
181191
182192
183- Python API
184- ----------
193+ Add type.__fully_qualified_name__ attribute
194+ -------------------------------------------
185195
186196Add ``type.__fully_qualified_name__ `` read-only attribute, the fully
187197qualified name of a type: similar to
@@ -190,39 +200,48 @@ qualified name of a type: similar to
190200equal to ``"__main__" ``.
191201
192202The ``type.__repr__() `` is left unchanged, it only omits the module if
193- the module is equal to ``"builtins" ``. It includes the module if the
194- module is equal to ``"__main__" ``. Pseudo-code::
195-
196- def type_repr(cls):
197- if isinstance(cls.__module__, str) and cls.__module__ != "builtins":
198- name = f"{cls.__module__}.{cls.__qualname__}"
199- else:
200- name = cls.__qualname__
201- return f"<class '{name}'>"
202-
203-
204- Add PyUnicode_FromFormat() formats
205- ----------------------------------
206-
207- Add formats to ``PyUnicode_FromFormat() ``:
208-
209- * ``%T `` formats the type fully qualified name of an **object **:
210- similar to ``type(obj).__fully_qualified_name__ ``.
211- * ``%#T `` formats the type short name of an **object **:
212- similar to ``type(obj).__name__ ``.
213- * ``%N `` formats the fully qualified name of a **type **:
214- similar to ``type.__fully_qualified_name__ ``.
215- * ``%#N `` formats the short name of an object of a **type **:
216- similar to ``type.__name__ ``.
217-
218- The hash character (``# ``) in the format string stands for
219- `alternative format
220- <https://docs.python.org/3/library/string.html#format-specification-mini-language> `_.
221- For example, ``f"{123:x}" `` returns ``'7b' `` and ``f"{123:#x}" `` returns
222- ``'0x7b' `` (``# `` adds ``'0x' `` prefix).
223-
224- The ``%T `` format is used by ``time.strftime() ``, but it's not used by
225- ``printf() ``.
203+ the module is equal to ``"builtins" ``.
204+
205+
206+ Add type.__format__() method
207+ ----------------------------
208+
209+ Add ``type.__format__() `` method with the following formats:
210+
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.
217+
218+ Examples using f-string::
219+
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'
225+
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.
230+
231+
232+ Add formats to PyUnicode_FromFormat()
233+ -------------------------------------
234+
235+ Add the following formats to ``PyUnicode_FromFormat() ``:
236+
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.
242+ * ``%#N `` and ``%#T ``: the alternative form uses the **colon ** separator
243+ (``: ``), instead of the dot separator (``. ``), between the module name
244+ and the qualified name.
226245
227246For example, the existing code using *tp_name *:
228247
@@ -247,8 +266,45 @@ Advantages of the updated code:
247266* The ``PyTypeObject.tp_name `` bytes string no longer has to be decoded
248267 from UTF-8 at each ``PyErr_Format() `` call, since
249268 ``type.__fully_qualified_name__ `` is already a Unicode string.
269+ * The formatted type name no longer depends on the type implementation.
250270* The type name is no longer truncated.
251271
272+ Note: The ``%T `` format is used by ``time.strftime() ``, but not by
273+ ``printf() ``.
274+
275+
276+ Formats Summary
277+ ---------------
278+
279+ .. list-table ::
280+ :header-rows: 1
281+
282+ * - C object
283+ - C type
284+ - Python
285+ - Format
286+ * - ``%T ``
287+ - ``%N ``
288+ - ``:N ``
289+ - Type **fully qualified ** name.
290+ * - ``%#T ``
291+ - ``%#N ``
292+ - ``:#N ``
293+ - Type **fully qualified ** name, **colon ** separator.
294+
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+
252308
253309Add PyType_GetFullyQualifiedName() function
254310-------------------------------------------
@@ -279,12 +335,9 @@ in an unambiguous way.
279335Recommend not truncating type names
280336-----------------------------------
281337
282- Type names must not be truncated. For example, the ``%.100s `` format
283- should be avoided: use the ``%s `` format instead (or ``%T `` and ``%#T ``
284- formats in C).
285-
286- Code in the standard library is updated to no longer truncate type
287- names.
338+ Type names should not be truncated in new code. For example, the
339+ ``%.100s `` format should be avoided: use the ``%s `` format instead (or
340+ ``%T `` format in C).
288341
289342
290343Implementation
@@ -303,12 +356,9 @@ Adding new APIs has no effect on the backward compatibility. Existing
303356APIs are left unchanged.
304357
305358Replacing the type short name with the type fully qualified name is only
306- recommended in new code. Existing code should be left
307- unchanged and so remains backward compatible.
308-
309- In the standard library, type names are no longer truncated. We believe
310- that no code should be affected in practice, since type names longer
311- than 100 characters are rare.
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.
312362
313363
314364Rejected Ideas
@@ -330,38 +380,14 @@ See the `pull request: type(str) returns the fully qualified name
330380<https://github.com/python/cpython/pull/112129> `_.
331381
332382
333- Add formats to type.__format__()
334- --------------------------------
335-
336- Examples of proposed formats for ``type.__format__() ``:
337-
338- * ``f"{type(obj):z}" `` formats ``type(obj).__name__ ``.
339- * ``f"{type(obj):M.T}" `` formats ``type(obj).__fully_qualified_name__ ``.
340- * ``f"{type(obj):M:T}" `` formats ``type(obj).__fully_qualified_name__ ``
341- using colon (``: ``) separator.
342- * ``f"{type(obj):T}" `` formats ``type(obj).__name__ ``.
343- * ``f"{type(obj):#T}" `` formats ``type(obj).__fully_qualified_name__ ``.
344-
345- Using short format (such as ``z ``, a single letter) requires to refer to
346- format documentation to understand how a type name is formatted, whereas
347- ``type(obj).__name__ `` is explicit.
348-
349- The dot character (``. ``) is already used for the "precision" in format
350- strings. The colon character (``: ``) is already used to separated the
351- expression from the format specification. For example, ``f"{3.14:g}" ``
352- uses ``g `` format which comes after the colon (``: ``). Usually, a format
353- type is a single letter, such as ``g `` in ``f"{3.14:g}" ``, not ``M.T ``
354- or ``M:T ``. Reusing dot and colon characters for a different purpose can
355- be misleading and make the format parser more complicated.
356-
357383Add !t formatter to get an object type
358384--------------------------------------
359385
360- Use ``f"{obj!t:T}" `` to format ``type(obj).__name__ ``, similar to
361- ``f"{type(obj).__name__ }" ``.
386+ Use ``f"{obj!t:T}" `` to format ``type(obj).__fully_qualified_name__ ``,
387+ similar to ``f"{type(obj):T }" ``.
362388
363- When the ``!t `` formatter was proposed in 2018, `Eric Smith was opposed
364- to this
389+ When the ``!t `` formatter was proposed in 2018, `Eric Smith was stronly
390+ opposed to this
365391<https://mail.python.org/archives/list/python-dev@python.org/message/BMIW3FEB77OS7OB3YYUUDUBITPWLRG3U/> `_;
366392Eric is the author of the f-string :pep: `498 ` "Literal String Interpolation".
367393
@@ -370,23 +396,12 @@ Add formats to str % args
370396-------------------------
371397
372398It was proposed to add formats to format a type name in ``str % arg ``.
373- For example, ``%T `` and ``%#T `` formats.
399+ For example, add the ``%T `` format to format a type fully qualified
400+ name.
374401
375402Nowadays, f-strings are preferred for new code.
376403
377404
378- Use colon separator in fully qualified name
379- -------------------------------------------
380-
381- The colon (``: ``) separator eliminates guesswork when you want to import
382- the name, see ``pkgutil.resolve_name() ``. A type fully qualified name
383- can be formatted as ``f"{type.__module__}:{type.__qualname__}" ``, or
384- ``type.__qualname__ `` if the type module is ``"builtins" ``.
385-
386- In the standard library, no code formats a type fully qualified name
387- this way.
388-
389-
390405Other ways to format type names in C
391406------------------------------------
392407
@@ -421,8 +436,23 @@ between different modules and make the API more error prone.
421436About the ``%t `` format, ``printf() `` now uses ``t `` as a length
422437modifier for ``ptrdiff_t `` argument.
423438
424- ``type.__qualname__ `` can be used in Python and ``PyType_GetQualName() ``
425- can be used in C to format a type qualified name.
439+ The following APIs to be used to format a type:
440+
441+ .. list-table ::
442+ :header-rows: 1
443+
444+ * - C API
445+ - Python API
446+ - Format
447+ * - ``PyType_GetName() ``
448+ - ``type.__name__ ``
449+ - Type **short ** name.
450+ * - ``PyType_GetQualName() ``
451+ - ``type.__qualname__ ``
452+ - Type **qualified ** name.
453+ * - ``PyType_GetModuleName() ``
454+ - ``type.__module__ ``
455+ - Type **module ** name.
426456
427457
428458Use %T format with Py_TYPE(): pass a type
@@ -471,13 +501,15 @@ Python does crash.
471501Other proposed APIs to get a type fully qualified name
472502------------------------------------------------------
473503
474- * ``type.__fullyqualname__ `` attribute name: attribute without an underscore
504+ * Add ``type.__fullyqualname__ `` attribute: name without underscore
475505 between words. Several dunders, including some of the most recently
476- added ones, include an underscore in the word: ``__class_getitem__ ``,
477- ``__release_buffer__ ``, ``__type_params__ ``, ``__init_subclass__ `` and
478- ``__text_signature__ ``.
479- * ``type.__fqn__ `` attribute name, where FQN stands for Fully Qualified
480- Name.
506+ added ones, include an underscore in the word:
507+ ``__class_getitem__ ``, ``__release_buffer__ ``, ``__type_params__ ``,
508+ ``__init_subclass__ `` and ``__text_signature__ ``.
509+ * Add ``type.__fqn__ `` attribute: FQN name stands for **F **\ ully
510+ **Q **\ ualified **N **\ ame.
511+ * Add ``type.fully_qualified_name() `` method. Methods added to ``type ``
512+ are inherited by all types and so can affect existing code.
481513* Add a function to the ``inspect `` module. Need to import the
482514 ``inspect `` module to use it.
483515
@@ -493,9 +525,10 @@ not treat the ``__main__`` module differently: include it in the name.
493525Existing code such as ``type.__repr__() ``, ``collections.abc `` and
494526``unittest `` modules format a type name with
495527``f'{obj.__module__}.{obj.__qualname__}' `` and only omit the module part
496- if the module is equal to ``builtins ``. Only the ``traceback `` and
497- ``pdb `` modules also the module if it's equal to ``"builtins" `` or
498- ``"__main__" ``.
528+ if the module is equal to ``builtins ``.
529+
530+ Only the ``traceback `` and ``pdb `` modules also omit the module if it's
531+ equal to ``"builtins" `` or ``"__main__" ``.
499532
500533The ``type.__fully_qualified_name__ `` attribute omits the ``__main__ ``
501534module to produce shorter names for a common case: types defined in a
0 commit comments