[Python-checkins] bpo-39549: reprlib.Repr uses a “fillvalue” attribute (GH-18343)

rhettinger webhook-mailer at python.org
Wed Sep 22 16:46:08 EDT 2021


https://github.com/python/cpython/commit/8c21941ddafdf4925170f9cea22e2382dd3b0184
commit: 8c21941ddafdf4925170f9cea22e2382dd3b0184
branch: main
author: Alexander Böhn <fish2000 at users.noreply.github.com>
committer: rhettinger <rhettinger at users.noreply.github.com>
date: 2021-09-22T15:45:58-05:00
summary:

bpo-39549: reprlib.Repr uses a “fillvalue” attribute (GH-18343)

files:
A Misc/NEWS.d/next/Library/2020-02-03-21-18-31.bpo-39549.l4a8uH.rst
M Doc/library/reprlib.rst
M Lib/reprlib.py
M Lib/test/test_reprlib.py

diff --git a/Doc/library/reprlib.rst b/Doc/library/reprlib.rst
index 1a0c1b0dcd1aa..4b37c5ba60f4e 100644
--- a/Doc/library/reprlib.rst
+++ b/Doc/library/reprlib.rst
@@ -76,6 +76,14 @@ size limits for the representations of different object types,  and methods
 which format specific object types.
 
 
+.. attribute:: Repr.fillvalue
+
+   This string is displayed for recursive references. It defaults to
+   ``...``.
+
+   .. versionadded:: 3.11
+
+
 .. attribute:: Repr.maxlevel
 
    Depth limit on the creation of recursive representations.  The default is ``6``.
diff --git a/Lib/reprlib.py b/Lib/reprlib.py
index 616b3439b5de3..f3518df105e41 100644
--- a/Lib/reprlib.py
+++ b/Lib/reprlib.py
@@ -36,6 +36,7 @@ def wrapper(self):
 class Repr:
 
     def __init__(self):
+        self.fillvalue = '...'
         self.maxlevel = 6
         self.maxtuple = 6
         self.maxlist = 6
@@ -64,14 +65,16 @@ def repr1(self, x, level):
     def _repr_iterable(self, x, level, left, right, maxiter, trail=''):
         n = len(x)
         if level <= 0 and n:
-            s = '...'
+            s = self.fillvalue
         else:
             newlevel = level - 1
             repr1 = self.repr1
             pieces = [repr1(elem, newlevel) for elem in islice(x, maxiter)]
-            if n > maxiter:  pieces.append('...')
+            if n > maxiter:
+                pieces.append(self.fillvalue)
             s = ', '.join(pieces)
-            if n == 1 and trail:  right = trail + right
+            if n == 1 and trail:
+                right = trail + right
         return '%s%s%s' % (left, s, right)
 
     def repr_tuple(self, x, level):
@@ -104,8 +107,10 @@ def repr_deque(self, x, level):
 
     def repr_dict(self, x, level):
         n = len(x)
-        if n == 0: return '{}'
-        if level <= 0: return '{...}'
+        if n == 0:
+            return '{}'
+        if level <= 0:
+            return '{' + self.fillvalue + '}'
         newlevel = level - 1
         repr1 = self.repr1
         pieces = []
@@ -113,7 +118,8 @@ def repr_dict(self, x, level):
             keyrepr = repr1(key, newlevel)
             valrepr = repr1(x[key], newlevel)
             pieces.append('%s: %s' % (keyrepr, valrepr))
-        if n > self.maxdict: pieces.append('...')
+        if n > self.maxdict:
+            pieces.append(self.fillvalue)
         s = ', '.join(pieces)
         return '{%s}' % (s,)
 
@@ -123,7 +129,7 @@ def repr_str(self, x, level):
             i = max(0, (self.maxstring-3)//2)
             j = max(0, self.maxstring-3-i)
             s = builtins.repr(x[:i] + x[len(x)-j:])
-            s = s[:i] + '...' + s[len(s)-j:]
+            s = s[:i] + self.fillvalue + s[len(s)-j:]
         return s
 
     def repr_int(self, x, level):
@@ -131,7 +137,7 @@ def repr_int(self, x, level):
         if len(s) > self.maxlong:
             i = max(0, (self.maxlong-3)//2)
             j = max(0, self.maxlong-3-i)
-            s = s[:i] + '...' + s[len(s)-j:]
+            s = s[:i] + self.fillvalue + s[len(s)-j:]
         return s
 
     def repr_instance(self, x, level):
@@ -144,7 +150,7 @@ def repr_instance(self, x, level):
         if len(s) > self.maxother:
             i = max(0, (self.maxother-3)//2)
             j = max(0, self.maxother-3-i)
-            s = s[:i] + '...' + s[len(s)-j:]
+            s = s[:i] + self.fillvalue + s[len(s)-j:]
         return s
 
 
diff --git a/Lib/test/test_reprlib.py b/Lib/test/test_reprlib.py
index 0555b71bbf21a..aa326399ab224 100644
--- a/Lib/test/test_reprlib.py
+++ b/Lib/test/test_reprlib.py
@@ -51,6 +51,13 @@ def test_tuple(self):
         expected = repr(t3)[:-2] + "...)"
         eq(r2.repr(t3), expected)
 
+        # modified fillvalue:
+        r3 = Repr()
+        r3.fillvalue = '+++'
+        r3.maxtuple = 2
+        expected = repr(t3)[:-2] + "+++)"
+        eq(r3.repr(t3), expected)
+
     def test_container(self):
         from array import array
         from collections import deque
diff --git a/Misc/NEWS.d/next/Library/2020-02-03-21-18-31.bpo-39549.l4a8uH.rst b/Misc/NEWS.d/next/Library/2020-02-03-21-18-31.bpo-39549.l4a8uH.rst
new file mode 100644
index 0000000000000..91d63a96763ce
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2020-02-03-21-18-31.bpo-39549.l4a8uH.rst
@@ -0,0 +1,4 @@
+Whereas the code for reprlib.Repr had previously used a hardcoded string
+value of '...', this PR updates it to use of a “fillvalue” attribute, whose
+value defaults to '...' and can be reset in either individual reprlib.Repr
+instances or in subclasses thereof.



More information about the Python-checkins mailing list