classification
Title: Do not define unneeded __str__ equal to __repr__
Type: enhancement Stage: resolved
Components: Interpreter Core Versions: Python 3.8
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: Nosy List: gregory.p.smith, josh.r, serhiy.storchaka
Priority: normal Keywords: patch

Created on 2019-05-04 13:10 by serhiy.storchaka, last changed 2019-08-31 19:37 by serhiy.storchaka. This issue is now closed.

Pull Requests
URL Status Linked Edit
PR 13081 merged serhiy.storchaka, 2019-05-04 13:21
Messages (4)
msg341382 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2019-05-04 13:10
object.__str__() calls the __repr__() method. Therefore by default you do not need to define the __str__() method if it is the same as __repr__(): just define the __repr__() method. But there are few builtin classes which define both __repr__() and __str__() methods which are equal. In most cases this is a legacy of Python 2 where they where different.

1. float and complex. In earlier Python 2 versions the repr of floating point number was longer (and more precise) that the str which was limited for readability. This was changed several times and in Python 3 the repr and the str are equal and contain as much digits as needed for the closest decimal approximation.

2. int. In Python 2 the repr of long integer was different from the str: it contained the "L" suffix.

3. bool. Since it is an int subclass with different repr, it needs to define __str__ to override int's __str__.

4. subprocess.Handle and sre_constants._NamedIntConstant. As bool they need to override int's __str__.

5. doctest.DocTestCase, doctest.DocFileCase. They need to override unittest.TestCase's __str__.

6. http.client.IncompleteRead, xmlrpc.client.Error. They need to override BaseException's __str__ (don't know why they want to do this).

7. asyncore.dispatcher, email.charset.Charset, logging.LogRecord, xmlrpc.client.MultiCall, xmlrpc.client.ServerProxy, decimal.Context (C implementation only), _pydecimal._WorkRep.  There is no need to define __str__.

In most of these cases the __str__ definition is redundant and can be removed. In cases 5 and 6 it is better to reset __str__ to object.__str__.

The only failing tests in the Python testsuite is the json module test. The json module calls int.__str__ explicitly. It can be fixed by replacing it with int.__repr__.

The user visible effect of these changes is that defining __repr__ in a subclass of these classes will affect the str() result (as for most of other classes). Although it is unlikely that you want to keep the str representation of the parent class when change the repr in the child class.
msg341476 - (view) Author: Josh Rosenberg (josh.r) * (Python triager) Date: 2019-05-05 21:59
I like this. Always annoying to explicitly override both __repr__ and __str__ on subclasses of stuff like int when they should be the same. Patch looks good to me; I was originally wondering why some classes were replacing:

__str__ = __repr__

with:

__str__ = object.__str__

but checking their inheritance chains, it's clear *some* overload is needed for consistency, and using object.__str__ means reverting to the default case where subclasses only need to overload __repr__, rather than forcing all subclasses to overload both.
msg341617 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2019-05-06 19:29
New changeset 96aeaec64738b730c719562125070a52ed570210 by Serhiy Storchaka in branch 'master':
bpo-36793: Remove unneeded __str__ definitions. (GH-13081)
https://github.com/python/cpython/commit/96aeaec64738b730c719562125070a52ed570210
msg348069 - (view) Author: Josh Rosenberg (josh.r) * (Python triager) Date: 2019-07-17 16:08
Serhiy: Did you plan to do any further work, or can this issue be closed?
History
Date User Action Args
2019-08-31 19:37:22serhiy.storchakasetstatus: open -> closed
resolution: fixed
stage: patch review -> resolved
2019-07-17 16:08:52josh.rsetmessages: + msg348069
2019-05-06 19:29:42serhiy.storchakasetmessages: + msg341617
2019-05-05 21:59:55josh.rsetnosy: + josh.r
messages: + msg341476
2019-05-05 16:35:10gregory.p.smithsettype: enhancement
2019-05-05 16:34:57gregory.p.smithsetnosy: + gregory.p.smith
2019-05-04 13:22:28serhiy.storchakasettitle: Do not set tp_str -> Do not define unneeded __str__ equal to __repr__
2019-05-04 13:21:30serhiy.storchakasetkeywords: + patch
stage: patch review
pull_requests: + pull_request12996
2019-05-04 13:10:23serhiy.storchakacreate