On 9/12/2018 8:33 PM, 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
I'm strongly opposed to this. This !t conversion would not be widely applicable enough to be generally useful, and would need to be exposed in the f-string and str.format() documentation, even though 99% of programmers would never need or see it. The purpose of the conversions is not to save you from making a function call when you know the type of the arguments. The purpose was specifically to convert arguments to strings so that your format specifier could always use the string formatting mini-language. It was more useful in str.format(), where the format string might be written separately (as user input or a translation, say) and not know the types of the arguments. You can (and I have!) argued that the conversions are completely unneeded in f-strings. raise TypeError(f"must be str, not {obj!t}") Should be written as: raise TypeError(f"must be str, not {type(obj)}")
* Add ":T" format to type.__format__() As you know (I've read the patch) this is just "T". I mention it here for future readers. They should understand that the ":" is a str.format() and f-string construct, and is unknown to __format__().
That said, I think this is a good idea. type.__format__() could also understand "#" to specify qualname.
* Add "%t" and "%T" formatters to PyUnicode_FromUnicodeV() I think "T" is a good idea, but I think you're adding in obj vs type(obj) just because of the borrowed reference issue in Py_TYPE(). That issue is so much larger than string formatting the type of an object that it shouldn't be addressed here.
* Add a read-only type.__fqn__ property I'm not sure of the purpose of this. When in your examples is it used? # Python: "!t" for instance raise TypeError(f"must be str, not {obj!t}")
/* C: "%t" for instance */ PyErr_Format(PyExc_TypeError, "must be str, not %t", obj);
/* C: "%T" for type */ PyErr_Format(PyExc_TypeError, "must be str, not %T", mytype);
# Python: ":T" for type raise TypeError(f"must be str, not {mytype!T}")
Open question: Should we also add "%t" and "%T" formatters to the str % args operator at the Python level?
No. Again, I think any formatting of type names should not be in a widely used interface, and should remain in our type-specific interface, __format__. %-formatting has no per-type extensibility, and I don't think we should start adding codes for every possible use case. Format codes for datetimes would be way more useful that %t, and I'd be opposed to adding them, too. (I realize my analogy is stretched, because every object has a type. But still.) Eric
I have a proof-of-concept implementation: https://github.com/python/cpython/pull/9251
Victor
Victor _______________________________________________ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/eric%2Ba-python-dev%40tru...