12.09.18 01:23, Victor Stinner пише:
But then Petr Viktorin asked me to open a thread on python-dev to get a wider discussion. So here I am.
Thank you for opening this discussion Victor. I wanted to do it myself, but you have wrote much better description of the problem. See also related issues: https://bugs.python.org/issue21861 https://bugs.python.org/issue22032 (solved) https://bugs.python.org/issue22033 (solved) https://bugs.python.org/issue27541 (solved) https://bugs.python.org/issue28062 There were also attempts to change repr/str of types so that they return just a FQN. It would help to solve the issue from Python side. This idea was initially suggested by Guido, but later he changed his mind.
The rationale for this change is to fix multiple issues:
* C extensions use Py_TYPE(obj)->tp_name which returns a fully qualified name for C types, but the name (without the module) for Python name. Python modules use type(obj).__name__ which always return the short name.
Sometimes Python modules use FQN, but this is not common, and the code is cumbersome. It is more common to use obj.__class__ instead of type(obj), the difference is intentionally ignored.
* currently, many C extensions truncate the type name: use "%.80s" instead of "%s" to format a type name
AFAIK the rationale of this in PyUnicode_FromFormat() is that if you have corrupted type object, tp_name can point on arbitrary place in memory, and an attempt to interpret it as null terminated string can output a large amount of trash. It is better to get a truncated type name in error message (names of real types usually are below that limit) than get tons of trash or an error in attempt to format it.
Maybe we can have "name: {0:t}, FQN: {0:T}".format(type(obj)). "t" for name and "T" for fully qualfied name. We would only have to modify type.__format__().
This will make the feature inconsistent in Python and C. In Python, the argument is a type, in C it is an instance of the type. We need a way to format a FQN in C for types themselves. It is less common case, but using _PyType_FullName() for it is very non-convenient as you have shown above.