------------------------------------------------------------
revno: 6595
committer: Barry Warsaw <[EMAIL PROTECTED]>
branch nick: 3.0
timestamp: Tue 2008-02-19 21:22:20 -0500
message:
The start of a cleaning up of Errors.py. Eventually, I want to get rid of
this module, in favor of moving exceptions into the interface modules that
they are appropriate for.
For now, this is just the low-hanging fruit.
Along the way, clean up by reSTifying some interfaces and implementations.
added:
Mailman/interfaces/errors.py
modified:
Mailman/Errors.py
Mailman/app/styles.py
Mailman/bin/newlist.py
Mailman/database/__init__.py
Mailman/database/listmanager.py
Mailman/database/user.py
Mailman/database/usermanager.py
Mailman/docs/listmanager.txt
Mailman/interfaces/address.py
Mailman/interfaces/database.py
Mailman/interfaces/listmanager.py
Mailman/interfaces/styles.py
Mailman/interfaces/usermanager.py
setup.py
=== modified file 'Mailman/Errors.py'
--- a/Mailman/Errors.py 2008-02-08 04:01:48 +0000
+++ b/Mailman/Errors.py 2008-02-20 02:22:20 +0000
@@ -36,9 +36,6 @@
def __str__(self):
return self._listname
-class MMCorruptListDatabaseError(MMListError): pass
-class MMListNotReadyError(MMListError): pass
-class MMListAlreadyExistsError(MMListError): pass
# Membership exceptions
class MMMemberError(MailmanException): pass
@@ -189,22 +186,6 @@
-# Database exceptions
-class DatabaseError(MailmanError):
- """A problem with the database occurred."""
-
-
-class SchemaVersionMismatchError(DatabaseError):
- def __init__(self, got):
- self._got = got
-
- def __str__(self):
- from Mailman.Version import DATABASE_SCHEMA_VERSION
- return 'Incompatible database schema version (got: %d, expected: %d)' \
- % (self._got, DATABASE_SCHEMA_VERSION)
-
-
-
class PasswordError(MailmanError):
"""A password related error."""
@@ -225,38 +206,3 @@
def __str__(self):
return 'A bad password scheme was given: %s' % self.scheme_name
-
-
-
-class UserError(MailmanError):
- """A general user-related error occurred."""
-
-
-class RosterError(UserError):
- """A roster-related error occurred."""
-
-
-class RosterExistsError(RosterError):
- """The named roster already exists."""
-
-
-
-class AddressError(MailmanError):
- """A general address-related error occurred."""
-
-
-class ExistingAddressError(AddressError):
- """The given email address already exists."""
-
-
-class AddressAlreadyLinkedError(AddressError):
- """The address is already linked to a user."""
-
-
-class AddressNotLinkedError(AddressError):
- """The address is not linked to the user."""
-
-
-
-class DuplicateStyleError(MailmanError):
- """A style with the same name is already registered."""
=== modified file 'Mailman/app/styles.py'
--- a/Mailman/app/styles.py 2008-02-19 02:24:46 +0000
+++ b/Mailman/app/styles.py 2008-02-20 02:22:20 +0000
@@ -30,22 +30,25 @@
from zope.interface.verify import verifyObject
from Mailman import Utils
-from Mailman.Errors import DuplicateStyleError
from Mailman.app.plugins import get_plugins
from Mailman.configuration import config
from Mailman.i18n import _
from Mailman.interfaces import (
- Action, IStyle, IStyleManager, NewsModeration, Personalization)
+ Action, DuplicateStyleError, IStyle, IStyleManager, NewsModeration,
+ Personalization)
class DefaultStyle:
+ """The defalt (i.e. legacy) style."""
+
implements(IStyle)
name = 'default'
priority = 0 # the lowest priority style
def apply(self, mailing_list):
+ """See `IStyle`."""
# For cut-n-paste convenience.
mlist = mailing_list
# Most of these were ripped from the old MailList.InitVars() method.
@@ -233,6 +236,7 @@
mlist.pipeline = u'built-in'
def match(self, mailing_list, styles):
+ """See `IStyle`."""
# If no other styles have matched, then the default style matches.
if len(styles) == 0:
styles.append(self)
@@ -240,9 +244,12 @@
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'):
@@ -251,9 +258,11 @@
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)
@@ -262,18 +271,21 @@
@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]
=== modified file 'Mailman/bin/newlist.py'
--- a/Mailman/bin/newlist.py 2008-02-19 02:24:46 +0000
+++ b/Mailman/bin/newlist.py 2008-02-20 02:22:20 +0000
@@ -31,6 +31,8 @@
from Mailman.app.lifecycle import create_list
from Mailman.configuration import config
from Mailman.initialize import initialize
+from Mailman.interfaces import ListAlreadyExistsError
+
_ = i18n._
@@ -107,7 +109,7 @@
mlist.preferred_language = opts.language
except Errors.InvalidEmailAddress:
parser.error(_('Illegal list name: $fqdn_listname'))
- except Errors.MMListAlreadyExistsError:
+ except ListAlreadyExistsError:
parser.error(_('List already exists: $fqdn_listname'))
except Errors.BadDomainSpecificationError, domain:
parser.error(_('Undefined domain: $domain'))
=== modified file 'Mailman/database/__init__.py'
--- a/Mailman/database/__init__.py 2008-02-08 04:01:48 +0000
+++ b/Mailman/database/__init__.py 2008-02-20 02:22:20 +0000
@@ -31,7 +31,6 @@
from urlparse import urlparse
from zope.interface import implements
-from Mailman.Errors import SchemaVersionMismatchError
from Mailman.configuration import config
from Mailman.database.listmanager import ListManager
from Mailman.database.messagestore import MessageStore
@@ -39,7 +38,7 @@
from Mailman.database.requests import Requests
from Mailman.database.usermanager import UserManager
from Mailman.database.version import Version
-from Mailman.interfaces import IDatabase
+from Mailman.interfaces import IDatabase, SchemaVersionMismatchError
=== modified file 'Mailman/database/listmanager.py'
--- a/Mailman/database/listmanager.py 2008-02-08 04:01:48 +0000
+++ b/Mailman/database/listmanager.py 2008-02-20 02:22:20 +0000
@@ -25,30 +25,31 @@
from Mailman.Utils import split_listname, fqdn_listname
from Mailman.configuration import config
from Mailman.database.mailinglist import MailingList
-from Mailman.interfaces import IListManager
+from Mailman.interfaces import IListManager, ListAlreadyExistsError
class ListManager(object):
+ """An implementation of the `IListManager` interface."""
+
implements(IListManager)
def create(self, fqdn_listname):
+ """See `IListManager`."""
listname, hostname = split_listname(fqdn_listname)
mlist = config.db.store.find(
MailingList,
MailingList.list_name == listname,
MailingList.host_name == hostname).one()
if mlist:
- raise Errors.MMListAlreadyExistsError(fqdn_listname)
+ raise ListAlreadyExistsError(fqdn_listname)
mlist = MailingList(fqdn_listname)
mlist.created_at = datetime.datetime.now()
config.db.store.add(mlist)
return mlist
- def delete(self, mlist):
- config.db.store.remove(mlist)
-
def get(self, fqdn_listname):
+ """See `IListManager`."""
listname, hostname = split_listname(fqdn_listname)
mlist = config.db.store.find(MailingList,
list_name=listname,
@@ -58,14 +59,18 @@
mlist._restore()
return mlist
+ def delete(self, mlist):
+ """See `IListManager`."""
+ config.db.store.remove(mlist)
+
@property
def mailing_lists(self):
- # Don't forget, the MailingList objects that this class manages must
- # be wrapped in a MailList object as expected by this interface.
+ """See `IListManager`."""
for fqdn_listname in self.names:
yield self.get(fqdn_listname)
@property
def names(self):
+ """See `IListManager`."""
for mlist in config.db.store.find(MailingList):
yield fqdn_listname(mlist.list_name, mlist.host_name)
=== modified file 'Mailman/database/user.py'
--- a/Mailman/database/user.py 2008-02-08 04:01:48 +0000
+++ b/Mailman/database/user.py 2008-02-20 02:22:20 +0000
@@ -19,16 +19,18 @@
from storm.locals import *
from zope.interface import implements
-from Mailman import Errors
from Mailman.configuration import config
from Mailman.database.model import Model
from Mailman.database.address import Address
from Mailman.database.preferences import Preferences
-from Mailman.interfaces import IUser
+from Mailman.interfaces import (
+ AddressAlreadyLinkedError, AddressNotLinkedError, IUser)
class User(Model):
+ """Mailman users."""
+
implements(IUser)
id = Int(primary=True)
@@ -43,16 +45,19 @@
return '<User "%s" at %#x>' % (self.real_name, id(self))
def link(self, address):
+ """See `IUser`."""
if address.user is not None:
- raise Errors.AddressAlreadyLinkedError(address)
+ raise AddressAlreadyLinkedError(address)
address.user = self
def unlink(self, address):
+ """See `IUser`."""
if address.user is None:
- raise Errors.AddressNotLinkedError(address)
+ raise AddressNotLinkedError(address)
address.user = None
def controls(self, address):
+ """See `IUser`."""
found = config.db.store.find(Address, address=address)
if found.count() == 0:
return False
@@ -60,6 +65,7 @@
return found[0].user is self
def register(self, address, real_name=None):
+ """See `IUser`."""
# First, see if the address already exists
addrobj = config.db.store.find(Address, address=address).one()
if addrobj is None:
@@ -69,6 +75,6 @@
addrobj.preferences = Preferences()
# Link the address to the user if it is not already linked.
if addrobj.user is not None:
- raise Errors.AddressAlreadyLinkedError(addrobj)
+ raise AddressAlreadyLinkedError(addrobj)
addrobj.user = self
return addrobj
=== modified file 'Mailman/database/usermanager.py'
--- a/Mailman/database/usermanager.py 2008-02-08 04:01:48 +0000
+++ b/Mailman/database/usermanager.py 2008-02-20 02:22:20 +0000
@@ -23,12 +23,11 @@
from zope.interface import implements
-from Mailman import Errors
from Mailman.configuration import config
from Mailman.database.address import Address
from Mailman.database.preferences import Preferences
from Mailman.database.user import User
-from Mailman.interfaces import IUserManager
+from Mailman.interfaces import ExistingAddressError, IUserManager
@@ -67,7 +66,7 @@
addresses = config.db.store.find(Address, address=address.lower())
if addresses.count() == 1:
found = addresses[0]
- raise Errors.ExistingAddressError(found.original_address)
+ raise ExistingAddressError(found.original_address)
assert addresses.count() == 0, 'Unexpected results'
if real_name is None:
real_name = u''
=== modified file 'Mailman/docs/listmanager.txt'
--- a/Mailman/docs/listmanager.txt 2007-11-10 18:14:51 +0000
+++ b/Mailman/docs/listmanager.txt 2008-02-20 02:22:20 +0000
@@ -40,7 +40,7 @@
>>> mlist_dup = listmgr.create(u'[EMAIL PROTECTED]')
Traceback (most recent call last):
...
- MMListAlreadyExistsError: [EMAIL PROTECTED]
+ ListAlreadyExistsError: [EMAIL PROTECTED]
Deleting a mailing list
=== modified file 'Mailman/interfaces/address.py'
--- a/Mailman/interfaces/address.py 2008-02-08 04:01:48 +0000
+++ b/Mailman/interfaces/address.py 2008-02-20 02:22:20 +0000
@@ -19,6 +19,26 @@
from zope.interface import Interface, Attribute
+from Mailman.interfaces.errors import MailmanError
+
+
+
+class AddressError(MailmanError):
+ """A general address-related error occurred."""
+
+
+class ExistingAddressError(AddressError):
+ """The given email address already exists."""
+
+
+class AddressAlreadyLinkedError(AddressError):
+ """The address is already linked to a user."""
+
+
+class AddressNotLinkedError(AddressError):
+ """The address is not linked to the user."""
+
+
class IAddress(Interface):
=== modified file 'Mailman/interfaces/database.py'
--- a/Mailman/interfaces/database.py 2008-02-08 04:01:48 +0000
+++ b/Mailman/interfaces/database.py 2008-02-20 02:22:20 +0000
@@ -25,6 +25,26 @@
from zope.interface import Interface, Attribute
+from Mailman.Version import DATABASE_SCHEMA_VERSION
+from Mailman.interfaces.errors import MailmanError
+
+
+
+class DatabaseError(MailmanError):
+ """A problem with the database occurred."""
+
+
+class SchemaVersionMismatchError(DatabaseError):
+ """The database schema version number did not match what was expected."""
+
+ def __init__(self, got):
+ self._got = got
+
+ def __str__(self):
+ return (
+ 'Incompatible database schema version (got: %d, expected: %d)'
+ % (self._got, DATABASE_SCHEMA_VERSION))
+
class IDatabase(Interface):
=== added file 'Mailman/interfaces/errors.py'
--- a/Mailman/interfaces/errors.py 1970-01-01 00:00:00 +0000
+++ b/Mailman/interfaces/errors.py 2008-02-20 02:22:20 +0000
@@ -0,0 +1,28 @@
+# Copyright (C) 1998-2008 by the Free Software Foundation, Inc.
+#
+# This program 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 2
+# of the License, or (at your option) any later version.
+#
+# This program 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 this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+# USA.
+
+"""Base Mailman exceptions.
+
+The exceptions in this module are those that are commonly shared among many
+components. More specific exceptions will be located in the relevant
+interfaces.
+"""
+
+
+
+class MailmanError(Exception):
+ """Base class for all Mailman exceptions."""
=== modified file 'Mailman/interfaces/listmanager.py'
--- a/Mailman/interfaces/listmanager.py 2008-02-08 04:01:48 +0000
+++ b/Mailman/interfaces/listmanager.py 2008-02-20 02:22:20 +0000
@@ -17,44 +17,64 @@
"""Interface for list storage, deleting, and finding."""
+__metaclass__ = type
+__all__ = [
+ 'IListManager',
+ 'ListAlreadyExistsError',
+ ]
+
+
from zope.interface import Interface, Attribute
+from Mailman.interfaces.errors import MailmanError
+
+
+
+class ListAlreadyExistsError(MailmanError):
+ """Attempted to create a mailing list that already exists.
+
+ Mailing list objects must be uniquely named by their fully qualified list
+ name.
+ """
class IListManager(Interface):
"""The interface of the global list manager.
- The list manager manages IMailingList objects. You can add and remove
- IMailingList objects from the list manager, and you can retrieve them
- from the manager via their fully qualified list name
- (e.g. '[EMAIL PROTECTED]').
+ The list manager manages `IMailingList` objects. You can add and remove
+ `IMailingList` objects from the list manager, and you can retrieve them
+ from the manager via their fully qualified list name, e.g.:
+ [EMAIL PROTECTED]
"""
def create(fqdn_listname):
- """Create an IMailingList with the given fully qualified list name.
+ """Create a mailing list with the given name.
- Raises MMListAlreadyExistsError if the named list already exists.
+ :type fqdn_listname: Unicode
+ :param fqdn_listname: The fully qualified name of the mailing list,
+ e.g. [EMAIL PROTECTED]
+ :return: The newly created `IMailingList`.
+ :raise `ListAlreadyExistsError` if the named list already exists.
"""
def get(fqdn_listname):
- """Return the IMailingList with the given fully qualified list name.
+ """Return the mailing list with the given name, if it exists.
- Raises MMUnknownListError if the names list does not exist.
+ :type fqdn_listname: Unicode.
+ :param fqdn_listname: The fully qualified name of the mailing list.
+ :return: the matching `IMailingList` or None if the named list does
+ not exist.
"""
def delete(mlist):
- """Remove the IMailingList from the backend storage."""
-
- def get(fqdn_listname):
- """Find the IMailingList with the matching fully qualified list name.
-
- :param fqdn_listname: Fully qualified list name to get.
- :return: The matching IMailingList or None if there was no such
- matching mailing list.
+ """Remove the mailing list from the database.
+
+ :type mlist: `IMailingList`
+ :param mlist: The mailing list to delete.
"""
mailing_lists = Attribute(
- """An iterator over all the IMailingList objects managed by this list
+ """An iterator over all the mailing list objects managed by this list
manager.""")
names = Attribute(
=== modified file 'Mailman/interfaces/styles.py'
--- a/Mailman/interfaces/styles.py 2008-02-08 04:01:48 +0000
+++ b/Mailman/interfaces/styles.py 2008-02-20 02:22:20 +0000
@@ -17,7 +17,21 @@
"""Interfaces for list styles."""
+__metaclass__ = type
+__all__ = [
+ 'DuplicateStyleError',
+ 'IStyle',
+ 'IStyleManager',
+ ]
+
+
from zope.interface import Interface, Attribute
+from Mailman.interfaces.errors import MailmanError
+
+
+
+class DuplicateStyleError(MailmanError):
+ """A style with the same name is already registered."""
@@ -33,7 +47,8 @@
def apply(mailing_list):
"""Apply the style to the mailing list.
- :param mailing_list: an IMailingList.
+ :type mailing_list: `IMailingList`.
+ :param mailing_list: the mailing list to apply the style to.
"""
def match(mailing_list, styles):
@@ -43,8 +58,9 @@
the style may append itself to the `styles` list. This list will be
ordered when returned from `IStyleManager.lookup()`.
- :param mailing_list: an IMailingList.
- :param styles: ordered list of IStyles matched so far.
+ :type mailing_list: `IMailingList`.
+ :param mailing_list: the mailing list object.
+ :param styles: ordered list of `IStyles` matched so far.
"""
@@ -55,20 +71,22 @@
def get(name):
"""Return the named style or None.
+ :type name: Unicode
:param name: A style name.
- :return: an IStyle or None.
+ :return: the named `IStyle` or None if the style doesn't exist.
"""
def lookup(mailing_list):
"""Return a list of styles for the given mailing list.
- Use various registered rules to find an IStyle for the given mailing
+ Use various registered rules to find an `IStyle` for the given mailing
list. The returned styles are ordered by their priority.
Style matches can be registered and reordered by plugins.
- :param mailing_list: An IMailingList.
- :return: ordered list of IStyles. Zero is the lowest priority.
+ :type mailing_list: `IMailingList`.
+ :param mailing_list: The mailing list object to find a style for.
+ :return: ordered list of `IStyles`. Zero is the lowest priority.
"""
styles = Attribute(
=== modified file 'Mailman/interfaces/usermanager.py'
--- a/Mailman/interfaces/usermanager.py 2008-02-08 04:01:48 +0000
+++ b/Mailman/interfaces/usermanager.py 2008-02-20 02:22:20 +0000
@@ -38,8 +38,9 @@
When address is given, an IAddress is also created and linked to the
new IUser object. If the address already exists, an
- ExistingAddressError is raised. If the address exists but is already
- linked to another user, an AddressAlreadyLinkedError is raised.
+ `ExistingAddressError` is raised. If the address exists but is
+ already linked to another user, an AddressAlreadyLinkedError is
+ raised.
When real_name is given, the IUser's real_name is set to this string.
If an IAddress is also created and linked, its real_name is set to the
=== modified file 'setup.py'
--- a/setup.py 2008-02-17 22:34:21 +0000
+++ b/setup.py 2008-02-20 02:22:20 +0000
@@ -92,7 +92,6 @@
'mailman.rules' : 'default = Mailman.rules:initialize',
'mailman.handlers' : 'default = Mailman.pipeline:initialize',
},
- # Third-party requirements.
install_requires = [
'locknix',
'munepy',
--
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