summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBarry Warsaw2009-07-18 22:31:45 -0400
committerBarry Warsaw2009-07-18 22:31:45 -0400
commitd9ad19e86ff658a74870fb488cd74e5002b63bc3 (patch)
tree29a7e53c290a95d6280772d6aa52a8b160649596
parent422a6757e6aafbd12c220aa8dfdc33f8c377718c (diff)
downloadmailman-d9ad19e86ff658a74870fb488cd74e5002b63bc3.tar.gz
mailman-d9ad19e86ff658a74870fb488cd74e5002b63bc3.tar.zst
mailman-d9ad19e86ff658a74870fb488cd74e5002b63bc3.zip
-rw-r--r--src/mailman/docs/chains.txt11
-rw-r--r--src/mailman/docs/languages.txt4
-rw-r--r--src/mailman/docs/lifecycle.txt2
-rw-r--r--src/mailman/docs/pending.txt2
-rw-r--r--src/mailman/docs/pipelines.txt2
-rw-r--r--src/mailman/docs/registration.txt64
-rw-r--r--src/mailman/docs/requests.txt68
-rw-r--r--src/mailman/docs/styles.txt37
-rw-r--r--src/mailman/docs/usermanager.txt21
-rw-r--r--src/mailman/docs/users.txt56
-rw-r--r--src/mailman/pipeline/docs/ack-headers.txt5
-rw-r--r--src/mailman/pipeline/docs/acknowledge.txt21
-rw-r--r--src/mailman/pipeline/docs/after-delivery.txt3
-rw-r--r--src/mailman/pipeline/docs/archives.txt3
-rw-r--r--src/mailman/pipeline/docs/avoid-duplicates.txt13
-rw-r--r--src/mailman/pipeline/docs/calc-recips.txt25
-rw-r--r--src/mailman/pipeline/docs/cleanse.txt9
-rw-r--r--src/mailman/pipeline/docs/cook-headers.txt53
-rw-r--r--src/mailman/pipeline/docs/decorate.txt64
-rw-r--r--src/mailman/pipeline/docs/file-recips.txt13
-rw-r--r--src/mailman/pipeline/docs/filtering.txt23
-rw-r--r--src/mailman/pipeline/docs/nntp.txt13
-rw-r--r--src/mailman/pipeline/docs/reply-to.txt39
-rw-r--r--src/mailman/pipeline/docs/replybot.txt19
-rw-r--r--src/mailman/pipeline/docs/scrubber.txt29
-rw-r--r--src/mailman/pipeline/docs/subject-munging.txt31
-rw-r--r--src/mailman/pipeline/docs/tagger.txt19
-rw-r--r--src/mailman/pipeline/docs/to-outgoing.txt3
-rw-r--r--src/mailman/queue/docs/archiver.txt3
-rw-r--r--src/mailman/queue/docs/command.txt9
-rw-r--r--src/mailman/queue/docs/digester.txt21
-rw-r--r--src/mailman/queue/docs/incoming.txt23
-rw-r--r--src/mailman/queue/docs/lmtp.txt9
-rw-r--r--src/mailman/queue/docs/news.txt15
-rw-r--r--src/mailman/queue/docs/outgoing.txt15
-rw-r--r--src/mailman/queue/docs/runner.txt7
-rw-r--r--src/mailman/rest/docs/domains.txt20
-rw-r--r--src/mailman/rules/docs/administrivia.txt5
-rw-r--r--src/mailman/rules/docs/approve.txt23
-rw-r--r--src/mailman/rules/docs/emergency.txt3
-rw-r--r--src/mailman/rules/docs/header-matching.txt5
-rw-r--r--src/mailman/rules/docs/implicit-dest.txt17
-rw-r--r--src/mailman/rules/docs/loop.txt5
-rw-r--r--src/mailman/rules/docs/max-size.txt7
-rw-r--r--src/mailman/rules/docs/moderation.txt7
-rw-r--r--src/mailman/rules/docs/news-moderation.txt3
-rw-r--r--src/mailman/rules/docs/no-subject.txt5
-rw-r--r--src/mailman/rules/docs/recipients.txt3
-rw-r--r--src/mailman/rules/docs/rules.txt7
-rw-r--r--src/mailman/rules/docs/suspicious.txt5
-rw-r--r--src/mailman/styles/default.py2
-rw-r--r--src/mailman/tests/test_documentation.py5
52 files changed, 461 insertions, 415 deletions
diff --git a/src/mailman/docs/chains.txt b/src/mailman/docs/chains.txt
index 186590a93..3fee28e7d 100644
--- a/src/mailman/docs/chains.txt
+++ b/src/mailman/docs/chains.txt
@@ -1,3 +1,4 @@
+======
Chains
======
@@ -10,7 +11,7 @@ processing of messages.
The Discard chain
------------------
+=================
The Discard chain simply throws the message away.
@@ -50,7 +51,7 @@ The Discard chain simply throws the message away.
The Reject chain
-----------------
+================
The Reject chain bounces the message back to the original sender, and logs
this action.
@@ -95,7 +96,7 @@ The bounce message is now sitting in the Virgin queue.
The Hold Chain
---------------
+==============
The Hold chain places the message into the admin request database and
depending on the list's settings, sends a notification to both the original
@@ -248,7 +249,7 @@ The message itself is held in the message store.
The Accept chain
-----------------
+================
The Accept chain sends the message on the 'prep' queue, where it will be
processed and sent on to the list membership.
@@ -282,7 +283,7 @@ processed and sent on to the list membership.
Run-time chains
----------------
+===============
We can also define chains at run time, and these chains can be mutated.
Run-time chains are made up of links where each link associates both a rule
diff --git a/src/mailman/docs/languages.txt b/src/mailman/docs/languages.txt
index 87c68f034..77b51cbeb 100644
--- a/src/mailman/docs/languages.txt
+++ b/src/mailman/docs/languages.txt
@@ -49,7 +49,7 @@ You can iterate over all the known language codes.
>>> mgr.add('pl', 'iso-8859-2', 'Polish')
>>> sorted(mgr.codes)
- ['en', 'it', 'pl']
+ [u'en', u'it', u'pl']
You can iterate over all the known languages.
@@ -76,7 +76,7 @@ You can get a particular language by its code.
>>> print mgr['xx'].code
Traceback (most recent call last):
...
- KeyError: 'xx'
+ KeyError: u'xx'
>>> print mgr.get('it').description
Italian
>>> print mgr.get('xx')
diff --git a/src/mailman/docs/lifecycle.txt b/src/mailman/docs/lifecycle.txt
index 8f45dc880..e6dcc7c33 100644
--- a/src/mailman/docs/lifecycle.txt
+++ b/src/mailman/docs/lifecycle.txt
@@ -28,7 +28,7 @@ bogus posting address, you get an exception.
>>> create_list('not a valid address')
Traceback (most recent call last):
...
- InvalidEmailAddress: 'not a valid address'
+ InvalidEmailAddress: u'not a valid address'
If the posting address is valid, but the domain has not been registered with
Mailman yet, you get an exception.
diff --git a/src/mailman/docs/pending.txt b/src/mailman/docs/pending.txt
index abfba4885..5d7706bf6 100644
--- a/src/mailman/docs/pending.txt
+++ b/src/mailman/docs/pending.txt
@@ -38,7 +38,7 @@ basically means returning the IPendable structure (as a dict) from the
database that matches the token. If the token isn't in the database, None is
returned.
- >>> pendable = pendingdb.confirm('missing')
+ >>> pendable = pendingdb.confirm(bytes('missing'))
>>> print pendable
None
>>> pendable = pendingdb.confirm(token)
diff --git a/src/mailman/docs/pipelines.txt b/src/mailman/docs/pipelines.txt
index 36bf2dd23..5ad6ba243 100644
--- a/src/mailman/docs/pipelines.txt
+++ b/src/mailman/docs/pipelines.txt
@@ -10,7 +10,7 @@ rules and chains, there is no way to stop a pipeline from processing the
message once it's started.
>>> from mailman.app.lifecycle import create_list
- >>> mlist = create_list(u'xtest@example.com')
+ >>> mlist = create_list('xtest@example.com')
>>> print mlist.pipeline
built-in
>>> from mailman.core.pipelines import process
diff --git a/src/mailman/docs/registration.txt b/src/mailman/docs/registration.txt
index 519b81ba8..ff6466f82 100644
--- a/src/mailman/docs/registration.txt
+++ b/src/mailman/docs/registration.txt
@@ -17,7 +17,7 @@ stuff.
>>> from mailman.interfaces.domain import IDomainManager
>>> manager = IDomainManager(config)
- >>> domain = manager[u'example.com']
+ >>> domain = manager['example.com']
Get a registrar by adapting a domain.
@@ -51,27 +51,27 @@ Some amount of sanity checks are performed on the email address, although
honestly, not as much as probably should be done. Still, some patently bad
addresses are rejected outright.
- >>> registrar.register(u'')
+ >>> registrar.register('')
Traceback (most recent call last):
...
InvalidEmailAddress: u''
- >>> registrar.register(u'some name@example.com')
+ >>> registrar.register('some name@example.com')
Traceback (most recent call last):
...
InvalidEmailAddress: u'some name@example.com'
- >>> registrar.register(u'<script>@example.com')
+ >>> registrar.register('<script>@example.com')
Traceback (most recent call last):
...
InvalidEmailAddress: u'<script>@example.com'
- >>> registrar.register(u'\xa0@example.com')
+ >>> registrar.register('\xa0@example.com')
Traceback (most recent call last):
...
InvalidEmailAddress: u'\xa0@example.com'
- >>> registrar.register(u'noatsign')
+ >>> registrar.register('noatsign')
Traceback (most recent call last):
...
InvalidEmailAddress: u'noatsign'
- >>> registrar.register(u'nodom@ain')
+ >>> registrar.register('nodom@ain')
Traceback (most recent call last):
...
InvalidEmailAddress: u'nodom@ain'
@@ -85,16 +85,16 @@ is complete. No IUser or IAddress is created at registration time, but a
record is added to the pending database, and the token for that record is
returned.
- >>> token = registrar.register(u'aperson@example.com', u'Anne Person')
+ >>> token = registrar.register('aperson@example.com', 'Anne Person')
>>> check_token(token)
ok
There should be no records in the user manager for this address yet.
>>> usermgr = config.db.user_manager
- >>> print usermgr.get_user(u'aperson@example.com')
+ >>> print usermgr.get_user('aperson@example.com')
None
- >>> print usermgr.get_address(u'aperson@example.com')
+ >>> print usermgr.get_address('aperson@example.com')
None
But this address is waiting for confirmation.
@@ -185,10 +185,10 @@ extracts the token and uses that to confirm the pending registration.
Now, there is an IAddress in the database matching the address, as well as an
IUser linked to this address. The IAddress is verified.
- >>> found_address = usermgr.get_address(u'aperson@example.com')
+ >>> found_address = usermgr.get_address('aperson@example.com')
>>> found_address
<Address: Anne Person <aperson@example.com> [verified] at ...>
- >>> found_user = usermgr.get_user(u'aperson@example.com')
+ >>> found_user = usermgr.get_user('aperson@example.com')
>>> found_user
<User "Anne Person" at ...>
>>> found_user.controls(found_address.address)
@@ -204,7 +204,7 @@ Non-standard registrations
If you try to confirm a registration token twice, of course only the first one
will work. The second one is ignored.
- >>> token = registrar.register(u'bperson@example.com')
+ >>> token = registrar.register('bperson@example.com')
>>> check_token(token)
ok
>>> filebase = switchboard.files[0]
@@ -222,25 +222,25 @@ If an address is in the system, but that address is not linked to a user yet
and the address is not yet validated, then no user is created until the
confirmation step is completed.
- >>> usermgr.create_address(u'cperson@example.com')
+ >>> usermgr.create_address('cperson@example.com')
<Address: cperson@example.com [not verified] at ...>
- >>> token = registrar.register(u'cperson@example.com', u'Claire Person')
- >>> print usermgr.get_user(u'cperson@example.com')
+ >>> token = registrar.register('cperson@example.com', 'Claire Person')
+ >>> print usermgr.get_user('cperson@example.com')
None
>>> filebase = switchboard.files[0]
>>> qmsg, qdata = switchboard.dequeue(filebase)
>>> switchboard.finish(filebase)
>>> registrar.confirm(token)
True
- >>> usermgr.get_user(u'cperson@example.com')
+ >>> usermgr.get_user('cperson@example.com')
<User "Claire Person" at ...>
- >>> usermgr.get_address(u'cperson@example.com')
+ >>> usermgr.get_address('cperson@example.com')
<Address: cperson@example.com [verified] at ...>
Even if the address being registered has already been verified, the
registration sends a confirmation.
- >>> token = registrar.register(u'cperson@example.com')
+ >>> token = registrar.register('cperson@example.com')
>>> token is not None
True
@@ -251,15 +251,15 @@ Discarding
A confirmation token can also be discarded, say if the user changes his or her
mind about registering. When discarded, no IAddress or IUser is created.
- >>> token = registrar.register(u'eperson@example.com', u'Elly Person')
+ >>> token = registrar.register('eperson@example.com', 'Elly Person')
>>> check_token(token)
ok
>>> registrar.discard(token)
>>> print pendingdb.confirm(token)
None
- >>> print usermgr.get_address(u'eperson@example.com')
+ >>> print usermgr.get_address('eperson@example.com')
None
- >>> print usermgr.get_user(u'eperson@example.com')
+ >>> print usermgr.get_user('eperson@example.com')
None
@@ -270,24 +270,24 @@ When a new address for an existing user is registered, there isn't too much
different except that the new address will still need to be verified before it
can be used.
- >>> dperson = usermgr.create_user(u'dperson@example.com', u'Dave Person')
+ >>> dperson = usermgr.create_user('dperson@example.com', 'Dave Person')
>>> dperson
<User "Dave Person" at ...>
- >>> address = usermgr.get_address(u'dperson@example.com')
+ >>> address = usermgr.get_address('dperson@example.com')
>>> address.verified_on = datetime.now()
>>> from operator import attrgetter
>>> sorted((addr for addr in dperson.addresses), key=attrgetter('address'))
[<Address: Dave Person <dperson@example.com> [verified] at ...>]
- >>> dperson.register(u'david.person@example.com', u'David Person')
+ >>> dperson.register('david.person@example.com', 'David Person')
<Address: David Person <david.person@example.com> [not verified] at ...>
- >>> token = registrar.register(u'david.person@example.com')
+ >>> token = registrar.register('david.person@example.com')
>>> filebase = switchboard.files[0]
>>> qmsg, qdata = switchboard.dequeue(filebase)
>>> switchboard.finish(filebase)
>>> registrar.confirm(token)
True
- >>> user = usermgr.get_user(u'david.person@example.com')
+ >>> user = usermgr.get_user('david.person@example.com')
>>> user is dperson
True
>>> user
@@ -303,7 +303,7 @@ Corner cases
If you try to confirm a token that doesn't exist in the pending database, the
confirm method will just return None.
- >>> registrar.confirm('no token')
+ >>> registrar.confirm(bytes('no token'))
False
Likewise, if you try to confirm, through the IUserRegistrar interface, a token
@@ -329,19 +329,19 @@ Registration and subscription
Fred registers with Mailman at the same time that he subscribes to a mailing
list.
- >>> mlist = create_list(u'alpha@example.com')
+ >>> mlist = create_list('alpha@example.com')
>>> token = registrar.register(
- ... u'fred.person@example.com', 'Fred Person', mlist)
+ ... 'fred.person@example.com', 'Fred Person', mlist)
Before confirmation, Fred is not a member of the mailing list.
- >>> print mlist.members.get_member(u'fred.person@example.com')
+ >>> print mlist.members.get_member('fred.person@example.com')
None
But after confirmation, he is.
>>> registrar.confirm(token)
True
- >>> print mlist.members.get_member(u'fred.person@example.com')
+ >>> print mlist.members.get_member('fred.person@example.com')
<Member: Fred Person <fred.person@example.com>
on alpha@example.com as MemberRole.member>
diff --git a/src/mailman/docs/requests.txt b/src/mailman/docs/requests.txt
index c49f09895..4a04017aa 100644
--- a/src/mailman/docs/requests.txt
+++ b/src/mailman/docs/requests.txt
@@ -39,7 +39,7 @@ mailing list you need to get its requests object.
>>> from zope.interface.verify import verifyObject
>>> verifyObject(IRequests, config.db.requests)
True
- >>> mlist = create_list(u'test@example.com')
+ >>> mlist = create_list('test@example.com')
>>> requests = config.db.requests.get_list_requests(mlist)
>>> verifyObject(IListRequests, requests)
True
@@ -63,10 +63,10 @@ of associated data. The request database assigns no semantics to the held
data, except for the request type. Here we hold some simple bits of data.
>>> from mailman.interfaces.requests import RequestType
- >>> id_1 = requests.hold_request(RequestType.held_message, u'hold_1')
- >>> id_2 = requests.hold_request(RequestType.subscription, u'hold_2')
- >>> id_3 = requests.hold_request(RequestType.unsubscription, u'hold_3')
- >>> id_4 = requests.hold_request(RequestType.held_message, u'hold_4')
+ >>> id_1 = requests.hold_request(RequestType.held_message, 'hold_1')
+ >>> id_2 = requests.hold_request(RequestType.subscription, 'hold_2')
+ >>> id_3 = requests.hold_request(RequestType.unsubscription, 'hold_3')
+ >>> id_4 = requests.hold_request(RequestType.held_message, 'hold_4')
>>> id_1, id_2, id_3, id_4
(1, 2, 3, 4)
@@ -96,7 +96,7 @@ If we try to hold a request with a bogus type, we get an exception.
We can hold requests with additional data.
>>> data = dict(foo='yes', bar='no')
- >>> id_5 = requests.hold_request(RequestType.held_message, u'hold_5', data)
+ >>> id_5 = requests.hold_request(RequestType.held_message, 'hold_5', data)
>>> id_5
5
>>> requests.count
@@ -215,9 +215,9 @@ Holding messages
For this section, we need a mailing list and at least one message.
- >>> mlist = create_list(u'alist@example.com')
- >>> mlist.preferred_language = u'en'
- >>> mlist.real_name = u'A Test List'
+ >>> mlist = create_list('alist@example.com')
+ >>> mlist.preferred_language = 'en'
+ >>> mlist.real_name = 'A Test List'
>>> msg = message_from_string("""\
... From: aperson@example.org
... To: alist@example.com
@@ -243,7 +243,7 @@ We can also hold a message with some additional metadata.
>>> msgdata = dict(sender='aperson@example.com',
... approved=True,
... received_time=123.45)
- >>> id_2 = moderator.hold_message(mlist, msg, msgdata, u'Feeling ornery')
+ >>> id_2 = moderator.hold_message(mlist, msg, msgdata, 'Feeling ornery')
>>> requests.get_request(id_2) is not None
True
@@ -346,7 +346,7 @@ is deleted.
... """)
>>> id_4 = moderator.hold_message(mlist, msg, {}, 'Needs approval')
>>> moderator.handle_message(mlist, id_4, Action.discard)
- >>> print config.db.message_store.get_message_by_id(u'<12345>')
+ >>> print config.db.message_store.get_message_by_id('<12345>')
None
But if we ask to preserve the message when we discard it, it will be held in
@@ -354,7 +354,7 @@ the message store after disposition.
>>> id_4 = moderator.hold_message(mlist, msg, {}, 'Needs approval')
>>> moderator.handle_message(mlist, id_4, Action.discard, preserve=True)
- >>> stored_msg = config.db.message_store.get_message_by_id(u'<12345>')
+ >>> stored_msg = config.db.message_store.get_message_by_id('<12345>')
>>> print stored_msg.as_string()
From: aperson@example.org
To: alist@example.com
@@ -372,10 +372,10 @@ moderators.
# Set a new Message-ID from the previous hold so we don't try to store
# collisions in the message storage.
>>> del msg['message-id']
- >>> msg['Message-ID'] = u'<abcde>'
+ >>> msg['Message-ID'] = '<abcde>'
>>> id_4 = moderator.hold_message(mlist, msg, {}, 'Needs approval')
>>> moderator.handle_message(mlist, id_4, Action.discard,
- ... forward=[u'zperson@example.com'])
+ ... forward=['zperson@example.com'])
>>> qmsg, qdata = dequeue()
>>> print qmsg.as_string()
Subject: Forward of moderated message
@@ -416,8 +416,8 @@ choosing and their preferred language.
>>> from mailman.interfaces.member import DeliveryMode
>>> mlist.admin_immed_notify = False
>>> id_3 = moderator.hold_subscription(mlist,
- ... u'bperson@example.org', u'Ben Person',
- ... u'{NONE}abcxyz', DeliveryMode.regular, u'en')
+ ... 'bperson@example.org', 'Ben Person',
+ ... '{NONE}abcxyz', DeliveryMode.regular, 'en')
>>> requests.get_request(id_3) is not None
True
@@ -436,8 +436,8 @@ queue when the message is held.
>>> # XXX This will almost certainly change once we've worked out the web
>>> # space layout for mailing lists now.
>>> id_4 = moderator.hold_subscription(mlist,
- ... u'cperson@example.org', u'Claire Person',
- ... u'{NONE}zyxcba', DeliveryMode.regular, u'en')
+ ... 'cperson@example.org', 'Claire Person',
+ ... '{NONE}zyxcba', DeliveryMode.regular, 'en')
>>> requests.get_request(id_4) is not None
True
>>> qmsg, qdata = dequeue()
@@ -533,8 +533,8 @@ mailing list.
>>> mlist.send_welcome_msg = True
>>> id_4 = moderator.hold_subscription(mlist,
- ... u'fperson@example.org', u'Frank Person',
- ... u'{NONE}abcxyz', DeliveryMode.regular, u'en')
+ ... 'fperson@example.org', 'Frank Person',
+ ... '{NONE}abcxyz', DeliveryMode.regular, 'en')
A message will be sent to the moderators telling them about the held
subscription and the fact that they may need to approve it.
@@ -673,7 +673,7 @@ The admin message is sent to the moderators.
Frank Person is now a member of the mailing list.
- >>> member = mlist.members.get_member(u'fperson@example.org')
+ >>> member = mlist.members.get_member('fperson@example.org')
>>> member
<Member: Frank Person <fperson@example.org>
on alist@example.com as MemberRole.member>
@@ -682,10 +682,10 @@ Frank Person is now a member of the mailing list.
>>> print member.delivery_mode
DeliveryMode.regular
>>> user = config.db.user_manager.get_user(member.address.address)
- >>> user.real_name
- u'Frank Person'
- >>> user.password
- u'{NONE}abcxyz'
+ >>> print user.real_name
+ Frank Person
+ >>> print user.password
+ {NONE}abcxyz
Holding unsubscription requests
@@ -697,21 +697,21 @@ unsubscription holds can send the list's moderators an immediate notification.
>>> mlist.admin_immed_notify = False
>>> from mailman.interfaces.member import MemberRole
- >>> user_1 = config.db.user_manager.create_user(u'gperson@example.com')
+ >>> user_1 = config.db.user_manager.create_user('gperson@example.com')
>>> address_1 = list(user_1.addresses)[0]
>>> address_1.subscribe(mlist, MemberRole.member)
<Member: gperson@example.com on alist@example.com as MemberRole.member>
- >>> user_2 = config.db.user_manager.create_user(u'hperson@example.com')
+ >>> user_2 = config.db.user_manager.create_user('hperson@example.com')
>>> address_2 = list(user_2.addresses)[0]
>>> address_2.subscribe(mlist, MemberRole.member)
<Member: hperson@example.com on alist@example.com as MemberRole.member>
- >>> id_5 = moderator.hold_unsubscription(mlist, u'gperson@example.com')
+ >>> id_5 = moderator.hold_unsubscription(mlist, 'gperson@example.com')
>>> requests.get_request(id_5) is not None
True
>>> virginq.files
[]
>>> mlist.admin_immed_notify = True
- >>> id_6 = moderator.hold_unsubscription(mlist, u'hperson@example.com')
+ >>> id_6 = moderator.hold_unsubscription(mlist, 'hperson@example.com')
>>> qmsg, qdata = dequeue()
>>> print qmsg.as_string()
MIME-Version: 1.0
@@ -758,7 +758,7 @@ subscribed.
>>> moderator.handle_unsubscription(mlist, id_5, Action.discard)
>>> print requests.get_request(id_5)
None
- >>> mlist.members.get_member(u'gperson@example.com')
+ >>> mlist.members.get_member('gperson@example.com')
<Member: gperson@example.com on alist@example.com as MemberRole.member>
The request can be rejected, in which case a message is sent to the member,
@@ -802,18 +802,18 @@ and the person remains a member of the mailing list.
reduced_list_headers: True
version : 3
- >>> mlist.members.get_member(u'hperson@example.com')
+ >>> mlist.members.get_member('hperson@example.com')
<Member: hperson@example.com on alist@example.com as MemberRole.member>
The unsubscription request can also be accepted. This removes the member from
the mailing list.
>>> mlist.send_goodbye_msg = True
- >>> mlist.goodbye_msg = u'So long!'
+ >>> mlist.goodbye_msg = 'So long!'
>>> mlist.admin_immed_notify = False
- >>> id_7 = moderator.hold_unsubscription(mlist, u'gperson@example.com')
+ >>> id_7 = moderator.hold_unsubscription(mlist, 'gperson@example.com')
>>> moderator.handle_unsubscription(mlist, id_7, Action.accept)
- >>> print mlist.members.get_member(u'gperson@example.com')
+ >>> print mlist.members.get_member('gperson@example.com')
None
There are now two messages in the virgin queue, one to the member who was just
diff --git a/src/mailman/docs/styles.txt b/src/mailman/docs/styles.txt
index d12e57b08..7524ecf64 100644
--- a/src/mailman/docs/styles.txt
+++ b/src/mailman/docs/styles.txt
@@ -1,3 +1,4 @@
+===========
List styles
===========
@@ -13,7 +14,7 @@ modify the mailing list any way it wants.
Let's start with a vanilla mailing list and a default style manager.
- >>> mlist = config.db.list_manager.create(u'_xtest@example.com')
+ >>> mlist = config.db.list_manager.create('_xtest@example.com')
>>> from mailman.styles.manager import StyleManager
>>> style_manager = StyleManager()
>>> style_manager.populate()
@@ -22,7 +23,7 @@ Let's start with a vanilla mailing list and a default style manager.
The default style
------------------
+=================
There is a default style which implements the legacy application of list
defaults from previous versions of Mailman. This style only matching a
@@ -49,7 +50,7 @@ manager's `lookup()` method.
Registering styles
-------------------
+==================
New styles must implement the IStyle interface.
@@ -61,7 +62,7 @@ New styles must implement the IStyle interface.
... priority = 10
... def apply(self, mailing_list):
... # Just does something very simple.
- ... mailing_list.msg_footer = u'test footer'
+ ... mailing_list.msg_footer = 'test footer'
... def match(self, mailing_list, styles):
... # Applies to any test list
... if 'test' in mailing_list.fqdn_listname:
@@ -76,15 +77,15 @@ style. This is because the default style only gets applied when no other
styles match the mailing list.
>>> sorted(style.name for style in style_manager.lookup(mlist))
- ['test']
+ [u'test']
>>> for style in style_manager.lookup(mlist):
... style.apply(mlist)
- >>> mlist.msg_footer
- u'test footer'
+ >>> print mlist.msg_footer
+ test footer
Style priority
---------------
+==============
When multiple styles match a particular mailing list, they are applied in
descending order of priority. In other words, a priority zero style would be
@@ -95,16 +96,16 @@ applied last.
... priority = 5
... # Use the base class's match() method.
... def apply(self, mailing_list):
- ... mailing_list.msg_footer = u'another footer'
+ ... mailing_list.msg_footer = 'another footer'
- >>> mlist.msg_footer = u''
+ >>> mlist.msg_footer = ''
>>> mlist.msg_footer
u''
>>> style_manager.register(AnotherTestStyle())
>>> for style in style_manager.lookup(mlist):
... style.apply(mlist)
- >>> mlist.msg_footer
- u'another footer'
+ >>> print mlist.msg_footer
+ another footer
You can change the priority of a style, and if you reapply the styles, they
will take effect in the new priority order.
@@ -115,22 +116,22 @@ will take effect in the new priority order.
>>> style_2.priority = 10
>>> for style in style_manager.lookup(mlist):
... style.apply(mlist)
- >>> mlist.msg_footer
- u'test footer'
+ >>> print mlist.msg_footer
+ test footer
Unregistering styles
---------------------
+====================
You can unregister a style, making it unavailable in the future.
>>> style_manager.unregister(style_2)
>>> sorted(style.name for style in style_manager.lookup(mlist))
- ['test']
+ [u'test']
Corner cases
-------------
+============
If you register a style with the same name as an already registered style, you
get an exception.
@@ -153,4 +154,4 @@ If you try to unregister a style that isn't registered, you get an exception.
>>> style_manager.unregister(style_2)
Traceback (most recent call last):
...
- KeyError: 'another'
+ KeyError: u'another'
diff --git a/src/mailman/docs/usermanager.txt b/src/mailman/docs/usermanager.txt
index f8cbfeef2..3c5369b84 100644
--- a/src/mailman/docs/usermanager.txt
+++ b/src/mailman/docs/usermanager.txt
@@ -1,3 +1,4 @@
+================
The user manager
================
@@ -14,7 +15,7 @@ config object.
Creating users
---------------
+==============
There are several ways you can create a user object. The simplest is to
create a 'blank' user by not providing an address or real name at creation
@@ -39,19 +40,19 @@ The user has preferences, but none of them will be specified.
A user can be assigned a real name.
- >>> user.real_name = u'Anne Person'
+ >>> user.real_name = 'Anne Person'
>>> sorted(user.real_name for user in usermgr.users)
[u'Anne Person']
A user can be assigned a password.
- >>> user.password = u'secret'
+ >>> user.password = 'secret'
>>> sorted(user.password for user in usermgr.users)
[u'secret']
You can also create a user with an address to start out with.
- >>> user_2 = usermgr.create_user(u'bperson@example.com')
+ >>> user_2 = usermgr.create_user('bperson@example.com')
>>> verifyObject(IUser, user_2)
True
>>> sorted(address.address for address in user_2.addresses)
@@ -61,13 +62,13 @@ You can also create a user with an address to start out with.
As above, you can assign a real name to such users.
- >>> user_2.real_name = u'Ben Person'
+ >>> user_2.real_name = 'Ben Person'
>>> sorted(user.real_name for user in usermgr.users)
[u'Anne Person', u'Ben Person']
You can also create a user with just a real name.
- >>> user_3 = usermgr.create_user(real_name=u'Claire Person')
+ >>> user_3 = usermgr.create_user(real_name='Claire Person')
>>> verifyObject(IUser, user_3)
True
>>> sorted(address.address for address in user.addresses)
@@ -77,7 +78,7 @@ You can also create a user with just a real name.
Finally, you can create a user with both an address and a real name.
- >>> user_4 = usermgr.create_user(u'dperson@example.com', u'Dan Person')
+ >>> user_4 = usermgr.create_user('dperson@example.com', 'Dan Person')
>>> verifyObject(IUser, user_3)
True
>>> sorted(address.address for address in user_4.addresses)
@@ -89,7 +90,7 @@ Finally, you can create a user with both an address and a real name.
Deleting users
---------------
+==============
You delete users by going through the user manager. The deleted user is no
longer available through the user manager iterator.
@@ -100,7 +101,7 @@ longer available through the user manager iterator.
Finding users
--------------
+=============
You can ask the user manager to find the IUser that controls a particular
email address. You'll get back the original user object if it's found. Note
@@ -117,7 +118,7 @@ object.
If the address is not in the user database or does not have a user associated
with it, you will get None back.
- >>> print usermgr.get_user(u'zperson@example.com')
+ >>> print usermgr.get_user('zperson@example.com')
None
>>> user_4.unlink(address)
>>> print usermgr.get_user(address.address)
diff --git a/src/mailman/docs/users.txt b/src/mailman/docs/users.txt
index b557a280d..ef4f3062b 100644
--- a/src/mailman/docs/users.txt
+++ b/src/mailman/docs/users.txt
@@ -1,3 +1,4 @@
+=====
Users
=====
@@ -11,13 +12,13 @@ See usermanager.txt for examples of how to create, delete, and find users.
User data
----------
+=========
Users may have a real name and a password.
>>> user_1 = usermgr.create_user()
- >>> user_1.password = u'my password'
- >>> user_1.real_name = u'Zoe Person'
+ >>> user_1.password = 'my password'
+ >>> user_1.real_name = 'Zoe Person'
>>> sorted(user.real_name for user in usermgr.users)
[u'Zoe Person']
>>> sorted(user.password for user in usermgr.users)
@@ -25,8 +26,8 @@ Users may have a real name and a password.
The password and real name can be changed at any time.
- >>> user_1.real_name = u'Zoe X. Person'
- >>> user_1.password = u'another password'
+ >>> user_1.real_name = 'Zoe X. Person'
+ >>> user_1.password = 'another password'
>>> sorted(user.real_name for user in usermgr.users)
[u'Zoe X. Person']
>>> sorted(user.password for user in usermgr.users)
@@ -34,7 +35,7 @@ The password and real name can be changed at any time.
Users addresses
----------------
+===============
One of the pieces of information that a user links to is a set of email
addresses they control, in the form of IAddress objects. A user can control
@@ -43,9 +44,9 @@ many addresses, but addresses may be controlled by only one user.
The easiest way to link a user to an address is to just register the new
address on a user object.
- >>> user_1.register(u'zperson@example.com', u'Zoe Person')
+ >>> user_1.register('zperson@example.com', 'Zoe Person')
<Address: Zoe Person <zperson@example.com> [not verified] at 0x...>
- >>> user_1.register(u'zperson@example.org')
+ >>> user_1.register('zperson@example.org')
<Address: zperson@example.org [not verified] at 0x...>
>>> sorted(address.address for address in user_1.addresses)
[u'zperson@example.com', u'zperson@example.org']
@@ -54,7 +55,7 @@ address on a user object.
You can also create the address separately and then link it to the user.
- >>> address_1 = usermgr.create_address(u'zperson@example.net')
+ >>> address_1 = usermgr.create_address('zperson@example.net')
>>> user_1.link(address_1)
>>> sorted(address.address for address in user_1.addresses)
[u'zperson@example.com', u'zperson@example.net', u'zperson@example.org']
@@ -73,27 +74,27 @@ You can also ask whether a given user controls a given address.
>>> user_1.controls(address_1.address)
True
- >>> user_1.controls(u'bperson@example.com')
+ >>> user_1.controls('bperson@example.com')
False
Given a text email address, the user manager can find the user that controls
that address.
- >>> usermgr.get_user(u'zperson@example.com') is user_1
+ >>> usermgr.get_user('zperson@example.com') is user_1
True
- >>> usermgr.get_user(u'zperson@example.net') is user_1
+ >>> usermgr.get_user('zperson@example.net') is user_1
True
- >>> usermgr.get_user(u'zperson@example.org') is user_1
+ >>> usermgr.get_user('zperson@example.org') is user_1
True
- >>> print usermgr.get_user(u'bperson@example.com')
+ >>> print usermgr.get_user('bperson@example.com')
None
Addresses can also be unlinked from a user.
>>> user_1.unlink(address_1)
- >>> user_1.controls(u'zperson@example.net')
+ >>> user_1.controls('zperson@example.net')
False
- >>> print usermgr.get_user(u'aperson@example.net')
+ >>> print usermgr.get_user('aperson@example.net')
None
But don't try to unlink the address from a user it's not linked to.
@@ -109,7 +110,7 @@ But don't try to unlink the address from a user it's not linked to.
Users and preferences
----------------------
+=====================
This is a helper function for the following section.
@@ -132,12 +133,12 @@ Users have preferences, but these preferences have no default settings.
Some of these preferences are booleans and they can be set to True or False.
- >>> config.languages.add(u'it', u'iso-8859-1', u'Italian')
+ >>> config.languages.add('it', 'iso-8859-1', 'Italian')
>>> from mailman.constants import DeliveryMode
>>> prefs = user_1.preferences
>>> prefs.acknowledge_posts = True
- >>> prefs.preferred_language = u'it'
+ >>> prefs.preferred_language = 'it'
>>> prefs.receive_list_copy = False
>>> prefs.receive_own_postings = False
>>> prefs.delivery_mode = DeliveryMode.regular
@@ -150,7 +151,7 @@ Some of these preferences are booleans and they can be set to True or False.
Subscriptions
--------------
+=============
Users know which mailing lists they are subscribed to, regardless of
membership role.
@@ -158,14 +159,14 @@ membership role.
>>> user_1.link(address_1)
>>> sorted(address.address for address in user_1.addresses)
[u'zperson@example.com', u'zperson@example.net', u'zperson@example.org']
- >>> com = usermgr.get_address(u'zperson@example.com')
- >>> org = usermgr.get_address(u'zperson@example.org')
- >>> net = usermgr.get_address(u'zperson@example.net')
+ >>> com = usermgr.get_address('zperson@example.com')
+ >>> org = usermgr.get_address('zperson@example.org')
+ >>> net = usermgr.get_address('zperson@example.net')
>>> from mailman.app.lifecycle import create_list
- >>> mlist_1 = create_list(u'xtest_1@example.com')
- >>> mlist_2 = create_list(u'xtest_2@example.com')
- >>> mlist_3 = create_list(u'xtest_3@example.com')
+ >>> mlist_1 = create_list('xtest_1@example.com')
+ >>> mlist_2 = create_list('xtest_2@example.com')
+ >>> mlist_3 = create_list('xtest_3@example.com')
>>> from mailman.interfaces.member import MemberRole
>>> com.subscribe(mlist_1, MemberRole.member)
@@ -188,7 +189,8 @@ membership role.
>>> len(members)
4
>>> def sortkey(member):
- ... return member.address.address, member.mailing_list, int(member.role)
+ ... return (member.address.address, member.mailing_list,
+ ... int(member.role))
>>> for member in sorted(members, key=sortkey):
... print member.address.address, member.mailing_list, member.role
zperson@example.com xtest_1@example.com MemberRole.member
diff --git a/src/mailman/pipeline/docs/ack-headers.txt b/src/mailman/pipeline/docs/ack-headers.txt
index ca41df03e..49b203cad 100644
--- a/src/mailman/pipeline/docs/ack-headers.txt
+++ b/src/mailman/pipeline/docs/ack-headers.txt
@@ -1,3 +1,4 @@
+======================
Acknowledgment headers
======================
@@ -8,8 +9,8 @@ changes depend on mailing list settings and others depend on how the message
is getting sent through the system. We'll take things one-by-one.
>>> from mailman.pipeline.cook_headers import process
- >>> mlist = config.db.list_manager.create(u'_xtest@example.com')
- >>> mlist.subject_prefix = u''
+ >>> mlist = config.db.list_manager.create('_xtest@example.com')
+ >>> mlist.subject_prefix = ''
When the message's metadata has a 'noack' key set, an 'X-Ack: no' header is
added.
diff --git a/src/mailman/pipeline/docs/acknowledge.txt b/src/mailman/pipeline/docs/acknowledge.txt
index a4c68f900..72292cd80 100644
--- a/src/mailman/pipeline/docs/acknowledge.txt
+++ b/src/mailman/pipeline/docs/acknowledge.txt
@@ -1,3 +1,4 @@
+======================
Message acknowledgment
======================
@@ -6,9 +7,9 @@ receive acknowledgments of their postings, Mailman will sent them such an
acknowledgment.
>>> handler = config.handlers['acknowledge']
- >>> mlist = config.db.list_manager.create(u'_xtest@example.com')
- >>> mlist.real_name = u'XTest'
- >>> mlist.preferred_language = u'en'
+ >>> mlist = config.db.list_manager.create('_xtest@example.com')
+ >>> mlist.real_name = 'XTest'
+ >>> mlist.preferred_language = 'en'
>>> # XXX This will almost certainly change once we've worked out the web
>>> # space layout for mailing lists now.
@@ -22,14 +23,14 @@ Subscribe a user to the mailing list.
>>> usermgr = config.db.user_manager
>>> from mailman.interfaces.member import MemberRole
- >>> user_1 = usermgr.create_user(u'aperson@example.com')
+ >>> user_1 = usermgr.create_user('aperson@example.com')
>>> address_1 = list(user_1.addresses)[0]
>>> address_1.subscribe(mlist, MemberRole.member)
<Member: aperson@example.com on _xtest@example.com as MemberRole.member>
Non-member posts
-----------------
+================
Non-members can't get acknowledgments of their posts to the mailing list.
@@ -49,13 +50,13 @@ person is also not a member, no acknowledgment will be sent either.
...
... """)
>>> handler.process(mlist, msg,
- ... dict(original_sender=u'cperson@example.com'))
+ ... dict(original_sender='cperson@example.com'))
>>> virginq.files
[]
No acknowledgment requested
----------------------------
+===========================
Unless the user has requested acknowledgments, they will not get one.
@@ -71,19 +72,19 @@ Similarly if the original sender is specified in the message metadata, and
that sender is a member but not one who has requested acknowledgments, none
will be sent.
- >>> user_2 = usermgr.create_user(u'dperson@example.com')
+ >>> user_2 = usermgr.create_user('dperson@example.com')
>>> address_2 = list(user_2.addresses)[0]
>>> address_2.subscribe(mlist, MemberRole.member)
<Member: dperson@example.com on _xtest@example.com as MemberRole.member>
>>> handler.process(mlist, msg,
- ... dict(original_sender=u'dperson@example.com'))
+ ... dict(original_sender='dperson@example.com'))
>>> virginq.files
[]
Requested acknowledgments
--------------------------
+=========================
If the member requests acknowledgments, Mailman will send them one when they
post to the mailing list.
diff --git a/src/mailman/pipeline/docs/after-delivery.txt b/src/mailman/pipeline/docs/after-delivery.txt
index b910e89a6..da1a3af08 100644
--- a/src/mailman/pipeline/docs/after-delivery.txt
+++ b/src/mailman/pipeline/docs/after-delivery.txt
@@ -1,3 +1,4 @@
+==============
After delivery
==============
@@ -7,7 +8,7 @@ bookkeeping pieces of information are updated.
>>> import datetime
>>> handler = config.handlers['after-delivery']
- >>> mlist = config.db.list_manager.create(u'_xtest@example.com')
+ >>> mlist = config.db.list_manager.create('_xtest@example.com')
>>> post_time = datetime.datetime.now() - datetime.timedelta(minutes=10)
>>> mlist.last_post_time = post_time
>>> mlist.post_id = 10
diff --git a/src/mailman/pipeline/docs/archives.txt b/src/mailman/pipeline/docs/archives.txt
index d90228525..c6351a659 100644
--- a/src/mailman/pipeline/docs/archives.txt
+++ b/src/mailman/pipeline/docs/archives.txt
@@ -1,3 +1,4 @@
+========
Archives
========
@@ -9,7 +10,7 @@ processes.
>>> from mailman.app.lifecycle import create_list
>>> handler = config.handlers['to-archive']
- >>> mlist = create_list(u'_xtest@example.com')
+ >>> mlist = create_list('_xtest@example.com')
>>> switchboard = config.switchboards['archive']
A helper function.
diff --git a/src/mailman/pipeline/docs/avoid-duplicates.txt b/src/mailman/pipeline/docs/avoid-duplicates.txt
index fe91a9a71..adca9cbe5 100644
--- a/src/mailman/pipeline/docs/avoid-duplicates.txt
+++ b/src/mailman/pipeline/docs/avoid-duplicates.txt
@@ -1,3 +1,4 @@
+================
Avoid duplicates
================
@@ -7,24 +8,24 @@ recipients from the list of recipients that earlier handler modules
(e.g. CalcRecips) calculates.
>>> handler = config.handlers['avoid-duplicates']
- >>> mlist = config.db.list_manager.create(u'_xtest@example.com')
+ >>> mlist = config.db.list_manager.create('_xtest@example.com')
Create some members we're going to use.
>>> from mailman.interfaces.member import MemberRole
>>> address_a = config.db.user_manager.create_address(
- ... u'aperson@example.com')
+ ... 'aperson@example.com')
>>> address_b = config.db.user_manager.create_address(
- ... u'bperson@example.com')
+ ... 'bperson@example.com')
>>> member_a = address_a.subscribe(mlist, MemberRole.member)
>>> member_b = address_b.subscribe(mlist, MemberRole.member)
>>> # This is the message metadata dictionary as it would be produced by
>>> # the CalcRecips handler.
- >>> recips = dict(recips=[u'aperson@example.com', u'bperson@example.com'])
+ >>> recips = dict(recips=['aperson@example.com', 'bperson@example.com'])
Short circuiting
-----------------
+================
The module short-circuits if there are no recipients.
@@ -47,7 +48,7 @@ The module short-circuits if there are no recipients.
Suppressing the list copy
--------------------------
+=========================
Members can elect not to receive a list copy of any message on which they are
explicitly named as a recipient. This is done by setting their
diff --git a/src/mailman/pipeline/docs/calc-recips.txt b/src/mailman/pipeline/docs/calc-recips.txt
index adfbeabbf..03a22e5dc 100644
--- a/src/mailman/pipeline/docs/calc-recips.txt
+++ b/src/mailman/pipeline/docs/calc-recips.txt
@@ -1,3 +1,4 @@
+======================
Calculating recipients
======================
@@ -6,18 +7,18 @@ of recipient addresses. These addresses are calculated by one of the handler
modules and depends on a host of factors.
>>> handler = config.handlers['calculate-recipients']
- >>> mlist = config.db.list_manager.create(u'_xtest@example.com')
+ >>> mlist = config.db.list_manager.create('_xtest@example.com')
Recipients are calculate from the list members, so add a bunch of members to
start out with. First, create a bunch of addresses...
>>> usermgr = config.db.user_manager
- >>> address_a = usermgr.create_address(u'aperson@example.com')
- >>> address_b = usermgr.create_address(u'bperson@example.com')
- >>> address_c = usermgr.create_address(u'cperson@example.com')
- >>> address_d = usermgr.create_address(u'dperson@example.com')
- >>> address_e = usermgr.create_address(u'eperson@example.com')
- >>> address_f = usermgr.create_address(u'fperson@example.com')
+ >>> address_a = usermgr.create_address('aperson@example.com')
+ >>> address_b = usermgr.create_address('bperson@example.com')
+ >>> address_c = usermgr.create_address('cperson@example.com')
+ >>> address_d = usermgr.create_address('dperson@example.com')
+ >>> address_e = usermgr.create_address('eperson@example.com')
+ >>> address_f = usermgr.create_address('fperson@example.com')
...then subscribe these addresses to the mailing list as members...
@@ -38,7 +39,7 @@ start out with. First, create a bunch of addresses...
Short-circuiting
-----------------
+================
Sometimes, the list of recipients already exists in the message metadata.
This can happen for example, when a message was previously delivered to some
@@ -49,7 +50,7 @@ but not all of the recipients.
...
... Something of great import.
... """)
- >>> recips = set((u'qperson@example.com', u'zperson@example.com'))
+ >>> recips = set(('qperson@example.com', 'zperson@example.com'))
>>> msgdata = dict(recips=recips)
>>> handler.process(mlist, msg, msgdata)
>>> sorted(msgdata['recips'])
@@ -57,7 +58,7 @@ but not all of the recipients.
Regular delivery recipients
----------------------------
+===========================
Regular delivery recipients are those people who get messages from the list as
soon as they are posted. In other words, these folks are not digest members.
@@ -86,13 +87,13 @@ for details.
Digest recipients
------------------
+=================
XXX Test various digest deliveries.
Urgent messages
----------------
+===============
XXX Test various urgent deliveries:
* test_urgent_moderator()
diff --git a/src/mailman/pipeline/docs/cleanse.txt b/src/mailman/pipeline/docs/cleanse.txt
index 0940cdb4b..778ecb19d 100644
--- a/src/mailman/pipeline/docs/cleanse.txt
+++ b/src/mailman/pipeline/docs/cleanse.txt
@@ -1,3 +1,4 @@
+=================
Cleansing headers
=================
@@ -6,7 +7,7 @@ related to additional permissions that can be granted to the message and other
headers can be used to fish for membership.
>>> handler = config.handlers['cleanse']
- >>> mlist = config.db.list_manager.create(u'_xtest@example.com')
+ >>> mlist = config.db.list_manager.create('_xtest@example.com')
Headers such as Approved, Approve, and Urgent are used to grant special
pemissions to individual messages. All may contain a password; the first two
@@ -62,7 +63,7 @@ Pegasus mail. I don't remember what program uses X-Confirm-Reading-To though
Anonymous lists
----------------
+===============
Anonymous mailing lists also try to cleanse certain identifying headers from
the original posting, so that it is at least a bit more difficult to determine
@@ -73,8 +74,8 @@ and Reply-To headers in the posted message are taken from list attributes.
Hotmail apparently sets X-Originating-Email.
>>> mlist.anonymous_list = True
- >>> mlist.description = u'A Test Mailing List'
- >>> mlist.preferred_language = u'en'
+ >>> mlist.description = 'A Test Mailing List'
+ >>> mlist.preferred_language = 'en'
>>> msg = message_from_string("""\
... From: bperson@example.com
... Reply-To: bperson@example.org
diff --git a/src/mailman/pipeline/docs/cook-headers.txt b/src/mailman/pipeline/docs/cook-headers.txt
index 2c6381c8f..127cd8aeb 100644
--- a/src/mailman/pipeline/docs/cook-headers.txt
+++ b/src/mailman/pipeline/docs/cook-headers.txt
@@ -1,3 +1,4 @@
+===============
Cooking headers
===============
@@ -7,14 +8,14 @@ transformations. Some headers get added, others get changed. Some of these
changes depend on mailing list settings and others depend on how the message
is getting sent through the system. We'll take things one-by-one.
- >>> mlist = create_list(u'_xtest@example.com')
- >>> mlist.subject_prefix = u''
+ >>> mlist = create_list('_xtest@example.com')
+ >>> mlist.subject_prefix = ''
>>> mlist.include_list_post_header = False
>>> mlist.archive = True
Saving the original sender
---------------------------
+==========================
Because the original sender headers may get deleted or changed, CookHeaders
will place the sender in the message metadata for safe keeping.
@@ -28,8 +29,8 @@ will place the sender in the message metadata for safe keeping.
>>> from mailman.pipeline.cook_headers import process
>>> process(mlist, msg, msgdata)
- >>> msgdata['original_sender']
- u'aperson@example.com'
+ >>> print msgdata['original_sender']
+ aperson@example.com
But if there was no original sender, then the empty string will be saved.
@@ -45,7 +46,7 @@ But if there was no original sender, then the empty string will be saved.
X-BeenThere header
-------------------
+==================
The X-BeenThere header is what Mailman uses to recognize messages that have
already been processed by this mailing list. It's one small measure against
@@ -57,8 +58,8 @@ mail loops.
... A message of great import.
... """)
>>> process(mlist, msg, {})
- >>> msg['x-beenthere']
- u'_xtest@example.com'
+ >>> print msg['x-beenthere']
+ _xtest@example.com
Mailman appends X-BeenThere headers, so if there already is one in the
original message, the posted message will contain two such headers.
@@ -75,7 +76,7 @@ original message, the posted message will contain two such headers.
Mailman version header
-----------------------
+======================
Mailman will also insert an X-Mailman-Version header...
@@ -98,12 +99,12 @@ Mailman will also insert an X-Mailman-Version header...
... A message of great import.
... """)
>>> process(mlist, msg, {})
- >>> msg['x-mailman-version']
- u'3000'
+ >>> print msg['x-mailman-version']
+ 3000
Precedence header
------------------
+=================
Mailman will insert a Precedence header, which is a de-facto standard for
telling automatic reply software (e.g. vacation(1)) not to respond to this
@@ -115,8 +116,8 @@ message.
... A message of great import.
... """)
>>> process(mlist, msg, {})
- >>> msg['precedence']
- u'list'
+ >>> print msg['precedence']
+ list
But Mailman will only add that header if the original message doesn't already
have one of them.
@@ -128,12 +129,12 @@ have one of them.
... A message of great import.
... """)
>>> process(mlist, msg, {})
- >>> msg['precedence']
- u'junk'
+ >>> print msg['precedence']
+ junk
RFC 2919 and 2369 headers
--------------------------
+=========================
This is a helper function for the following section.
@@ -180,7 +181,7 @@ But normally, a list will include these headers.
>>> mlist.include_rfc2369_headers = True
>>> mlist.include_list_post_header = True
- >>> mlist.preferred_language = u'en'
+ >>> mlist.preferred_language = 'en'
>>> msg = message_from_string("""\
... From: aperson@example.com
... Message-ID: <12345>
@@ -202,7 +203,7 @@ But normally, a list will include these headers.
If the mailing list has a description, then it is included in the List-Id
header.
- >>> mlist.description = u'My test mailing list'
+ >>> mlist.description = 'My test mailing list'
>>> msg = message_from_string("""\
... From: aperson@example.com
...
@@ -225,20 +226,20 @@ set the List-ID header. Start by creating a new domain.
>>> from mailman.interfaces.domain import IDomainManager
>>> manager = IDomainManager(config)
- >>> domain = manager.add(u'mail.example.net')
- >>> mlist.host_name = u'mail.example.net'
+ >>> domain = manager.add('mail.example.net')
+ >>> mlist.host_name = 'mail.example.net'
>>> process(mlist, msg, {})
>>> print msg['list-id']
My test mailing list <_xtest.example.com>
- >>> mlist.list_id = u'_xtest.mail.example.net'
+ >>> mlist.list_id = '_xtest.mail.example.net'
>>> process(mlist, msg, {})
>>> print msg['list-id']
My test mailing list <_xtest.mail.example.net>
- >>> mlist.host_name = u'example.com'
- >>> mlist.list_id = u'_xtest.example.com'
+ >>> mlist.host_name = 'example.com'
+ >>> mlist.list_id = '_xtest.example.com'
Any existing List-ID headers are removed from the original message.
@@ -313,7 +314,7 @@ List-Archive header either.
Archived-At
------------
+===========
RFC 5064 (draft) defines a new Archived-At header which contains the url to
the individual message in the archives. The stock Pipermail archiver doesn't
@@ -326,7 +327,7 @@ available to us now.
Personalization
----------------
+===============
The To field normally contains the list posting address. However when
messages are fully personalized, that header will get overwritten with the
diff --git a/src/mailman/pipeline/docs/decorate.txt b/src/mailman/pipeline/docs/decorate.txt
index b805e23cf..ee2f4d10e 100644
--- a/src/mailman/pipeline/docs/decorate.txt
+++ b/src/mailman/pipeline/docs/decorate.txt
@@ -1,3 +1,4 @@
+==================
Message decoration
==================
@@ -6,7 +7,7 @@ original message. A handler module takes care of this based on the settings
of the mailing list and the type of message being processed.
>>> from mailman.pipeline.decorate import process
- >>> mlist = config.db.list_manager.create(u'_xtest@example.com')
+ >>> mlist = config.db.list_manager.create('_xtest@example.com')
>>> msg_text = """\
... From: aperson@example.org
...
@@ -16,7 +17,7 @@ of the mailing list and the type of message being processed.
Short circuiting
-----------------
+================
Digest messages get decorated during the digest creation phase so no extra
decorations are added for digest messages.
@@ -35,7 +36,7 @@ decorations are added for digest messages.
Decorating simple text messages
--------------------------------
+===============================
Text messages that have no declared content type character set are by default,
encoded in us-ascii. When the mailing list's preferred language is 'en'
@@ -45,9 +46,9 @@ placeholder variables, the message's payload will be prepended by the verbatim
header, and appended with the verbatim footer.
>>> msg = message_from_string(msg_text)
- >>> mlist.msg_header = u'header\n'
- >>> mlist.msg_footer = u'footer'
- >>> mlist.preferred_language = u'en'
+ >>> mlist.msg_header = 'header\n'
+ >>> mlist.msg_footer = 'footer'
+ >>> mlist.preferred_language = 'en'
>>> process(mlist, msg, {})
>>> print msg.as_string()
From: aperson@example.org
@@ -63,9 +64,9 @@ data. An example of such information is the mailing list's "real name" (a
short descriptive name for the mailing list).
>>> msg = message_from_string(msg_text)
- >>> mlist.msg_header = u'$real_name header\n'
- >>> mlist.msg_footer = u'$real_name footer'
- >>> mlist.real_name = u'XTest'
+ >>> mlist.msg_header = '$real_name header\n'
+ >>> mlist.msg_footer = '$real_name footer'
+ >>> mlist.real_name = 'XTest'
>>> process(mlist, msg, {})
>>> print msg.as_string()
From: aperson@example.org
@@ -78,8 +79,8 @@ You can't just pick any interpolation variable though; if you do, the variable
will remain in the header or footer unchanged.
>>> msg = message_from_string(msg_text)
- >>> mlist.msg_header = u'$dummy header\n'
- >>> mlist.msg_footer = u'$dummy footer'
+ >>> mlist.msg_header = '$dummy header\n'
+ >>> mlist.msg_footer = '$dummy footer'
>>> process(mlist, msg, {})
>>> print msg.as_string()
From: aperson@example.org
@@ -90,7 +91,7 @@ will remain in the header or footer unchanged.
Handling RFC 3676 'format=flowed' parameters
---------------------------------------------
+============================================
RFC 3676 describes a standard by which text/plain messages can marked by
generating MUAs for better readability in compatible receiving MUAs. The
@@ -102,9 +103,9 @@ When Mailman sees text/plain messages with such RFC 3676 parameters, it
preserves these parameters when it concatenates headers and footers to the
message payload.
- >>> mlist.msg_header = u'header'
- >>> mlist.msg_footer = u'footer'
- >>> mlist.preferred_language = u'en'
+ >>> mlist.msg_header = 'header'
+ >>> mlist.msg_footer = 'footer'
+ >>> mlist.preferred_language = 'en'
>>> msg = message_from_string("""\
... From: aperson@example.org
... Content-Type: text/plain; format=flowed; delsp=no
@@ -116,14 +117,14 @@ message payload.
>>> # Don't use 'print' here as above because it won't be obvious from the
>>> # output that the soft-line break space at the end of the 'Here is a
>>> # message' line will be retained in the output.
- >>> msg['content-type']
- u'text/plain; format="flowed"; delsp="no"; charset="us-ascii"'
+ >>> print msg['content-type']
+ text/plain; format="flowed"; delsp="no"; charset="us-ascii"
>>> [line for line in msg.get_payload().splitlines()]
['header', 'Here is a message ', 'with soft line breaks.', 'footer']
Decorating mixed-charset messages
----------------------------------
+=================================
When a message has no explicit character set, it is assumed to be us-ascii.
However, if the mailing list's preferred language has a different character
@@ -131,10 +132,10 @@ set, Mailman will still try to concatenate the header and footer, but it will
convert the text to utf-8 and base-64 encode the message payload.
# 'ja' = Japanese; charset = 'euc-jp'
- >>> mlist.preferred_language = u'ja'
- >>> mlist.msg_header = u'$description header'
- >>> mlist.msg_footer = u'$description footer'
- >>> mlist.description = u'\u65e5\u672c\u8a9e'
+ >>> mlist.preferred_language = 'ja'
+ >>> mlist.msg_header = '$description header'
+ >>> mlist.msg_footer = '$description footer'
+ >>> mlist.description = '\u65e5\u672c\u8a9e'
>>> from email.message import Message
>>> msg = Message()
@@ -153,14 +154,13 @@ convert the text to utf-8 and base-64 encode the message payload.
<BLANKLINE>
5pel5pys6KqeIGhlYWRlcgpGcmFuw6dhaXNlCuaXpeacrOiqniBmb290ZXI=
-
Sometimes the message even has an unknown character set. In this case,
Mailman has no choice but to decorate the original message with MIME
attachments.
- >>> mlist.preferred_language = u'en'
- >>> mlist.msg_header = u'header'
- >>> mlist.msg_footer = u'footer'
+ >>> mlist.preferred_language = 'en'
+ >>> mlist.msg_header = 'header'
+ >>> mlist.msg_footer = 'footer'
>>> msg = message_from_string("""\
... From: aperson@example.org
... Content-Type: text/plain; charset=unknown
@@ -198,7 +198,7 @@ attachments.
Decorating multipart messages
------------------------------
+=============================
Multipart messages have to be decorated differently. The header and footer
cannot be simply concatenated into the payload because that will break the
@@ -209,9 +209,9 @@ When the outerpart is multipart/mixed, the header and footer can have a
Content-Disposition of 'inline' so that MUAs can display these headers as if
they were simply concatenated.
- >>> mlist.preferred_language = u'en'
- >>> mlist.msg_header = u'header'
- >>> mlist.msg_footer = u'footer'
+ >>> mlist.preferred_language = 'en'
+ >>> mlist.msg_header = 'header'
+ >>> mlist.msg_footer = 'footer'
>>> part_1 = message_from_string("""\
... From: aperson@example.org
...
@@ -258,7 +258,7 @@ they were simply concatenated.
Decorating other content types
-------------------------------
+==============================
Non-multipart non-text content types will get wrapped in a multipart/mixed so
that the header and footer can be added as attachments.
@@ -297,7 +297,7 @@ that the header and footer can be added as attachments.
Personalization
----------------
+===============
A mailing list can be 'personalized', meaning that each message is unique for
each recipient. When the list is personalized, additional interpolation
diff --git a/src/mailman/pipeline/docs/file-recips.txt b/src/mailman/pipeline/docs/file-recips.txt
index 81510b6e7..479ae9975 100644
--- a/src/mailman/pipeline/docs/file-recips.txt
+++ b/src/mailman/pipeline/docs/file-recips.txt
@@ -1,3 +1,4 @@
+===============
File recipients
===============
@@ -6,11 +7,11 @@ include file. This file must be called members.txt and it must live in the
list's data directory.
>>> handler = config.handlers['file-recipients']
- >>> mlist = config.db.list_manager.create(u'_xtest@example.com')
+ >>> mlist = config.db.list_manager.create('_xtest@example.com')
Short circuiting
-----------------
+================
If the message's metadata already has recipients, this handler immediately
returns.
@@ -28,11 +29,11 @@ returns.
A message.
<BLANKLINE>
>>> msgdata
- {'recips': 7}
+ {u'recips': 7}
Missing file
-------------
+============
The include file must live inside the list's data directory, under the name
members.txt. If the file doesn't exist, the list of recipients will be
@@ -52,7 +53,7 @@ empty.
Existing file
--------------
+=============
If the file exists, it contains a list of addresses, one per line. These
addresses are returned as the set of recipients.
@@ -80,7 +81,7 @@ in the recipients list.
>>> from mailman.interfaces.member import MemberRole
>>> address_1 = config.db.user_manager.create_address(
- ... u'cperson@example.com')
+ ... 'cperson@example.com')
>>> address_1.subscribe(mlist, MemberRole.member)
<Member: cperson@example.com on _xtest@example.com as MemberRole.member>
diff --git a/src/mailman/pipeline/docs/filtering.txt b/src/mailman/pipeline/docs/filtering.txt
index f895220f0..241f282d9 100644
--- a/src/mailman/pipeline/docs/filtering.txt
+++ b/src/mailman/pipeline/docs/filtering.txt
@@ -1,3 +1,4 @@
+=================
Content filtering
=================
@@ -5,7 +6,7 @@ Mailman can filter the content of messages posted to a mailing list by
stripping MIME subparts, and possibly reorganizing the MIME structure of a
message.
- >>> mlist = create_list(u'test@example.com')
+ >>> mlist = create_list('test@example.com')
Several mailing list options control content filtering. First, the feature
must be enabled, then there are two options that control which MIME types get
@@ -20,7 +21,7 @@ for these variables, then we'll explain them in more detail below.
Filtering the outer content type
---------------------------------
+================================
A simple filtering setting will just search the content types of the messages
parts, discarding all parts with a matching MIME type. If the message's outer
@@ -28,7 +29,7 @@ content type matches the filter, the entire message will be discarded.
>>> from mailman.interfaces.mime import FilterAction
- >>> mlist.filter_types = [u'image/jpeg']
+ >>> mlist.filter_types = ['image/jpeg']
>>> mlist.filter_action = FilterAction.discard
>>> msg = message_from_string("""\
@@ -73,11 +74,11 @@ crafted internally by Mailman.
<BLANKLINE>
xxxxx
>>> msgdata
- {'isdigest': True}
+ {u'isdigest': True}
Simple multipart filtering
---------------------------
+==========================
If one of the subparts in a multipart message matches the filter type, then
just that subpart will be stripped.
@@ -118,7 +119,7 @@ just that subpart will be stripped.
Collapsing multipart/alternative messages
------------------------------------------
+=========================================
When content filtering encounters a multipart/alternative part, and the
results of filtering leave only one of the subparts, then the
@@ -178,7 +179,7 @@ part with just one subpart, the entire message is converted to the left over
part's content type. In other words, the left over inner part is promoted to
being the outer part.
- >>> mlist.filter_types = [u'image/jpeg', u'text/html']
+ >>> mlist.filter_types = ['image/jpeg', 'text/html']
>>> msg = message_from_string("""\
... From: aperson@example.com
... Content-Type: multipart/alternative; boundary=AAA
@@ -204,11 +205,11 @@ being the outer part.
Clean up.
- >>> mlist.filter_types = [u'image/jpeg']
+ >>> mlist.filter_types = ['image/jpeg']
Conversion to plain text
-------------------------
+========================
Many mailing lists prohibit HTML email, and in fact, such email can be a
phishing or spam vector. However, many mail readers will send HTML email by
@@ -265,7 +266,7 @@ name of the file containing the message payload to filter.
Discarding empty parts
-----------------------
+======================
Similarly, if after filtering a multipart section ends up empty, then the
entire multipart is discarded. For example, here's a message where an inner
@@ -337,7 +338,7 @@ the entire inner multipart/mixed is discarded.
Passing MIME types
-------------------
+==================
XXX Describe the pass_mime_types setting and how it interacts with
filter_mime_types.
diff --git a/src/mailman/pipeline/docs/nntp.txt b/src/mailman/pipeline/docs/nntp.txt
index 3f48be1da..dda104309 100644
--- a/src/mailman/pipeline/docs/nntp.txt
+++ b/src/mailman/pipeline/docs/nntp.txt
@@ -1,13 +1,14 @@
-NNTP (i.e. Usenet) Gateway
-==========================
+============
+NNTP Gateway
+============
Mailman has an NNTP gateway, whereby messages posted to the mailing list can
be forwarded onto an NNTP newsgroup. Typically this means Usenet, but since
NNTP is to Usenet as IP is to the web, it's more general than that.
>>> handler = config.handlers['to-usenet']
- >>> mlist = config.db.list_manager.create(u'_xtest@example.com')
- >>> mlist.preferred_language = u'en'
+ >>> mlist = config.db.list_manager.create('_xtest@example.com')
+ >>> mlist.preferred_language = 'en'
>>> switchboard = config.switchboards['news']
Gatewaying from the mailing list to the newsgroup happens through a separate
@@ -46,8 +47,8 @@ However, other posted messages get gated to the newsgroup via the nntp queue.
The list owner can set the linked newsgroup and the nntp host that its
messages are gated to.
- >>> mlist.linked_newsgroup = u'comp.lang.thing'
- >>> mlist.nntp_host = u'news.example.com'
+ >>> mlist.linked_newsgroup = 'comp.lang.thing'
+ >>> mlist.nntp_host = 'news.example.com'
>>> handler.process(mlist, msg, {})
>>> len(switchboard.files)
1
diff --git a/src/mailman/pipeline/docs/reply-to.txt b/src/mailman/pipeline/docs/reply-to.txt
index e57b97e5d..2652753d6 100644
--- a/src/mailman/pipeline/docs/reply-to.txt
+++ b/src/mailman/pipeline/docs/reply-to.txt
@@ -1,3 +1,4 @@
+================
Reply-to munging
================
@@ -8,8 +9,8 @@ changes depend on mailing list settings and others depend on how the message
is getting sent through the system. We'll take things one-by-one.
>>> from mailman.pipeline.cook_headers import process
- >>> mlist = config.db.list_manager.create(u'_xtest@example.com')
- >>> mlist.subject_prefix = u''
+ >>> mlist = config.db.list_manager.create('_xtest@example.com')
+ >>> mlist.subject_prefix = ''
Reply-to munging refers to the behavior where a mailing list can be configured
to change or augment an existing Reply-To header in a message posted to the
@@ -30,7 +31,7 @@ this mis-feature.
Reply to list
--------------
+=============
A list can be configured to add a Reply-To header pointing back to the mailing
list's posting address. If there's no Reply-To header in the original
@@ -38,8 +39,8 @@ message, the list's posting address simply gets inserted.
>>> from mailman.interfaces.mailinglist import ReplyToMunging
>>> mlist.reply_goes_to_list = ReplyToMunging.point_to_list
- >>> mlist.preferred_language = u'en'
- >>> mlist.description = u''
+ >>> mlist.preferred_language = 'en'
+ >>> mlist.description = ''
>>> msg = message_from_string("""\
... From: aperson@example.com
...
@@ -47,8 +48,8 @@ message, the list's posting address simply gets inserted.
>>> process(mlist, msg, {})
>>> len(msg.get_all('reply-to'))
1
- >>> msg['reply-to']
- u'_xtest@example.com'
+ >>> print msg['reply-to']
+ _xtest@example.com
It's also possible to strip any existing Reply-To header first, before adding
the list's posting address.
@@ -62,8 +63,8 @@ the list's posting address.
>>> process(mlist, msg, {})
>>> len(msg.get_all('reply-to'))
1
- >>> msg['reply-to']
- u'_xtest@example.com'
+ >>> print msg['reply-to']
+ _xtest@example.com
If you don't first strip the header, then the list's posting address will just
get appended to whatever the original version was.
@@ -77,17 +78,17 @@ get appended to whatever the original version was.
>>> process(mlist, msg, {})
>>> len(msg.get_all('reply-to'))
1
- >>> msg['reply-to']
- u'bperson@example.com, _xtest@example.com'
+ >>> print msg['reply-to']
+ bperson@example.com, _xtest@example.com
Explicit Reply-To
------------------
+=================
The list can also be configured to have an explicit Reply-To header.
>>> mlist.reply_goes_to_list = ReplyToMunging.explicit_header
- >>> mlist.reply_to_address = u'my-list@example.com'
+ >>> mlist.reply_to_address = 'my-list@example.com'
>>> msg = message_from_string("""\
... From: aperson@example.com
...
@@ -95,8 +96,8 @@ The list can also be configured to have an explicit Reply-To header.
>>> process(mlist, msg, {})
>>> len(msg.get_all('reply-to'))
1
- >>> msg['reply-to']
- u'my-list@example.com'
+ >>> print msg['reply-to']
+ my-list@example.com
And as before, it's possible to either strip any existing Reply-To header...
@@ -109,8 +110,8 @@ And as before, it's possible to either strip any existing Reply-To header...
>>> process(mlist, msg, {})
>>> len(msg.get_all('reply-to'))
1
- >>> msg['reply-to']
- u'my-list@example.com'
+ >>> print msg['reply-to']
+ my-list@example.com
...or not.
@@ -123,5 +124,5 @@ And as before, it's possible to either strip any existing Reply-To header...
>>> process(mlist, msg, {})
>>> len(msg.get_all('reply-to'))
1
- >>> msg['reply-to']
- u'my-list@example.com, bperson@example.com'
+ >>> print msg['reply-to']
+ my-list@example.com, bperson@example.com
diff --git a/src/mailman/pipeline/docs/replybot.txt b/src/mailman/pipeline/docs/replybot.txt
index 6c4d896a4..36bc6198f 100644
--- a/src/mailman/pipeline/docs/replybot.txt
+++ b/src/mailman/pipeline/docs/replybot.txt
@@ -1,3 +1,4 @@
+==========================
Automatic response handler
==========================
@@ -6,12 +7,12 @@ receives on its posting address, owner address, or robot address. Automatic
responses are subject to various conditions, such as headers in the original
message or the amount of time since the last auto-response.
- >>> mlist = create_list(u'_xtest@example.com')
- >>> mlist.real_name = u'XTest'
+ >>> mlist = create_list('_xtest@example.com')
+ >>> mlist.real_name = 'XTest'
Basic automatic responding
---------------------------
+==========================
Basic automatic responding occurs when the list is set up to respond to either
its -owner address, its -request address, or to the posting address, and a
@@ -24,7 +25,7 @@ a second response will be sent, with 0 meaning "there is no grace period".
>>> mlist.autorespond_owner = ResponseAction.respond_and_continue
>>> mlist.autoresponse_grace_period = datetime.timedelta()
- >>> mlist.autoresponse_owner_text = u'owner autoresponse text'
+ >>> mlist.autoresponse_owner_text = 'owner autoresponse text'
>>> msg = message_from_string("""\
... From: aperson@example.com
@@ -69,7 +70,7 @@ response.
Short circuiting
-----------------
+================
Several headers in the original message determine whether an automatic
response should even be sent. For example, if the message has an "X-Ack: No"
@@ -157,14 +158,14 @@ header is ignored.
Available auto-responses
-------------------------
+========================
As shown above, a message sent to the -owner address will get an auto-response
with the text set for owner responses. Two other types of email will get
auto-responses: those sent to the -request address...
>>> mlist.autorespond_requests = ResponseAction.respond_and_continue
- >>> mlist.autoresponse_request_text = u'robot autoresponse text'
+ >>> mlist.autoresponse_request_text = 'robot autoresponse text'
>>> msg = message_from_string("""\
... From: aperson@example.com
@@ -196,7 +197,7 @@ auto-responses: those sent to the -request address...
...and those sent to the posting address.
>>> mlist.autorespond_postings = ResponseAction.respond_and_continue
- >>> mlist.autoresponse_postings_text = u'postings autoresponse text'
+ >>> mlist.autoresponse_postings_text = 'postings autoresponse text'
>>> msg = message_from_string("""\
... From: aperson@example.com
@@ -227,7 +228,7 @@ auto-responses: those sent to the -request address...
Grace periods
--------------
+=============
Automatic responses have a grace period, during which no additional responses
will be sent. This is so as not to bombard the sender with responses. The
diff --git a/src/mailman/pipeline/docs/scrubber.txt b/src/mailman/pipeline/docs/scrubber.txt
index dec1c1f64..8bc33aa13 100644
--- a/src/mailman/pipeline/docs/scrubber.txt
+++ b/src/mailman/pipeline/docs/scrubber.txt
@@ -1,3 +1,4 @@
+============
The scrubber
============
@@ -7,8 +8,8 @@ scrub attachments from messages so that binary goop doesn't end up in an
archive message.
>>> from mailman.pipeline.scrubber import process, save_attachment
- >>> mlist = config.db.list_manager.create(u'_xtest@example.com')
- >>> mlist.preferred_language = u'en'
+ >>> mlist = config.db.list_manager.create('_xtest@example.com')
+ >>> mlist.preferred_language = 'en'
Helper functions for getting the attachment data.
@@ -38,7 +39,7 @@ Helper functions for getting the attachment data.
Saving attachments
-------------------
+==================
The Scrubber handler exposes a function called save_attachments() which can be
used to strip various types of attachments and store them in the archive
@@ -61,11 +62,11 @@ this is an unfortunate double negative).
...
... R0lGODdhAQABAIAAAAAAAAAAACwAAAAAAQABAAACAQUAOw==
... """)
- >>> save_attachment(mlist, msg, 'dir')
- u'<http://www.example.com/pipermail/_xtest@example.com/dir/xtest.gif>'
+ >>> print save_attachment(mlist, msg, 'dir')
+ <http://www.example.com/pipermail/_xtest@example.com/dir/xtest.gif>
>>> data = read_attachment('dir/xtest.gif')
- >>> data[:6]
- 'GIF87a'
+ >>> print data[:6]
+ GIF87a
>>> len(data)
34
@@ -93,21 +94,21 @@ Content-Disposition: filename. This is the default.
...
... R0lGODdhAQABAIAAAAAAAAAAACwAAAAAAQABAAACAQUAOw==
... """)
- >>> save_attachment(mlist, msg, 'dir')
- u'<http://www.example.com/pipermail/_xtest@example.com/dir/attachment.gif>'
+ >>> print save_attachment(mlist, msg, 'dir')
+ <http://www.example.com/pipermail/_xtest@example.com/dir/attachment.gif>
>>> data = read_attachment('dir/xtest.gif')
Traceback (most recent call last):
IOError: [Errno ...] No such file or directory:
u'.../archives/private/_xtest@example.com/dir/xtest.gif'
>>> data = read_attachment('dir/attachment.gif')
- >>> data[:6]
- 'GIF87a'
+ >>> print data[:6]
+ GIF87a
>>> len(data)
34
Scrubbing image attachments
----------------------------
+===========================
When scrubbing image attachments, the original message is modified to include
a reference to the attachment file as available through the on-line archive.
@@ -182,7 +183,7 @@ The URL will point to the attachment sitting in the archive.
Scrubbing text attachments
---------------------------
+==========================
Similar to image attachments, text attachments will also be scrubbed, but the
placeholder will be slightly different.
@@ -220,6 +221,6 @@ placeholder will be slightly different.
Clean up
---------
+========
>>> config.pop('test config')
diff --git a/src/mailman/pipeline/docs/subject-munging.txt b/src/mailman/pipeline/docs/subject-munging.txt
index b2972683b..68ad940e8 100644
--- a/src/mailman/pipeline/docs/subject-munging.txt
+++ b/src/mailman/pipeline/docs/subject-munging.txt
@@ -1,3 +1,4 @@
+===============
Subject munging
===============
@@ -8,20 +9,20 @@ changes depend on mailing list settings and others depend on how the message
is getting sent through the system. We'll take things one-by-one.
>>> from mailman.pipeline.cook_headers import process
- >>> mlist = config.db.list_manager.create(u'_xtest@example.com')
- >>> mlist.subject_prefix = u''
+ >>> mlist = config.db.list_manager.create('_xtest@example.com')
+ >>> mlist.subject_prefix = ''
Inserting a prefix
-------------------
+==================
Another thing CookHeaders does is 'munge' the Subject header by inserting the
subject prefix for the list at the front. If there's no subject header in the
original message, Mailman uses a canned default. In order to do subject
munging, a mailing list must have a preferred language.
- >>> mlist.subject_prefix = u'[XTest] '
- >>> mlist.preferred_language = u'en'
+ >>> mlist.subject_prefix = '[XTest] '
+ >>> mlist.preferred_language = 'en'
>>> msg = message_from_string("""\
... From: aperson@example.com
...
@@ -50,8 +51,8 @@ the beginning of the header's value.
... """)
>>> msgdata = {}
>>> process(mlist, msg, msgdata)
- >>> msgdata['origsubj']
- u'Something important'
+ >>> print msgdata['origsubj']
+ Something important
>>> print msg['subject']
[XTest] Something important
@@ -64,8 +65,8 @@ Subject headers are not munged for digest messages.
... A message of great import.
... """)
>>> process(mlist, msg, dict(isdigest=True))
- >>> msg['subject']
- u'Something important'
+ >>> print msg['subject']
+ Something important
Nor are they munged for 'fast tracked' messages, which are generally defined
as messages that Mailman crafts internally.
@@ -77,8 +78,8 @@ as messages that Mailman crafts internally.
... A message of great import.
... """)
>>> process(mlist, msg, dict(_fasttrack=True))
- >>> msg['subject']
- u'Something important'
+ >>> print msg['subject']
+ Something important
If a Subject header already has a prefix, usually following a Re: marker,
another one will not be added but the prefix will be moved to the front of the
@@ -110,7 +111,7 @@ option available in Mailman 3.
Internationalized headers
--------------------------
+=========================
Internationalization adds some interesting twists to the handling of subject
prefixes. Part of what makes this interesting is the encoding of i18n headers
@@ -129,14 +130,14 @@ set than the encoded header.
Prefix numbers
---------------
+==============
Subject prefixes support a placeholder for the numeric post id. Every time a
message is posted to the mailing list, a 'post id' gets incremented. This is
a purely sequential integer that increases monotonically. By added a '%d'
placeholder to the subject prefix, this post id can be included in the prefix.
- >>> mlist.subject_prefix = u'[XTest %d] '
+ >>> mlist.subject_prefix = '[XTest %d] '
>>> mlist.post_id = 456
>>> msg = message_from_string("""\
... Subject: Something important
@@ -218,7 +219,7 @@ In this test case, we get an extra space between the prefix and the original
subject. It's because the original is 'crooked'. Note that a Subject
starting with '\n ' is generated by some version of Eudora Japanese edition.
- >>> mlist.subject_prefix = u'[XTest] '
+ >>> mlist.subject_prefix = '[XTest] '
>>> msg = message_from_string("""\
... Subject:
... Important message
diff --git a/src/mailman/pipeline/docs/tagger.txt b/src/mailman/pipeline/docs/tagger.txt
index 9f0bcd4b2..a552401f7 100644
--- a/src/mailman/pipeline/docs/tagger.txt
+++ b/src/mailman/pipeline/docs/tagger.txt
@@ -1,3 +1,4 @@
+==============
Message tagger
==============
@@ -9,7 +10,7 @@ its Subject: and Keywords: headers compared against these regular
expressions. The message then gets tagged with the topic names of each hit.
>>> from mailman.pipeline.tagger import process
- >>> mlist = config.db.list_manager.create(u'_xtest@example.com')
+ >>> mlist = config.db.list_manager.create('_xtest@example.com')
Topics must be enabled for Mailman to do any topic matching, even if topics
are defined.
@@ -52,11 +53,11 @@ the message metadata gets a key with a list of matching topic names.
<BLANKLINE>
<BLANKLINE>
>>> msgdata['topichits']
- ['bar fight']
+ [u'bar fight']
Scanning body lines
--------------------
+===================
The tagger can also look at a certain number of body lines, but only for
Subject: and Keyword: header-like lines. When set to zero, no body lines are
@@ -111,7 +112,7 @@ found.
Keywords: barbaz
<BLANKLINE>
>>> msgdata['topichits']
- ['bar fight']
+ [u'bar fight']
However, scanning stops at the first body line that doesn't look like a
header.
@@ -155,14 +156,14 @@ When set to a negative number, all body lines will be scanned.
>>> process(mlist, msg, msgdata)
>>> # Rather than print out 100 X-Ignore: headers, let's just prove that
>>> # the X-Topics: header exists, meaning that the tagger did its job.
- >>> msg['x-topics']
- u'bar fight'
+ >>> print msg['x-topics']
+ bar fight
>>> msgdata['topichits']
- ['bar fight']
+ [u'bar fight']
Scanning sub-parts
-------------------
+==================
The tagger will also scan the body lines of text subparts in a multipart
message, using the same rules as if all those body lines lived in a single
@@ -200,7 +201,7 @@ text payload.
--BOUNDARY--
<BLANKLINE>
>>> msgdata['topichits']
- ['bar fight']
+ [u'bar fight']
But the tagger will not descend into non-text parts.
diff --git a/src/mailman/pipeline/docs/to-outgoing.txt b/src/mailman/pipeline/docs/to-outgoing.txt
index 5305db19f..9d467bb5e 100644
--- a/src/mailman/pipeline/docs/to-outgoing.txt
+++ b/src/mailman/pipeline/docs/to-outgoing.txt
@@ -1,3 +1,4 @@
+====================
The outgoing handler
====================
@@ -10,7 +11,7 @@ basically describes how to encode the recipient's address in the originator
headers for unambigous bounce processing.
>>> handler = config.handlers['to-outgoing']
- >>> mlist = config.db.list_manager.create(u'_xtest@example.com')
+ >>> mlist = config.db.list_manager.create('_xtest@example.com')
>>> switchboard = config.switchboards['out']
>>> def queue_size():
diff --git a/src/mailman/queue/docs/archiver.txt b/src/mailman/queue/docs/archiver.txt
index 601857cd9..7d404cf56 100644
--- a/src/mailman/queue/docs/archiver.txt
+++ b/src/mailman/queue/docs/archiver.txt
@@ -1,3 +1,4 @@
+=========
Archiving
=========
@@ -5,7 +6,7 @@ Mailman can archive to any number of archivers that adhere to the IArchiver
interface. By default, there's a Pipermail archiver.
>>> from mailman.app.lifecycle import create_list
- >>> mlist = create_list(u'test@example.com')
+ >>> mlist = create_list('test@example.com')
>>> commit()
>>> msg = message_from_string("""\
diff --git a/src/mailman/queue/docs/command.txt b/src/mailman/queue/docs/command.txt
index c9a55d2a9..73be64de0 100644
--- a/src/mailman/queue/docs/command.txt
+++ b/src/mailman/queue/docs/command.txt
@@ -1,3 +1,4 @@
+========================
The command queue runner
========================
@@ -6,11 +7,11 @@ Commands are extensible using the Mailman plugin system, but Mailman comes
with a number of email commands out of the box. These are processed when a
message is sent to the list's -request address.
- >>> mlist = create_list(u'test@example.com')
+ >>> mlist = create_list('test@example.com')
A command in the Subject
-------------------------
+========================
For example, the 'echo' command simply echoes the original command back to the
sender. The command can be in the Subject header.
@@ -64,7 +65,7 @@ And now the response is in the virgin queue.
A command in the body
----------------------
+=====================
The command can also be found in the body of the message, as long as the
message is plain text.
@@ -105,7 +106,7 @@ message is plain text.
Stopping command processing
----------------------------
+===========================
The 'end' command stops email processing, so that nothing following is looked
at by the command queue.
diff --git a/src/mailman/queue/docs/digester.txt b/src/mailman/queue/docs/digester.txt
index 2c9c813b2..bb2c05819 100644
--- a/src/mailman/queue/docs/digester.txt
+++ b/src/mailman/queue/docs/digester.txt
@@ -1,3 +1,4 @@
+=========
Digesting
=========
@@ -272,7 +273,7 @@ The RFC 1153 contains the digest in a single plain text message.
Internationalized digests
--------------------------
+=========================
When messages come in with a content-type character set different than that of
the list's preferred language, recipients will get an internationalized
@@ -286,7 +287,7 @@ digest. French is not enabled by default site-wide, so enable that now.
... default_language: fr
... """)
- >>> mlist.preferred_language = u'fr'
+ >>> mlist.preferred_language = 'fr'
>>> msg = message_from_string("""\
... From: aperson@example.org
... To: test@example.com
@@ -467,7 +468,7 @@ The content can be decoded to see the actual digest text.
Digest delivery
----------------
+===============
A mailing list's members can choose to receive normal delivery, plain text
digests, or MIME digests.
@@ -484,24 +485,24 @@ digests, or MIME digests.
Two regular delivery members subscribe to the mailing list.
- >>> member_1 = subscribe(u'uperson@example.com', DeliveryMode.regular)
- >>> member_2 = subscribe(u'vperson@example.com', DeliveryMode.regular)
+ >>> member_1 = subscribe('uperson@example.com', DeliveryMode.regular)
+ >>> member_2 = subscribe('vperson@example.com', DeliveryMode.regular)
Two MIME digest members subscribe to the mailing list.
- >>> member_3 = subscribe(u'wperson@example.com', DeliveryMode.mime_digests)
- >>> member_4 = subscribe(u'xperson@example.com', DeliveryMode.mime_digests)
+ >>> member_3 = subscribe('wperson@example.com', DeliveryMode.mime_digests)
+ >>> member_4 = subscribe('xperson@example.com', DeliveryMode.mime_digests)
One RFC 1153 digest member subscribes to the mailing list.
>>> member_5 = subscribe(
- ... u'yperson@example.com', DeliveryMode.plaintext_digests)
+ ... 'yperson@example.com', DeliveryMode.plaintext_digests)
>>> member_6 = subscribe(
- ... u'zperson@example.com', DeliveryMode.plaintext_digests)
+ ... 'zperson@example.com', DeliveryMode.plaintext_digests)
When a digest gets sent, the appropriate recipient list is chosen.
- >>> mlist.preferred_language = u'en'
+ >>> mlist.preferred_language = 'en'
>>> mlist.digest_size_threshold = 0.5
>>> fill_digest()
>>> runner.run()
diff --git a/src/mailman/queue/docs/incoming.txt b/src/mailman/queue/docs/incoming.txt
index 7e1a98f6b..926b60965 100644
--- a/src/mailman/queue/docs/incoming.txt
+++ b/src/mailman/queue/docs/incoming.txt
@@ -1,3 +1,4 @@
+=========================
The incoming queue runner
=========================
@@ -12,13 +13,13 @@ message eventually ending up in one of the four disposition states described
above.
>>> from mailman.app.lifecycle import create_list
- >>> mlist = create_list(u'_xtest@example.com')
- >>> mlist.start_chain
- u'built-in'
+ >>> mlist = create_list('_xtest@example.com')
+ >>> print mlist.start_chain
+ built-in
Accepted messages
------------------
+=================
We have a message that is going to be sent to the mailing list. This message
is so perfectly fine for posting that it will be accepted and forward to the
@@ -76,7 +77,7 @@ And now the message is in the pipeline queue.
Held messages
--------------
+=============
The list moderator sets the emergency flag on the mailing list. The built-in
chain will now hold all posted messages, so nothing will show up in the
@@ -106,7 +107,7 @@ pipeline queue.
Discarded messages
-------------------
+==================
Another possibility is that the message would get immediately discarded. The
built-in chain does not have such a disposition by default, so let's craft a
@@ -116,10 +117,10 @@ new chain and set it as the mailing list's start chain.
>>> from mailman.interfaces.chain import LinkAction
>>> truth_rule = config.rules['truth']
>>> discard_chain = config.chains['discard']
- >>> test_chain = Chain('always-discard', u'Testing discards')
+ >>> test_chain = Chain('always-discard', 'Testing discards')
>>> link = Link(truth_rule, LinkAction.jump, discard_chain)
>>> test_chain.append_link(link)
- >>> mlist.start_chain = u'always-discard'
+ >>> mlist.start_chain = 'always-discard'
>>> inject_message(mlist, msg)
>>> file_pos = fp.tell()
@@ -137,17 +138,17 @@ new chain and set it as the mailing list's start chain.
Rejected messages
------------------
+=================
Similar to discarded messages, a message can be rejected, or bounced back to
the original sender. Again, the built-in chain doesn't support this so we'll
just create a new chain that does.
>>> reject_chain = config.chains['reject']
- >>> test_chain = Chain('always-reject', u'Testing rejections')
+ >>> test_chain = Chain('always-reject', 'Testing rejections')
>>> link = Link(truth_rule, LinkAction.jump, reject_chain)
>>> test_chain.append_link(link)
- >>> mlist.start_chain = u'always-reject'
+ >>> mlist.start_chain = 'always-reject'
The virgin queue needs to be cleared out due to artifacts from the previous
tests above.
diff --git a/src/mailman/queue/docs/lmtp.txt b/src/mailman/queue/docs/lmtp.txt
index 75e91fd4e..b8b6335fb 100644
--- a/src/mailman/queue/docs/lmtp.txt
+++ b/src/mailman/queue/docs/lmtp.txt
@@ -1,3 +1,4 @@
+===========
LTMP server
===========
@@ -23,7 +24,7 @@ It also helps to have a nice LMTP client.
Posting address
----------------
+===============
If the mail server tries to send a message to a nonexistent mailing list, it
will get a 550 error.
@@ -45,7 +46,7 @@ will get a 550 error.
Once the mailing list is created, the posting address is valid.
>>> from mailman.app.lifecycle import create_list
- >>> create_list(u'mylist@example.com')
+ >>> create_list('mylist@example.com')
<mailing list "mylist@example.com" at ...>
>>> commit()
>>> lmtp.sendmail(
@@ -62,7 +63,7 @@ Once the mailing list is created, the posting address is valid.
Sub-addresses
--------------
+=============
The LMTP server understands each of the list's sub-addreses, such as -join,
-leave, -request and so on. If the message is posted to an invalid
@@ -98,6 +99,6 @@ But the message is accepted if posted to a valid sub-address.
Clean up
---------
+========
>>> master.stop()
diff --git a/src/mailman/queue/docs/news.txt b/src/mailman/queue/docs/news.txt
index f149ef93a..c9f2417a0 100644
--- a/src/mailman/queue/docs/news.txt
+++ b/src/mailman/queue/docs/news.txt
@@ -1,3 +1,4 @@
+===============
The news runner
===============
@@ -7,8 +8,8 @@ the message for Usenet (yes, I know that NNTP is not Usenet, but this runner
was originally written to gate to Usenet, which has its own rules).
>>> from mailman.queue.news import prepare_message
- >>> mlist = config.db.list_manager.create(u'_xtest@example.com')
- >>> mlist.linked_newsgroup = u'comp.lang.python'
+ >>> mlist = config.db.list_manager.create('_xtest@example.com')
+ >>> mlist.linked_newsgroup = 'comp.lang.python'
Some NNTP servers such as INN reject messages containing a set of prohibited
headers, so one of the things that the news runner does is remove these
@@ -112,7 +113,7 @@ the message.
Newsgroup moderation
---------------------
+====================
When the newsgroup is moderated, an Approved: header with the list's posting
address is added for the benefit of the Usenet system.
@@ -126,8 +127,8 @@ address is added for the benefit of the Usenet system.
...
... """)
>>> prepare_message(mlist, msg, {})
- >>> msg['approved']
- u'_xtest@example.com'
+ >>> print msg['approved']
+ _xtest@example.com
>>> mlist.news_moderation = NewsModeration.moderated
>>> msg = message_from_string("""\
@@ -137,8 +138,8 @@ address is added for the benefit of the Usenet system.
...
... """)
>>> prepare_message(mlist, msg, {})
- >>> msg['approved']
- u'_xtest@example.com'
+ >>> print msg['approved']
+ _xtest@example.com
But if the newsgroup is not moderated, the Approved: header is not changed.
diff --git a/src/mailman/queue/docs/outgoing.txt b/src/mailman/queue/docs/outgoing.txt
index 1c9d89041..b8cf25033 100644
--- a/src/mailman/queue/docs/outgoing.txt
+++ b/src/mailman/queue/docs/outgoing.txt
@@ -1,3 +1,4 @@
+=====================
Outgoing queue runner
=====================
@@ -11,16 +12,16 @@ recipient set will be batched, whether messages will be personalized and
VERP'd, etc. The outgoing runner doesn't itself support retrying but it can
move messages to the 'retry queue' for handling delivery failures.
- >>> mlist = create_list(u'test@example.com')
+ >>> mlist = create_list('test@example.com')
>>> from mailman.app.membership import add_member
>>> from mailman.interfaces.member import DeliveryMode
- >>> add_member(mlist, u'aperson@example.com', u'Anne Person',
- ... u'password', DeliveryMode.regular, u'en')
- >>> add_member(mlist, u'bperson@example.com', u'Bart Person',
- ... u'password', DeliveryMode.regular, u'en')
- >>> add_member(mlist, u'cperson@example.com', u'Cris Person',
- ... u'password', DeliveryMode.regular, u'en')
+ >>> add_member(mlist, 'aperson@example.com', 'Anne Person',
+ ... 'password', DeliveryMode.regular, 'en')
+ >>> add_member(mlist, 'bperson@example.com', 'Bart Person',
+ ... 'password', DeliveryMode.regular, 'en')
+ >>> add_member(mlist, 'cperson@example.com', 'Cris Person',
+ ... 'password', DeliveryMode.regular, 'en')
By setting the mailing list to personalize messages, each recipient will get a
unique copy of the message, with certain headers tailored for that recipient.
diff --git a/src/mailman/queue/docs/runner.txt b/src/mailman/queue/docs/runner.txt
index d24a8334c..032ea4c50 100644
--- a/src/mailman/queue/docs/runner.txt
+++ b/src/mailman/queue/docs/runner.txt
@@ -1,3 +1,4 @@
+=============
Queue runners
=============
@@ -8,14 +9,14 @@ while, then wakes up and runs through its queue files again.
Basic architecture
-------------------
+==================
The basic architecture of qrunner is implemented in the base class that all
runners inherit from. This base class implements a .run() method that runs
continuously in a loop until the .stop() method is called.
- >>> mlist = config.db.list_manager.create(u'_xtest@example.com')
- >>> mlist.preferred_language = u'en'
+ >>> mlist = config.db.list_manager.create('_xtest@example.com')
+ >>> mlist.preferred_language = 'en'
Here is a very simple derived qrunner class. Queue runners use a
configuration section in the configuration files to determine run
diff --git a/src/mailman/rest/docs/domains.txt b/src/mailman/rest/docs/domains.txt
index 2afdce49d..db1fe7258 100644
--- a/src/mailman/rest/docs/domains.txt
+++ b/src/mailman/rest/docs/domains.txt
@@ -6,7 +6,7 @@ Domains
# that first.
>>> from mailman.interfaces.domain import IDomainManager
>>> manager = IDomainManager(config)
- >>> manager.remove(u'example.com')
+ >>> manager.remove('example.com')
<Domain example.com...>
>>> commit()
@@ -20,8 +20,8 @@ initially none.
Once a domain is added though, it is accessible through the API.
- >>> manager.add(u'example.com', u'An example domain',
- ... u'http://lists.example.com')
+ >>> manager.add('example.com', 'An example domain',
+ ... 'http://lists.example.com')
<Domain example.com, An example domain,
base_url: http://lists.example.com,
contact_address: postmaster@example.com>
@@ -43,15 +43,15 @@ Once a domain is added though, it is accessible through the API.
At the top level, all domains are returned as separate entries.
- >>> manager.add(u'example.org',
- ... base_url=u'http://mail.example.org',
- ... contact_address=u'listmaster@example.org')
+ >>> manager.add('example.org',
+ ... base_url='http://mail.example.org',
+ ... contact_address='listmaster@example.org')
<Domain example.org, base_url: http://mail.example.org,
contact_address: listmaster@example.org>
- >>> manager.add(u'lists.example.net',
- ... u'Porkmasters',
- ... u'http://example.net',
- ... u'porkmaster@example.net')
+ >>> manager.add('lists.example.net',
+ ... 'Porkmasters',
+ ... 'http://example.net',
+ ... 'porkmaster@example.net')
<Domain lists.example.net, Porkmasters,
base_url: http://example.net,
contact_address: porkmaster@example.net>
diff --git a/src/mailman/rules/docs/administrivia.txt b/src/mailman/rules/docs/administrivia.txt
index dba882775..f43a31834 100644
--- a/src/mailman/rules/docs/administrivia.txt
+++ b/src/mailman/rules/docs/administrivia.txt
@@ -1,3 +1,4 @@
+=============
Administrivia
=============
@@ -6,7 +7,7 @@ commands in the Subject header or first few lines of the payload. This is
used to catch messages posted to the list which should have been sent to the
-request robot address.
- >>> mlist = config.db.list_manager.create(u'_xtest@example.com')
+ >>> mlist = config.db.list_manager.create('_xtest@example.com')
>>> mlist.administrivia = True
>>> rule = config.rules['administrivia']
>>> print rule.name
@@ -72,7 +73,7 @@ We don't show all the other possible email commands, but you get the idea.
Non-administrivia
------------------
+=================
Of course, messages that don't contain administrivia, don't match the rule.
diff --git a/src/mailman/rules/docs/approve.txt b/src/mailman/rules/docs/approve.txt
index dda531a4c..8ae23b8f3 100644
--- a/src/mailman/rules/docs/approve.txt
+++ b/src/mailman/rules/docs/approve.txt
@@ -1,3 +1,4 @@
+=====================
Pre-approved postings
=====================
@@ -13,8 +14,8 @@ approval queue. This has several use cases:
In order to support this, a mailing list can be given a 'moderator password'
which is shared among all the administrators.
- >>> mlist = config.db.list_manager.create(u'_xtest@example.com')
- >>> mlist.moderator_password = u'abcxyz'
+ >>> mlist = config.db.list_manager.create('_xtest@example.com')
+ >>> mlist.moderator_password = 'abcxyz'
The 'approved' rule determines whether the message contains the proper
approval or not.
@@ -25,7 +26,7 @@ approval or not.
No approval
------------
+===========
If the message has no Approve or Approved header, then the rule does not
match.
@@ -42,14 +43,14 @@ If the message has an Approve or Approved header with a value that does not
match the moderator password, then the rule does not match. However, the
header is still removed.
- >>> msg['Approve'] = u'12345'
+ >>> msg['Approve'] = '12345'
>>> rule.check(mlist, msg, {})
False
>>> print msg['approve']
None
>>> del msg['approve']
- >>> msg['Approved'] = u'12345'
+ >>> msg['Approved'] = '12345'
>>> rule.check(mlist, msg, {})
False
>>> print msg['approved']
@@ -59,12 +60,12 @@ header is still removed.
Using an approval header
-------------------------
+========================
If the moderator password is given in an Approve header, then the rule
matches, and the Approve header is stripped.
- >>> msg['Approve'] = u'abcxyz'
+ >>> msg['Approve'] = 'abcxyz'
>>> rule.check(mlist, msg, {})
True
>>> print msg['approve']
@@ -72,7 +73,7 @@ matches, and the Approve header is stripped.
Similarly, for the Approved header.
- >>> msg['Approved'] = u'abcxyz'
+ >>> msg['Approved'] = 'abcxyz'
>>> rule.check(mlist, msg, {})
True
>>> print msg['approved']
@@ -80,7 +81,7 @@ Similarly, for the Approved header.
Using a pseudo-header
----------------------
+=====================
Different mail user agents have varying degrees to which they support custom
headers like Approve and Approved. For this reason, Mailman also supports
@@ -171,7 +172,7 @@ Similarly for the Approved header.
MIME multipart support
-----------------------
+======================
Mailman searches for the pseudo-header as the first non-whitespace line in the
first text/plain message part of the message. This allows the feature to be
@@ -355,7 +356,7 @@ And the pseudo-header is removed.
Stripping text/html parts
--------------------------
+=========================
Because some mail readers will include both a text/plain part and a text/html
alternative, the 'approved' rule has to search the alternatives and strip
diff --git a/src/mailman/rules/docs/emergency.txt b/src/mailman/rules/docs/emergency.txt
index 9d80fdb40..2c56d967b 100644
--- a/src/mailman/rules/docs/emergency.txt
+++ b/src/mailman/rules/docs/emergency.txt
@@ -1,3 +1,4 @@
+=========
Emergency
=========
@@ -5,7 +6,7 @@ When the mailing list has its emergency flag set, all messages posted to the
list are held for moderator approval.
>>> from mailman.app.lifecycle import create_list
- >>> mlist = create_list(u'_xtest@example.com')
+ >>> mlist = create_list('_xtest@example.com')
>>> msg = message_from_string("""\
... From: aperson@example.com
... To: _xtest@example.com
diff --git a/src/mailman/rules/docs/header-matching.txt b/src/mailman/rules/docs/header-matching.txt
index 417000d67..9956832ea 100644
--- a/src/mailman/rules/docs/header-matching.txt
+++ b/src/mailman/rules/docs/header-matching.txt
@@ -1,3 +1,4 @@
+===============
Header matching
===============
@@ -6,7 +7,7 @@ processing. There is a set of site-wide default header matches specified in
the configuration file under the [spam.headers] section.
>>> from mailman.app.lifecycle import create_list
- >>> mlist = create_list(u'_xtest@example.com')
+ >>> mlist = create_list('_xtest@example.com')
Because the default [spam.headers] section is empty, we'll just extend the
current header matching chain with a pattern that matches 4 or more stars,
@@ -94,7 +95,7 @@ Flush out the extended header matching rules.
List-specific header matching
------------------------------
+=============================
Each mailing list can also be configured with a set of header matching regular
expression rules. These are used to impose list-specific header filtering
diff --git a/src/mailman/rules/docs/implicit-dest.txt b/src/mailman/rules/docs/implicit-dest.txt
index 8666c1f5c..04e93615e 100644
--- a/src/mailman/rules/docs/implicit-dest.txt
+++ b/src/mailman/rules/docs/implicit-dest.txt
@@ -1,10 +1,11 @@
+====================
Implicit destination
====================
The 'implicit-dest' rule matches when the mailing list's posting address is
not explicitly mentioned in the set of message recipients.
- >>> mlist = create_list(u'_xtest@example.com')
+ >>> mlist = create_list('_xtest@example.com')
>>> rule = config.rules['implicit-dest']
>>> print rule.name
implicit-dest
@@ -56,7 +57,7 @@ then the rule will not match.
>>> rule.check(mlist, msg, {})
True
- >>> alias_set.add(u'myfriend@example.com')
+ >>> alias_set.add('myfriend@example.com')
>>> rule.check(mlist, msg, {})
False
@@ -69,7 +70,7 @@ that Mailman pulled it from the appropriate news group.
Additional aliases can be added.
- >>> alias_set.add(u'other@example.com')
+ >>> alias_set.add('other@example.com')
>>> del msg['to']
>>> rule.check(mlist, msg, {})
True
@@ -80,13 +81,13 @@ Additional aliases can be added.
Aliases can be removed.
- >>> alias_set.remove(u'other@example.com')
+ >>> alias_set.remove('other@example.com')
>>> rule.check(mlist, msg, {})
True
Aliases can also be cleared.
- >>> msg['Cc'] = u'myfriend@example.com'
+ >>> msg['Cc'] = 'myfriend@example.com'
>>> rule.check(mlist, msg, {})
False
@@ -96,13 +97,13 @@ Aliases can also be cleared.
Alias patterns
---------------
+==============
It's also possible to specify an alias pattern, i.e. a regular expression to
match against the recipients. For example, we can say that if there is a
recipient in the example.net domain, then the rule does not match.
- >>> alias_set.add(u'^.*@example.net')
+ >>> alias_set.add('^.*@example.net')
>>> rule.check(mlist, msg, {})
True
@@ -112,7 +113,7 @@ recipient in the example.net domain, then the rule does not match.
Bad aliases
------------
+===========
You cannot add an alias that looks like neither a pattern nor an email
address.
diff --git a/src/mailman/rules/docs/loop.txt b/src/mailman/rules/docs/loop.txt
index 61612cd75..5015d3d95 100644
--- a/src/mailman/rules/docs/loop.txt
+++ b/src/mailman/rules/docs/loop.txt
@@ -1,10 +1,11 @@
+=============
Posting loops
=============
To avoid a posting loop, Mailman has a rule to check for the existence of an
X-BeenThere header with the value of the list's posting address.
- >>> mlist = config.db.list_manager.create(u'_xtest@example.com')
+ >>> mlist = config.db.list_manager.create('_xtest@example.com')
>>> rule = config.rules['loop']
>>> print rule.name
loop
@@ -21,7 +22,7 @@ The header could be missing, in which case the rule does not match.
The header could be present, but not match the list's posting address.
- >>> msg['X-BeenThere'] = u'not-this-list@example.com'
+ >>> msg['X-BeenThere'] = 'not-this-list@example.com'
>>> rule.check(mlist, msg, {})
False
diff --git a/src/mailman/rules/docs/max-size.txt b/src/mailman/rules/docs/max-size.txt
index 117691e59..a34c98627 100644
--- a/src/mailman/rules/docs/max-size.txt
+++ b/src/mailman/rules/docs/max-size.txt
@@ -1,3 +1,4 @@
+============
Message size
============
@@ -6,7 +7,7 @@ specified maximum. Generally this is used to prevent huge attachments from
getting posted to the list. This value is calculated in terms of KB (1024
bytes).
- >>> mlist = config.db.list_manager.create(u'_xtest@example.com')
+ >>> mlist = config.db.list_manager.create('_xtest@example.com')
>>> rule = config.rules['max-size']
>>> print rule.name
max-size
@@ -15,8 +16,8 @@ For example, setting the maximum message size to 1 means that any message
bigger than that will match the rule.
>>> mlist.max_message_size = 1 # 1024 bytes
- >>> one_line = u'x' * 79
- >>> big_body = u'\n'.join([one_line] * 15)
+ >>> one_line = 'x' * 79
+ >>> big_body = '\n'.join([one_line] * 15)
>>> msg = message_from_string("""\
... From: aperson@example.com
... To: _xtest@example.com
diff --git a/src/mailman/rules/docs/moderation.txt b/src/mailman/rules/docs/moderation.txt
index 65be0d7da..c4adcdf53 100644
--- a/src/mailman/rules/docs/moderation.txt
+++ b/src/mailman/rules/docs/moderation.txt
@@ -1,3 +1,4 @@
+=================
Member moderation
=================
@@ -6,7 +7,7 @@ postings, then only members with a cleared moderation flag will be able to
email the list without having those messages be held for approval. The
'moderation' rule determines whether the message should be moderated or not.
- >>> mlist = config.db.list_manager.create(u'_xtest@example.com')
+ >>> mlist = config.db.list_manager.create('_xtest@example.com')
>>> rule = config.rules['moderation']
>>> print rule.name
moderation
@@ -26,7 +27,7 @@ moderation rule can't match.
Let's add the message author as a non-moderated member.
>>> user = config.db.user_manager.create_user(
- ... u'aperson@example.org', u'Anne Person')
+ ... 'aperson@example.org', 'Anne Person')
>>> address = list(user.addresses)[0]
>>> from mailman.interfaces.member import MemberRole
>>> member = address.subscribe(mlist, MemberRole.member)
@@ -43,7 +44,7 @@ Once the member's moderation flag is set though, the rule matches.
Non-members
------------
+===========
There is another, related rule for matching non-members, which simply matches
if the sender is /not/ a member of the mailing list.
diff --git a/src/mailman/rules/docs/news-moderation.txt b/src/mailman/rules/docs/news-moderation.txt
index 2ba6aa065..5658ccfef 100644
--- a/src/mailman/rules/docs/news-moderation.txt
+++ b/src/mailman/rules/docs/news-moderation.txt
@@ -1,3 +1,4 @@
+====================
Newsgroup moderation
====================
@@ -8,7 +9,7 @@ posted to the newsgroup, and from there, gated to the mailing list. It's a
circuitous route, but it works nonetheless by holding all messages posted
directly to the mailing list.
- >>> mlist = config.db.list_manager.create(u'_xtest@example.com')
+ >>> mlist = config.db.list_manager.create('_xtest@example.com')
>>> rule = config.rules['news-moderation']
>>> print rule.name
news-moderation
diff --git a/src/mailman/rules/docs/no-subject.txt b/src/mailman/rules/docs/no-subject.txt
index 576111cd7..f9b3ece03 100644
--- a/src/mailman/rules/docs/no-subject.txt
+++ b/src/mailman/rules/docs/no-subject.txt
@@ -1,10 +1,11 @@
+=================
No Subject header
=================
This rule matches if the message has no Subject header, or if the header is
the empty string when stripped.
- >>> mlist = config.db.list_manager.create(u'_xtest@example.com')
+ >>> mlist = config.db.list_manager.create('_xtest@example.com')
>>> rule = config.rules['no-subject']
>>> print rule.name
no-subject
@@ -28,6 +29,6 @@ Delete the Subject header and the rule matches.
Even a Subject header with only whitespace still matches the rule.
- >>> msg['Subject'] = u' '
+ >>> msg['Subject'] = ' '
>>> rule.check(mlist, msg, {})
True
diff --git a/src/mailman/rules/docs/recipients.txt b/src/mailman/rules/docs/recipients.txt
index 3cd49d501..e8c63b59a 100644
--- a/src/mailman/rules/docs/recipients.txt
+++ b/src/mailman/rules/docs/recipients.txt
@@ -1,10 +1,11 @@
+============================
Maximum number of recipients
============================
The 'max-recipients' rule matches when there are more than the maximum allowed
number of explicit recipients addressed by the message.
- >>> mlist = config.db.list_manager.create(u'_xtest@example.com')
+ >>> mlist = config.db.list_manager.create('_xtest@example.com')
>>> rule = config.rules['max-recipients']
>>> print rule.name
max-recipients
diff --git a/src/mailman/rules/docs/rules.txt b/src/mailman/rules/docs/rules.txt
index 095d11466..2836d10a1 100644
--- a/src/mailman/rules/docs/rules.txt
+++ b/src/mailman/rules/docs/rules.txt
@@ -1,3 +1,4 @@
+=====
Rules
=====
@@ -7,7 +8,7 @@ links determine what happens when a rule matches.
All rules
----------
+=========
Rules are maintained in the configuration object as a dictionary mapping rule
names to rule objects.
@@ -40,13 +41,13 @@ You can get a rule by name.
Rule checks
------------
+===========
Individual rules can be checked to see if they match, by running the rule's
`check()` method. This returns a boolean indicating whether the rule was
matched or not.
- >>> mlist = config.db.list_manager.create(u'_xtest@example.com')
+ >>> mlist = config.db.list_manager.create('_xtest@example.com')
>>> msg = message_from_string("""\
... From: aperson@example.com
...
diff --git a/src/mailman/rules/docs/suspicious.txt b/src/mailman/rules/docs/suspicious.txt
index 190a34aca..79d3eeea5 100644
--- a/src/mailman/rules/docs/suspicious.txt
+++ b/src/mailman/rules/docs/suspicious.txt
@@ -1,3 +1,4 @@
+==================
Suspicious headers
==================
@@ -5,14 +6,14 @@ Suspicious headers are a way for Mailman to hold messages that match a
particular regular expression. This mostly historical feature is fairly
confusing to users, and the list attribute that controls this is misnamed.
- >>> mlist = config.db.list_manager.create(u'_xtest@example.com')
+ >>> mlist = config.db.list_manager.create('_xtest@example.com')
>>> rule = config.rules['suspicious-header']
>>> print rule.name
suspicious-header
Set the so-called suspicious header configuration variable.
- >>> mlist.bounce_matching_headers = u'From: .*person@(blah.)?example.com'
+ >>> mlist.bounce_matching_headers = 'From: .*person@(blah.)?example.com'
>>> msg = message_from_string("""\
... From: aperson@example.com
... To: _xtest@example.com
diff --git a/src/mailman/styles/default.py b/src/mailman/styles/default.py
index 2b07b6f49..d1904a150 100644
--- a/src/mailman/styles/default.py
+++ b/src/mailman/styles/default.py
@@ -55,7 +55,7 @@ class DefaultStyle:
mlist = mailing_list
# List identity.
mlist.real_name = mlist.list_name.capitalize()
- mlist.list_id = u'{0.list_name}.{0.host_name}'.format(mlist)
+ mlist.list_id = '{0.list_name}.{0.host_name}'.format(mlist)
mlist.include_rfc2369_headers = True
mlist.include_list_post_header = True
# Most of these were ripped from the old MailList.InitVars() method.
diff --git a/src/mailman/tests/test_documentation.py b/src/mailman/tests/test_documentation.py
index 48b71d72c..0409e737c 100644
--- a/src/mailman/tests/test_documentation.py
+++ b/src/mailman/tests/test_documentation.py
@@ -69,16 +69,19 @@ class chdir:
-def specialized_message_from_string(text):
+def specialized_message_from_string(unicode_text):
"""Parse text into a message object.
This is specialized in the sense that an instance of Mailman's own Message
object is returned, and this message object has an attribute
`original_size` which is the pre-calculated size in bytes of the message's
text representation.
+
+ Also, the text must be ASCII-only unicode.
"""
# This mimic what Switchboard.dequeue() does when parsing a message from
# text into a Message instance.
+ text = unicode_text.encode('ascii')
original_size = len(text)
message = message_from_string(text, Message)
message.original_size = original_size