summaryrefslogtreecommitdiff
path: root/mailman/queue/__init__.py
diff options
context:
space:
mode:
Diffstat (limited to 'mailman/queue/__init__.py')
-rw-r--r--mailman/queue/__init__.py36
1 files changed, 19 insertions, 17 deletions
diff --git a/mailman/queue/__init__.py b/mailman/queue/__init__.py
index e6d39ee1b..cb2225b13 100644
--- a/mailman/queue/__init__.py
+++ b/mailman/queue/__init__.py
@@ -24,6 +24,8 @@ written. First, the message is written to the pickle, then the metadata
dictionary is written.
"""
+from __future__ import absolute_import, unicode_literals
+
__metaclass__ = type
__all__ = [
'Runner',
@@ -45,7 +47,6 @@ import traceback
from cStringIO import StringIO
from lazr.config import as_boolean, as_timedelta
-from string import Template
from zope.interface import implements
from mailman import Message
@@ -54,6 +55,7 @@ from mailman import i18n
from mailman.config import config
from mailman.interfaces.runner import IRunner
from mailman.interfaces.switchboard import ISwitchboard
+from mailman.utilities.string import expand
# 20 bytes of all bits set, maximum hashlib.sha.digest() value
shamax = 0xffffffffffffffffffffffffffffffffffffffffL
@@ -81,10 +83,10 @@ class Switchboard:
for conf in config.qrunner_configs:
name = conf.name.split('.')[-1]
assert name not in config.switchboards, (
- 'Duplicate qrunner name: %s' % name)
+ 'Duplicate qrunner name: {0}'.format(name))
substitutions = config.paths
substitutions['name'] = name
- path = Template(conf.path).safe_substitute(substitutions)
+ path = expand(conf.path, substitutions)
config.switchboards[name] = Switchboard(path)
def __init__(self, queue_directory,
@@ -103,7 +105,7 @@ class Switchboard:
:type recover: bool
"""
assert (numslices & (numslices - 1)) == 0, (
- 'Not a power of 2: %s' % numslices)
+ 'Not a power of 2: {0}'.format(numslices))
self.queue_directory = queue_directory
# Create the directory if it doesn't yet exist.
Utils.makedirs(self.queue_directory, 0770)
@@ -148,7 +150,8 @@ class Switchboard:
tmpfile = filename + '.tmp'
# Always add the metadata schema version number
data['version'] = config.QFILE_SCHEMA_VERSION
- # Filter out volatile entries
+ # Filter out volatile entries. Use .keys() so that we can mutate the
+ # dictionary during the iteration.
for k in data.keys():
if k.startswith('_'):
del data[k]
@@ -197,7 +200,7 @@ class Switchboard:
os.rename(bakfile, psvfile)
else:
os.unlink(bakfile)
- except EnvironmentError, e:
+ except EnvironmentError:
elog.exception(
'Failed to unlink/preserve backup file: %s', bakfile)
@@ -246,11 +249,11 @@ class Switchboard:
msg = cPickle.load(fp)
data_pos = fp.tell()
data = cPickle.load(fp)
- except Exception, s:
+ except Exception as error:
# If unpickling throws any exception, just log and
# preserve this entry
elog.error('Unpickling .bak exception: %s\n'
- 'Preserving file: %s', s, filebase)
+ 'Preserving file: %s', error, filebase)
self.finish(filebase, preserve=True)
else:
data['_bak_count'] = data.get('_bak_count', 0) + 1
@@ -289,8 +292,7 @@ class Runner:
section = getattr(config, 'qrunner.' + name)
substitutions = config.paths
substitutions['name'] = name
- self.queue_directory = Template(section.path).safe_substitute(
- substitutions)
+ self.queue_directory = expand(section.path, substitutions)
numslices = int(section.instances)
self.switchboard = Switchboard(
self.queue_directory, slice, numslices, True)
@@ -304,7 +306,7 @@ class Runner:
self._stop = False
def __repr__(self):
- return '<%s at %s>' % (self.__class__.__name__, id(self))
+ return '<{0} at {1:#x}>'.format(self.__class__.__name__, id(self))
def stop(self):
"""See `IRunner`."""
@@ -345,13 +347,13 @@ class Runner:
# Ask the switchboard for the message and metadata objects
# associated with this queue file.
msg, msgdata = self.switchboard.dequeue(filebase)
- except Exception, e:
+ except Exception as error:
# This used to just catch email.Errors.MessageParseError, but
# other problems can occur in message parsing, e.g.
# ValueError, and exceptions can occur in unpickling too. We
# don't want the runner to die, so we just log and skip this
# entry, but preserve it for analysis.
- self._log(e)
+ self._log(error)
elog.error('Skipping and preserving unparseable message: %s',
filebase)
self.switchboard.finish(filebase, preserve=True)
@@ -362,14 +364,14 @@ class Runner:
self._process_one_file(msg, msgdata)
dlog.debug('[%s] finishing filebase: %s', me, filebase)
self.switchboard.finish(filebase)
- except Exception, e:
+ except Exception as error:
# All runners that implement _dispose() must guarantee that
# exceptions are caught and dealt with properly. Still, there
# may be a bug in the infrastructure, and we do not want those
# to cause messages to be lost. Any uncaught exceptions will
# cause the message to be stored in the shunt queue for human
# intervention.
- self._log(e)
+ self._log(error)
# Put a marker in the metadata for unshunting.
msgdata['whichq'] = self.switchboard.queue_directory
# It is possible that shunting can throw an exception, e.g. a
@@ -380,11 +382,11 @@ class Runner:
new_filebase = shunt.enqueue(msg, msgdata)
elog.error('SHUNTING: %s', new_filebase)
self.switchboard.finish(filebase)
- except Exception, e:
+ except Exception as error:
# The message wasn't successfully shunted. Log the
# exception and try to preserve the original queue entry
# for possible analysis.
- self._log(e)
+ self._log(error)
elog.error(
'SHUNTING FAILED, preserving original entry: %s',
filebase)