diff --git a/peps/pep-0737.rst b/peps/pep-0737.rst index 59a1a5df4..a74b7d50c 100644 --- a/peps/pep-0737.rst +++ b/peps/pep-0737.rst @@ -1,5 +1,5 @@ PEP: 737 -Title: Unify type name formatting +Title: C API to format a type fully qualified name Author: Victor Stinner Discussions-To: https://discuss.python.org/t/pep-737-unify-type-name-formatting/39872 Status: Draft @@ -12,17 +12,12 @@ Post-History: `29-Nov-2023 tp_name); + +can be replaced with the ``%T`` format: + +.. code-block:: c + + PyErr_Format(PyExc_TypeError, + "__format__ must return a str, not %T", result); + +Advantages of the updated code: + +* Safer C code: avoid ``Py_TYPE()`` which returns a borrowed reference. +* The ``PyTypeObject.tp_name`` member is no longer read explicitly: the + code becomes compatible with the limited C API. +* The formatted type name no longer depends on the type implementation. +* The type name is no longer truncated. + +Note: The ``%T`` format is used by ``time.strftime()``, but not by +``printf()``. + + +Formats Summary +--------------- + +.. list-table:: + :header-rows: 1 + + * - C object + - C type + - Format + * - ``%T`` + - ``%N`` + - Type **fully qualified** name. + * - ``%#T`` + - ``%#N`` + - Type **fully qualified** name, **colon** separator. + +Recommend using the type fully qualified name +--------------------------------------------- + +The type fully qualified name is recommended in error messages and in +``__repr__()`` methods in new C code. + +In non-trivial applications, it is likely to have two types with the +same short name defined in two different modules, especially with +generic names. Using the fully qualified name helps identifying the type +in an unambiguous way. + + +Recommend not truncating type names +----------------------------------- + +Type names should not be truncated in new C code. For example, the +``%.100s`` format should be avoided: use the ``%s`` format instead (or +``%T`` format in C). + + +Implementation +============== + +* Pull request: `Add type.__fully_qualified_name__ attribute `_. +* Pull request: `Add %T format to PyUnicode_FromFormat() `_. + + +Backwards Compatibility +======================= + +Changes proposed in this PEP are backward compatible. + +Adding new C APIs has no effect on the backward compatibility. Existing +C APIs are left unchanged. No Python API is changed. + +Replacing the type short name with the type fully qualified name is only +recommended in new C code. No longer truncating type names is only +recommended in new C code. Existing code should be left unchanged and so +remains backward compatible. There is no recommendation for Python code. + + +Rejected Ideas +============== + Add type.__fully_qualified_name__ attribute ------------------------------------------- @@ -202,6 +330,22 @@ equal to ``"__main__"``. The ``type.__repr__()`` is left unchanged, it only omits the module if the module is equal to ``"builtins"``. +This change was `rejected by the Steering Council +`__: + + We can see the usefulness of the C API changes proposed by the PEP + and would likely accept those changes as is. + + We see less justification for the Python level changes. We + especially question the need for ``__fully_qualified_name__``. + +Thomas Wouters added: + + If there really is a desire for formatting types the exact same way + the C API does it, a utility function would make more sense to me, + personally, than ``type.__format__``, but I think the SC could be + persuaded given some concrete use-cases. + Add type.__format__() method ---------------------------- @@ -228,141 +372,9 @@ guesswork when you want to import the name, see ``pkgutil.resolve_name()``, ``python -m inspect`` command line interface, and ``setuptools`` entry points. +This change was `rejected by the Steering Council +`__. -Add formats to PyUnicode_FromFormat() -------------------------------------- - -Add the following formats to ``PyUnicode_FromFormat()``: - -* ``%N`` formats the **fully qualified name** of a **type** - (``type.__fully_qualified_name__``); **N** stands for type **N**\ ame. -* ``%T`` formats the type **fully qualified name** of an **object** - (``type(obj).__fully_qualified_name__``); **T** stands for object - **T**\ ype. -* ``%#N`` and ``%#T``: the alternative form uses the **colon** separator - (``:``), instead of the dot separator (``.``), between the module name - and the qualified name. - -For example, the existing code using *tp_name*: - -.. code-block:: c - - PyErr_Format(PyExc_TypeError, - "__format__ must return a str, not %.200s", - Py_TYPE(result)->tp_name); - -can be replaced with the ``%T`` format: - -.. code-block:: c - - PyErr_Format(PyExc_TypeError, - "__format__ must return a str, not %T", result); - -Advantages of the updated code: - -* Safer C code: avoid ``Py_TYPE()`` which returns a borrowed reference. -* The ``PyTypeObject.tp_name`` member is no longer read explicitly: the - code becomes compatible with the limited C API. -* The ``PyTypeObject.tp_name`` bytes string no longer has to be decoded - from UTF-8 at each ``PyErr_Format()`` call, since - ``type.__fully_qualified_name__`` is already a Unicode string. -* The formatted type name no longer depends on the type implementation. -* The type name is no longer truncated. - -Note: The ``%T`` format is used by ``time.strftime()``, but not by -``printf()``. - - -Formats Summary ---------------- - -.. list-table:: - :header-rows: 1 - - * - C object - - C type - - Python - - Format - * - ``%T`` - - ``%N`` - - ``:N`` - - Type **fully qualified** name. - * - ``%#T`` - - ``%#N`` - - ``:#N`` - - Type **fully qualified** name, **colon** separator. - -Add PyType_GetModuleName() function ------------------------------------ - -Add the ``PyType_GetModuleName()`` function to get the module name of a -type (``type.__module__``). API: - -.. code-block:: c - - PyObject* PyType_GetModuleName(PyTypeObject *type) - -On success, return a new reference to the string. On error, raise an -exception and return ``NULL``. - - -Add PyType_GetFullyQualifiedName() function -------------------------------------------- - -Add the ``PyType_GetFullyQualifiedName()`` function to get the fully -qualified name of a type (``type.__fully_qualified_name__``). API: - -.. code-block:: c - - PyObject* PyType_GetFullyQualifiedName(PyTypeObject *type) - -On success, return a new reference to the string. On error, raise an -exception and return ``NULL``. - - -Recommend using the type fully qualified name ---------------------------------------------- - -The type fully qualified name is recommended in error messages and in -``__repr__()`` methods in new code. - -In non-trivial applications, it is likely to have two types with the -same short name defined in two different modules, especially with -generic names. Using the fully qualified name helps identifying the type -in an unambiguous way. - - -Recommend not truncating type names ------------------------------------ - -Type names should not be truncated in new code. For example, the -``%.100s`` format should be avoided: use the ``%s`` format instead (or -``%T`` format in C). - - -Implementation -============== - -* Pull request: `Add type.__fully_qualified_name__ attribute `_. -* Pull request: `Add %T format to PyUnicode_FromFormat() `_. - - -Backwards Compatibility -======================= - -Changes proposed in this PEP are backward compatible. - -Adding new APIs has no effect on the backward compatibility. Existing -APIs are left unchanged. - -Replacing the type short name with the type fully qualified name is only -recommended in new code. No longer truncating type names is only -recommended in new code. Existing code should be left unchanged and so -remains backward compatible. - - -Rejected Ideas -============== Change str(type) ---------------- @@ -386,7 +398,7 @@ Add !t formatter to get an object type Use ``f"{obj!t:T}"`` to format ``type(obj).__fully_qualified_name__``, similar to ``f"{type(obj):T}"``. -When the ``!t`` formatter was proposed in 2018, `Eric Smith was stronly +When the ``!t`` formatter was proposed in 2018, `Eric Smith was strongly opposed to this `_; Eric is the author of the f-string :pep:`498` "Literal String Interpolation".