It seems to me that this thread is a bit too focused. I know I’ve found that often I wish I knew better exactly what caused a particular Exception— there are many that can be raised for various reasons, and you may need to know which one in order to handle it properly. At this point, parsing the error msg is often the only option. Though since you can tack on arbitrary data to an Exception, some have ways of knowing. So maybe a more formal and standardized way to to specify more detailed information is in order. But it shouldn’t be just about TypeError. On the other hand, subclassing exceptions works pretty well, so maybe that’s fine. It worked pretty well for OSError, for example. As for TypeError and calling functions. I believe the OP wanted to distinguish between calling the function the wrong way: e.g. the wrong [number of, name of, order of] arguments, and calling the function with the wrong type of a given parameter. And Python being dynamically typed, calling a function with the wrong Type is really an arbitrary somthing-went-wrong-inside-the-function, not an error with calling per se. And I think this is a useful distinction. It's actually a common problem, when you do: try: func(...) Except SomeError: do_something you never know where in the entire call stack SomeError came from. In the case at hand, a TypeError may have come from how you are calling func, or it may have come from somewhere inside func(), or indeed, anywhere else deep in that hierachy. So I think it would be very useful to have an Exception that is about the "how the function was called" part. Of course, it could still have come from another call inside the top-l;evel function, but I think it sill makes a useful distinction. -CHB On Wed, Mar 4, 2020 at 7:11 AM Alex Hall <alex.mojaki@gmail.com> wrote:
Both of these calls raise TypeError, but for different reasons: # right number of arguments passed to the key function, # but the wrong argument type sorted([3, 5, 1], key=len)
# wrong number of arguments passed to the key function sorted([3, 5, 1], key=isinstance)
It might be useful to be able to distinguish the two cases.
I'm hearing a lot of hypotheticals and nothing close to what feels like a real use case. Both those cases are completely wrong and I don't know why I'd need to distinguish the reason, or even catch TypeError at all.
It seems to me that using this is like stating "this code might be wrong" and would generally produce bad code. It seems to me that your comment above could be equally said about any use of exceptions: "this code might be wrong, so we'll stick it in a try...except block". Only that's not how most of us actually use exceptions.
I don't understand, you seem to be contradicting yourself between "any use of exceptions" and "that's not how most of us actually use exceptions". The examples you're giving explicitly look like "this code might be wrong". The examples of exceptions I'm looking at in my own code are more like "the inputs might be wrong" or "something might go wrong beyond my control".
try: # Test whether the aardvark function supports a # `hovercraft` parameter. result = aardvark( spam, eggs, cheese, hovercraft=1 ) except ParameterError: # No hovercraft parameter allowed, create a wrapper. ...
This is a weird hypothetical. Please provide a real example. Code that you have actually written vs what you wish you could have written. I have certainly never wanted to do something like this. And if I was in such a situation that's still not the way I'd want to solve it.
What if the caller of my library has back-ported the new, advanced version of aardvark() to their Python? Instead of using the faster, better tested official backport, my code will use my wrapper.
I don't really understand how this would work, can you elaborate?
If you catch ParameterError, how do you know that it came directly from the line you caught it from and not deeper within? Does it matter? If the call aardvark(*args, hovercraft=1) leaks a ParameterError from deep inside its internals, then even if the feature is technically available according to a version check, it is too buggy to use and I need to use my wrapper.
But maybe the function `spam` that you passed to aardvark didn't take the right number of parameters?
To make it more concrete, imagine code like this from a time when newer versions of `sort` accepted `key` but older versions could only accept `cmp` (I'm not sure if this is actually what happened, it's not important).
try: lst.sort(key=foo_key) except ParameterError: lst.sort(cmp=foo_cmp)
Does `except ParameterError:` mean that `sort` doesn't accept `key`, or does it mean that `foo_key` is wrong?
py> inspect.signature(math.gcd) Traceback (most recent call last): [...] TypeError: 'feature_version' is an invalid keyword argument for compile()
That's interesting, what version of Python gives you that? It works for me. _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/WEPACE... Code of Conduct: http://python.org/psf/codeofconduct/