Replies: 14 comments 4 replies
-
|
To start the discussion in concrete terms, here is a possible structure: import sys
class MyException(Exception):
def custom_description(self):
return "Some description using markdown syntax"
def custom_solution(self):
exc_type, exc_value, tb = sys.exc_info
# use the above to analyse the problem
return "Some solution"
def custom_link(self):
return "Useful URL"
Programs making use of custom exceptions could retrieve the relevant information and do their own formatting. Initially, I suspect that there would be very little need for translations. Still, it could easily be added after the fact by adding explicit functions, as follows: import sys
class MyException(Exception):
def custom_description(self):
return "Some description using markdown syntax"
def custom_description_fr(self):
return "Some description in French using markdown syntax"Suppose that a user of friendly uses French as their preferred language. Internally, friendly might do something like this: lang = get_user_language()
if hasattr(exc, f'custom_description_{lang}'):
description = getattr(exc, f'custom_description_{lang}')()
elif hasattr(exc, 'custom_description'):
description =exc.custom_description()
else:
description = '' |
Beta Was this translation helpful? Give feedback.
-
|
That's along the lines of what I was thinking of. I'd be tempted to make them dunder methods, to avoid any naming clashes (as unlikely as that is). Where does I'm thinking it might be better implemented as attributes, that way they could be properties if required to be dynamic, but the typical case would be a string: class MyException:
__help__ = "Something went *wrong*"In the case of languages, they help could be a dict: class MyException:
__help__ = {
"en": "Something went *wrong*"
"fr": "Quelque chose a mal tourné"
}Additional help texts could be provided via similarly named attributes, like Links could be exposed in a similar way. Thoughts? Once we hammer out a spec, we should get community feedback. It would be fantastic if it became a standard. |
Beta Was this translation helpful? Give feedback.
-
About language support
I suspect that 99% of the users would not want to either use or support any language other than English. This is why I thought that the default names for the attributes or functions should contain (or return) the text in English., and (to use your notation) simply require to get About attributes vs functionsI do like attributes for the description ( class MyException(Exception):
"Something went wrong"
__help__ = __doc__Having the For custom exceptions, I could imagine then being called with custom arguments, and having the solution depend on the value of these arguments. This is why I would have a preference to use a function by default. With friendly, I found it often useful to query the frame's locals and globals to provide an accurate explanation. I'm wondering if the value of the arguments might also affect the description. For the link, an attribute would likely be adequate . About dundersI've created my own dunders in the past for some toy projects and got criticisms from people who wrote that dunders were meant to be reserved for Python's own usage. While I like the idea of using dunders, to avoid any pushback, if possible, I'd prefer to have dunder that are split in two words, such as However, if there's enough support from the community, I think that single word dunders, such as |
Beta Was this translation helpful? Give feedback.
-
I will address the issue of support for languages other than English separately. But, before that, I will create a custom example to illustrate why I think it might make sense to have |
Beta Was this translation helpful? Give feedback.
-
|
Here is a contrived example, which shows the advantage of having salaries = {
"employee": [25_000, 50_000],
"manager": [50_000, 75_000]
}
class SalaryMismatch(Exception):
"""Indicates that the salary is not in the valid range
for the stated position.
"""
__help__ = __doc__
__help_link__ = "URL_for_employee_compensation_range"
def __init__(self, position, salary):
self.position = position
self.salary = salary
super().__init__(f"{salary} is not valid for this position: {position}.")
def __help_solution__(self):
valid_range = f"${salaries[self.position][0]} to ${salaries[self.position][1]}"
return (f"{self.salary} is not valid for {self.position}s.\n"
f"The valid salary range for {self.position}s is {valid_range}.")
def create_position(position, salary):
if not salaries[position][0] <= salary <= salaries[position][1]:
raise SalaryMismatch(position, salary)
print(f"{position} created; everything is good.\n")
create_position("manager", 60000)
try:
create_position("employee", 60000)
except SalaryMismatch as e:
print(e)
print("---")
print(e.__help_solution__())
print(f"See {e.__help_link__} for details.")The output (which I did to make sure that it was all valid code) is as follows: If I think of this in the context of using friendly: friendly replaces the default So, in an interactive session, I might have the following With friendly, I could then query further and use Instead of a multi-parameter exception, I could create many different exceptions, for example: one for each position type. However, as the number of arguments increase, one would get a "combinatorial explosion" for the number of custom exceptions to create. For your project, perhaps there would never be a risk of such combinatorial explosion. However, if a protocol for custom exception is to be adopted, I think it should be flexible enough to accommodate other cases. |
Beta Was this translation helpful? Give feedback.
-
|
Using the above example, it literally took me less than 10 minutes to implement support for (I use |
Beta Was this translation helpful? Give feedback.
-
|
Regarding support for languages other than English. As mentioned before, I suspect that the vast majority of people that would decide to include support for this proposed protocole in their own library would only support English (in the foreseeable future). I also suspect that the vast majority of people writing program/tools making use of this as clients would also want to support only English. The intersection of library writer and users who both want to have support for the same language is likely going to be tiny. Still, there might be the odd ones (like me) who would like to support multiple languages. When I created friendly/friendly-traceback, my hope was that many people might want to contribute to support languages other than French and English. I've received a few emails and saw a few forks with feeble attempts at supporting other languages ... but nothing significant. One third-party site (https://hackinscience.org) uses friendly-traceback and gives its users the option of selecting English or French. So ... even though I raise the issue of supporting languages other than English, I don't seen any justification for complicating the API just to support other languages. As I mentioned before, an easy solution is to add custom names following an agreed upon scheme, such as Finally: in friendly, I do not set the locale when a user changes the default language used by friendly as it might mess with other parameters (such as how number are displayed in some parts of the application being looked at, etc.). |
Beta Was this translation helpful? Give feedback.
-
|
On Twitter, (https://twitter.com/pradyunsg/status/1450573310308364294) Pradyun Gedam posted this: The context is for improved errors from Pip; see pypa/pip#10538 |
Beta Was this translation helpful? Give feedback.
-
About
|
Beta Was this translation helpful? Give feedback.
-
|
I see why I think if we have re Languages, I like your scheme to expose the translations with the two letter codes. I'm loathed to give up |
Beta Was this translation helpful? Give feedback.
-
|
See also https://bugs.python.org/issue45607 |
Beta Was this translation helpful? Give feedback.
-
|
Something I forgot to mention before about custom exceptions. Friendly/Friendly-traceback already supports third-party projects from defining custom exception handling. This is documented on https://friendly-traceback.github.io/docs/custom_errors.html with an example shown, and has been used by a third-party project currently set to be private. (I'm hoping they will make it public in the near future.) However, this approach requires the third-party project to have friendly-traceback as a dependency whreas the discussion here is for a more generic protocole that could be adopted independently of friendly-traceback. |
Beta Was this translation helpful? Give feedback.
-
|
See also https://bugs.python.org/issue45990 |
Beta Was this translation helpful? Give feedback.
-
|
There is a new PEP (https://www.python.org/dev/peps/pep-0678/) about adding a field ( |
Beta Was this translation helpful? Give feedback.

Uh oh!
There was an error while loading. Please reload this page.
-
Background
On Twitter (https://twitter.com/willmcgugan/status/1450097933169405956), Will McGugan suggested the following:
Regarding exceptions, wouldn't it be great if:
a) the exception rendered a brief piece of markdown with a description of the problem.
b) gave you a link to a web service with a more detailed error.
c) proposed a solution
He indicated later that this was for exceptions in a custom project.
friendly already attempts to do something like a) and c) for an ever growing number of cases for standard Python exceptions. It can either give the information all at once, or breaking it up (in an interactive session) as answers to the questions "what" (for part a) and "why" (for part c). Internally, the answer to "what" is known as the "generic" explanation, and the answer to "why" is known as the "specific" explanation.
friendlyhas also a
www()function that can open up a browser at some predetermined locations.friendly uses markdown, processed by Rich (https://github.com/willmcgugan/rich).
The following screenshot is a concrete example.
In addition, friendly support translation for these explanations; currently only English and French are the only two language supported.
Comments welcome
Feel free to contribute to the discussion below.
Beta Was this translation helpful? Give feedback.
All reactions