| Index: sitescripts/extensions/utils.py | 
| =================================================================== | 
| --- a/sitescripts/extensions/utils.py | 
| +++ b/sitescripts/extensions/utils.py | 
| @@ -9,16 +9,17 @@ | 
| # but WITHOUT ANY WARRANTY; without even the implied warranty of | 
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 
| # GNU General Public License for more details. | 
| # | 
| # You should have received a copy of the GNU General Public License | 
| # along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. | 
| import codecs | 
| +import contextlib | 
| import os | 
| import json | 
| import re | 
| import subprocess | 
| import traceback | 
| import time | 
| import urlparse | 
| import urllib | 
| @@ -244,29 +245,28 @@ | 
| def _urlopen(url, attempts=3): | 
| """ | 
| Tries to open a particular URL, retries on failure. | 
| """ | 
| for i in range(attempts): | 
| try: | 
| - return urllib.urlopen(url) | 
| + return contextlib.closing(urllib.urlopen(url)) | 
| except IOError as e: | 
| error = Exception('Error {0} while opening {1} url' | 
| .format(e, url)) | 
| time.sleep(5) | 
| raise error | 
| def _parseXMLDocument(url, attempts=2): | 
| for i in range(attempts): | 
| - page = _urlopen(url) | 
| - content = page.read() | 
| - page.close() | 
| + with _urlopen(url) as page: | 
| + content = page.read() | 
| try: | 
| return dom.parseString(content) | 
| except ExpatError as err: | 
| exception = Exception('Error {0} while parsing xml:\n{1}\nfrom {2}' | 
| .format(err, content, url)) | 
| raise exception |