From 92dcb15c79514cff8035b82df3a863b869088bea Mon Sep 17 00:00:00 2001 From: Jason Madden Date: Sun, 12 Nov 2017 08:29:58 -0600 Subject: Fix ResourceWarnings for unclosed files when compiling .mo files. --- CHANGES.rst | 3 ++- src/zope/i18n/compile.py | 17 +++++++++++------ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 1a33a09..d6c62cb 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -5,7 +5,8 @@ CHANGES 4.2.1 (unreleased) ------------------ -- Nothing changed yet. +- Ensure that all files are properly closed when compiling .mo files, + such as when the ``registerTranslations`` ZCML directive is used. 4.2.0 (2017-05-23) diff --git a/src/zope/i18n/compile.py b/src/zope/i18n/compile.py index 2cc8d75..88de796 100644 --- a/src/zope/i18n/compile.py +++ b/src/zope/i18n/compile.py @@ -1,3 +1,4 @@ +from contextlib import closing import logging import os from os.path import join @@ -39,11 +40,15 @@ def compile_mo_file(domain, lc_messages_path): if po_mtime > mo_mtime: try: - mo = Msgfmt(pofile, domain).getAsFile() - fd = open(mofile, 'wb') - fd.write(mo.read()) - fd.close() + # Msgfmt.getAsFile returns io.BytesIO on Python 3, and cStringIO.StringIO + # on Python 2; sadly StringIO isn't a proper context manager, so we have to + # wrap it with `closing`. Also, Msgfmt doesn't properly close a file + # it opens for reading if you pass the path, but it does if you pass + # the file. + with closing(Msgfmt(open(pofile, 'rb'), domain).getAsFile()) as mo: + with open(mofile, 'wb') as fd: + fd.write(mo.read()) except PoSyntaxError as err: - logger.warn('Syntax error while compiling %s (%s).' % (pofile, err.msg)) + logger.warning('Syntax error while compiling %s (%s).', pofile, err.msg) except (IOError, OSError) as err: - logger.warn('Error while compiling %s (%s).' % (pofile, err)) + logger.warning('Error while compiling %s (%s).', pofile, err) -- cgit v1.2.1