Irit Katriel <iritkatr...@yahoo.com> added the comment:

For the issue of which contexts need to be suppressed when __suppress_context__ 
is true, I think we don't need to keep the whole tree of exceptions. It might 
be enough to save the dynamic "nesting depth of the try-excepts".  Here is a 
solution with two integers per exception, plus one on the thread state. Would 
it work?


We add an int field called except_depth to the thread state (incremented in 
ceval just before the try of a try-except and decremented after the last 
except: block).

Whenever an exception is caught, this value is copied to it (to a new int we 
put on BaseException, call it depth).

The __suppress_context__ field we change from bool to int (alternatively: add a 
new field and leave this one alone). Instead of setting it to True when there 
is __cause__, we set it to the except-depth of the raise...from that raised it.

Then the code displaying the traceback can use the depths information to 
determine which contexts to suppress (the ones up to and not including the 
first one with depth < the suppress_context value).

Returning to Nick's examples from 2013-11-08 14:34:

  # No context on Exception3 is exactly what we want
  try:
      try:
          raise Exception1
      except Exception1:
          raise Exception2
  except Exception2 as exc
      raise Exception3 from Exception2

Exception1 - depth = 2
Exception2 - depth = 1
Exception3 - depth = ?  suppress_context = 1
(suppress both Exception1 and Exception2, they have depths >= 1)


  # Not seeing Exception1 as the context for Exception3 is surprising!
  try:
      raise Exception1
  except Exception1:
      try:
          raise Exception2
      except Exception2 as exc
          raise Exception3 from Exception2
                                  
Exception1 - depth = 1
Exception2 - depth = 2
Exception3 - depth = ?  suppress_context = 2
(suppress only Exception2, Exception1 is too shallow)
                  

To consider more elaborate nesting:

  try:
      try:
          raise Exception0
      except T: # Does not catch Exception0
          pass
  except Exception1:
      try:
          raise Exception2
      except Exception2 as exc
          raise Exception3 from Exception2

Whatever happens in the topmost try-block, if Exception0 is the context of 
anything raised inside the "except Exception1" block, then its depth is 1 
because it was caught by this except. So it won't be suppressed by anything 
raised at a deeper level.

----------
nosy: +iritkatriel

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue18861>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to