I didn’t mean to be that absolute. You “fix” the issue by documenting your interface clearly. You can never protect against everything (KeyboardInterrupt or MemoryError can happen pretty much anywhere).
What exceptions get suppressed in your example? If you can’t find that out easily from the documentation, that’s the sort of issue I’m talking about. When do those exceptions occur? Can you make sure the conditions that could cause them don’t happen?
Yes, it could be time consuming. But more so than trying to get a language change implemented, and then desupporting all versions of Python prior to the one the new feature is available in?
To be worth a new language feature, this problem should be common enough that there should be many examples we can all relate to, not just a single bit of problem code. Or, the feature should be something that people can immediately relate to, and understand the usefulness of, in another way.
Also, let’s be clear here, when I say “bad design” I’m not saying that can’t happen. Pretty much every software project is “badly designed” at some level. Looking for perfection is futile.
I’m not seeing what would make it easy to check. The else clause seems designed to help with not checking, but actually just reacting. Whoops, something got suppressed, but we don’t know exactly what and we don’t know how much of the code in the with statement got executed.
What if core.extend_axis_env suppressed ZeroDivisionError, and mlir_module_to_xla_computation divided by zero for some reason? How would you write your else clause so that it handled that case properly, as well as the unbound name case? And if your answer is “by reporting the problem and stopping” they why suppress exceptions at all?
And if you want to avoid suppressing exceptions, use a helper:
>>> class MustNotSuppress:
... def __init__(self, inner):
... self.inner = inner
... def __enter__(self, *args, **kw):
... return self.inner.__enter__(*args, **kw)
... def __exit__(self, *args, **kw):
... ret = self.inner.__exit__(*args, **kw)
... if ret: raise RuntimeError("Context manager suppressed an exception!")
... return ret
...
>>> with MustNotSuppress(suppress(ZeroDivisionError)):
... 1/0
...
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
ZeroDivisionError: division by zero
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 8, in __exit__
RuntimeError: Context manager suppressed an exception!