This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author jbw
Recipients andrei.avk, iritkatriel, jbw, kj, moi90, serhiy.storchaka
Date 2021-10-28.18:19:10
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1635445151.02.0.621157025631.issue43656@roundup.psfhosted.org>
In-reply-to
Content
1. As background, it is worth remembering that a major motivation for why FrameSummary.__init__ stringifies the local variable values in its parameter locals is to prevent the resulting data structure from keeping those values live.  This enables them to be garbage collected.

2. It has been suggested that TracebackException.__init__ or StackSummary.extract could be given a function parameter.  This could either be a new parameter or could involve using the existing capture_locals parameter with a non-bool.  The purpose of this suggestion is to allow customizing the use of repr to stringify local variable values.  If this suggestion is followed, it would be quite useful if this function parameter was given not just the local variable values, but also the name of the local variable and maybe also the stack frame it is in.  This would enable filtering out undesired variables.  For example, I would usually prefer to filter most of the variables from the __main__ module frame, because they are just noise that makes it hard to see the important details.  Some ability to filter would also help with the security issue that is discussed in issue 23597 that Irit pointed to.

3. I doubt that new students will be setting up calls to TracebackException or modifying sys.excepthook on their own.  Although a simple interface is clearly good, it might be more important to have an interface that maximizes the usefulness of the feature.

4. I no longer have the tracebacks my students were getting.  You can look at the traceback from the example in msg 404319 for a traceback.  While I was debugging this, I got much more complicated tracebacks because two of the classes in traceback.py also throw exceptions during their __init__ method that leave the not-yet-initialized object in a repr-will-raise-an-exception state.  Despite having decades of programming experience, it actually took me a long time before I realized that the exceptions I was debugging were junk exceptions due to attempts to call repr on not-yet-initialized objects.  I think figuring this out would be extremely challenging for my second-year undergraduate students.

5. If one of the calls to repr in FrameSummary.__init__ raises an exception, this prevents all the other local variable values from being inspected.  If it is desired to report local variable values that cause repr to raise an exception, then it would be good to collect all such exceptions, which requires handling each exception and then continuing to traverse the traceback stack.  Because of point 1 above, it might often be best to turn each such exception into a string.  To avoid infinite loops in the debugging/logging tools, it would often be best not to attempt to traverse the traceback stack of each of these extra exceptions.  If this argument is a good argument, this seems to mean that my most recent proposed fix is a good balance.

6. It is not clear if there is a reliable way to detect whether repr raises an exception due to an object's initialization having been interrupted, but all of the failures that I observed of this sort were for the variable name “self”.  In one case, the repr failure was for a normal local variable of an __new__ method which was not a parameter of this method; the variable was named “self” by convention, but this convention would be difficult to automatically verify.  In the two other cases, the repr failure was for a parameter named “self” which was the first parameter of an __init__ method.  So it would help to give special treatment to the first parameter of __init__ methods, but this would not solve the problem for __new__ methods.

7. In some cases, it might be a bit complicated to ensure the object is always in a safe state for repr-ing during initialization.  This is because there may be many attributes that need to be modified and this is not generally done atomically.  One attribute could be designated to indicate that initialization is done, so that repr will be extra careful if that attribute does not have an expected value.  Given that this is only (so far) an issue for debuggers and traceback inspection tools, it is not clear how to motivate everyone who writes a __new__, __init__, or __repr__ method to do this safely.  Documentation can of course help.
History
Date User Action Args
2021-10-28 18:19:11jbwsetrecipients: + jbw, serhiy.storchaka, iritkatriel, moi90, kj, andrei.avk
2021-10-28 18:19:11jbwsetmessageid: <1635445151.02.0.621157025631.issue43656@roundup.psfhosted.org>
2021-10-28 18:19:11jbwlinkissue43656 messages
2021-10-28 18:19:10jbwcreate