-
-
Notifications
You must be signed in to change notification settings - Fork 32.5k
Description
Bug report
Bug description:
Hello. When debugging a problem in sip which hanged and caused OOM kills when building PyQt5 and PyQt6 on Python 3.13, I found the following:
217f47d is the first new commit that introduces the hangs/kills.
The commit changes the exception message in list.remove(x)
to include repr(x)
in it.
sip has the following code: https://github.com/Python-SIP/sip/blob/6.8.3/sipbuild/generator/parser/parser_manager.py#L435-L438
try:
self._template_arg_classes.remove(klass)
except ValueError:
pass
klass
is a complex dataclass member- the block is called many times in a loop
- the
ValueError
exception message is never retrieved
When changing the code to:
if klass in self._template_arg_classes:
self._template_arg_classes.remove(klass)
The hang/kill does not happen.
Further investigating the problem, it became obvious that it is the repr()
call that now implicitly happens when constructing the ValueError
in list.remove()
causes the hang. In fact, calling repr(klass)
directly in the else
branch of the if
even on Python 3.12.2 causes the hangs/kills in sip-build as well.
Unfortunately, I don't have a smaller reproducer than building PyQt from sources on Python 3.13.
I don't know why repr of a dataclass eats all my RAM. Perhaps the dataclass is somehow recursive like in #116647 -- that might be a problem in dataclass repr implementation.
However, I opened this issue to report this:
Constructing the ValueError
's exception message in list.remove(x)
is now expensive when repr(x)
is expensive. Could the message be perhaps lazily evaluated to avoid calling repr(x)
when the message will never be shown, like in the trivial try-except case?
CPython versions tested on:
3.13
Operating systems tested on:
Linux