Mailing lists

The mailing list is a core object in Mailman. It is uniquely identified in the system by its list-id which is derived from its posting address, i.e. the email address you would send a message to in order to post a message to the mailing list. The list id is defined in RFC 2369.

>>> from mailman.app.lifecycle import create_list
>>> mlist = create_list('aardvark@example.com')
>>> print(mlist.list_id)
aardvark.example.com
>>> print(mlist.fqdn_listname)
aardvark@example.com

The mailing list also has convenient attributes for accessing the list’s short name (i.e. local part) and host name.

>>> print(mlist.list_name)
aardvark
>>> print(mlist.mail_host)
example.com

Rosters

Mailing list membership is represented by rosters. Each mailing list has several rosters of members, representing the subscribers to the mailing list, the owners, the moderators, and so on. The rosters are defined by a membership role.

Addresses can be explicitly subscribed to a mailing list. By default, a subscription puts the address in the member role, meaning that address will receive a copy of any message sent to the mailing list.

>>> from mailman.interfaces.usermanager import IUserManager
>>> from zope.component import getUtility
>>> user_manager = getUtility(IUserManager)

>>> aperson = user_manager.create_address('aperson@example.com')
>>> bperson = user_manager.create_address('bperson@example.com')
>>> mlist.subscribe(aperson)
<Member: aperson@example.com on aardvark@example.com as MemberRole.member>
>>> mlist.subscribe(bperson)
<Member: bperson@example.com on aardvark@example.com as MemberRole.member>

Both addresses appear on the roster of members.

>>> from operator import attrgetter
>>> sort_key = attrgetter('address.email')
>>> for member in sorted(mlist.members.members, key=sort_key):
...     print(member)
<Member: aperson@example.com on aardvark@example.com as MemberRole.member>
<Member: bperson@example.com on aardvark@example.com as MemberRole.member>

By explicitly specifying the role of the subscription, an address can be added to the owner and moderator rosters.

>>> from mailman.interfaces.member import MemberRole
>>> mlist.subscribe(aperson, MemberRole.owner)
<Member: aperson@example.com on aardvark@example.com as MemberRole.owner>
>>> cperson = user_manager.create_address('cperson@example.com')
>>> mlist.subscribe(cperson, MemberRole.owner)
<Member: cperson@example.com on aardvark@example.com as MemberRole.owner>
>>> mlist.subscribe(cperson, MemberRole.moderator)
<Member: cperson@example.com on aardvark@example.com
         as MemberRole.moderator>

A Person is now both a member and an owner of the mailing list. C Person is an owner and a moderator.

>>> for member in sorted(mlist.owners.members, key=sort_key):
...     print(member)
<Member: aperson@example.com on aardvark@example.com as MemberRole.owner>
<Member: cperson@example.com on aardvark@example.com as MemberRole.owner>

>>> for member in mlist.moderators.members:
...     print(member)
<Member: cperson@example.com on aardvark@example.com
         as MemberRole.moderator>

All rosters can also be accessed indirectly.

>>> roster = mlist.get_roster(MemberRole.member)
>>> for member in sorted(roster.members, key=sort_key):
...     print(member)
<Member: aperson@example.com on aardvark@example.com as MemberRole.member>
<Member: bperson@example.com on aardvark@example.com as MemberRole.member>

>>> roster = mlist.get_roster(MemberRole.owner)
>>> for member in sorted(roster.members, key=sort_key):
...     print(member)
<Member: aperson@example.com on aardvark@example.com as MemberRole.owner>
<Member: cperson@example.com on aardvark@example.com as MemberRole.owner>

>>> roster = mlist.get_roster(MemberRole.moderator)
>>> for member in roster.members:
...     print(member)
<Member: cperson@example.com on aardvark@example.com
         as MemberRole.moderator>

Subscribing users

An alternative way of subscribing to a mailing list is as a user with a preferred address. This way the user can change their subscription address just by changing their preferred address.

The user must have a preferred address.

>>> from mailman.utilities.datetime import now
>>> user = user_manager.create_user('dperson@example.com', 'Dave Person')
>>> address = list(user.addresses)[0]
>>> address.verified_on = now()
>>> user.preferred_address = address

The preferred address is used in the subscription.

>>> mlist.subscribe(user)
<Member: Dave Person <dperson@example.com> on aardvark@example.com
         as MemberRole.member>
>>> for member in sorted(mlist.members.members, key=sort_key):
...     print(member)
<Member: aperson@example.com on aardvark@example.com as MemberRole.member>
<Member: bperson@example.com on aardvark@example.com as MemberRole.member>
<Member: Dave Person <dperson@example.com> on aardvark@example.com
         as MemberRole.member>

If the user’s preferred address changes, their subscribed email address also changes automatically.

>>> new_address = user.register('dave.person@example.com')
>>> new_address.verified_on = now()
>>> user.preferred_address = new_address

>>> for member in sorted(mlist.members.members, key=sort_key):
...     print(member)
<Member: aperson@example.com on aardvark@example.com as MemberRole.member>
<Member: bperson@example.com on aardvark@example.com as MemberRole.member>
<Member: dave.person@example.com on aardvark@example.com
         as MemberRole.member>

A user is allowed to explicitly subscribe again with a specific address, even if this address is their preferred address.

>>> mlist.subscribe(user.preferred_address)
<Member: dave.person@example.com
         on aardvark@example.com as MemberRole.member>

MailingList Attributes

This defines all the attributes of a MailingList.

interface mailman.interfaces.mailinglist.IMailingList[source]

A mailing list.

acceptable_aliases = <zope.interface.interface.Attribute object at 0x7f2e6b7213d0 mailman.interfaces.mailinglist.IMailingList.acceptable_aliases>
admin_immed_notify = <zope.interface.interface.Attribute object at 0x7f2e6b7935e0 mailman.interfaces.mailinglist.IMailingList.admin_immed_notify>
admin_notify_mchanges = <zope.interface.interface.Attribute object at 0x7f2e6b793640 mailman.interfaces.mailinglist.IMailingList.admin_notify_mchanges>
administrators = <zope.interface.interface.Attribute object at 0x7f2e6b73d7c0 mailman.interfaces.mailinglist.IMailingList.administrators>
administrivia = <zope.interface.interface.Attribute object at 0x7f2e6b721730 mailman.interfaces.mailinglist.IMailingList.administrivia>
advertised = <zope.interface.interface.Attribute object at 0x7f2e6b6e7f10 mailman.interfaces.mailinglist.IMailingList.advertised>
allow_list_posts = <zope.interface.interface.Attribute object at 0x7f2e6b6fa0a0 mailman.interfaces.mailinglist.IMailingList.allow_list_posts>
anonymous_list = <zope.interface.interface.Attribute object at 0x7f2e6b6e7d60 mailman.interfaces.mailinglist.IMailingList.anonymous_list>
archive_policy = <zope.interface.interface.Attribute object at 0x7f2e6b72fa00 mailman.interfaces.mailinglist.IMailingList.archive_policy>
archive_rendering_mode = <zope.interface.interface.Attribute object at 0x7f2e6b77c070 mailman.interfaces.mailinglist.IMailingList.archive_rendering_mode>
autorespond_owner = <zope.interface.interface.Attribute object at 0x7f2e6b7211c0 mailman.interfaces.mailinglist.IMailingList.autorespond_owner>
autorespond_postings = <zope.interface.interface.Attribute object at 0x7f2e6b7210a0 mailman.interfaces.mailinglist.IMailingList.autorespond_postings>
autorespond_requests = <zope.interface.interface.Attribute object at 0x7f2e6b7211f0 mailman.interfaces.mailinglist.IMailingList.autorespond_requests>
autoresponse_grace_period = <zope.interface.interface.Attribute object at 0x7f2e6b721250 mailman.interfaces.mailinglist.IMailingList.autoresponse_grace_period>
autoresponse_owner_text = <zope.interface.interface.Attribute object at 0x7f2e6b721130 mailman.interfaces.mailinglist.IMailingList.autoresponse_owner_text>
autoresponse_postings_text = <zope.interface.interface.Attribute object at 0x7f2e6b721280 mailman.interfaces.mailinglist.IMailingList.autoresponse_postings_text>
autoresponse_request_text = <zope.interface.interface.Attribute object at 0x7f2e6b7212e0 mailman.interfaces.mailinglist.IMailingList.autoresponse_request_text>
bounce_info_stale_after = <zope.interface.interface.Attribute object at 0x7f2e6b793610 mailman.interfaces.mailinglist.IMailingList.bounce_info_stale_after>
bounce_notify_owner_on_disable = <zope.interface.interface.Attribute object at 0x7f2e6b793f70 mailman.interfaces.mailinglist.IMailingList.bounce_notify_owner_on_disable>
bounce_notify_owner_on_removal = <zope.interface.interface.Attribute object at 0x7f2e6b793f10 mailman.interfaces.mailinglist.IMailingList.bounce_notify_owner_on_removal>
bounce_score_threshold = <zope.interface.interface.Attribute object at 0x7f2e6b793eb0 mailman.interfaces.mailinglist.IMailingList.bounce_score_threshold>
bounce_you_are_disabled_warnings = <zope.interface.interface.Attribute object at 0x7f2e6b793e50 mailman.interfaces.mailinglist.IMailingList.bounce_you_are_disabled_warnings>
bounce_you_are_disabled_warnings_interval = <zope.interface.interface.Attribute object at 0x7f2e6b793df0 mailman.interfaces.mailinglist.IMailingList.bounce_you_are_disabled_warnings_interval>
bounces_address = <zope.interface.interface.Attribute object at 0x7f2e6b6e7d00 mailman.interfaces.mailinglist.IMailingList.bounces_address>
collapse_alternatives = <zope.interface.interface.Attribute object at 0x7f2e6b7218b0 mailman.interfaces.mailinglist.IMailingList.collapse_alternatives>
confirm_address(cookie='')

The address used for various forms of email confirmation.

convert_html_to_plaintext = <zope.interface.interface.Attribute object at 0x7f2e6b721820 mailman.interfaces.mailinglist.IMailingList.convert_html_to_plaintext>
created_at = <zope.interface.interface.Attribute object at 0x7f2e6b716490 mailman.interfaces.mailinglist.IMailingList.created_at>
data_path = <zope.interface.interface.Attribute object at 0x7f2e6b7214f0 mailman.interfaces.mailinglist.IMailingList.data_path>
default_member_action = <zope.interface.interface.Attribute object at 0x7f2e6b793670 mailman.interfaces.mailinglist.IMailingList.default_member_action>
default_nonmember_action = <zope.interface.interface.Attribute object at 0x7f2e6b793550 mailman.interfaces.mailinglist.IMailingList.default_nonmember_action>
description = <zope.interface.interface.Attribute object at 0x7f2e6b6fa220 mailman.interfaces.mailinglist.IMailingList.description>
digest_last_sent_at = <zope.interface.interface.Attribute object at 0x7f2e6b721d30 mailman.interfaces.mailinglist.IMailingList.digest_last_sent_at>
digest_members = <zope.interface.interface.Attribute object at 0x7f2e6b72fbb0 mailman.interfaces.mailinglist.IMailingList.digest_members>
digest_send_periodic = <zope.interface.interface.Attribute object at 0x7f2e6b7218e0 mailman.interfaces.mailinglist.IMailingList.digest_send_periodic>
digest_size_threshold = <zope.interface.interface.Attribute object at 0x7f2e6b721970 mailman.interfaces.mailinglist.IMailingList.digest_size_threshold>
digest_volume_frequency = <zope.interface.interface.Attribute object at 0x7f2e6b7219a0 mailman.interfaces.mailinglist.IMailingList.digest_volume_frequency>
digests_enabled = <zope.interface.interface.Attribute object at 0x7f2e6b721a60 mailman.interfaces.mailinglist.IMailingList.digests_enabled>
display_name = <zope.interface.interface.Attribute object at 0x7f2e6b6fa280 mailman.interfaces.mailinglist.IMailingList.display_name>
dmarc_mitigate_action = <zope.interface.interface.Attribute object at 0x7f2e6b6e7520 mailman.interfaces.mailinglist.IMailingList.dmarc_mitigate_action>
dmarc_mitigate_unconditionally = <zope.interface.interface.Attribute object at 0x7f2e6b6e78e0 mailman.interfaces.mailinglist.IMailingList.dmarc_mitigate_unconditionally>
dmarc_moderation_notice = <zope.interface.interface.Attribute object at 0x7f2e6b6e7850 mailman.interfaces.mailinglist.IMailingList.dmarc_moderation_notice>
dmarc_wrapped_message_text = <zope.interface.interface.Attribute object at 0x7f2e6b6e7670 mailman.interfaces.mailinglist.IMailingList.dmarc_wrapped_message_text>
domain = <zope.interface.interface.Attribute object at 0x7f2e6b6fa310 mailman.interfaces.mailinglist.IMailingList.domain>
filter_action = <zope.interface.interface.Attribute object at 0x7f2e6b721760 mailman.interfaces.mailinglist.IMailingList.filter_action>
filter_content = <zope.interface.interface.Attribute object at 0x7f2e6b7216a0 mailman.interfaces.mailinglist.IMailingList.filter_content>
filter_extensions = <zope.interface.interface.Attribute object at 0x7f2e6b768f40 mailman.interfaces.mailinglist.IMailingList.filter_extensions>
filter_types = <zope.interface.interface.Attribute object at 0x7f2e6b768700 mailman.interfaces.mailinglist.IMailingList.filter_types>
forward_unrecognized_bounces_to = <zope.interface.interface.Attribute object at 0x7f2e6b793d30 mailman.interfaces.mailinglist.IMailingList.forward_unrecognized_bounces_to>
fqdn_listname = <zope.interface.interface.Attribute object at 0x7f2e6b6fa370 mailman.interfaces.mailinglist.IMailingList.fqdn_listname>
gateway_to_mail = <zope.interface.interface.Attribute object at 0x7f2e6b793250 mailman.interfaces.mailinglist.IMailingList.gateway_to_mail>
gateway_to_news = <zope.interface.interface.Attribute object at 0x7f2e6b793100 mailman.interfaces.mailinglist.IMailingList.gateway_to_news>
get_roster(role)

Return the appropriate roster for the given role.

Parameters:role (MemberRole) – The requested roster’s role.
Returns:The requested roster.
Return type:Roster
include_rfc2369_headers = <zope.interface.interface.Attribute object at 0x7f2e6b6fa040 mailman.interfaces.mailinglist.IMailingList.include_rfc2369_headers>
info = <zope.interface.interface.Attribute object at 0x7f2e6b6fa190 mailman.interfaces.mailinglist.IMailingList.info>
is_subscribed(subscriber, role=<MemberRole.member: 1>)

Is the given address or user subscribed to the mailing list?

Parameters:
  • subscriber (IUser or IAddress) – The address or user to check.
  • role (MemberRole) – The role being checked (e.g. a member, owner, or moderator of a mailing list).
Returns:

A flag indicating whether the subscriber is already subscribed to the mailing list or not.

join_address = <zope.interface.interface.Attribute object at 0x7f2e6b6e7310 mailman.interfaces.mailinglist.IMailingList.join_address>
last_digest_recipients = <zope.interface.interface.Attribute object at 0x7f2e6b7217f0 mailman.interfaces.mailinglist.IMailingList.last_digest_recipients>
last_post_at = <zope.interface.interface.Attribute object at 0x7f2e6bb26eb0 mailman.interfaces.mailinglist.IMailingList.last_post_at>
leave_address = <zope.interface.interface.Attribute object at 0x7f2e6b6e7130 mailman.interfaces.mailinglist.IMailingList.leave_address>
linked_newsgroup = <zope.interface.interface.Attribute object at 0x7f2e6bbd5370 mailman.interfaces.mailinglist.IMailingList.linked_newsgroup>
list_id = <zope.interface.interface.Attribute object at 0x7f2e6b6d9e20 mailman.interfaces.mailinglist.IMailingList.list_id>
list_name = <zope.interface.interface.Attribute object at 0x7f2e6b6d91c0 mailman.interfaces.mailinglist.IMailingList.list_name>
mail_host = <zope.interface.interface.Attribute object at 0x7f2e6b6d9dc0 mailman.interfaces.mailinglist.IMailingList.mail_host>
member_roster_visibility = <zope.interface.interface.Attribute object at 0x7f2e6b721ac0 mailman.interfaces.mailinglist.IMailingList.member_roster_visibility>
members = <zope.interface.interface.Attribute object at 0x7f2e6b72fee0 mailman.interfaces.mailinglist.IMailingList.members>
moderators = <zope.interface.interface.Attribute object at 0x7f2e6b73d6a0 mailman.interfaces.mailinglist.IMailingList.moderators>
newsgroup_moderation = <zope.interface.interface.Attribute object at 0x7f2e6b77cd90 mailman.interfaces.mailinglist.IMailingList.newsgroup_moderation>
next_digest_number = <zope.interface.interface.Attribute object at 0x7f2e6b721d00 mailman.interfaces.mailinglist.IMailingList.next_digest_number>
nntp_prefix_subject_too = <zope.interface.interface.Attribute object at 0x7f2e6b77cc70 mailman.interfaces.mailinglist.IMailingList.nntp_prefix_subject_too>
no_reply_address = <zope.interface.interface.Attribute object at 0x7f2e6b6e7280 mailman.interfaces.mailinglist.IMailingList.no_reply_address>
nonmembers = <zope.interface.interface.Attribute object at 0x7f2e6b73d700 mailman.interfaces.mailinglist.IMailingList.nonmembers>
owner_address = <zope.interface.interface.Attribute object at 0x7f2e6b6e7ca0 mailman.interfaces.mailinglist.IMailingList.owner_address>
owner_chain = <zope.interface.interface.Attribute object at 0x7f2e6b7213a0 mailman.interfaces.mailinglist.IMailingList.owner_chain>
owner_pipeline = <zope.interface.interface.Attribute object at 0x7f2e6b721580 mailman.interfaces.mailinglist.IMailingList.owner_pipeline>
owners = <zope.interface.interface.Attribute object at 0x7f2e6b73d6d0 mailman.interfaces.mailinglist.IMailingList.owners>
pass_extensions = <zope.interface.interface.Attribute object at 0x7f2e6b768850 mailman.interfaces.mailinglist.IMailingList.pass_extensions>
pass_types = <zope.interface.interface.Attribute object at 0x7f2e6b768fd0 mailman.interfaces.mailinglist.IMailingList.pass_types>
personalize = <zope.interface.interface.Attribute object at 0x7f2e6b7217c0 mailman.interfaces.mailinglist.IMailingList.personalize>
post_id = <zope.interface.interface.Attribute object at 0x7f2e6bb79be0 mailman.interfaces.mailinglist.IMailingList.post_id>
posting_address = <zope.interface.interface.Attribute object at 0x7f2e6b6e7a60 mailman.interfaces.mailinglist.IMailingList.posting_address>
posting_chain = <zope.interface.interface.Attribute object at 0x7f2e6b7210d0 mailman.interfaces.mailinglist.IMailingList.posting_chain>
posting_pipeline = <zope.interface.interface.Attribute object at 0x7f2e6b721430 mailman.interfaces.mailinglist.IMailingList.posting_pipeline>
preferred_language = <zope.interface.interface.Attribute object at 0x7f2e6b6fa130 mailman.interfaces.mailinglist.IMailingList.preferred_language>
process_bounces = <zope.interface.interface.Attribute object at 0x7f2e6b793580 mailman.interfaces.mailinglist.IMailingList.process_bounces>
regular_members = <zope.interface.interface.Attribute object at 0x7f2e6b72fe20 mailman.interfaces.mailinglist.IMailingList.regular_members>
reply_goes_to_list = <zope.interface.interface.Attribute object at 0x7f2e6b721b20 mailman.interfaces.mailinglist.IMailingList.reply_goes_to_list>
request_address = <zope.interface.interface.Attribute object at 0x7f2e6b6e71f0 mailman.interfaces.mailinglist.IMailingList.request_address>
require_explicit_destination = <zope.interface.interface.Attribute object at 0x7f2e6b7215e0 mailman.interfaces.mailinglist.IMailingList.require_explicit_destination>
send_goodbye_message = <zope.interface.interface.Attribute object at 0x7f2e6b7932b0 mailman.interfaces.mailinglist.IMailingList.send_goodbye_message>
send_one_last_digest_to(address, delivery_mode)

Make sure to send one last digest to an address.

This is used when a person transitions from digest delivery to regular delivery and wants to make sure they don’t miss anything. By indicating that they’d like to receive one last digest, they will ensure continuity in receiving mailing lists posts.

Parameters:
  • address (IAddress) – The address of the person receiving one last digest.
  • delivery_mode (DeliveryMode) – The type of digest to receive.
send_welcome_message = <zope.interface.interface.Attribute object at 0x7f2e6b793310 mailman.interfaces.mailinglist.IMailingList.send_welcome_message>
subject_prefix = <zope.interface.interface.Attribute object at 0x7f2e6b6fa100 mailman.interfaces.mailinglist.IMailingList.subject_prefix>
subscribe(subscriber, role=<MemberRole.member: 1>)

Subscribe the given address or user to the mailing list.

Parameters:
  • subscriber (IUser or IAddress) – The address or user to subscribe to the mailing list. The user’s preferred address receives deliveries, if she has one, otherwise no address for the user appears in the rosters.
  • role (MemberRole) – The role being subscribed to (e.g. a member, owner, or moderator of a mailing list).
Returns:

The member object representing the subscription.

Return type:

IMember

Raises:
  • AlreadySubscribedError – If the address or user is already subscribed to the mailing list with the given role. Note however that it is possible to subscribe an address to a mailing list with a particular role, and also subscribe a user with a matching preferred address that is explicitly subscribed with the same role.
  • InvalidEmailAddressError – If the address being subscribed is the list’s posting address.
subscribe_address = <zope.interface.interface.Attribute object at 0x7f2e6b6e7e50 mailman.interfaces.mailinglist.IMailingList.subscribe_address>
subscribers = <zope.interface.interface.Attribute object at 0x7f2e6b72fac0 mailman.interfaces.mailinglist.IMailingList.subscribers>
subscription_policy = <zope.interface.interface.Attribute object at 0x7f2e6b72fb80 mailman.interfaces.mailinglist.IMailingList.subscription_policy>
unsubscribe_address = <zope.interface.interface.Attribute object at 0x7f2e6b6e7df0 mailman.interfaces.mailinglist.IMailingList.unsubscribe_address>
unsubscription_policy = <zope.interface.interface.Attribute object at 0x7f2e6b72fb20 mailman.interfaces.mailinglist.IMailingList.unsubscription_policy>
usenet_watermark = <zope.interface.interface.Attribute object at 0x7f2e6b77cf40 mailman.interfaces.mailinglist.IMailingList.usenet_watermark>
volume = <zope.interface.interface.Attribute object at 0x7f2e6b721d90 mailman.interfaces.mailinglist.IMailingList.volume>