I think in trying to illustrate the existing behavior I made things more confusing than they needed to be. Let me try again.
Consider this code. >>> import Food >>> try: ... import meals ... except NameError as e: ... name = str(e).split("'")[1] # <-- fragile code ... from difflib import get_close_matches ... candidates = ', '.join(get_close_matches(name, Food.foods, 1, 0.6)) ... print(f'{name}: not found. Did you mean {candidates}?') In this case *meals* instantiates a collection of foods. It is a Python file, but it is also a data file (in this case the user knows Python, so Python is a convenient data format). In that file thousands of foods may be instantiated. If the user misspells a food, I would like to present the available alternatives. To do so, I need the misspelled name. The only way I can get it is by parsing the error message. That is the problem. To write the error handler, I need the misspelled name. The only way to get it is to extract it from the error message. The need to unpack information that was just packed suggests that the packing was done too early. That is my point. Fundamentally, pulling the name out of an error message is a really bad coding practice because it is fragile. The code will likely break if the formatting or the wording of the message changes. But given the way the exception was implemented, I am forced to choose between two unpleasant choices: pulling the name from the error message or not giving the enhanced message at all. The above is an example. It is a bit contrived. I simply wanted to illustrate the basic issue in a few lines of code. However, my intent was also to illustrate what I see as a basic philosophical problem in the way we approach exceptions in Python: It is a nice convenience that an error message is provided by the source of the error, but it should not have the final say on the matter. Fundamentally, the code that actually presents the error to the user is in a better position to produce a message that is meaningful to the user. So, when we raise exceptions, not only should we provide a convenient human readable error message, we should anticipate that the exception handler may need to reformat or reinterpret the exception and provide it with what it need to do so. The current approach taken by exceptions in Python makes that unnecessarily difficult. PEP 352 suggests that this situation can be handled with a custom exception, and that is certainly true, but that only works if the person writing the code that raises the exception anticipates the need for passing the components of the error message as separate arguments. But as we can see from the NameError, AttributeError, etc, they don't always do. And PEP 352 actively discourages them from doing so. What I am hoping to do with this proposal is to get the Python developer community to see that: 1. The code that handles the exception benefits from having access to the components of the error message. In the least it can present the message to the user is the best possible way. Perhaps that means enforcing a particular style, or presenting it in the user's native language, or perhaps it means providing additional related information as in the example above. 2. The current approach to exceptions follows the opposite philosophy, suggesting that the best place to construct the error message is at the source of the error. It inadvertently puts obstacles in place that make it difficult to customize the message in the handler. 3. Changing the approach in the BaseException class to provide the best of both approaches provides considerable value and is both trivial and backward compatible. -Ken _______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/