[Python-Dev] bpo-34595: How to format a type name? (original) (raw)

Walter Dörwald walter at livinglogic.de
Thu Sep 13 05:00:28 EDT 2018


On 13 Sep 2018, at 2:33, Victor Stinner wrote:

Hi,

For the type name, sometimes, we only get a type (not an instance), and we want to format its FQN. IMHO we need to provide ways to format the FQN of a type for types and for instances. Here is my proposal: * Add !t conversion to format string * Add ":T" format to type.format() * Add "%t" and "%T" formatters to PyUnicodeFromUnicodeV()

As far as I can remember, the distinction between lowercase and uppercase format letter for PyUnicode_FromUnicodeV() and friends was: lowercase letters are for formatting C types (like char * etc.) and uppercase formatting letters are for Python types (i.e. the C type is PyObject *). IMHO we should keep that distinction.

* Add a read-only type.fqn property

I like that.

# Python: "!t" for instance raise TypeError(f"must be str, not {obj!t}")

/* C: "%t" for instance */ PyErrFormat(PyExcTypeError, "must be str, not %t", obj);

/* C: "%T" for type */ PyErrFormat(PyExcTypeError, "must be str, not %T", mytype); # Python: ":T" for type raise TypeError(f"must be str, not {mytype!T}")

We could solve the problem with instances and classes by adding two new ! operators to str.format/f-strings and making them chainable. The !t operator would get the class of the argument and the !c operator would require a class argument and would convert it to its name (which is obj.module + "." + obj.qualname (or only obj.qualname for builtin types)). So:

>>> import pathlib
>>> p = pathlib.Path("spam.py")
>>> print(f"{pathlib.Path}")
 <class 'pathlib.Path'>
>>> print(f"{pathlib.Path!c}")
 pathlib.Path
>>> print(f"{pathlib.Path!c!r}")
 'pathlib.Path'
>>> print(f"{p!t}")
 <class 'pathlib.Path'>
>>> print(f"{p!t!c}")
 pathlib.Path
>>> print(f"{p!c}")
 Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
 TypeError: object is not a class

This would also give us:

>>> print(f"{p!s!r}")
 'spam.py'

Which is different from:

>>> print(f"{p}")
 spam.py
>>> print(f"{p!r}")
 PosixPath('spam.py')

Open question: Should we also add "%t" and "%T" formatters to the str % args operator at the Python level?

I have a proof-of-concept implementation: https://github.com/python/cpython/pull/9251 Victor

Servus, Walter



More information about the Python-Dev mailing list