Re: Newbie naive question ... int() throws ValueError
Devin Jeanpierre wrote: On Fri, May 11, 2012 at 11:21 PM, Chris Angelico ros...@gmail.com wrote: There are times when you want to catch all exceptions, though. Top-level code will often want to replace exception tracebacks with error messages appropriate to some external caller, or possibly log the exception and return to some primary loop. Otherwise, though, most code will just let unexpected exceptions through. I'm not talking about unexpected exceptions. I'm saying, if I expect invalid input for int, where should I go to find out how to deal with said invalid input properly? How do I know that int raises ValueError on failure, and not, for example, something like ArgumentError (something that Python doesn't have) or (like chr) TypeError? Apparently the answer is to read the documentation for ValueError. It's a bit like putting the documentation on the return type for `map` in the list documentation. Kinda hard to get there without already knowing the answer. Unit tests. :) ~Ethan~ -- http://mail.python.org/mailman/listinfo/python-list
Re: Newbie naive question ... int() throws ValueError
On Sat, May 12, 2012 at 8:27 AM, Karl Knechtel zahl...@gmail.com wrote: I really wish gmail picked up the mailing list as a default reply-to address... There is some labs thing that makes reply to all the default if you click the button on the top-right. Unfortunately, that applies for non-mailing-lists too... The easiest way is to try it. In fact, in most cases, this will be easier than looking it up in the documentation could ever be, because looking something up in documentation requires you to read through a bunch of documentation until you find key info like 'raises FooError in bar circumstance', and then interpret it; by trial and error, you see exactly what happens right away, and you can do it by just banging out a couple of lines on the REPL. Eh, this doesn't make sense. Before I would ever try the int() function, I would've read about it in the documentation -- otherwise how would I know what it does at all? How would I even know that it exists? What having to try-it-and-see does is give me extra steps to know what it does. Instead of only reading the documentation, now I have to both read the documentation *and* try it out in the interactive interpreter to see its behaviour in a bunch of undocumented error cases. What should actually happen is that the error cases should be documented explicitly, so that I don't have to run around in the REPL or orthogonal bits of documentation trying to figure out the behaviour of the function. You should have already read the documentation for things like ValueError as a part of learning the language (i.e. the first time something raised a ValueError and you wanted to know what that meant); or at the very least you should have a good idea of what the standard exceptions are all named, and *develop an intuition* for which apply to what circumstances. As noted by others, you should not expect `int` to throw a `TypeError` when fed a bad string, because a `TypeError` means something is wrong with the type of some object, and the problem with the bad string isn't that it's a string (its type), but that the string contents are not interpretable as int (its value, hence ValueError). And yet this is what ord does. Every rule has an exception. I concede that reading the docs on ValueError is probably worth doing the first time you see it. Although, it's also one of those exceptions that has a clear name, so it isn't something everyone will do. I'm not sure if I ever did it. And certainly the OP never looked there. -- Devin -- http://mail.python.org/mailman/listinfo/python-list
Re: Newbie naive question ... int() throws ValueError
On Sun, May 13, 2012 at 4:25 AM, Devin Jeanpierre jeanpierr...@gmail.com wrote: What having to try-it-and-see does is give me extra steps to know what it does. Instead of only reading the documentation, now I have to both read the documentation *and* try it out in the interactive interpreter to see its behaviour in a bunch of undocumented error cases. Point to note: The Python documentation tells you about the language. Trying it in the interpreter tells you about your implementation. There can be differences. I doubt there will be in something as simple as casting to int, but in other functions, it wouldn't surprise me to find that CPython (the one that most people think of as Python) and IronPython, PyPy, or Jython have differences in what they can throw. ChrisA -- http://mail.python.org/mailman/listinfo/python-list
Re: Newbie naive question ... int() throws ValueError
On Fri, May 11, 2012 at 3:55 PM, John Terrak john.ter...@gmail.com wrote: I couldnt find anywhere in the documentation that int() can throw a ValueError. I checked the The Python Language Reference, and the The Python Standard Library to no avail. Did I missed something? Unlike in Java, a function's list of things it can throw isn't part of its signature. Instead of trying to catch every possible exception, it's generally best to simply let exceptions propagate unless you KNOW you're expecting them. In the case of int(), that would mean that you catch ValueError if you're taking arbitrary strings from the user and want integers (and then you could handle the ValueError by using a default, for instance); but if you're writing a function that's documented as taking a number as a parameter, let the exception go up to the caller. If it helps, think of all Python's exceptions as deriving from RuntimeException - anything can happen, worry only about what really worries you :) Thanks for your help - and sorry again for such a naive question. It's a perfectly legitimate question, and you clearly did read the docs before asking. Nothing to apologize for there! Chris Angelico -- http://mail.python.org/mailman/listinfo/python-list
Re: Newbie naive question ... int() throws ValueError
On 5/11/2012 1:55 AM, John Terrak wrote: I couldnt find anywhere in the documentation that int() can throw a ValueError. I checked the The Python Language Reference, and the The Python Standard Library to no avail. Did I missed something? To add to Chris' answer: If the domain of a function is truly all Python objects, it cannot raise an error. I believe id(x) is such an example. Even if the domain is intended to be all Python objects, you cannot be sure if the function uses any special method defined on the object or its class. For examples, type(x) *should* always work, but I would not be surprised if a buggy __getattribute__ method or buggy metaclass could result in an exception instead. If the arguments for a function include a function, for example map(f, 'abc'), then the passed function can raise any exception and hence the called function will pass along the exception unless, unusually, it catches it. As to your specific question, if the domain of a function is a subset of types and values of allowed types, then you should expect that it can raise either TypeError or ValueError. If the domain So here is the question - if it is not in the documentation - how does one find out the exceptions that are thrown by a constructor, a method or a function? One way is to try specific examples, as you did. Following what Chris said, especially do that for bad input whose exception you want to catch. Sometimes this is faster than trying to find the answer in the doc, and it gives the actual answer rather than the intended answer. Example: int(not_an_int) int(not_an_int) Traceback (most recent call last): File stdin, line 1, inmodule ValueError: invalid literal for int() with base 10: 'not_an_int' Some strings are legal input, hence not a TypeError, but not all, hence ValueError. From what I gathered: class int(object): int(x[, base]) - integer Convert a string or number to an integer, if possible. A floating point argument will be truncated towards zero (this does not include a string representation of a floating point number!) When converting a string, use the optional base. It is an error to supply a base when converting a non-string. If base is zero, the proper base is guessed based on the string content. If the argument is outside the integer range a long object will be returned instead. 'error' should say 'TypeError' as it is a TypeError to provide the wrong number of args. However, the current 3.3 manual entry is more accurate and informative, starting with the signature. -- Terry Jan Reedy -- http://mail.python.org/mailman/listinfo/python-list
Re: Newbie naive question ... int() throws ValueError
Am 11.05.2012 17:51, schrieb Terry Reedy: If the domain of a function is truly all Python objects, it cannot raise an error. I believe id(x) is such an example. Even id() can raise an exception, for example MemoryError when you are running out of memory. Christian -- http://mail.python.org/mailman/listinfo/python-list
Re: Newbie naive question ... int() throws ValueError
On Sat, May 12, 2012 at 2:15 AM, Christian Heimes li...@cheimes.de wrote: Am 11.05.2012 17:51, schrieb Terry Reedy: If the domain of a function is truly all Python objects, it cannot raise an error. I believe id(x) is such an example. Even id() can raise an exception, for example MemoryError when you are running out of memory. KeyboardInterrupt can also be raised at (effectively) any time, but I'm not sure that that really counts as id() raising the exception. If I understand it correctly, MemoryError would be because the interpreter can't allocate an int object for id's return value. But these are definitely part of why you don't just catch all exceptions. Hmm. What happens if the interpreter can't construct a MemoryError exception? ChrisA -- http://mail.python.org/mailman/listinfo/python-list
Re: Newbie naive question ... int() throws ValueError
On Fri, May 11, 2012 at 10:23 AM, Chris Angelico ros...@gmail.com wrote: Hmm. What happens if the interpreter can't construct a MemoryError exception? I believe that a MemoryError instance is pre-allocated for just this scenario. You can see it in the result of gc.get_objects(). [x for x in gc.get_objects() if isinstance(x, MemoryError)] [MemoryError()] Cheers, Ian -- http://mail.python.org/mailman/listinfo/python-list
Re: Newbie naive question ... int() throws ValueError
On Sat, May 12, 2012 at 3:12 AM, Ian Kelly ian.g.ke...@gmail.com wrote: I believe that a MemoryError instance is pre-allocated for just this scenario. Ah, wise move. It's one of those largely-imponderables, like figuring out how to alert the sysadmin to a router failure. ChrisA -- http://mail.python.org/mailman/listinfo/python-list
Re: Newbie naive question ... int() throws ValueError
Thank you all for your help. Greatly appreciated. John -- http://mail.python.org/mailman/listinfo/python-list
Re: Newbie naive question ... int() throws ValueError
On Fri, May 11, 2012 at 2:10 AM, Chris Angelico ros...@gmail.com wrote: Unlike in Java, a function's list of things it can throw isn't part of its signature. Instead of trying to catch every possible exception, it's generally best to simply let exceptions propagate unless you KNOW you're expecting them. How am I supposed to know to expect them, if they are undocumented? Trial and error? That seems like a poor replacement for documented error conditions. -- Devin -- http://mail.python.org/mailman/listinfo/python-list
Re: Newbie naive question ... int() throws ValueError
On Sat, May 12, 2012 at 5:34 AM, Devin Jeanpierre jeanpierr...@gmail.com wrote: On Fri, May 11, 2012 at 2:10 AM, Chris Angelico ros...@gmail.com wrote: Unlike in Java, a function's list of things it can throw isn't part of its signature. Instead of trying to catch every possible exception, it's generally best to simply let exceptions propagate unless you KNOW you're expecting them. How am I supposed to know to expect them, if they are undocumented? Trial and error? That seems like a poor replacement for documented error conditions. Expect exceptions any time anything goes wrong. Don't try to code to prevent them. Here's an example. Suppose you write a function that takes a number and returns that many copies of your club's charter. (Yeah, pretty stupid, but examples usually are!) def charter(copies): return _chartertext * copies Does this function need to catch any exceptions? No. Can that expression throw exceptions? Totally! You might be given a non-number (can't give foo copies); you might get a floating point (can't get three-and-a-half copies); your charter text might have been replaced with a pizza; the user might hit Ctrl-C right while it's copying; the number might be so large that you run out of memory; all sorts of things. But they're not your problems - they're your caller's problems. If you caught all those exceptions, what would you do? You'd have to signal the error conditions yourself, which probably means... raising an exception. There are times when you want to catch all exceptions, though. Top-level code will often want to replace exception tracebacks with error messages appropriate to some external caller, or possibly log the exception and return to some primary loop. Otherwise, though, most code will just let unexpected exceptions through. This is one of those massively freeing leaps of thinking. Java binds you to a bureaucracy of catching exceptions or declaring them (but then still has RuntimeException - and I'm sure there've been MANY programmers who just derive all their exceptions from that); Python sets you free to care only about what you want to care about. ChrisA -- http://mail.python.org/mailman/listinfo/python-list
Re: Newbie naive question ... int() throws ValueError
On Fri, May 11, 2012 at 11:21 PM, Chris Angelico ros...@gmail.com wrote: There are times when you want to catch all exceptions, though. Top-level code will often want to replace exception tracebacks with error messages appropriate to some external caller, or possibly log the exception and return to some primary loop. Otherwise, though, most code will just let unexpected exceptions through. I'm not talking about unexpected exceptions. I'm saying, if I expect invalid input for int, where should I go to find out how to deal with said invalid input properly? How do I know that int raises ValueError on failure, and not, for example, something like ArgumentError (something that Python doesn't have) or (like chr) TypeError? Apparently the answer is to read the documentation for ValueError. It's a bit like putting the documentation on the return type for `map` in the list documentation. Kinda hard to get there without already knowing the answer. -- Devin -- http://mail.python.org/mailman/listinfo/python-list
Re: Newbie naive question ... int() throws ValueError
On Sat, May 12, 2012 at 2:11 PM, Devin Jeanpierre jeanpierr...@gmail.com wrote: I'm not talking about unexpected exceptions. I'm saying, if I expect invalid input for int, where should I go to find out how to deal with said invalid input properly? How do I know that int raises ValueError on failure, and not, for example, something like ArgumentError (something that Python doesn't have) or (like chr) TypeError? Ah, I see what you mean. The easiest way to find out what exception gets thrown is to try it. For obvious things like int(foo) you can simply test it in the interactive interpreter; unusual cases you'll discover as you run your script. ChrisA -- http://mail.python.org/mailman/listinfo/python-list