This issue tracker has been migrated to GitHub ,
and is currently read-only.
For more information,
see the GitHub FAQs in the Python's Developer Guide.
Created on 2011年10月19日 19:44 by eric.araujo, last changed 2022年04月11日 14:57 by admin. This issue is now closed.
| Files | ||||
|---|---|---|---|---|
| File name | Uploaded | Description | Edit | |
| change-some-str.diff | eric.araujo, 2011年11月24日 15:55 | |||
| test-str-repr.py | eric.araujo, 2011年11月24日 15:56 | |||
| Pull Requests | |||
|---|---|---|---|
| URL | Status | Linked | Edit |
| PR 3608 | closed | eric.araujo, 2017年09月16日 02:15 | |
| Messages (34) | |||
|---|---|---|---|
| msg145946 - (view) | Author: Éric Araujo (eric.araujo) * (Python committer) | Date: 2011年10月19日 19:45 | |
Suggestion by Guido on #868845: > I sometimes wish that the str() of a class would return the class name > rather than its repr(); that way "print(str)" would print "str" > instead of <class 'str'>. (Use case: printing an exception and its > message: I wish I could print("%s: %s" % (err.__class__, err)) instead > of having to use err.__class__.__name__.) I wrote a simple patch for that. I just copied the definition of type_repr to a new type_str function, edited the format strings and updated the member mapping (I checked in another file than casting to reprfunc is okay for a str func). It compiles and runs just fine, but I’m still learning C, so there may be things I’ve missed: I don’t know if I have to declare the new function or something like that. The test suite passes with very few edits. Guido added this: > One could even claim that the repr() of a class could be the same I for one think of repr first as "string form for debugging", so I like the angle brackets. My patch leaves __repr__ alone. If this get approved, I’ll update my patch with doc changes. If there is no feedback I’ll go to python-ideas. |
|||
| msg145965 - (view) | Author: STINNER Victor (vstinner) * (Python committer) | Date: 2011年10月19日 21:02 | |
It looks like your change breaks backward compatibility (e.g. tests written using doctests). I don't know if it's a problem or not. |
|||
| msg146080 - (view) | Author: Éric Araujo (eric.araujo) * (Python committer) | Date: 2011年10月21日 13:29 | |
I would argue that the previous behavior of str(class) was undefined, or an implementation detail; as a new feature, my patch can break some code that relied on the previous behavior, but we may judge think it’s worth the cost. BTW, doctest is inherently fragile and broken by many changes, so I’m not too concerned about it. |
|||
| msg146216 - (view) | Author: Éric Araujo (eric.araujo) * (Python committer) | Date: 2011年10月23日 02:31 | |
Here’s the python-ideas thread: http://mail.python.org/pipermail/python-ideas/2011-October/thread.html#12459 |
|||
| msg146530 - (view) | Author: Guido van Rossum (gvanrossum) * (Python committer) | Date: 2011年10月28日 02:01 | |
What's holding this up? |
|||
| msg146566 - (view) | Author: Éric Araujo (eric.araujo) * (Python committer) | Date: 2011年10月28日 14:44 | |
[Guido] > What's holding this up? - I haven’t updated the patch for function and module objects yet - I need to catch up with the python-ideas discussion - There is at least one strong argument against the idea (I’ll point it out on the ML) |
|||
| msg146844 - (view) | Author: Éric Araujo (eric.araujo) * (Python committer) | Date: 2011年11月02日 16:31 | |
I’ve updated my patch to handle modules and functions too, but there is a decision to make. The functions of built-in modules are implemented by methodobject.c, not functionobject.c (that’s for Python functions), so if we want str(sys.exc_info) to be equal to 'exc_info', then we’ll have str(dict.update) == 'update'. Is this okay?
The patch needs a review.
- I tried using PyUnicode_FromString(name) instead of PyUnicode_FromFormat("%U", name), just like in Python I would use str(x) instead of '%s' % x, but this caused segfaults. Is there a simpler function to use?
- I’ve used copy-paste-tweak and checked the results; I’m still learning C and know very little about Python’s types and refcounting internals, so review mercilessly! I forgot to run the tests in findleaks mode, so I’m doing it right now.
|
|||
| msg146854 - (view) | Author: Guido van Rossum (gvanrossum) * (Python committer) | Date: 2011年11月02日 17:19 | |
On Wed, Nov 2, 2011 at 9:31 AM, Éric Araujo <report@bugs.python.org> wrote: > > Éric Araujo <merwok@netwok.org> added the comment: > > I’ve updated my patch to handle modules and functions too, but there is a decision to make. The functions of built-in modules are implemented by methodobject.c, not functionobject.c (that’s for Python functions), so if we want str(sys.exc_info) to be equal to 'exc_info', then we’ll have str(dict.update) == 'update'. Is this okay? Hm, that doesn't seem right. Currently, str(sys.exc_info) says <built-in function exc_info> but str(dict.update) is <built-in function exc_info>. So the latter definitely knows that it is an unbound method! And {}.update is <built-in method update of dict object at 0x10040c050> so that knows it is a bound method. I'd be okay if str(sys.exc_info) and str({}.update) were unchanged from today and if str(dict.update) returned 'dict.update', but if that's too complicated I'd also be okay with all three being unchanged, thus limiting this to Python functions (and classes and modules). |
|||
| msg146858 - (view) | Author: Antoine Pitrou (pitrou) * (Python committer) | Date: 2011年11月02日 17:49 | |
Please also see the proposed PEP 3155 - http://mail.python.org/pipermail/python-ideas/2011-October/012609.html |
|||
| msg146938 - (view) | Author: Éric Araujo (eric.araujo) * (Python committer) | Date: 2011年11月03日 15:27 | |
> Please also see the proposed PEP 3155 I’ve seen it and like it. I assume you’re telling that we should consider str(cls/mod/func) to return the qname instead of the name? I think it could be good. My patch can wait for your PEP, or go in first and be updated later if your PEP is accepted. |
|||
| msg147227 - (view) | Author: Éric Araujo (eric.araujo) * (Python committer) | Date: 2011年11月07日 14:59 | |
I misreported: dict.update is actually okay, but collections.Counter.update (a Python method) is a not an unbound method but a function (py3k-style). |
|||
| msg148122 - (view) | Author: Éric Araujo (eric.araujo) * (Python committer) | Date: 2011年11月22日 15:27 | |
PEP 3155 is accepted and makes str(cls) and str(function) as well as repr(cls) and repr(function) return the qualified name, which obsoletes part of this request. I haven’t checked if it has the same problem with Python methods. str(module) is not changed by the PEP. |
|||
| msg148129 - (view) | Author: Guido van Rossum (gvanrossum) * (Python committer) | Date: 2011年11月22日 16:55 | |
Are you sure? The way I read the PEP, it just said that str(cls) and str(func) should *use* qualname. That could mean returning '<function f.g.h at 0x1234>' or '<class '__main__.C.D>'. On Tue, Nov 22, 2011 at 7:27 AM, Éric Araujo <report@bugs.python.org> wrote: > > Éric Araujo <merwok@netwok.org> added the comment: > > PEP 3155 is accepted and makes str(cls) and str(function) as well as repr(cls) and repr(function) return the qualified name, which obsoletes part of this request. I haven’t checked if it has the same problem with Python methods. str(module) is not changed by the PEP. > > ---------- > title: Change str(class) to return only the class name -> Change str(x) to return only __qualname__ for some types > > _______________________________________ > Python tracker <report@bugs.python.org> > <http://bugs.python.org/issue13224> > _______________________________________ > |
|||
| msg148266 - (view) | Author: Éric Araujo (eric.araujo) * (Python committer) | Date: 2011年11月24日 15:55 | |
You are right, I misinterpreted "use". I cloned the the PEP 3155 repo and ran my test script (I’ll attach it for reference) and reprs/strs are indeed "<class '__main__.A.B'>" and "<function makestrip.<locals>.strip at ...>", so this request is not obsoleted. I’ve updated my patch to use qualnames for str(cls) and str(func). As I reported before, if I want str(sys.exc_info) to be 'exc_info', then Python unbound methods (i.e. functions) are affected: <method 'update' of 'dict' objects> <built-in method update of dict object at ...> <method 'tolist' of 'array.array' objects> <built-in method tolist of array.array object at ...> → Counter.update <bound method Counter.update of Counter()> → Top.Nested.method # this checks qualnames are used <bound method Nested.method of <__main__.Top.Nested object at ...> It seems to me that this is not a problem: Python 3 unbound methods *are* functions. If you decide that having str(method) unchanged for all kinds of methods is more important than giving all kinds of functions a short str, I can do it. |
|||
| msg154309 - (view) | Author: Éric Araujo (eric.araujo) * (Python committer) | Date: 2012年02月26日 06:28 | |
Ping: I’d like opinions on the request in my last message; |
|||
| msg154360 - (view) | Author: Guido van Rossum (gvanrossum) * (Python committer) | Date: 2012年02月26日 15:35 | |
Not 100% sure what you're asking. Is your specific question whether it is okay that str(Counter.update) returns 'Counter.update'? Yes, it is. Same for Top.Nested.method. |
|||
| msg154444 - (view) | Author: Éric Araujo (eric.araujo) * (Python committer) | Date: 2012年02月27日 09:03 | |
> Is your specific question whether it is okay that str(Counter.update) returns 'Counter.update'? Yes, sorry if I was unclear. > Yes, it is. Same for Top.Nested.method. Good! I’ll commit soon. I’ll make a note in Misc/NEWS, but I don’t think this should go to whatsnew or other doc, as it’s an implementation detail anyway (as discussed on the python-ideas thread). |
|||
| msg244997 - (view) | Author: Vedran Čačić (veky) * | Date: 2015年06月08日 11:27 | |
What's going on with this? It seems we have the patch, but discussions have just stopped - both on Python-ideas and here. The idea is great, BDFL-approved, and would simplify a lot of code, especially with new typehinting. |
|||
| msg245011 - (view) | Author: Éric Araujo (eric.araujo) * (Python committer) | Date: 2015年06月08日 15:52 | |
I am no longer an active core contributor. Someone should take this and apply it for the next version. |
|||
| msg245031 - (view) | Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) | Date: 2015年06月08日 18:37 | |
Other discussion: http://comments.gmane.org/gmane.comp.python.ideas/32192 . |
|||
| msg248069 - (view) | Author: Robert Collins (rbcollins) * (Python committer) | Date: 2015年08月05日 20:00 | |
The patch is a little stale but it seems easy enough to fix up. I'll commit it tomorrowish in the absence of other discussion. |
|||
| msg248088 - (view) | Author: Martin Panter (martin.panter) * (Python committer) | Date: 2015年08月06日 00:15 | |
I’m a bit confused. In the current patch, the new type_str() function appears to use the "qualname" (which I support), but some of the test changes seem to contradict this, e.g.: >>> C.foo(1) -classmethod <class 'test.test_descrtut.C'> 1 +classmethod C 1 Also, I think this new feature should be documented. |
|||
| msg248629 - (view) | Author: Robert Collins (rbcollins) * (Python committer) | Date: 2015年08月15日 00:52 | |
Ok, so needs more work. Moving back to patch review. |
|||
| msg302311 - (view) | Author: Éric Araujo (eric.araujo) * (Python committer) | Date: 2017年09月16日 02:28 | |
I converted my patch to a PR. One use case mentioned on python-ideas was for reprs of PEP 384 types; need to hunt down where typing could benefit from the new str(class). The quote in my first message mentions printing err.__class__ rather than err.__class__.__name__; see if tutorial or logging or other docs could be made short and sweet with this change. Finally, I don’t remember why I changed functions and modules when the two original use cases were only for classes. |
|||
| msg302316 - (view) | Author: Vedran Čačić (veky) * | Date: 2017年09月16日 03:30 | |
I'm very glad this is moving forward. Yes, types (classes) are most important, functions and modules not so much. The biggest use case for me is easier construction of sane error messages. In many cases, something like f'Got a {type(argument)}' should be enough.
|
|||
| msg302495 - (view) | Author: Éric Araujo (eric.araujo) * (Python committer) | Date: 2017年09月19日 02:38 | |
Martin Panter > I’m a bit confused. In the current patch, the new type_str() function > appears to use the "qualname" (which I support), but some of the test > changes seem to contradict this, e.g.: > >>> C.foo(1) > -classmethod <class 'test.test_descrtut.C'> 1 > +classmethod C 1 C is a qualname, as would be C.NestedD or something.<locals>.NestedD The qualname PEP explains why the module is not part of the qualname. Me > Finally, I don’t remember why I changed functions and modules when the two > original use cases were only for classes. The reason is a message by Nick on python-ideas. |
|||
| msg302496 - (view) | Author: Éric Araujo (eric.araujo) * (Python committer) | Date: 2017年09月19日 02:39 | |
(Nick and Guido! «My proposal is to make str(x) return x.__name__ for exactly these three types of objects: modules, classes, and functions.») |
|||
| msg302499 - (view) | Author: Guido van Rossum (gvanrossum) * (Python committer) | Date: 2017年09月19日 03:25 | |
For modules, __name__ is the fully-qualified name, and that's fine. But for classes and functions __name__ is just the "given name" from the syntax (whatever came after 'def' or 'class') and that's not fine -- for anything except builtins where we do this I would like the str() to produce the fully-qualified name. I presume by "functions" you mean only things defined with 'def' and excluding bound methods? |
|||
| msg302502 - (view) | Author: Alyssa Coghlan (ncoghlan) * (Python committer) | Date: 2017年09月19日 05:46 | |
Specifically this message, where the unwritten rationale is to offer behavioural consistency across the builtin types that know their own name and include it in their current repr() output: https://mail.python.org/pipermail/python-ideas/2011-October/012464.html As per Guido's comment and the discussion of PEP 3155 above, the idea now is that for classes/functions/methods, we make it so that: repr(x) -> gives both the type and the qualified name (as now) str(x) -> gives just the qualified name Importantly, this *won't* change the result of printing full namespaces, since the dict repr calls repr() on values, not str(). |
|||
| msg302506 - (view) | Author: Alyssa Coghlan (ncoghlan) * (Python committer) | Date: 2017年09月19日 07:53 | |
That said, bringing over my overall comment from the PR review:
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_structures and test_xmlrpc show 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 !r or %r in a formatting string)
Perhaps a less disruptive way of tackling the problem with the verbosity of name access would be to add a new `getname()` builtin that understood how to get the names of various things (e.g. via `__class__`), and preferred __qualname__ to __name__ when both were available? Then Guido's original motivating example could be written as:
print(f"{getname(err)}: {err}") # f-string
print("{}: {}".format(getname(err), err) # str.format
print("%s: %s" % (getname(err), err)) # printf-style
As a new builtin, it could be trivially added to cross-version compatibility libraries like six and python-future, whereas directly changing the behaviour of __str__ on the affected builtin types isn't really something that can be readily emulated on old versions.
|
|||
| msg302510 - (view) | Author: Vedran Čačić (veky) * | Date: 2017年09月19日 08:42 | |
getname sounds good, but is in fact very confusing. In most cases, what you'd actually want, and end up writing, is getname(type(x)), but we can't make it the default since for classes we would actually like x.__name__ directly. It seems you say the same with "get the names of various things (e.g. via `__class__`)", but the interface is very complicated if we try to guess what people meant, and clumsy if we force people to write type almost all the time. The point is, we want to be explicit about whether we are speaking about x or type(x). Everything else is simply presentation details. type does it perfectly well, only the presentation details are canonically handled via str and repr. And it's perfectly natural, BTW. Imagine if str(5) gave you '<integer 5>'. :-o |
|||
| msg302534 - (view) | Author: Guido van Rossum (gvanrossum) * (Python committer) | Date: 2017年09月19日 15:49 | |
Given Nick's feedback (and imagining what this would do to some codebases I know) I think this idea is dead, sadly. A helper function just doesn't give enough value, so let's not pursue that (it's easy to write the helper you want, it's hard to agree on what helper everybody should want). |
|||
| msg302536 - (view) | Author: Éric Araujo (eric.araujo) * (Python committer) | Date: 2017年09月19日 16:08 | |
Yeah, it was interesting to explore but there are significant drawbacks and not enough benefit. Thanks for the guidance all! |
|||
| msg302539 - (view) | Author: Guido van Rossum (gvanrossum) * (Python committer) | Date: 2017年09月19日 16:27 | |
And thanks for working it through! It was a valuable exercise. |
|||
| History | |||
|---|---|---|---|
| Date | User | Action | Args |
| 2022年04月11日 14:57:22 | admin | set | github: 57433 |
| 2017年09月19日 16:27:20 | gvanrossum | set | messages: + msg302539 |
| 2017年09月19日 16:08:41 | eric.araujo | set | status: open -> closed resolution: rejected messages: + msg302536 stage: patch review -> resolved |
| 2017年09月19日 15:49:44 | gvanrossum | set | messages: + msg302534 |
| 2017年09月19日 08:42:48 | veky | set | messages: + msg302510 |
| 2017年09月19日 07:53:10 | ncoghlan | set | messages: + msg302506 |
| 2017年09月19日 05:46:58 | ncoghlan | set | nosy:
+ ncoghlan messages: + msg302502 |
| 2017年09月19日 03:25:48 | gvanrossum | set | messages: + msg302499 |
| 2017年09月19日 02:39:50 | eric.araujo | set | messages: + msg302496 |
| 2017年09月19日 02:38:26 | eric.araujo | set | messages: + msg302495 |
| 2017年09月16日 03:30:35 | veky | set | messages: + msg302316 |
| 2017年09月16日 02:28:37 | eric.araujo | set | keywords:
+ needs review assignee: eric.araujo messages: + msg302311 versions: + Python 3.7, - Python 3.6 |
| 2017年09月16日 02:15:18 | eric.araujo | set | pull_requests: + pull_request3599 |
| 2015年08月15日 00:52:16 | rbcollins | set | messages:
+ msg248629 stage: commit review -> patch review |
| 2015年08月06日 00:15:52 | martin.panter | set | messages: + msg248088 |
| 2015年08月05日 20:00:29 | rbcollins | set | messages: + msg248069 |
| 2015年08月05日 19:57:15 | rbcollins | set | nosy:
+ rbcollins |
| 2015年06月08日 18:37:48 | serhiy.storchaka | set | nosy:
+ serhiy.storchaka messages: + msg245031 |
| 2015年06月08日 15:52:22 | eric.araujo | set | versions:
+ Python 3.6, - Python 3.4 title: Change str(x) to return only the (qual)name for some types -> Change str(x) to return only the qualname for some types messages: + msg245011 assignee: eric.araujo -> (no value) stage: patch review -> commit review |
| 2015年06月08日 11:27:42 | veky | set | nosy:
+ veky messages: + msg244997 |
| 2015年03月21日 21:59:40 | martin.panter | set | nosy:
+ martin.panter |
| 2012年09月26日 14:55:27 | ezio.melotti | set | versions: + Python 3.4, - Python 3.3 |
| 2012年02月27日 09:03:39 | eric.araujo | set | messages: + msg154444 |
| 2012年02月26日 15:35:13 | gvanrossum | set | messages: + msg154360 |
| 2012年02月26日 06:28:11 | eric.araujo | set | messages: + msg154309 |
| 2011年11月24日 15:57:55 | eric.araujo | set | title: Change str(x) to return only __qualname__ for some types -> Change str(x) to return only the (qual)name for some types |
| 2011年11月24日 15:56:43 | eric.araujo | set | files: - change-some-__str__.diff |
| 2011年11月24日 15:56:42 | eric.araujo | set | files: - change-class-__str__.diff |
| 2011年11月24日 15:56:39 | eric.araujo | set | files: + test-str-repr.py |
| 2011年11月24日 15:55:41 | eric.araujo | set | files:
+ change-some-str.diff dependencies: + PEP 3155 implementation messages: + msg148266 |
| 2011年11月22日 21:44:23 | eric.snow | set | nosy:
+ eric.snow |
| 2011年11月22日 16:55:10 | gvanrossum | set | messages: + msg148129 |
| 2011年11月22日 15:27:51 | eric.araujo | set | messages:
+ msg148122 title: Change str(class) to return only the class name -> Change str(x) to return only __qualname__ for some types |
| 2011年11月07日 14:59:00 | eric.araujo | set | messages: + msg147227 |
| 2011年11月03日 15:27:03 | eric.araujo | set | messages: + msg146938 |
| 2011年11月02日 17:49:36 | pitrou | set | nosy:
+ pitrou messages: + msg146858 |
| 2011年11月02日 17:19:59 | gvanrossum | set | messages: + msg146854 |
| 2011年11月02日 16:31:11 | eric.araujo | set | files:
+ change-some-__str__.diff messages: + msg146844 |
| 2011年10月28日 14:44:38 | eric.araujo | set | messages: + msg146566 |
| 2011年10月28日 02:01:25 | gvanrossum | set | messages: + msg146530 |
| 2011年10月23日 02:31:46 | eric.araujo | set | messages: + msg146216 |
| 2011年10月21日 13:29:40 | eric.araujo | set | messages: + msg146080 |
| 2011年10月19日 21:46:15 | ezio.melotti | set | nosy:
+ gvanrossum, ezio.melotti |
| 2011年10月19日 21:02:17 | vstinner | set | nosy:
+ vstinner messages: + msg145965 |
| 2011年10月19日 19:45:43 | eric.araujo | set | messages: - msg145945 |
| 2011年10月19日 19:45:31 | eric.araujo | set | messages: + msg145946 |
| 2011年10月19日 19:45:03 | eric.araujo | set | files:
+ change-class-__str__.diff keywords: + patch |
| 2011年10月19日 19:44:54 | eric.araujo | create | |