neděle 9. prosince 2012

Python SyntaxError: unexpected EOF while parsing

This error just popped on me after my development virtual machine crashed (grr). 
All I needed to do was remove all *.pyc and *.pyo files from my project (or at least from the package which fails to import). Everything was alright then.
You can use pyclean program which is usually installed together with python on debian / ubuntu.

sobota 1. prosince 2012

Python exception handling

Exceptions are a very useful and powerful tool. But they must be used carefully, especially in the Python. Recently, my python program stopped working. Hmm. Not exactly stopped. No exception was raised, but all values that should be correclty loaded from database were set to default value. 

After few hours of debugging and head scratching, I realized that the problem is in "pythonic" approach of setting default value for object attributes that do not exist.

Instead of testing object with hasattr, we can just try to access the searched attribute directly and catch the AttributeException if it does not exist. (btw. this is exactly what hasattr does, so it is more effective approach to do it directly)

The problems occurs when you implement data descriptors __getattr__ or __getattribute__ in your objects and underlying business code raise unexpected AttributeError (or it´s subclass) during data descriptor call.



In example above, if AttributeError (or it´s subclass) is raised during self.business.do method (line 4), except statement on line 8. will catch it and the error will disappear silently. 

Of course it is logical and understandable behavior. But! If you will not wrap your implementation of __getattr__ or __getattribute__ in try ... except AttributeError (which can re raise exception other than AttributeException), you will spend a lot of time in debugging later :-)

My last tip on the Python exceptions for today: Always specify most concrete exception class that you are willing do catch. If you decide to catch all ValueErrors intead of some concrete class YourBusinessValueException(ValueError), you have to count on with possibility that not only YourBusinessValueException will be raised and catched in your try ... except statement! That except statement can catch any exception which is subclass of ValueError. There can be plenty of them!

I hope I helped you. Feel free to leave comment!