Python: less trouble through the 'with' statement

2015-12-02 06:54

I always preferred to use the with-statement when reading or writing files since I learned about this feature. By using with and open you make sure that regardless of the outcome of your actions the file you just opened will be closed. This had me to suggest the use of with whenever possible. And I can now share an anecdote where using that statement would have saved us some trouble.

I spend my daytime usually developing on opsi, a open source tool to manage computers (we say clients) from a central point. On Windows clients there has to be an agent running. This agent manages communication with the server that may trigger an software installation. Information about the server endpoint and client credentials are stored inside a file. Windows has this nice feature that it installs updates during shutdown. And it allows applications to register a program that is triggered during shutdown. If you want to install software during shutdown thats totally fine: opsi can hook in there.

The problem we faced is that the program we triggered for on-shutdown-installation opened the configuration file to access credentials of the service. The program is just a hundred lines of code what could go wrong? Well, it never closes the file after reading it. This ususally is not a problem. It starts to become one if another task then wants to access the config. We experienced this rare case when updating the agent on the client. During this the new application is copied to the client - together with a new configuration file. This part did indeed work fine. After copying the new data we patch the configuration file with current and client-specific settings - but our process to do this failed because the file was already in use!

This left the system with clients that lacked their configuration and did not know how to access their server anymore. Whoops!

Identifying those clients and then fixing their configuration luckily is nowhere near impossible. And the fix for our problem is a small one - you probably already know it: use the with-statement if you are working with files!