------------------------------------------------------------
revno: 6665
committer: Barry Warsaw <[email protected]>
branch nick: configs
timestamp: Mon 2009-01-05 00:54:19 -0500
message:
  Defaults module is mostly eradicated, converted to lazr.config.  The test
  suite does not yet work though.
added:
  mailman/styles/
  mailman/styles/__init__.py
renamed:
  mailman/Defaults.py => mailman/attic/Defaults.py
  mailman/core/styles.py => mailman/styles/default.py
modified:
  buildout.cfg
  mailman/Mailbox.py
  mailman/Message.py
  mailman/Utils.py
  mailman/app/lifecycle.py
  mailman/app/notifications.py
  mailman/app/replybot.py
  mailman/bin/master.py
  mailman/config/__init__.py
  mailman/config/config.py
  mailman/config/mailman.cfg
  mailman/config/schema.cfg
  mailman/database/mailinglist.py
  mailman/database/pending.py
  mailman/pipeline/cleanse_dkim.py
  mailman/pipeline/scrubber.py
  mailman/pipeline/smtp_direct.py
  mailman/pipeline/to_digest.py
  mailman/pipeline/to_outgoing.py
  mailman/queue/__init__.py
  mailman/testing/layers.py
  setup.py
  mailman/styles/default.py

=== modified file 'buildout.cfg'
--- a/buildout.cfg      2009-01-05 00:41:05 +0000
+++ b/buildout.cfg      2009-01-05 05:54:19 +0000
@@ -5,7 +5,7 @@
     test
 unzip = true
 # bzr branch lp:~barry/lazr.config/megamerge
-develop = . /home/barry/projects/lazr/megamerge
+develop = . /Users/barry/projects/lazr/megamerge
 
 [interpreter]
 recipe = zc.recipe.egg

=== modified file 'mailman/Mailbox.py'
--- a/mailman/Mailbox.py        2009-01-05 00:41:05 +0000
+++ b/mailman/Mailbox.py        2009-01-05 05:54:19 +0000
@@ -25,7 +25,6 @@
 from email.Errors import MessageParseError
 from email.Generator import Generator
 
-from mailman import Defaults
 from mailman.Message import Message
 
 
@@ -90,7 +89,7 @@
     # scrub() method, giving the scrubber module a chance to do its thing
     # before the message is archived.
     def __init__(self, fp, mlist):
-        scrubber_module = Defaults.ARCHIVE_SCRUBBER
+        scrubber_module = config.scrubber.archive_scrubber
         if scrubber_module:
             __import__(scrubber_module)
             self._scrubber = sys.modules[scrubber_module].process

=== modified file 'mailman/Message.py'
--- a/mailman/Message.py        2009-01-01 22:16:51 +0000
+++ b/mailman/Message.py        2009-01-05 05:54:19 +0000
@@ -17,8 +17,8 @@
 
 """Standard Mailman message object.
 
-This is a subclass of mimeo.Message but provides a slightly extended interface
-which is more convenient for use inside Mailman.
+This is a subclass of email.message.Message but provides a slightly extended
+interface which is more convenient for use inside Mailman.
 """
 
 import re
@@ -28,15 +28,15 @@
 
 from email.charset import Charset
 from email.header import Header
+from lazr.config import as_boolean
 
-from mailman import Defaults
 from mailman import Utils
 from mailman.config import config
 
 COMMASPACE = ', '
 
 mo = re.match(r'([\d.]+)', email.__version__)
-VERSION = tuple([int(s) for s in mo.group().split('.')])
+VERSION = tuple(int(s) for s in mo.group().split('.'))
 
 
 
@@ -111,7 +111,7 @@
             self._headers = headers
 
     # I think this method ought to eventually be deprecated
-    def get_sender(self, use_envelope=None, preserve_case=0):
+    def get_sender(self):
         """Return the address considered to be the author of the email.
 
         This can return either the From: header, the Sender: header or the
@@ -124,20 +124,13 @@
 
         - Otherwise, the search order is From:, Sender:, unixfrom
 
-        The optional argument use_envelope, if given overrides the
-        config.mailman.use_envelope_sender setting.  It should be set to
-        either True or False (don't use None since that indicates
-        no-override).
-
         unixfrom should never be empty.  The return address is always
-        lowercased, unless preserve_case is true.
+        lower cased.
 
         This method differs from get_senders() in that it returns one and only
         one address, and uses a different search order.
         """
-        senderfirst = config.mailman.use_envelope_sender
-        if use_envelope is not None:
-            senderfirst = use_envelope
+        senderfirst = as_boolean(config.mailman.use_envelope_sender)
         if senderfirst:
             headers = ('sender', 'from')
         else:
@@ -166,46 +159,41 @@
             else:
                 # TBD: now what?!
                 address = ''
-        if not preserve_case:
-            return address.lower()
-        return address
+        return address.lower()
 
-    def get_senders(self, preserve_case=0, headers=None):
+    def get_senders(self):
         """Return a list of addresses representing the author of the email.
 
         The list will contain the following addresses (in order)
         depending on availability:
 
         1. From:
-        2. unixfrom
+        2. unixfrom (From_)
         3. Reply-To:
         4. Sender:
 
-        The return addresses are always lower cased, unless `preserve_case' is
-        true.  Optional `headers' gives an alternative search order, with None
-        meaning, search the unixfrom header.  Items in `headers' are field
-        names without the trailing colon.
+        The return addresses are always lower cased.
         """
-        if headers is None:
-            headers = Defaults.SENDER_HEADERS
         pairs = []
-        for h in headers:
-            if h is None:
+        for header in config.mailman.sender_headers.split():
+            header = header.lower()
+            if header == 'from_':
                 # get_unixfrom() returns None if there's no envelope
-                fieldval = self.get_unixfrom() or ''
+                unix_from = self.get_unixfrom()
+                fieldval = (unix_from if unix_from is not None else '')
                 try:
                     pairs.append(('', fieldval.split()[1]))
                 except IndexError:
                     # Ignore badly formatted unixfroms
                     pass
             else:
-                fieldvals = self.get_all(h)
+                fieldvals = self.get_all(header)
                 if fieldvals:
                     pairs.extend(email.utils.getaddresses(fieldvals))
         authors = []
         for pair in pairs:
             address = pair[1]
-            if address is not None and not preserve_case:
+            if address is not None:
                 address = address.lower()
             authors.append(address)
         return authors

=== modified file 'mailman/Utils.py'
--- a/mailman/Utils.py  2009-01-05 00:41:05 +0000
+++ b/mailman/Utils.py  2009-01-05 05:54:19 +0000
@@ -35,11 +35,11 @@
 import email.Iterators
 
 from email.Errors import HeaderParseError
+from lazr.config import as_boolean
 from string import ascii_letters, digits, whitespace, Template
 
 import mailman.templates
 
-from mailman import Defaults
 from mailman import passwords
 from mailman.config import config
 from mailman.core import errors
@@ -318,8 +318,8 @@
 
 def MakeRandomPassword(length=None):
     if length is None:
-        length = Defaults.MEMBER_PASSWORD_LENGTH
-    if Defaults.USER_FRIENDLY_PASSWORDS:
+        length = int(config.member_password_length)
+    if as_boolean(config.user_friendly_passwords):
         password = UserFriendly_MakeRandomPassword(length)
     else:
         password = Secure_MakeRandomPassword(length)

=== modified file 'mailman/app/lifecycle.py'
--- a/mailman/app/lifecycle.py  2009-01-04 05:22:08 +0000
+++ b/mailman/app/lifecycle.py  2009-01-05 05:54:19 +0000
@@ -33,7 +33,6 @@
 from mailman.Utils import ValidateEmail
 from mailman.config import config
 from mailman.core import errors
-from mailman.core.styles import style_manager
 from mailman.interfaces.member import MemberRole
 
 
@@ -50,7 +49,7 @@
     if domain not in config.domains:
         raise errors.BadDomainSpecificationError(domain)
     mlist = config.db.list_manager.create(fqdn_listname)
-    for style in style_manager.lookup(mlist):
+    for style in config.style_manager.lookup(mlist):
         style.apply(mlist)
     # Coordinate with the MTA, as defined in the configuration file.
     module_name, class_name = config.mta.incoming.rsplit('.', 1)

=== modified file 'mailman/app/notifications.py'
--- a/mailman/app/notifications.py      2009-01-01 22:16:51 +0000
+++ b/mailman/app/notifications.py      2009-01-05 05:54:19 +0000
@@ -26,8 +26,8 @@
 
 
 from email.utils import formataddr
+from lazr.config import as_boolean
 
-from mailman import Defaults
 from mailman import Message
 from mailman import Utils
 from mailman import i18n
@@ -79,7 +79,7 @@
         _('Welcome to the "$mlist.real_name" mailing list${digmode}'),
         text, language)
     msg['X-No-Archive'] = 'yes'
-    msg.send(mlist, verp=Defaults.VERP_PERSONALIZED_DELIVERIES)
+    msg.send(mlist, verp=as_boolean(config.mta.verp_personalized_deliveries))
 
 
 
@@ -104,7 +104,7 @@
         address, mlist.bounces_address,
         _('You have been unsubscribed from the $mlist.real_name mailing list'),
         goodbye, language)
-    msg.send(mlist, verp=Defaults.VERP_PERSONALIZED_DELIVERIES)
+    msg.send(mlist, verp=as_boolean(config.mta.verp_personalized_deliveries))
 
 
 

=== modified file 'mailman/app/replybot.py'
--- a/mailman/app/replybot.py   2009-01-01 22:16:51 +0000
+++ b/mailman/app/replybot.py   2009-01-05 05:54:19 +0000
@@ -29,7 +29,6 @@
 import logging
 import datetime
 
-from mailman import Defaults
 from mailman import Utils
 from mailman import i18n
 
@@ -48,7 +47,8 @@
     """
     if lang is None:
         lang = mlist.preferred_language
-    if Defaults.MAX_AUTORESPONSES_PER_DAY == 0:
+    max_autoresponses_per_day = int(config.mta.max_autoresponses_per_day)
+    if max_autoresponses_per_day == 0:
         # Unlimited.
         return True
     today = datetime.date.today()
@@ -64,7 +64,7 @@
         # them of this fact, so there's nothing more to do.
         log.info('-request/hold autoresponse discarded for: %s', sender)
         return False
-    if count >= Defaults.MAX_AUTORESPONSES_PER_DAY:
+    if count >= max_autoresponses_per_day:
         log.info('-request/hold autoresponse limit hit for: %s', sender)
         mlist.hold_and_cmd_autoresponses[sender] = (today, -1)
         # Send this notification message instead.

=== renamed file 'mailman/Defaults.py' => 'mailman/attic/Defaults.py'
=== modified file 'mailman/bin/master.py'
--- a/mailman/bin/master.py     2009-01-01 22:16:51 +0000
+++ b/mailman/bin/master.py     2009-01-05 05:54:19 +0000
@@ -36,7 +36,6 @@
 from locknix import lockfile
 from munepy import Enum
 
-from mailman import Defaults
 from mailman.config import config
 from mailman.core.logging import reopen
 from mailman.i18n import _
@@ -44,7 +43,8 @@
 
 
 DOT = '.'
-LOCK_LIFETIME = Defaults.days(1) + Defaults.hours(6)
+LOCK_LIFETIME = timedelta(days=1, hours=6)
+SECONDS_IN_A_DAY = 86400
 
 
 
@@ -233,9 +233,9 @@
         # so this should be plenty.
         def sigalrm_handler(signum, frame):
             self._lock.refresh()
-            signal.alarm(int(Defaults.days(1)))
+            signal.alarm(SECONDS_IN_A_DAY)
         signal.signal(signal.SIGALRM, sigalrm_handler)
-        signal.alarm(int(Defaults.days(1)))
+        signal.alarm(SECONDS_IN_A_DAY)
         # SIGHUP tells the qrunners to close and reopen their log files.
         def sighup_handler(signum, frame):
             reopen()

=== modified file 'mailman/config/__init__.py'
--- a/mailman/config/__init__.py        2009-01-01 22:16:51 +0000
+++ b/mailman/config/__init__.py        2009-01-05 05:54:19 +0000
@@ -15,6 +15,12 @@
 # You should have received a copy of the GNU General Public License along with
 # GNU Mailman.  If not, see <http://www.gnu.org/licenses/>.
 
+__metaclass__ = type
+__all__ = [
+    'config',
+    ]
+
+
 from mailman.config.config import Configuration
 
 config = Configuration()

=== modified file 'mailman/config/config.py'
--- a/mailman/config/config.py  2009-01-03 10:13:41 +0000
+++ b/mailman/config/config.py  2009-01-05 05:54:19 +0000
@@ -32,11 +32,11 @@
 from lazr.config import ConfigSchema, as_boolean
 from pkg_resources import resource_string
 
-from mailman import Defaults
 from mailman import version
 from mailman.core import errors
 from mailman.domain import Domain
 from mailman.languages import LanguageManager
+from mailman.styles.manager import StyleManager
 
 
 SPACE = ' '
@@ -149,6 +149,7 @@
         # Always enable the server default language, which must be defined.
         self.languages.enable_language(self._config.mailman.default_language)
         self.ensure_directories_exist()
+        self.style_manager = StyleManager()
 
     @property
     def logger_configs(self):
@@ -189,6 +190,12 @@
             yield getattr(sys.modules[module_name], class_name)()
 
     @property
+    def style_configs(self):
+        """Iterate over all the style configuration sections."""
+        for section in self._config.getByCategory('style', []):
+            yield section
+
+    @property
     def header_matches(self):
         """Iterate over all spam matching headers.
 

=== modified file 'mailman/config/mailman.cfg'
--- a/mailman/config/mailman.cfg        2009-01-01 22:16:51 +0000
+++ b/mailman/config/mailman.cfg        2009-01-05 05:54:19 +0000
@@ -65,3 +65,5 @@
 
 [qrunner.virgin]
 class: mailman.queue.virgin.VirginRunner
+
+[style.default]

=== modified file 'mailman/config/schema.cfg'
--- a/mailman/config/schema.cfg 2009-01-03 14:21:50 +0000
+++ b/mailman/config/schema.cfg 2009-01-05 05:54:19 +0000
@@ -54,9 +54,37 @@
 # spoofed messages may get through.
 use_envelope_sender: no
 
+# Membership tests for posting purposes are usually performed by looking at a
+# set of headers, passing the test if any of their values match a member of
+# the list.  Headers are checked in the order given in this variable.  The
+# value From_ means to use the envelope sender.  Field names are case
+# insensitive.  This is a space separate list of headers.
+sender_headers: from from_ reply-to sender
+
 # Mail command processor will ignore mail command lines after designated max.
 email_commands_max_lines: 10
 
+# Default length of time a pending request is live before it is evicted from
+# the pending database.
+pending_request_life: 3d
+
+
+[passwords]
+# When Mailman generates them, this is the default length of member passwords.
+member_password_length: 8
+
+# Specify the type of passwords to use, when Mailman generates the passwords
+# itself, as would be the case for membership requests where the user did not
+# fill in a password, or during list creation, when auto-generation of admin
+# passwords was selected.
+#
+# Set this value to 'yes' for classic Mailman user-friendly(er) passwords.
+# These generate semi-pronounceable passwords which are easier to remember.
+# Set this value to 'no' to use more cryptographically secure, but harder to
+# remember, passwords -- if your operating system and Python version support
+# the necessary feature (specifically that /dev/urandom be available).
+user_friendly_passwords: yes
+
 
 [qrunner.master]
 # Define which process queue runners, and how many of them, to start.
@@ -248,6 +276,118 @@
 lmtp_host: localhost
 lmtp_port: 8025
 
+# Ceiling on the number of recipients that can be specified in a single SMTP
+# transaction.  Set to 0 to submit the entire recipient list in one
+# transaction.
+max_recipients: 500
+
+# Ceiling on the number of SMTP sessions to perform on a single socket
+# connection.  Some MTAs have limits.  Set this to 0 to do as many as we like
+# (i.e. your MTA has no limits).  Set this to some number great than 0 and
+# Mailman will close the SMTP connection and re-open it after this number of
+# consecutive sessions.
+max_sessions_per_connection: 0
+
+# Maximum number of simultaneous subthreads that will be used for SMTP
+# delivery.  After the recipients list is chunked according to max_recipients,
+# each chunk is handed off to the SMTP server by a separate such thread.  If
+# your Python interpreter was not built for threads, this feature is disabled.
+# You can explicitly disable it in all cases by setting max_delivery_threads
+# to 0.
+max_delivery_threads: 0
+
+# These variables control the format and frequency of VERP-like delivery for
+# better bounce detection.  VERP is Variable Envelope Return Path, defined
+# here:
+#
+# http://cr.yp.to/proto/verp.txt
+#
+# This involves encoding the address of the recipient as we (Mailman) know it
+# into the envelope sender address (i.e. the SMTP `MAIL FROM:' address).
+# Thus, no matter what kind of forwarding the recipient has in place, should
+# it eventually bounce, we will receive an unambiguous notice of the bouncing
+# address.
+#
+# However, we're technically only "VERP-like" because we're doing the envelope
+# sender encoding in Mailman, not in the MTA.  We do require cooperation from
+# the MTA, so you must be sure your MTA can be configured for extended address
+# semantics.
+#
+# The first variable describes how to encode VERP envelopes.  It must contain
+# these three string interpolations:
+#
+# $bounces -- the list-bounces mailbox will be set here
+# $mailbox -- the recipient's mailbox will be set here
+# $host    -- the recipient's host name will be set here
+#
+# This example uses the default below.
+#
+# FQDN list address is: [email protected]
+# Recipient is:         [email protected]
+#
+# The envelope sender will be [email protected]
+#
+# Note that your MTA /must/ be configured to deliver such an addressed message
+# to mylist-bounces!
+verp_delimiter: +
+verp_format: ${bounces}+${mailbox}=${host}
+
+# For nicer confirmation emails, use a VERP-like format which encodes the
+# confirmation cookie in the reply address.  This lets us put a more user
+# friendly Subject: on the message, but requires cooperation from the MTA.
+# Format is like verp_format, but with the following substitutions:
+#
+# $address  -- the list-confirm address
+# $cookie   -- the confirmation cookie
+verp_confirm_format: $address+$cookie
+
+# This is analogous to verp_regexp, but for splitting apart the
+# verp_confirm_format.  MUAs have been observed that mung
+#
+# From: local_p...@host
+#
+# into
+#
+# To: "local_part" <local_p...@host>
+#
+# when replying, so we skip everything up to '<' if any.
+verp_confirm_regexp: ^(.*<)?(?P<addr>[^+]+?)\+(?P<cookie>[...@]+)@.*$
+
+# Set this to 'yes' to enable VERP-like (more user friendly) confirmations.
+verp_confirmations: no
+
+# Another good opportunity is when regular delivery is personalized.  Here
+# again, we're already incurring the performance hit for addressing each
+# individual recipient.  Set this to 'yes' to enable VERPs on all personalized
+# regular deliveries (personalized digests aren't supported yet).
+verp_personalized_deliveries: no
+
+# And finally, we can VERP normal, non-personalized deliveries.  However,
+# because it can be a significant performance hit, we allow you to decide how
+# often to VERP regular deliveries.  This is the interval, in number of
+# messages, to do a VERP recipient address.  The same variable controls both
+# regular and digest deliveries.  Set to 0 to disable occasional VERPs, set to
+# 1 to VERP every delivery, or to some number > 1 for only occasional VERPs.
+verp_delivery_interval: 0
+
+# This is the maximum number of automatic responses sent to an address because
+# of -request messages or posting hold messages.  This limit prevents response
+# loops between Mailman and misconfigured remote email robots.  Mailman
+# already inhibits automatic replies to any message labeled with a header
+# "Precendence: bulk|list|junk".  This is a fallback safety valve so it should
+# be set fairly high.  Set to 0 for no limit (probably useful only for
+# debugging).
+max_autoresponses_per_day: 10
+
+# Some list posts and mail to the -owner address may contain DomainKey or
+# DomainKeys Identified Mail (DKIM) signature headers <http://www.dkim.org/>.
+# Various list transformations to the message such as adding a list header or
+# footer or scrubbing attachments or even reply-to munging can break these
+# signatures.  It is generally felt that these signatures have value, even if
+# broken and even if the outgoing message is resigned.  However, some sites
+# may wish to remove these headers by setting this to 'yes'.
+remove_dkim_headers: no
+
 
 [archiver.master]
 # To add new archivers, define a new section based on this one, overriding the
@@ -287,3 +427,81 @@
 [archiver.prototype]
 # This is a prototypical sample archiver.
 class: mailman.archiving.prototype.Prototype
+
+
+[style.master]
+# The style's priority, with 0 being the lowest priority.
+priority: 0
+
+# The class implementing the IStyle interface, which applies the style.
+class: mailman.styles.default.DefaultStyle
+
+
+[scrubber]
+# A filter module that converts from multipart messages to "flat" messages
+# (i.e. containing a single payload).  This is required for Pipermail, and you
+# may want to set it to 0 for external archivers.  You can also replace it
+# with your own module as long as it contains a process() function that takes
+# a MailList object and a Message object.  It should raise
+# Errors.DiscardMessage if it wants to throw the message away.  Otherwise it
+# should modify the Message object as necessary.
+archive_scrubber: mailman.pipeline.scrubber
+
+# This variable defines what happens to text/html subparts.  They can be
+# stripped completely, escaped, or filtered through an external program.  The
+# legal values are:
+# 0 - Strip out text/html parts completely, leaving a notice of the removal in
+#     the message.  If the outer part is text/html, the entire message is
+#     discarded.
+# 1 - Remove any embedded text/html parts, leaving them as HTML-escaped
+#     attachments which can be separately viewed.  Outer text/html parts are
+#     simply HTML-escaped.
+# 2 - Leave it inline, but HTML-escape it
+# 3 - Remove text/html as attachments but don't HTML-escape them. Note: this
+#     is very dangerous because it essentially means anybody can send an HTML
+#     email to your site containing evil JavaScript or web bugs, or other
+#     nasty things, and folks viewing your archives will be susceptible.  You
+#     should only consider this option if you do heavy moderation of your list
+#     postings.
+#
+# Note: given the current archiving code, it is not possible to leave
+# text/html parts inline and un-escaped.  I wouldn't think it'd be a good idea
+# to do anyway.
+#
+# The value can also be a string, in which case it is the name of a command to
+# filter the HTML page through.  The resulting output is left in an attachment
+# or as the entirety of the message when the outer part is text/html.  The
+# format of the string must include a $filename substitution variable which
+# will contain the name of the temporary file that the program should operate
+# on.  It should write the processed message to stdout.  Set this to
+# HTML_TO_PLAIN_TEXT_COMMAND to specify an HTML to plain text conversion
+# program.
+archive_html_sanitizer: 1
+
+# Control parameter whether the scrubber should use the message attachment's
+# filename as is indicated by the filename parameter or use 'attachement-xxx'
+# instead.  The default is set 'no' because the applications on PC and Mac
+# begin to use longer non-ascii filenames.
+use_attachment_filename: no
+
+# Use of attachment filename extension per se is may be dangerous because
+# viruses fakes it.  You can set this 'yes' if you filter the attachment by
+# filename extension.
+use_attachment_filename_extension: no
+
+
+[digests]
+# Headers which should be kept in both RFC 1153 (plain) and MIME digests.  RFC
+# 1153 also specifies these headers in this exact order, so order matters.
+# These are space separated and case insensitive.
+mime_digest_keep_headers:
+    Date From To Cc Subject Message-ID Keywords
+    In-Reply-To References Content-Type MIME-Version
+    Content-Transfer-Encoding Precedence Reply-To
+    Message
+
+plain_digest_keep_headers:
+    Message Date From
+    Subject To Cc
+    Message-ID Keywords
+    Content-Type

=== modified file 'mailman/database/mailinglist.py'
--- a/mailman/database/mailinglist.py   2009-01-04 05:22:08 +0000
+++ b/mailman/database/mailinglist.py   2009-01-05 05:54:19 +0000
@@ -22,7 +22,6 @@
 from urlparse import urljoin
 from zope.interface import implements
 
-from mailman import Defaults
 from mailman.Utils import fqdn_listname, makedirs, split_listname
 from mailman.config import config
 from mailman.database import roster
@@ -206,8 +205,7 @@
         domain = config.domains[self.host_name]
         # XXX Handle the case for when context is not None; those would be
         # relative URLs.
-        return urljoin(domain.base_url,
-                       target + Defaults.CGIEXT + '/' + self.fqdn_listname)
+        return urljoin(domain.base_url, target + '/' + self.fqdn_listname)
 
     @property
     def data_path(self):
@@ -253,7 +251,7 @@
         return '%s-unsubscr...@%s' % (self.list_name, self.host_name)
 
     def confirm_address(self, cookie):
-        template = string.Template(Defaults.VERP_CONFIRM_FORMAT)
+        template = string.Template(config.mta.verp_confirm_format)
         local_part = template.safe_substitute(
             address = '%s-confirm' % self.list_name,
             cookie  = cookie)

=== modified file 'mailman/database/pending.py'
--- a/mailman/database/pending.py       2009-01-05 00:41:05 +0000
+++ b/mailman/database/pending.py       2009-01-05 05:54:19 +0000
@@ -29,11 +29,11 @@
 import hashlib
 import datetime
 
+from lazr.config import as_timedelta
 from storm.locals import *
 from zope.interface import implements
 from zope.interface.verify import verifyObject
 
-from mailman import Defaults
 from mailman.config import config
 from mailman.database.model import Model
 from mailman.interfaces.pending import (
@@ -87,7 +87,7 @@
         verifyObject(IPendable, pendable)
         # Calculate the token and the lifetime.
         if lifetime is None:
-            lifetime = Defaults.PENDING_REQUEST_LIFE
+            lifetime = as_timedelta(config.pending_request_life)
         # Calculate a unique token.  Algorithm vetted by the Timbot.  time()
         # has high resolution on Linux, clock() on Windows.  random gives us
         # about 45 bits in Python 2.2, 53 bits on Python 2.3.  The time and

=== modified file 'mailman/pipeline/cleanse_dkim.py'
--- a/mailman/pipeline/cleanse_dkim.py  2009-01-04 05:22:08 +0000
+++ b/mailman/pipeline/cleanse_dkim.py  2009-01-05 05:54:19 +0000
@@ -26,12 +26,14 @@
 """
 
 __metaclass__ = type
-__all__ = ['CleanseDKIM']
-
-
+__all__ = [
+    'CleanseDKIM',
+    ]
+
+
+from lazr.config import as_boolean
 from zope.interface import implements
 
-from mailman import Defaults
 from mailman.i18n import _
 from mailman.interfaces.handler import IHandler
 
@@ -47,7 +49,7 @@
 
     def process(self, mlist, msg, msgdata):
         """See `IHandler`."""
-        if Defaults.REMOVE_DKIM_HEADERS:
+        if as_boolean(config.mta.remove_dkim_headers):
             del msg['domainkey-signature']
             del msg['dkim-signature']
             del msg['authentication-results']

=== modified file 'mailman/pipeline/scrubber.py'
--- a/mailman/pipeline/scrubber.py      2009-01-04 05:22:08 +0000
+++ b/mailman/pipeline/scrubber.py      2009-01-05 05:54:19 +0000
@@ -34,11 +34,12 @@
 from email.charset import Charset
 from email.generator import Generator
 from email.utils import make_msgid, parsedate
+from lazr.config import as_boolean
 from locknix.lockfile import Lock
 from mimetypes import guess_all_extensions
+from string import Template
 from zope.interface import implements
 
-from mailman import Defaults
 from mailman import Utils
 from mailman.config import config
 from mailman.core.errors import DiscardMessage
@@ -159,7 +160,7 @@
 
 
 def process(mlist, msg, msgdata=None):
-    sanitize = Defaults.ARCHIVE_HTML_SANITIZER
+    sanitize = int(config.scrubber.archive_html_sanitizer)
     outer = True
     if msgdata is None:
         msgdata = {}
@@ -410,7 +411,7 @@
     filename, fnext = os.path.splitext(filename)
     # For safety, we should confirm this is valid ext for content-type
     # but we can use fnext if we introduce fnext filtering
-    if Defaults.SCRUBBER_USE_ATTACHMENT_FILENAME_EXTENSION:
+    if as_boolean(config.scrubber.use_attachment_filename_extension):
         # HTML message doesn't have filename :-(
         ext = fnext or guess_extension(ctype, fnext)
     else:
@@ -431,7 +432,8 @@
     with Lock(os.path.join(fsdir, 'attachments.lock')):
         # Now base the filename on what's in the attachment, uniquifying it if
         # necessary.
-        if not filename or Defaults.SCRUBBER_DONT_USE_ATTACHMENT_FILENAME:
+        if (not filename or
+            not as_boolean(config.scrubber.use_attachment_filename)):
             filebase = 'attachment'
         else:
             # Sanitize the filename given in the message headers
@@ -476,7 +478,8 @@
         try:
             fp.write(decodedpayload)
             fp.close()
-            cmd = Defaults.ARCHIVE_HTML_SANITIZER % {'filename' : tmppath}
+            cmd = Template(config.mta.archive_html_sanitizer).safe_substitue(
+                filename=tmppath)
             progfp = os.popen(cmd, 'r')
             decodedpayload = progfp.read()
             status = progfp.close()

=== modified file 'mailman/pipeline/smtp_direct.py'
--- a/mailman/pipeline/smtp_direct.py   2009-01-05 00:41:05 +0000
+++ b/mailman/pipeline/smtp_direct.py   2009-01-05 05:54:19 +0000
@@ -44,7 +44,6 @@
 from string import Template
 from zope.interface import implements
 
-from mailman import Defaults
 from mailman import Utils
 from mailman.config import config
 from mailman.core import errors
@@ -70,7 +69,7 @@
         port = int(config.mta.smtp_port)
         log.debug('Connecting to %s:%s', host, port)
         self.__conn.connect(host, port)
-        self.__numsessions = Defaults.SMTP_MAX_SESSIONS_PER_CONNECTION
+        self.__numsessions = int(config.mta.max_sessions_per_connection)
 
     def sendmail(self, envsender, recips, msgtext):
         if self.__conn is None:
@@ -126,10 +125,10 @@
         chunks = [[recip] for recip in recips]
         msgdata['personalize'] = 1
         deliveryfunc = verpdeliver
-    elif Defaults.SMTP_MAX_RCPTS <= 0:
+    elif int(config.mta.max_recipients) <= 0:
         chunks = [recips]
     else:
-        chunks = chunkify(recips, Defaults.SMTP_MAX_RCPTS)
+        chunks = chunkify(recips, int(config.mta.max_recipients))
     # See if this is an unshunted message for which some were undelivered
     if msgdata.has_key('undelivered'):
         chunks = msgdata['undelivered']
@@ -316,12 +315,9 @@
                 # this recipient.
                 log.info('Skipping VERP delivery to unqual recip: %s', recip)
                 continue
-            d = {'bounces': bmailbox,
-                 'mailbox': rmailbox,
-                 'host'   : DOT.join(rdomain),
-                 }
-            envsender = '%...@%s' % ((Defaults.VERP_FORMAT % d),
-                                   DOT.join(bdomain))
+            envsender = Template(config.mta.verp_format).safe_substitute(
+                bounces=bmailbox, mailbox=rmailbox,
+                host=DOT.join(rdomain)) + '@' + DOT.join(bdomain)
         if mlist.personalize == Personalization.full:
             # When fully personalizing, we want the To address to point to the
             # recipient, not to the mailing list

=== modified file 'mailman/pipeline/to_digest.py'
--- a/mailman/pipeline/to_digest.py     2009-01-04 05:22:08 +0000
+++ b/mailman/pipeline/to_digest.py     2009-01-05 05:54:19 +0000
@@ -48,7 +48,6 @@
 from email.utils import formatdate, getaddresses, make_msgid
 from zope.interface import implements
 
-from mailman import Defaults
 from mailman import Message
 from mailman import Utils
 from mailman import i18n
@@ -268,11 +267,10 @@
         # headers according to RFC 1153.  Later, we'll strip out headers for
         # for the specific MIME or plain digests.
         keeper = {}
-        all_keepers = {}
-        for header in (Defaults.MIME_DIGEST_KEEP_HEADERS +
-                       Defaults.PLAIN_DIGEST_KEEP_HEADERS):
-            all_keepers[header] = True
-        all_keepers = all_keepers.keys()
+        all_keepers = set(
+            header for header in
+            config.digests.mime_digest_keep_headers.split() +
+            config.digests.plain_digest_keep_headers.split())
         for keep in all_keepers:
             keeper[keep] = msg.get_all(keep, [])
         # Now remove all unkempt headers :)
@@ -283,7 +281,7 @@
             for field in keeper[keep]:
                 msg[keep] = field
         # And a bit of extra stuff
-        msg['Message'] = `msgcount`
+        msg['Message'] = repr(msgcount)
         # Get the next message in the digest mailbox
         msg = mbox.next()
     # Now we're finished with all the messages in the digest.  First do some
@@ -326,7 +324,7 @@
             print >> plainmsg, _('[Message discarded by content filter]')
             continue
         # Honor the default setting
-        for h in Defaults.PLAIN_DIGEST_KEEP_HEADERS:
+        for h in config.digests.plain_digest_keep_headers.split():
             if msg[h]:
                 uh = Utils.wrap('%s: %s' % (h, Utils.oneline(msg[h],
                                                              in_unicode=True)))

=== modified file 'mailman/pipeline/to_outgoing.py'
--- a/mailman/pipeline/to_outgoing.py   2009-01-04 05:22:08 +0000
+++ b/mailman/pipeline/to_outgoing.py   2009-01-05 05:54:19 +0000
@@ -23,12 +23,14 @@
 """
 
 __metaclass__ = type
-__all__ = ['ToOutgoing']
-
-
+__all__ = [
+    'ToOutgoing',
+    ]
+
+
+from lazr.config import as_boolean
 from zope.interface import implements
 
-from mailman import Defaults
 from mailman.config import config
 from mailman.i18n import _
 from mailman.interfaces.handler import IHandler
@@ -46,7 +48,7 @@
 
     def process(self, mlist, msg, msgdata):
         """See `IHandler`."""
-        interval = Defaults.VERP_DELIVERY_INTERVAL
+        interval = int(config.mta.verp_delivery_interval)
         # Should we VERP this message?  If personalization is enabled for this
         # list and VERP_PERSONALIZED_DELIVERIES is true, then yes we VERP it.
         # Also, if personalization is /not/ enabled, but
@@ -58,7 +60,7 @@
         if 'verp' in  msgdata:
             pass
         elif mlist.personalize <> Personalization.none:
-            if Defaults.VERP_PERSONALIZED_DELIVERIES:
+            if as_boolean(config.mta.verp_personalized_deliveries):
                 msgdata['verp'] = True
         elif interval == 0:
             # Never VERP

=== modified file 'mailman/queue/__init__.py'
--- a/mailman/queue/__init__.py 2009-01-04 21:55:59 +0000
+++ b/mailman/queue/__init__.py 2009-01-05 05:54:19 +0000
@@ -298,7 +298,7 @@
         # sleep_time is a timedelta; turn it into a float for time.sleep().
         self.sleep_float = (86400 * self.sleep_time.days +
                             self.sleep_time.seconds +
-                            self.sleep_time.microseconds / 1000000.0)
+                            self.sleep_time.microseconds / 1.0e6)
         self.max_restarts = int(section.max_restarts)
         self.start = as_boolean(section.start)
         self._stop = False

=== added directory 'mailman/styles'
=== added file 'mailman/styles/__init__.py'
=== renamed file 'mailman/core/styles.py' => 'mailman/styles/default.py'
--- a/mailman/core/styles.py    2009-01-05 00:41:05 +0000
+++ b/mailman/styles/default.py 2009-01-05 05:54:19 +0000
@@ -20,25 +20,19 @@
 __metaclass__ = type
 __all__ = [
     'DefaultStyle',
-    'style_manager',
     ]
 
 # XXX Styles need to be reconciled with lazr.config.
 
 import datetime
 
-from operator import attrgetter
 from zope.interface import implements
-from zope.interface.verify import verifyObject
 
-from mailman import Defaults
 from mailman import Utils
-from mailman.core.plugins import get_plugins
 from mailman.i18n import _
 from mailman.interfaces import Action, NewsModeration
-from mailman.interfaces.mailinglist import Personalization
-from mailman.interfaces.styles import (
-    DuplicateStyleError, IStyle, IStyleManager)
+from mailman.interfaces.mailinglist import Personalization, ReplyToMunging
+from mailman.interfaces.styles import IStyle
 
 
 
@@ -57,77 +51,84 @@
         # Most of these were ripped from the old MailList.InitVars() method.
         mlist.volume = 1
         mlist.post_id = 1
-        mlist.new_member_options = Defaults.DEFAULT_NEW_MEMBER_OPTIONS
+        mlist.new_member_options = 256
         # This stuff is configurable
         mlist.real_name = mlist.list_name.capitalize()
         mlist.respond_to_post_requests = True
-        mlist.advertised = Defaults.DEFAULT_LIST_ADVERTISED
-        mlist.max_num_recipients = Defaults.DEFAULT_MAX_NUM_RECIPIENTS
-        mlist.max_message_size = Defaults.DEFAULT_MAX_MESSAGE_SIZE
-        mlist.reply_goes_to_list = Defaults.DEFAULT_REPLY_GOES_TO_LIST
+        mlist.advertised = True
+        mlist.max_num_recipients = 10
+        mlist.max_message_size = 40 # KB
+        mlist.reply_goes_to_list = ReplyToMunging.no_munging
         mlist.reply_to_address = u''
-        mlist.first_strip_reply_to = Defaults.DEFAULT_FIRST_STRIP_REPLY_TO
-        mlist.admin_immed_notify = Defaults.DEFAULT_ADMIN_IMMED_NOTIFY
-        mlist.admin_notify_mchanges = (
-            Defaults.DEFAULT_ADMIN_NOTIFY_MCHANGES)
-        mlist.require_explicit_destination = (
-            Defaults.DEFAULT_REQUIRE_EXPLICIT_DESTINATION)
-        mlist.acceptable_aliases = Defaults.DEFAULT_ACCEPTABLE_ALIASES
-        mlist.send_reminders = Defaults.DEFAULT_SEND_REMINDERS
-        mlist.send_welcome_msg = Defaults.DEFAULT_SEND_WELCOME_MSG
-        mlist.send_goodbye_msg = Defaults.DEFAULT_SEND_GOODBYE_MSG
-        mlist.bounce_matching_headers = (
-            Defaults.DEFAULT_BOUNCE_MATCHING_HEADERS)
+        mlist.first_strip_reply_to = False
+        mlist.admin_immed_notify = True
+        mlist.admin_notify_mchanges = False
+        mlist.require_explicit_destination = True
+        mlist.acceptable_aliases = u''
+        mlist.send_reminders = True
+        mlist.send_welcome_msg = True
+        mlist.send_goodbye_msg = True
+        mlist.bounce_matching_headers = u"""
+# Lines that *start* with a '#' are comments.
+to: [email protected]
+message-id: relay.comanche.denmark.eu
+from: [email protected]
+from: [email protected]
+"""
         mlist.header_matches = []
-        mlist.anonymous_list = Defaults.DEFAULT_ANONYMOUS_LIST
+        mlist.anonymous_list = False
         mlist.description = u''
         mlist.info = u''
         mlist.welcome_msg = u''
         mlist.goodbye_msg = u''
-        mlist.subscribe_policy = Defaults.DEFAULT_SUBSCRIBE_POLICY
-        mlist.subscribe_auto_approval = (
-            Defaults.DEFAULT_SUBSCRIBE_AUTO_APPROVAL)
-        mlist.unsubscribe_policy = Defaults.DEFAULT_UNSUBSCRIBE_POLICY
-        mlist.private_roster = Defaults.DEFAULT_PRIVATE_ROSTER
-        mlist.obscure_addresses = Defaults.DEFAULT_OBSCURE_ADDRESSES
-        mlist.admin_member_chunksize = Defaults.DEFAULT_ADMIN_MEMBER_CHUNKSIZE
-        mlist.administrivia = Defaults.DEFAULT_ADMINISTRIVIA
-        mlist.preferred_language = Defaults.DEFAULT_SERVER_LANGUAGE
+        mlist.subscribe_policy = 1
+        mlist.subscribe_auto_approval = []
+        mlist.unsubscribe_policy = 0
+        mlist.private_roster = 1
+        mlist.obscure_addresses = True
+        mlist.admin_member_chunksize = 30
+        mlist.administrivia = True
+        mlist.preferred_language = u'en'
         mlist.include_rfc2369_headers = True
         mlist.include_list_post_header = True
-        mlist.filter_mime_types = Defaults.DEFAULT_FILTER_MIME_TYPES
-        mlist.pass_mime_types = Defaults.DEFAULT_PASS_MIME_TYPES
-        mlist.filter_filename_extensions = (
-            Defaults.DEFAULT_FILTER_FILENAME_EXTENSIONS)
-        mlist.pass_filename_extensions = (
-            Defaults.DEFAULT_PASS_FILENAME_EXTENSIONS)
-        mlist.filter_content = Defaults.DEFAULT_FILTER_CONTENT
-        mlist.collapse_alternatives = Defaults.DEFAULT_COLLAPSE_ALTERNATIVES
-        mlist.convert_html_to_plaintext = (
-            Defaults.DEFAULT_CONVERT_HTML_TO_PLAINTEXT)
-        mlist.filter_action = Defaults.DEFAULT_FILTER_ACTION
+        mlist.filter_mime_types = []
+        mlist.pass_mime_types = [
+            'multipart/mixed',
+            'multipart/alternative',
+            'text/plain',
+            ]
+        mlist.filter_filename_extensions = [
+            'exe', 'bat', 'cmd', 'com', 'pif', 'scr', 'vbs', 'cpl',
+            ]
+        mlist.pass_filename_extensions = []
+        mlist.filter_content = False
+        mlist.collapse_alternatives = True
+        mlist.convert_html_to_plaintext = True
+        mlist.filter_action = 0
         # Digest related variables
-        mlist.digestable = Defaults.DEFAULT_DIGESTABLE
-        mlist.digest_is_default = Defaults.DEFAULT_DIGEST_IS_DEFAULT
-        mlist.mime_is_default_digest = Defaults.DEFAULT_MIME_IS_DEFAULT_DIGEST
-        mlist.digest_size_threshold = Defaults.DEFAULT_DIGEST_SIZE_THRESHOLD
-        mlist.digest_send_periodic = Defaults.DEFAULT_DIGEST_SEND_PERIODIC
-        mlist.digest_header = Defaults.DEFAULT_DIGEST_HEADER
-        mlist.digest_footer = Defaults.DEFAULT_DIGEST_FOOTER
-        mlist.digest_volume_frequency = (
-            Defaults.DEFAULT_DIGEST_VOLUME_FREQUENCY)
+        mlist.digestable = True
+        mlist.digest_is_default = False
+        mlist.mime_is_default_digest = False
+        mlist.digest_size_threshold = 30 # KB
+        mlist.digest_send_periodic = True
+        mlist.digest_header = u''
+        mlist.digest_footer = u"""\
+_______________________________________________
+$real_name mailing list
+$fqdn_listname
+${listinfo_page}
+"""
+        mlist.digest_volume_frequency = 1
         mlist.one_last_digest = {}
         mlist.next_digest_number = 1
-        mlist.nondigestable = Defaults.DEFAULT_NONDIGESTABLE
+        mlist.nondigestable = True
         mlist.personalize = Personalization.none
         # New sender-centric moderation (privacy) options
-        mlist.default_member_moderation = (
-            Defaults.DEFAULT_DEFAULT_MEMBER_MODERATION)
+        mlist.default_member_moderation = False
         # Archiver
-        mlist.archive = Defaults.DEFAULT_ARCHIVE
-        mlist.archive_private = Defaults.DEFAULT_ARCHIVE_PRIVATE
-        mlist.archive_volume_frequency = (
-            Defaults.DEFAULT_ARCHIVE_VOLUME_FREQUENCY)
+        mlist.archive = True
+        mlist.archive_private = 0
+        mlist.archive_volume_frequency = 1
         mlist.emergency = False
         mlist.member_moderation_action = Action.hold
         mlist.member_moderation_notice = u''
@@ -135,9 +136,8 @@
         mlist.hold_these_nonmembers = []
         mlist.reject_these_nonmembers = []
         mlist.discard_these_nonmembers = []
-        mlist.forward_auto_discards = Defaults.DEFAULT_FORWARD_AUTO_DISCARDS
-        mlist.generic_nonmember_action = (
-            Defaults.DEFAULT_GENERIC_NONMEMBER_ACTION)
+        mlist.forward_auto_discards = True
+        mlist.generic_nonmember_action = 1
         mlist.nonmember_rejection_notice = u''
         # Ban lists
         mlist.ban_list = []
@@ -145,9 +145,14 @@
         # 2-tuple of the date of the last autoresponse and the number of
         # autoresponses sent on that date.
         mlist.hold_and_cmd_autoresponses = {}
-        mlist.subject_prefix = _(Defaults.DEFAULT_SUBJECT_PREFIX)
-        mlist.msg_header = Defaults.DEFAULT_MSG_HEADER
-        mlist.msg_footer = Defaults.DEFAULT_MSG_FOOTER
+        mlist.subject_prefix = _(u'[$mlist.real_name] ')
+        mlist.msg_header = u''
+        mlist.msg_footer = u"""\
+_______________________________________________
+$real_name mailing list
+$fqdn_listname
+${listinfo_page}
+"""
         # Set this to Never if the list's preferred language uses us-ascii,
         # otherwise set it to As Needed
         if Utils.GetCharSet(mlist.preferred_language) == 'us-ascii':
@@ -155,9 +160,9 @@
         else:
             mlist.encode_ascii_prefixes = 2
         # scrub regular delivery
-        mlist.scrub_nondigest = Defaults.DEFAULT_SCRUB_NONDIGEST
+        mlist.scrub_nondigest = False
         # automatic discarding
-        mlist.max_days_to_hold = Defaults.DEFAULT_MAX_DAYS_TO_HOLD
+        mlist.max_days_to_hold = 0
         # Autoresponder
         mlist.autorespond_postings = False
         mlist.autorespond_admin = False
@@ -174,20 +179,15 @@
         mlist.admin_responses = {}
         mlist.request_responses = {}
         # Bounces
-        mlist.bounce_processing = Defaults.DEFAULT_BOUNCE_PROCESSING
-        mlist.bounce_score_threshold = Defaults.DEFAULT_BOUNCE_SCORE_THRESHOLD
-        mlist.bounce_info_stale_after = (
-            Defaults.DEFAULT_BOUNCE_INFO_STALE_AFTER)
-        mlist.bounce_you_are_disabled_warnings = (
-            Defaults.DEFAULT_BOUNCE_YOU_ARE_DISABLED_WARNINGS)
+        mlist.bounce_processing = True
+        mlist.bounce_score_threshold = 5.0
+        mlist.bounce_info_stale_after = datetime.timedelta(days=7)
+        mlist.bounce_you_are_disabled_warnings = 3
         mlist.bounce_you_are_disabled_warnings_interval = (
-            Defaults.DEFAULT_BOUNCE_YOU_ARE_DISABLED_WARNINGS_INTERVAL)
-        mlist.bounce_unrecognized_goes_to_list_owner = (
-            Defaults.DEFAULT_BOUNCE_UNRECOGNIZED_GOES_TO_LIST_OWNER)
-        mlist.bounce_notify_owner_on_disable = (
-            Defaults.DEFAULT_BOUNCE_NOTIFY_OWNER_ON_DISABLE)
-        mlist.bounce_notify_owner_on_removal = (
-            Defaults.DEFAULT_BOUNCE_NOTIFY_OWNER_ON_REMOVAL)
+            datetime.timedelta(days=7))
+        mlist.bounce_unrecognized_goes_to_list_owner = True
+        mlist.bounce_notify_owner_on_disable = True
+        mlist.bounce_notify_owner_on_removal = True
         # This holds legacy member related information.  It's keyed by the
         # member address, and the value is an object containing the bounce
         # score, the date of the last received bounce, and a count of the
@@ -196,7 +196,7 @@
         # New style delivery status
         mlist.delivery_status = {}
         # NNTP gateway
-        mlist.nntp_host = Defaults.DEFAULT_NNTP_HOST
+        mlist.nntp_host = u''
         mlist.linked_newsgroup = u''
         mlist.gateway_to_news = False
         mlist.gateway_to_mail = False
@@ -246,55 +246,3 @@
         # If no other styles have matched, then the default style matches.
         if len(styles) == 0:
             styles.append(self)
-
-
-
-class StyleManager:
-    """The built-in style manager."""
-
-    implements(IStyleManager)
-
-    def __init__(self):
-        """Install all styles from registered plugins, and install them."""
-        self._styles = {}
-        # Install all the styles provided by plugins.
-        for style_factory in get_plugins('mailman.styles'):
-            style = style_factory()
-            # Let DuplicateStyleErrors percolate up.
-            self.register(style)
-
-    def get(self, name):
-        """See `IStyleManager`."""
-        return self._styles.get(name)
-
-    def lookup(self, mailing_list):
-        """See `IStyleManager`."""
-        matched_styles = []
-        for style in self.styles:
-            style.match(mailing_list, matched_styles)
-        for style in matched_styles:
-            yield style
-
-    @property
-    def styles(self):
-        """See `IStyleManager`."""
-        for style in sorted(self._styles.values(),
-                            key=attrgetter('priority'),
-                            reverse=True):
-            yield style
-
-    def register(self, style):
-        """See `IStyleManager`."""
-        verifyObject(IStyle, style)
-        if style.name in self._styles:
-            raise DuplicateStyleError(style.name)
-        self._styles[style.name] = style
-
-    def unregister(self, style):
-        """See `IStyleManager`."""
-        # Let KeyErrors percolate up.
-        del self._styles[style.name]
-
-
-
-style_manager = StyleManager()

=== modified file 'mailman/testing/layers.py'
--- a/mailman/testing/layers.py 2009-01-01 22:16:51 +0000
+++ b/mailman/testing/layers.py 2009-01-05 05:54:19 +0000
@@ -37,7 +37,6 @@
 from mailman.config import config
 from mailman.core import initialize
 from mailman.core.logging import get_handler
-from mailman.core.styles import style_manager
 from mailman.i18n import _
 from mailman.testing.helpers import SMTPServer
 
@@ -139,7 +138,7 @@
     def testSetUp(cls):
         # Record the current (default) set of styles so that we can reset them
         # easily in the tear down.
-        cls.styles = set(style_manager.styles)
+        cls.styles = set(config.style_manager.styles)
 
     @classmethod
     def testTearDown(cls):
@@ -154,9 +153,9 @@
             config.db.message_store.delete_message(message['message-id'])
         config.db.commit()
         # Reset the global style manager.
-        new_styles = set(style_manager.styles) - cls.styles
+        new_styles = set(config.style_manager.styles) - cls.styles
         for style in new_styles:
-            style_manager.unregister(style)
+            config.style_manager.unregister(style)
         cls.styles = None
 
     # Flag to indicate that loggers should propagate to the console.

=== modified file 'setup.py'
--- a/setup.py  2009-01-03 10:13:41 +0000
+++ b/setup.py  2009-01-05 05:54:19 +0000
@@ -95,7 +95,6 @@
         'mailman.handlers'  : 'default = mailman.pipeline:initialize',
         'mailman.rules'     : 'default = mailman.rules:initialize',
         'mailman.scrubber'  : 'stock = mailman.archiving.pipermail:Pipermail',
-        'mailman.styles'    : 'default = mailman.core.styles:DefaultStyle',
         },
     install_requires = [
         'lazr.config',



--
Primary development focus
https://code.launchpad.net/~mailman-coders/mailman/3.0

You are receiving this branch notification because you are subscribed to it.
_______________________________________________
Mailman-checkins mailing list
[email protected]
Unsubscribe: 
http://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org

Reply via email to