summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBarry Warsaw2009-05-16 11:08:46 -0400
committerBarry Warsaw2009-05-16 11:08:46 -0400
commit7e23b2f358806cb14b92dc7833ce773738534d41 (patch)
tree5499b536a163ebb4dedab62f4f7a97b460cece18
parentad07de3dcdbf0ef11b5b324b9521b748da207fc7 (diff)
downloadmailman-7e23b2f358806cb14b92dc7833ce773738534d41.tar.gz
mailman-7e23b2f358806cb14b92dc7833ce773738534d41.tar.zst
mailman-7e23b2f358806cb14b92dc7833ce773738534d41.zip
-rw-r--r--src/mailman/app/lifecycle.py9
-rw-r--r--src/mailman/bin/genaliases.py5
-rw-r--r--src/mailman/bin/master.py6
-rw-r--r--src/mailman/bin/qrunner.py9
-rw-r--r--src/mailman/config/config.py6
-rw-r--r--src/mailman/core/initialize.py13
-rw-r--r--src/mailman/database/pending.py8
-rw-r--r--src/mailman/database/types.py8
-rw-r--r--src/mailman/pipeline/scrubber.py11
-rw-r--r--src/mailman/queue/lmtp.py2
-rw-r--r--src/mailman/queue/outgoing.py6
-rw-r--r--src/mailman/styles/manager.py5
-rw-r--r--src/mailman/utilities/modules.py59
13 files changed, 95 insertions, 52 deletions
diff --git a/src/mailman/app/lifecycle.py b/src/mailman/app/lifecycle.py
index 56eb88d32..051b7cec3 100644
--- a/src/mailman/app/lifecycle.py
+++ b/src/mailman/app/lifecycle.py
@@ -36,6 +36,7 @@ from mailman.config import config
from mailman.core import errors
from mailman.email.validate import validate
from mailman.interfaces.member import MemberRole
+from mailman.utilities.modules import call_name
log = logging.getLogger('mailman.error')
@@ -54,9 +55,7 @@ def create_list(fqdn_listname, owners=None):
for style in config.style_manager.lookup(mlist):
style.apply(mlist)
# Coordinate with the MTA, as defined in the configuration file.
- package, dot, class_name = config.mta.incoming.rpartition('.')
- __import__(package)
- getattr(sys.modules[package], class_name)().create(mlist)
+ call_name(config.mta.incoming).create(mlist)
# Create any owners that don't yet exist, and subscribe all addresses as
# owners of the mailing list.
usermgr = config.db.user_manager
@@ -83,9 +82,7 @@ def remove_list(fqdn_listname, mailing_list=None, archives=True):
# Delete the mailing list from the database.
config.db.list_manager.delete(mailing_list)
# Do the MTA-specific list deletion tasks
- package, dot, class_name = config.mta.incoming.rpartition('.')
- __import__(package)
- getattr(sys.modules[package], class_name)().create(mailing_list)
+ call_name(config.mta.incoming).create(mailing_list)
# Remove the list directory.
removeables.append(os.path.join(config.LIST_DATA_DIR, fqdn_listname))
# Remove any stale locks associated with the list.
diff --git a/src/mailman/bin/genaliases.py b/src/mailman/bin/genaliases.py
index fe587cb02..8fe37f543 100644
--- a/src/mailman/bin/genaliases.py
+++ b/src/mailman/bin/genaliases.py
@@ -26,6 +26,7 @@ import sys
from mailman.config import config
from mailman.i18n import _
from mailman.options import Options
+from mailman.utilities.modules import call_name
@@ -54,9 +55,7 @@ def main():
options.initialize()
# Get the MTA-specific module.
- package, dot, class_path = config.mta.incoming.rpartition('.')
- __import__(module_path)
- getattr(sys.modules[module_path], class_path)().regenerate()
+ call_name(config.mta.incoming).regenerate()
diff --git a/src/mailman/bin/master.py b/src/mailman/bin/master.py
index 1156f8a33..076b3acfb 100644
--- a/src/mailman/bin/master.py
+++ b/src/mailman/bin/master.py
@@ -40,6 +40,7 @@ from mailman.config import config
from mailman.core.logging import reopen
from mailman.i18n import _
from mailman.options import Options
+from mailman.utilities.modules import find_name
DOT = '.'
@@ -319,10 +320,7 @@ class Loop:
qrunner_config = getattr(config, section_name)
if not as_boolean(qrunner_config.start):
continue
- package, dot, class_name = qrunner_config['class'].rpartition(DOT)
- __import__(package)
- # Let AttributeError propagate.
- class_ = getattr(sys.modules[package], class_name)
+ class_ = find_name(qrunner_config['class'])
# Find out how many qrunners to instantiate. This must be a power
# of 2.
count = int(qrunner_config.instances)
diff --git a/src/mailman/bin/qrunner.py b/src/mailman/bin/qrunner.py
index 99cb564bc..318b62c68 100644
--- a/src/mailman/bin/qrunner.py
+++ b/src/mailman/bin/qrunner.py
@@ -23,6 +23,7 @@ from mailman.config import config
from mailman.core.logging import reopen
from mailman.i18n import _
from mailman.options import Options
+from mailman.utilities.modules import find_name
COMMASPACE = ', '
@@ -133,19 +134,17 @@ def make_qrunner(name, slice, range, once=False):
class_path = 'mailman.queue' + name
else:
class_path = name
- package, dot, class_name = class_path.rpartition('.')
try:
- __import__(package)
- except ImportError, e:
+ qrclass = find_name(class_path)
+ except ImportError as error:
if config.options.options.subproc:
# Exit with SIGTERM exit code so the master watcher won't try to
# restart us.
print >> sys.stderr, _('Cannot import runner module: $module_name')
- print >> sys.stderr, e
+ print >> sys.stderr, error
sys.exit(signal.SIGTERM)
else:
raise
- qrclass = getattr(sys.modules[package], class_name)
if once:
# Subclass to hack in the setting of the stop flag in _do_periodic()
class Once(qrclass):
diff --git a/src/mailman/config/config.py b/src/mailman/config/config.py
index 1b86e8f67..4ae2e85be 100644
--- a/src/mailman/config/config.py
+++ b/src/mailman/config/config.py
@@ -39,6 +39,8 @@ from mailman.domain import Domain
from mailman.languages.manager import LanguageManager
from mailman.styles.manager import StyleManager
from mailman.utilities.filesystem import makedirs
+from mailman.utilities.modules import call_name
+
SPACE = ' '
@@ -191,9 +193,7 @@ class Configuration(object):
if not as_boolean(section.enable):
continue
class_path = section['class']
- package, dot, class_name = class_path.rpartition('.')
- __import__(package)
- yield getattr(sys.modules[package], class_name)()
+ yield call_name(class_path)
@property
def style_configs(self):
diff --git a/src/mailman/core/initialize.py b/src/mailman/core/initialize.py
index 18cb823ee..885174fb0 100644
--- a/src/mailman/core/initialize.py
+++ b/src/mailman/core/initialize.py
@@ -45,6 +45,7 @@ import mailman.config.config
import mailman.core.logging
from mailman.interfaces.database import IDatabase
+from mailman.utilities.modules import call_name
@@ -92,15 +93,11 @@ def initialize_2(debug=False):
# Run the pre-hook if there is one.
config = mailman.config.config
if config.mailman.pre_hook:
- package, dot, function = config.mailman.pre_hook.rpartition('.')
- __import__(package)
- getattr(sys.modules[package], function)()
+ call_name(config.mailman.pre_hook)
# Instantiate the database class, ensure that it's of the right type, and
# initialize it. Then stash the object on our configuration object.
database_class = config.database['class']
- package, dot, class_name = database_class.rpartition('.')
- __import__(package)
- database = getattr(sys.modules[package], class_name)()
+ database = call_name(database_class)
verifyObject(IDatabase, database)
database.initialize(debug)
config.db = database
@@ -132,9 +129,7 @@ def initialize_3():
# Run the post-hook if there is one.
config = mailman.config.config
if config.mailman.post_hook:
- package, dot, function = config.mailman.post_hook.rpartition('.')
- __import__(package)
- getattr(sys.modules[package], function)()
+ call_name(config.mailman.post_hook)
diff --git a/src/mailman/database/pending.py b/src/mailman/database/pending.py
index 9c2da9064..2a0e5d09e 100644
--- a/src/mailman/database/pending.py
+++ b/src/mailman/database/pending.py
@@ -40,6 +40,7 @@ from mailman.config import config
from mailman.database.model import Model
from mailman.interfaces.pending import (
IPendable, IPended, IPendedKeyValue, IPendings)
+from mailman.utilities.modules import call_name
@@ -145,11 +146,8 @@ class Pendings:
for keyvalue in store.find(PendedKeyValue,
PendedKeyValue.pended_id == pending.id):
if keyvalue.value is not None and '\1' in keyvalue.value:
- typename, value = keyvalue.value.split('\1', 1)
- package, dot, classname = typename.rpartition('.')
- __import__(package)
- module = sys.modules[package]
- pendable[keyvalue.key] = getattr(module, classname)(value)
+ type_name, value = keyvalue.value.split('\1', 1)
+ pendable[keyvalue.key] = call_name(type_name, value)
else:
pendable[keyvalue.key] = keyvalue.value
if expunge:
diff --git a/src/mailman/database/types.py b/src/mailman/database/types.py
index 4b3031c3b..f559737e2 100644
--- a/src/mailman/database/types.py
+++ b/src/mailman/database/types.py
@@ -31,6 +31,8 @@ import sys
from storm.properties import SimpleProperty
from storm.variables import Variable
+from mailman.utilities.modules import find_name
+
class _EnumVariable(Variable):
@@ -42,10 +44,8 @@ class _EnumVariable(Variable):
if not from_db:
return value
path, colon, intvalue = value.rpartition(':')
- package, dot, classname = path.rpartition('.')
- __import__(package)
- cls = getattr(sys.modules[package], classname)
- return cls[int(intvalue)]
+ class_ = find_name(path)
+ return class_[int(intvalue)]
def parse_get(self, value, to_db):
if value is None:
diff --git a/src/mailman/pipeline/scrubber.py b/src/mailman/pipeline/scrubber.py
index 18d50c7a5..e5510e0ab 100644
--- a/src/mailman/pipeline/scrubber.py
+++ b/src/mailman/pipeline/scrubber.py
@@ -49,6 +49,7 @@ from mailman.core.errors import DiscardMessage
from mailman.i18n import _
from mailman.interfaces.handler import IHandler
from mailman.utilities.filesystem import makedirs
+from mailman.utilities.modules import find_name
# Path characters for common platforms
@@ -487,14 +488,12 @@ def save_attachment(mlist, msg, dir, filter_html=True):
fp.close()
# Now calculate the url to the list's archive.
scrubber_path = config.scrubber.archive_scrubber
- package, dot, module_name = scrubber_path.rpartition('.')
- __import__(package)
- baseurl = getattr(sys.modules[package], module_name).list_url(mlist)
- if not baseurl.endswith('/'):
- baseurl += '/'
+ base_url = find_name(scrubber_path).list_url(mlist)
+ if not base_url.endswith('/'):
+ base_url += '/'
# Trailing space will definitely be a problem with format=flowed.
# Bracket the URL instead.
- url = '<' + baseurl + '%s/%s%s%s>' % (dir, filebase, extra, ext)
+ url = '<' + base_url + '%s/%s%s%s>' % (dir, filebase, extra, ext)
return url
diff --git a/src/mailman/queue/lmtp.py b/src/mailman/queue/lmtp.py
index 68a86eeb3..00c9ad988 100644
--- a/src/mailman/queue/lmtp.py
+++ b/src/mailman/queue/lmtp.py
@@ -119,9 +119,9 @@ class LMTPRunner(Runner, smtpd.SMTPServer):
def __init__(self, slice=None, numslices=1):
localaddr = config.mta.lmtp_host, int(config.mta.lmtp_port)
# Do not call Runner's constructor because there's no QDIR to create
- smtpd.SMTPServer.__init__(self, localaddr, remoteaddr=None)
qlog.debug('LMTP server listening on %s:%s',
localaddr[0], localaddr[1])
+ smtpd.SMTPServer.__init__(self, localaddr, remoteaddr=None)
def handle_accept(self):
conn, addr = self.accept()
diff --git a/src/mailman/queue/outgoing.py b/src/mailman/queue/outgoing.py
index 2093534b4..e64e8c57b 100644
--- a/src/mailman/queue/outgoing.py
+++ b/src/mailman/queue/outgoing.py
@@ -29,6 +29,8 @@ from mailman.config import config
from mailman.core import errors
from mailman.queue import Runner
from mailman.queue.bounce import BounceMixin
+from mailman.utilities.modules import find_name
+
# This controls how often _do_periodic() will try to deal with deferred
# permanent failures. It is a count of calls to _do_periodic()
@@ -45,9 +47,7 @@ class OutgoingRunner(Runner, BounceMixin):
Runner.__init__(self, slice, numslices)
BounceMixin.__init__(self)
# We look this function up only at startup time.
- package, dot, callable_name = config.mta.outgoing.rpartition('.')
- __import__(package)
- self._func = getattr(sys.modules[package], callable_name)
+ self._func = find_name(config.mta.outgoing)
# This prevents smtp server connection problems from filling up the
# error log. It gets reset if the message was successfully sent, and
# set if there was a socket.error.
diff --git a/src/mailman/styles/manager.py b/src/mailman/styles/manager.py
index e9682d7c5..fb7c54efd 100644
--- a/src/mailman/styles/manager.py
+++ b/src/mailman/styles/manager.py
@@ -33,6 +33,7 @@ from zope.interface.verify import verifyObject
from mailman.interfaces.styles import (
DuplicateStyleError, IStyle, IStyleManager)
+from mailman.utilities.modules import call_name
@@ -52,9 +53,7 @@ class StyleManager:
# Install all the styles described by the configuration files.
for section in config.style_configs:
class_path = section['class']
- package, dot, class_name = class_path.rpartition('.')
- __import__(package)
- style = getattr(sys.modules[package], class_name)()
+ style = call_name(class_path)
assert section.name.startswith('style'), (
'Bad style section name: %s' % section.name)
style.name = section.name[6:]
diff --git a/src/mailman/utilities/modules.py b/src/mailman/utilities/modules.py
new file mode 100644
index 000000000..bcee3f39e
--- /dev/null
+++ b/src/mailman/utilities/modules.py
@@ -0,0 +1,59 @@
+# Copyright (C) 2009 by the Free Software Foundation, Inc.
+#
+# This file is part of GNU Mailman.
+#
+# GNU Mailman is free software: you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option)
+# any later version.
+#
+# GNU Mailman is distributed in the hope that it will be useful, 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
+# GNU Mailman. If not, see <http://www.gnu.org/licenses/>.
+
+"""Package and module utilities."""
+
+from __future__ import absolute_import, unicode_literals
+
+__metaclass__ = type
+__all__ = [
+ 'call_name'
+ 'find_name',
+ ]
+
+
+import sys
+
+
+
+def find_name(dotted_name):
+ """Import and return the named object in package space.
+
+ :param dotted_name: The dotted module path name to the object.
+ :type dotted_name: string
+ :return: The object.
+ :rtype: object
+ """
+ package_path, dot, object_name = dotted_name.rpartition('.')
+ __import__(package_path)
+ return getattr(sys.modules[package_path], object_name)
+
+
+def call_name(dotted_name, *args, **kws):
+ """Imports and calls the named object in package space.
+
+ :param dotted_name: The dotted module path name to the object.
+ :type dotted_name: string
+ :param args: The positional arguments.
+ :type args: tuple
+ :param kws: The keyword arguments.
+ :type kws: dict
+ :return: The object.
+ :rtype: object
+ """
+ named_callable = find_name(dotted_name)
+ return named_callable(*args, **kws)