Skip to content

Using reprlib.repr fails for very large numbers #135487

Open
@MarcellPerger1

Description

@MarcellPerger1

Bug report

Bug description:

The bug

reprlib.Repr.repr_int fails if the integer exceeds the string conversion limit (on line 184)

cpython/Lib/reprlib.py

Lines 183 to 189 in 6eb6c5d

def repr_int(self, x, level):
s = builtins.repr(x) # XXX Hope this isn't too slow...
if len(s) > self.maxlong:
i = max(0, (self.maxlong-3)//2)
j = max(0, self.maxlong-3-i)
s = s[:i] + self.fillvalue + s[len(s)-j:]
return s

This impacts other parts of the standard library which use reprlib.Repr. A quick code search reveals that this affects/could affect:

  • pydoc
  • bdb
  • idlelib & IDLE (debugger-related things)
  • asyncio

See #135487 (comment) for detailed rationale for why IMHO this is a bug.

pydoc example

Given the following code (in a file called temp11.py),

a = 1 << 19000

running pydoc on it like python -m pydoc '.\temp11.py' gives the following error:

Stack trace

Traceback (most recent call last):
  File "", line 198, in _run_module_as_main
  File "", line 88, in _run_code
  File "C:\Python313\Lib\pydoc.py", line 2846, in 
    cli()
    ~~~^^
  File "C:\Python313\Lib\pydoc.py", line 2807, in cli
    help.help(arg, is_cli=True)
    ~~~~~~~~~^^^^^^^^^^^^^^^^^^
  File "C:\Python313\Lib\pydoc.py", line 2062, in help
    else: doc(request, 'Help on %s:', output=self._output, is_cli=is_cli)
          ~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Python313\Lib\pydoc.py", line 1773, in doc
    pager(render_doc(thing, title, forceload), f'Help on {what!s}')
          ~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Python313\Lib\pydoc.py", line 1758, in render_doc
    return title % desc + '\n\n' + renderer.document(object, name)
                                   ~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^
  File "C:\Python313\Lib\pydoc.py", line 543, in document
    if inspect.ismodule(object): return self.docmodule(*args)
                                        ~~~~~~~~~~~~~~^^^^^^^
  File "C:\Python313\Lib\pydoc.py", line 1375, in docmodule
    contents.append(self.docother(value, key, name, maxlen=70))
                    ~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Python313\Lib\pydoc.py", line 1642, in docother
    repr = self.repr(object)
  File "C:\Python313\Lib\reprlib.py", line 71, in repr
    return self.repr1(x, self.maxlevel)
           ~~~~~~~~~~^^^^^^^^^^^^^^^^^^
  File "C:\Python313\Lib\pydoc.py", line 1234, in repr1
    return getattr(self, methodname)(x, level)
           ~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^
  File "C:\Python313\Lib\reprlib.py", line 184, in repr_int
    s = builtins.repr(x) # XXX Hope this isn't too slow...
ValueError: Exceeds the limit (4300 digits) for integer string conversion; use sys.set_int_max_str_digits() to increase the limit

Possible fix

The underlying issue is that the size of the integer isn't checked before calling builtin repr.
A way to fix this may be to display it as hexadecimal over a certain threshold (then truncate the middle like usual). (IMHO it's not worth it to add a special method to compute the first and last n digits of a number without calculating the middle ones)

CPython versions tested on:

3.13

Operating systems tested on:

Windows

Linked PRs

Metadata

Metadata

Assignees

Labels

stdlibPython modules in the Lib dirtype-bugAn unexpected behavior, bug, or error

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions