On Wednesday 10 August 2016 15:20, Juan Pablo Romero Méndez wrote: > Ok, so you suggested 1) catching exceptions at the point where you care, 2) > preemptively check for certain runtime conditions to avoid exceptions 3) > write as many tests as possible 4) learn to live with runtime errors. > > Is that a fair characterization?
(1) Not quite. Only catch exceptions you expect and *can deal with*. By deal with, I mean either recover from, or convert to a user-friendly error message (perhaps displaying it in a dialog for GUI apps). Your script or application may want to use a top-level exception handler to catch any *unexpected* exceptions, log them, perform any extra cleanup needed, and display a nice error message before exiting. But that counts as gold- plating: for many applications or scripts, aimed at technical or semi-technical users, its acceptable to just let the traceback print and the interpreter exit. (2) Sometimes. Its a judgement call whether it is better to "Look Before You Leap" or "Easier To Ask For Forgiveness Rather Than Permission". It depends on what you are doing, how often you expect an exceptional case, the performance implications, whether there is a risk of "Time Of Check To Time Of Use" bug, etc. In other words, that's usually a technical question, not a matter of style. Google for LBYL versus EAFP for more discussion. Occasionally it comes down to both being equally good, in which case you get to pick whichever you like. (3) Yes, this is correct. Basically, with a dynamically-typed language like Python, you have to write all the tests you would write with a statically-typed language, plus some more. There's no question that the cost of the freedom dynamic typing gives you is that you have to write extra tests. But not as many as you might think. The major differences in mindset between dynamic/static typing are: - Where the compiler would detect a type error at compile time, you get the same result with a small unit test that checks for TypeError or AttributeError instead. (Although see also the MyPy project, which brings an optional static type- checker to Python.) - As much as possible, avoid thinking "I need a list", and instead think "I need anything which offers the list interface". (Duck-typing.) That *especially* counts for writing library code, application code you can be a bit more strict about types because you're only limiting yourself, not other users. - A Python runtime exception is not like a segmentation fault. Its not going to overflow a buffer and execute random code. It's a controlled failure, not an uncontrolled one. (4) There's no necessary reason to expect that you'll get more runtime errors in a well-written and tested Python application than you get in a well-written and tested C application. Regardless of the language, you have to deal with runtime errors: - network is down; - disk is full; - user lacks permission to edit that file; - database error; - account not found; etc. Python is no different. And regardless of the language, the compiler can't check that "add_account" actually adds the account, you need a unit-test to check that. So you have to write tests either way. Basically, just relax -- static type checks aren't useless, but they do very little that a runtime exception won't give you. So long as you have a good suite of unit tests that exercises the whole program, you'll find your type errors when they raise TypeError, then you fix them. You may be gathering from this that dynamic typing and Test Driven Development go hand in hand. That's exactly right. They complement each other very well. -- Steve -- https://mail.python.org/mailman/listinfo/python-list