Skip to content

Commit c7eb1ff

Browse files
andresdelfinoclaude
andcommitted
gh-161289: Respect fillvalue length when truncating in reprlib.Repr
repr_str(), repr_int() and repr_instance() computed how many characters to keep around the fill value assuming it is always three characters long (the default '...'). With a custom Repr.fillvalue of another length, the result exceeded or fell short of maxstring, maxlong and maxother. Use len(self.fillvalue) instead. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent 7e3290d commit c7eb1ff

3 files changed

Lines changed: 27 additions & 6 deletions

File tree

‎Lib/reprlib.py‎

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -174,8 +174,8 @@ def repr_dict(self, x, level):
174174
def repr_str(self, x, level):
175175
s = builtins.repr(x[:self.maxstring])
176176
if len(s) > self.maxstring:
177-
i = max(0, (self.maxstring-3)//2)
178-
j = max(0, self.maxstring-3-i)
177+
i = max(0, (self.maxstring-len(self.fillvalue))//2)
178+
j = max(0, self.maxstring-len(self.fillvalue)-i)
179179
s = builtins.repr(x[:i] + x[len(x)-j:])
180180
s = s[:i] + self.fillvalue + s[len(s)-j:]
181181
return s
@@ -198,8 +198,8 @@ def repr_int(self, x, level):
198198
return (f'<{x.__class__.__name__} instance with roughly {k} '
199199
f'digits (limit at {max_digits}) at 0x{id(x):x}>')
200200
if len(s) > self.maxlong:
201-
i = max(0, (self.maxlong-3)//2)
202-
j = max(0, self.maxlong-3-i)
201+
i = max(0, (self.maxlong-len(self.fillvalue))//2)
202+
j = max(0, self.maxlong-len(self.fillvalue)-i)
203203
s = s[:i] + self.fillvalue + s[len(s)-j:]
204204
return s
205205

@@ -211,8 +211,8 @@ def repr_instance(self, x, level):
211211
except Exception:
212212
return '<%s instance at %#x>' % (x.__class__.__name__, id(x))
213213
if len(s) > self.maxother:
214-
i = max(0, (self.maxother-3)//2)
215-
j = max(0, self.maxother-3-i)
214+
i = max(0, (self.maxother-len(self.fillvalue))//2)
215+
j = max(0, self.maxother-len(self.fillvalue)-i)
216216
s = s[:i] + self.fillvalue + s[len(s)-j:]
217217
return s
218218

‎Lib/test/test_reprlib.py‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,23 @@ def test_instance(self):
201201
self.assertEndsWith(s, ">")
202202
self.assertIn(s.find("..."), [12, 13])
203203

204+
def test_truncation_with_custom_fillvalue(self):
205+
# The truncated repr must fit the limit whatever the fillvalue length.
206+
eq = self.assertEqual
207+
s = 'abcdefghijklmnopqrstuvwxyz'
208+
n = 12345678901234567890
209+
i = ClassWithRepr('x' * 100)
210+
211+
r1 = Repr(maxstring=10, maxlong=10, maxother=10, fillvalue='…')
212+
eq(r1.repr(s), "'abc…wxyz'")
213+
eq(r1.repr(n), '1234…67890')
214+
eq(r1.repr(i), "Clas…xxx')")
215+
216+
r2 = Repr(maxstring=10, maxlong=10, maxother=10, fillvalue='<snip>')
217+
eq(r2.repr(s), "'a<snip>z'")
218+
eq(r2.repr(n), '12<snip>90')
219+
eq(r2.repr(i), "Cl<snip>')")
220+
204221
def test_lambda(self):
205222
r = repr(lambda x: x)
206223
self.assertStartsWith(r, "<function ReprTests.test_lambda.<locals>.<lambda")
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Fix :class:`reprlib.Repr` truncation of strings, integers and other objects
2+
when a custom :attr:`~reprlib.Repr.fillvalue` is not three characters long.
3+
The result now fits :attr:`~reprlib.Repr.maxstring`,
4+
:attr:`~reprlib.Repr.maxlong` and :attr:`~reprlib.Repr.maxother`.

0 commit comments

Comments
 (0)