------------------------------------------------------------ revno: 6554 committer: Barry Warsaw <[EMAIL PROTECTED]> branch nick: 3.0 timestamp: Wed 2007-09-19 07:28:58 -0400 message: Implement a context manager for Python 2.5's with statement, which is used where we used to do a try/except to temporarily change the global translation language. This makes the code shorter and cleaner. E.g. with i18n.using_language(another_language): # do something modified: Mailman/Archiver/HyperArch.py Mailman/Cgi/subscribe.py Mailman/Deliverer.py Mailman/Handlers/Hold.py Mailman/Handlers/ToDigest.py Mailman/MailList.py Mailman/Queue/Runner.py Mailman/app/membership.py Mailman/app/moderator.py Mailman/bin/add_members.py Mailman/bin/change_pw.py Mailman/bin/newlist.py Mailman/i18n.py TODO.txt
=== modified file 'Mailman/Archiver/HyperArch.py' --- a/Mailman/Archiver/HyperArch.py 2007-07-15 01:23:28 +0000 +++ b/Mailman/Archiver/HyperArch.py 2007-09-19 11:28:58 +0000 @@ -26,6 +26,8 @@ (probably in the 'update_dirty_archives' method). """ +from __future__ import with_statement + import os import re import sys @@ -114,13 +116,8 @@ if e.errno <> errno.ENOENT: raise return _('size not available') if size < 1000: - # Avoid i18n side-effects - otrans = i18n.get_translation() - try: - i18n.set_language(lang) + with i18n.using_language(lang): out = _(' %(size)i bytes ') - finally: - i18n.set_translation(otrans) return out elif size < 1000000: return ' %d KB ' % (size / 1000) @@ -269,17 +266,12 @@ # article (for this list) could be different from the site-wide # preferred language, so we need to ensure no side-effects will # occur. Think what happens when executing bin/arch. - otrans = i18n.get_translation() - try: - i18n.set_language(lang) + with i18n.using_language(lang): if self.author == self.email: self.author = self.email = re.sub('@', _(' at '), self.email) else: self.email = re.sub('@', _(' at '), self.email) - finally: - i18n.set_translation(otrans) - # Snag the content-* headers. RFC 1521 states that their values are # case insensitive. ctype = message.get('Content-Type', 'text/plain') @@ -401,14 +393,10 @@ self.decoded['email'] = email if subject: if config.ARCHIVER_OBSCURES_EMAILADDRS: - otrans = i18n.get_translation() - try: - i18n.set_language(self._lang) + with i18n.using_language(self._lang): atmark = unicode(_(' at '), Utils.GetCharSet(self._lang)) subject = re.sub(r'([-+,.\w]+)@([-+.\w]+)', '\g<1>' + atmark + '\g<2>', subject) - finally: - i18n.set_translation(otrans) self.decoded['subject'] = subject self.decoded['stripped'] = self.strip_subject(subject or self.subject) @@ -443,9 +431,7 @@ def as_html(self): d = self.__dict__.copy() # avoid i18n side-effects - otrans = i18n.get_translation() - i18n.set_language(self._lang) - try: + with i18n.using_language(self._lang): d["prev"], d["prev_wsubj"] = self._get_prev() d["next"], d["next_wsubj"] = self._get_next() @@ -468,9 +454,6 @@ d['listurl'] = self._mlist.GetScriptURL('listinfo', absolute=1) d['listname'] = self._mlist.real_name d['encoding'] = '' - finally: - i18n.set_translation(otrans) - charset = Utils.GetCharSet(self._lang) d["encoding"] = html_charset % charset @@ -562,14 +545,10 @@ if not isinstance(body, unicode): body = unicode(body, cset, 'replace') if config.ARCHIVER_OBSCURES_EMAILADDRS: - otrans = i18n.get_translation() - try: + with i18n.using_language(self._lang): atmark = unicode(_(' at '), cset) - i18n.set_language(self._lang) body = re.sub(r'([-+,.\w]+)@([-+.\w]+)', '\g<1>' + atmark + '\g<2>', body) - finally: - i18n.set_translation(otrans) # Return body to character set of article. body = body.encode(cset, 'replace') return NL.join(headers) % d + '\n\n' + body + '\n' @@ -668,12 +647,10 @@ def html_foot(self): # avoid i18n side-effects mlist = self.maillist - otrans = i18n.get_translation() - i18n.set_language(mlist.preferred_language) # Convenience def quotetime(s): return html_quote(i18n.ctime(s), self.lang) - try: + with i18n.using_language(mlist.preferred_language): d = {"lastdate": quotetime(self.lastdate), "archivedate": quotetime(self.archivedate), "listinfo": mlist.GetScriptURL('listinfo', absolute=1), @@ -684,9 +661,6 @@ "author": _("author"), "date": _("date") } - finally: - i18n.set_translation(otrans) - for t in i.keys(): cap = t[0].upper() + t[1:] if self.type == cap: @@ -701,12 +675,10 @@ def html_head(self): # avoid i18n side-effects mlist = self.maillist - otrans = i18n.get_translation() - i18n.set_language(mlist.preferred_language) # Convenience def quotetime(s): return html_quote(i18n.ctime(s), self.lang) - try: + with i18n.using_language(mlist.preferred_language): d = {"listname": html_quote(mlist.real_name, self.lang), "archtype": self.type, "archive": self.volNameToDesc(self.archive), @@ -720,9 +692,6 @@ "author": _("author"), "date": _("date"), } - finally: - i18n.set_translation(otrans) - for t in i.keys(): cap = t[0].upper() + t[1:] if self.type == cap: @@ -750,9 +719,7 @@ 'meta': '', } # Avoid i18n side-effects - otrans = i18n.get_translation() - i18n.set_language(mlist.preferred_language) - try: + with i18n.using_language(mlist.preferred_language): if not self.archives: d["noarchive_msg"] = _( '<P>Currently, there are no archives. </P>') @@ -773,8 +740,6 @@ for a in self.archives: accum.append(self.html_TOC_entry(a)) d["archive_listing"] = EMPTYSTRING.join(accum) - finally: - i18n.set_translation(otrans) # The TOC is always in the charset of the list's preferred language d['meta'] += html_charset % Utils.GetCharSet(mlist.preferred_language) # The site can disable public access to the mbox file. === modified file 'Mailman/Cgi/subscribe.py' --- a/Mailman/Cgi/subscribe.py 2007-08-01 20:11:08 +0000 +++ b/Mailman/Cgi/subscribe.py 2007-09-19 11:28:58 +0000 @@ -17,6 +17,8 @@ """Process subscription or roster requests from listinfo form.""" +from __future__ import with_statement + import os import cgi import sys @@ -199,9 +201,7 @@ listaddr = mlist.GetListEmail() # Set the language for this email message to the member's language. mlang = mlist.getMemberLanguage(email) - otrans = i18n.get_translation() - i18n.set_language(mlang) - try: + with i18n.using_language(mlang): msg = Message.UserNotification( mlist.getMemberCPAddress(email), mlist.GetBouncesEmail(), @@ -220,8 +220,6 @@ list, and you are worried about your privacy, then feel free to send a message to the list administrator at %(listowner)s. """), lang=mlang) - finally: - i18n.set_translation(otrans) msg.send(mlist) # These shouldn't happen unless someone's tampering with the form except Errors.MMCantDigestError: === modified file 'Mailman/Deliverer.py' --- a/Mailman/Deliverer.py 2007-09-16 16:08:24 +0000 +++ b/Mailman/Deliverer.py 2007-09-19 11:28:58 +0000 @@ -18,6 +18,8 @@ """Mixin class with message delivery routines.""" +from __future__ import with_statement + import logging from email.MIMEMessage import MIMEMessage @@ -126,9 +128,7 @@ except Errors.MMListError: # Oh well return - otrans = i18n.get_translation() - i18n.set_language(mlist.preferred_language) - try: + with i18n.using_language(mlist.preferred_language): msg = Message.OwnerNotification( mlist, _('Hostile subscription attempt detected'), @@ -137,8 +137,6 @@ different list. We just thought you'd like to know. No further action by you is required."""))) msg.send(mlist) - finally: - i18n.set_translation(otrans) def sendProbe(self, member, msg): listname = self.real_name @@ -162,12 +160,8 @@ self.host_name) # Calculate the Subject header, in the member's preferred language ulang = self.getMemberLanguage(member) - otrans = i18n.get_translation() - i18n.set_language(ulang) - try: + with i18n.using_language(ulang): subject = _('%(listname)s mailing list probe message') - finally: - i18n.set_translation(otrans) outer = Message.UserNotification(member, probeaddr, subject, lang=ulang) outer.set_type('multipart/mixed') === modified file 'Mailman/Handlers/Hold.py' --- a/Mailman/Handlers/Hold.py 2007-09-17 02:10:05 +0000 +++ b/Mailman/Handlers/Hold.py 2007-09-19 11:28:58 +0000 @@ -28,6 +28,8 @@ message handling should stop. """ +from __future__ import with_statement + import email import logging import email.utils @@ -272,9 +274,7 @@ if mlist.admin_immed_notify: # Now let's temporarily set the language context to that which the # admin is expecting. - otranslation = i18n.get_translation() - i18n.set_language(mlist.preferred_language) - try: + with i18n.using_language(mlist.preferred_language): lang = mlist.preferred_language charset = Utils.GetCharSet(lang) # We need to regenerate or re-translate a few values in d @@ -304,8 +304,6 @@ nmsg.attach(MIMEMessage(msg)) nmsg.attach(MIMEMessage(dmsg)) nmsg.send(mlist, **{'tomoderators': 1}) - finally: - i18n.set_translation(otranslation) # Log the held message log.info('%s post from %s held, message-id=%s: %s', listname, sender, message_id, reason) === modified file 'Mailman/Handlers/ToDigest.py' --- a/Mailman/Handlers/ToDigest.py 2007-08-01 20:11:08 +0000 +++ b/Mailman/Handlers/ToDigest.py 2007-09-19 11:28:58 +0000 @@ -25,6 +25,8 @@ # directory and the DigestRunner will craft the MIME, rfc1153, and # (eventually) URL-subject linked digests from the mbox. +from __future__ import with_statement + import os import re import copy @@ -129,12 +131,8 @@ mlist.digest_last_sent_at = time.time() # Wrapper around actually digest crafter to set up the language context # properly. All digests are translated to the list's preferred language. - otranslation = i18n.get_translation() - i18n.set_language(mlist.preferred_language) - try: + with i18n.using_language(mlist.preferred_language): send_i18n_digests(mlist, mboxfp) - finally: - i18n.set_translation(otranslation) === modified file 'Mailman/MailList.py' --- a/Mailman/MailList.py 2007-09-16 16:08:24 +0000 +++ b/Mailman/MailList.py 2007-09-19 11:28:58 +0000 @@ -21,6 +21,8 @@ Mixes in many task-specific classes. """ +from __future__ import with_statement + import os import re import sys @@ -722,19 +724,15 @@ slog.info('%s: changed member address from %s to %s', self.internal_name(), oldaddr, newaddr) if self.admin_notify_mchanges: - lang = self.preferred_language - otrans = i18n.get_translation() - i18n.set_language(lang) - try: + with i18n.using_language(self.preferred_language): realname = self.real_name subject = _('%(realname)s address change notification') - finally: - i18n.set_translation(otrans) name = self.getMemberName(newaddr) if name is None: name = '' if isinstance(name, unicode): - name = name.encode(Utils.GetCharSet(lang), 'replace') + name = name.encode(Utils.GetCharSet(self.preferred_language), + 'replace') text = Utils.maketext( 'adminaddrchgack.txt', {'name' : name, === modified file 'Mailman/Queue/Runner.py' --- a/Mailman/Queue/Runner.py 2007-08-02 14:47:56 +0000 +++ b/Mailman/Queue/Runner.py 2007-09-19 11:28:58 +0000 @@ -17,6 +17,8 @@ """Generic queue runner class.""" +from __future__ import with_statement + import time import weakref import logging @@ -162,19 +164,15 @@ # special care to reset the defaults, otherwise subsequent messages # may be translated incorrectly. BAW: I'm not sure I like this # approach, but I can't think of anything better right now. - otranslation = i18n.get_translation() sender = msg.get_sender() member = mlist.members.get_member(sender) if member: lang = member.preferred_language else: lang = mlist.preferred_language - i18n.set_language(lang) - msgdata['lang'] = lang - try: + with i18n.using_language(lang): + msgdata['lang'] = lang keepqueued = self._dispose(mlist, msg, msgdata) - finally: - i18n.set_translation(otranslation) # Keep tabs on any child processes that got spawned. kids = msgdata.get('_kids') if kids: === modified file 'Mailman/app/membership.py' --- a/Mailman/app/membership.py 2007-09-16 16:08:24 +0000 +++ b/Mailman/app/membership.py 2007-09-19 11:28:58 +0000 @@ -17,6 +17,8 @@ """Application support for membership management.""" +from __future__ import with_statement + from email.utils import formataddr from Mailman import Message @@ -102,12 +104,8 @@ if ack: send_welcome_message(mlist, address, language, delivery_mode, text) if admin_notif: - otrans = i18n.get_translation() - i18n.set_language(mlist.preferred_language) - try: + with i18n.using_language(mlist.preferred_language): subject = _('$mlist.real_name subscription notification') - finally: - i18n.set_translation(otrans) if isinstance(realname, unicode): realname = name.encode(Utils.GetCharSet(language), 'replace') text = Utils.maketext( === modified file 'Mailman/app/moderator.py' --- a/Mailman/app/moderator.py 2007-09-16 16:08:24 +0000 +++ b/Mailman/app/moderator.py 2007-09-19 11:28:58 +0000 @@ -17,6 +17,8 @@ """Application support for moderators.""" +from __future__ import with_statement + __all__ = [ 'handle_message', 'handle_subscription', @@ -149,15 +151,11 @@ member = mlist.members.get_member(addresses[0]) if member: language = member.preferred_language - otrans = i18n.get_translation() - i18n.set_language(language) - try: + with i18n.using_language(language): fmsg = Message.UserNotification( addresses, mlist.bounces_address, _('Forward of moderated message'), lang=language) - finally: - i18n.set_translation(otrans) fmsg.set_type('message/rfc822') fmsg.attach(msg) fmsg.send(mlist) @@ -318,9 +316,7 @@ 'reason' : comment, 'adminaddr': mlist.owner_address, }, lang=lang, mlist=mlist) - otrans = i18n.get_translation() - i18n.set_language(lang) - try: + with i18n.using_language(lang): # add in original message, but not wrap/filled if origmsg: text = NL.join( @@ -329,8 +325,6 @@ str(origmsg) ]) subject = _('Request to mailing list "$realname" rejected') - finally: - i18n.set_translation(otrans) msg = Message.UserNotification(recip, mlist.bounces_address, subject, text, lang) msg.send(mlist) === modified file 'Mailman/bin/add_members.py' --- a/Mailman/bin/add_members.py 2007-08-01 20:11:08 +0000 +++ b/Mailman/bin/add_members.py 2007-09-19 11:28:58 +0000 @@ -15,6 +15,8 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, # USA. +from __future__ import with_statement + import os import sys import optparse @@ -177,9 +179,7 @@ else: admin_notify = opts.admin_notify - otrans = i18n.get_translation() - # Read the regular and digest member files - try: + with i18n.using_language(mlist.preferred_language): if opts.digest: dmembers = readfile(opts.digest) else: @@ -194,7 +194,6 @@ sys.exit(0) s = StringIO() - i18n.set_language(mlist.preferred_language) if nmembers: addall(mlist, nmembers, False, send_welcome_msg, s) @@ -211,7 +210,7 @@ mlist.Save() finally: mlist.Unlock() - i18n.set_translation(otrans) + if __name__ == '__main__': === modified file 'Mailman/bin/change_pw.py' --- a/Mailman/bin/change_pw.py 2007-05-28 20:21:41 +0000 +++ b/Mailman/bin/change_pw.py 2007-09-19 11:28:58 +0000 @@ -15,6 +15,8 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, # USA. +from __future__ import with_statement + import sha import sys import optparse @@ -150,9 +152,7 @@ # Notification print _('New $listname password: $notifypassword') if not opts.quiet: - otrans = i18n.get_translation() - i18n.set_language(mlist.preferred_language) - try: + with i18n.using_language(mlist.preferred_language): hostname = mlist.host_name adminurl = mlist.GetScriptURL('admin', absolute=True) msg = Message.UserNotification( @@ -171,8 +171,6 @@ $adminurl '''), mlist.preferred_language) - finally: - i18n.set_translation(otrans) msg.send(mlist) === modified file 'Mailman/bin/newlist.py' --- a/Mailman/bin/newlist.py 2007-08-06 03:49:04 +0000 +++ b/Mailman/bin/newlist.py 2007-09-19 11:28:58 +0000 @@ -15,6 +15,8 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, # USA. +from __future__ import with_statement + import sha import sys import getpass @@ -131,13 +133,9 @@ # Set the I18N language to the list's preferred language so the header # will match the template language. Stashing and restoring the old # translation context is just (healthy? :) paranoia. - otrans = i18n.get_translation() - i18n.set_language(mlist.preferred_language) - try: + with i18n.using_language(mlist.preferred_language): msg = Message.UserNotification( owner_mail, mlist.no_reply_address, _('Your new mailing list: $listname'), text, mlist.preferred_language) msg.send(mlist) - finally: - i18n.set_translation(otrans) === modified file 'Mailman/i18n.py' --- a/Mailman/i18n.py 2007-07-17 03:55:49 +0000 +++ b/Mailman/i18n.py 2007-09-19 11:28:58 +0000 @@ -69,6 +69,21 @@ _translation = translation +class using_language(object): + """Context manager for Python 2.5's `with` statement.""" + def __init__(self, language): + self._language = language + self._old_translation = None + + def __enter__(self): + self._old_translation = _translation + set_language(self._language) + + def __exit__(self, exc_type, exc_val, exc_tb): + global _translation + _translation = self._old_translation + + # Set up the global translation based on environment variables. Mostly used # for command line scripts. if _translation is None: === modified file 'TODO.txt' --- a/TODO.txt 2007-09-17 02:16:41 +0000 +++ b/TODO.txt 2007-09-19 11:28:58 +0000 @@ -13,5 +13,4 @@ Fix the roster creation cruft for mailing lists Suss out the IDomain stuff Remove Date: header from messagestore requirements (see list thread) -Make i18n.get_translation() a context manager Handle moderation flag (see Mailman.app.membership) -- https://code.launchpad.net/~mailman-coders/mailman/3.0 You are receiving this branch notification because you are subscribed to it. To unsubscribe from this branch go to https://code.launchpad.net/~mailman-coders/mailman/3.0/+subscription/mailman-checkins. _______________________________________________ Mailman-checkins mailing list Mailman-checkins@python.org Unsubscribe: http://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org