[WIP] bpo-13224 Change str for classes, functions and modules#3608
[WIP] bpo-13224 Change str for classes, functions and modules#3608merwok wants to merge 4 commits intopython:masterfrom
Conversation
|
|
||
| >>> print(defaultdict) # show our type | ||
| <class 'test.test_descrtut.defaultdict'> | ||
| defaultdict |
There was a problem hiding this comment.
I think these tests looked better with the previous outputs. Revert changes and change inputs instead (>>> defaultdict should show repr unless doctest doesn’t emulate the REPL displayhook)
|
|
||
| >>> C.foo(1) | ||
| classmethod <class 'test.test_descrtut.C'> 1 | ||
| classmethod C 1 |
There was a problem hiding this comment.
We want classmethod test.test_descrtut.C 1
There was a problem hiding this comment.
Turns out we don't: qualname is defined to not include the module name, so C is good here.
Alternative: change the code of the foo method to print repr(cls) instead of cls.
| name = PyModule_GetNameObject((PyObject *)m); | ||
| if (name == NULL) { | ||
| /* XXX PyUnicode_FromStringAndSize is documented as part of | ||
| the legacy API */ |
| (hashfunc)meth_hash, /* tp_hash */ | ||
| PyCFunction_Call, /* tp_call */ | ||
| 0, /* tp_str */ | ||
| (reprfunc)meth_str, /* tp_str */ |
There was a problem hiding this comment.
The point of the change is to have a __str__ that’s different than __repr__ :) But see the ticket, I think I will scale back this PR to classes only.
There was a problem hiding this comment.
Oh well, it is Guido who wanted a unified behaviour for modules, classes and functions (since they are things created by syntax (import*, class and def) with a __name__ attribute).
* I think a module’s __name__ depends on its loader, not on the name used in the import statement (import as doesn’t change __name__)
| name = PyModule_GetNameObject((PyObject *)m); | ||
| if (name == NULL) { | ||
| /* XXX PyUnicode_FromStringAndSize is documented as part of | ||
| the legacy API */ |
There was a problem hiding this comment.
Really? I never heart that PyUnicode_FromStringAndSize is a legacy API. This is the main way of creating strings in C. Could you point the place in the documentation where it declared legacy?
There was a problem hiding this comment.
Thanks for the comment. I don’t have the original Mercurial clone on this laptop, so I can’t look for my original commit. This code is removed in my latest changes (not pushed yet).
| if (name == NULL) { | ||
| /* XXX PyUnicode_FromStringAndSize is documented as part of | ||
| the legacy API */ | ||
| PyErr_Clear(); |
There was a problem hiding this comment.
Don't silence all errors. Only AttributeError.
| /* XXX PyUnicode_FromStringAndSize is documented as part of | ||
| the legacy API */ | ||
| PyErr_Clear(); | ||
| name = PyUnicode_FromStringAndSize("?", 1); |
There was a problem hiding this comment.
Wouldn't be better to fall back to repr()?
| return NULL; | ||
| } | ||
|
|
||
| str = PyUnicode_FromFormat("%U", name); |
There was a problem hiding this comment.
What is the purpose of this line?
| type_str(PyTypeObject *type) | ||
| { | ||
| PyObject *name, *rtn; | ||
|
|
There was a problem hiding this comment.
Wouldn't be better to include a module name for getting rid of ambiguity?
I would just return PyUnicode_FromString(type->tp_name).
There was a problem hiding this comment.
The original discussion on the ticket mentioned only the type qualname, without its module. Looking at Lib/typing.py and other files (for example the error message in functools), I think maybe including the module name too would be useful. Let’s see comments after I get a smaller patch that passes the test suite.
684c931 to
eb99067
Compare
eb99067 to
c3c84ad
Compare
ncoghlan
left a comment
There was a problem hiding this comment.
I think the number of additional changes needed in the test suite and the standard library highlights the compatibility restoration busy-work risks of actually making this change:
- while
test_structuresandtest_xmlrpcshow the kinds of error messages that the change is aimed at improving (and I think it does indeed improve them), it still requires the kind of test case change that is going to be awkward from projects spanning multiple distinct versions of CPython - most of the other cases were for code that actually wanted the current formatting, and needed to be updated to explicitly request
repr()(either by calling it directly, or by switching to!ror%rin a formatting string)
|
Rejected per Nick’s and Guido’s opinions. |
https://bugs.python.org/issue13224