Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Python 2.5-3.2 compatible!

  • Loading branch information...
commit 20c0abafbda6ae0f8a487ced39ffbd5eafab21d8 1 parent 60ae523
@rpatterson rpatterson authored
View
12 repoze/sendmail/delivery.py
@@ -32,7 +32,6 @@
from transaction.interfaces import IDataManager
import transaction
-@implementer(IDataManager)
class MailDataManager(object):
def __init__(self, callable, args=(), onAbort=None):
@@ -74,6 +73,9 @@ def tpc_finish(self, transaction):
tpc_abort = abort
+# BBB Python 2.5 compat
+MailDataManager = implementer(IDataManager)(MailDataManager)
+
class AbstractMailDelivery(object):
@@ -98,7 +100,6 @@ def send(self, fromaddr, toaddrs, message):
return messageid
-@implementer(IMailDelivery)
class DirectMailDelivery(AbstractMailDelivery):
def __init__(self, mailer):
@@ -108,8 +109,10 @@ def createDataManager(self, fromaddr, toaddrs, message):
return MailDataManager(self.mailer.send,
args=(fromaddr, toaddrs, message))
+# BBB Python 2.5 compat
+DirectMailDelivery = implementer(IMailDelivery)(DirectMailDelivery)
+
-@implementer(IMailDelivery)
class QueuedMailDelivery(AbstractMailDelivery):
def __init__(self, queuePath):
@@ -126,6 +129,9 @@ def createDataManager(self, fromaddr, toaddrs, message):
tx_message = maildir.add(message)
return MailDataManager(tx_message.commit, onAbort=tx_message.abort)
+# BBB Python 2.5 compat
+QueuedMailDelivery = implementer(IMailDelivery)(QueuedMailDelivery)
+
def copy_message(message):
parser = Parser()
View
5 repoze/sendmail/maildir.py
@@ -17,6 +17,7 @@
Read/write access to `Maildir` folders.
"""
+import sys
import os
import errno
import socket
@@ -87,7 +88,9 @@ def add(self, message):
os.O_CREAT|os.O_EXCL|os.O_WRONLY,
384 # BBB Python 2 vs 3, 0o600 in octal
)
- except OSError as e:
+ except OSError:
+ # BBB Python 2.5 compat
+ e = sys.exc_info()[1]
if e.errno != errno.EEXIST:
raise
# File exists
View
14 repoze/sendmail/mailer.py
@@ -15,16 +15,21 @@
from email.message import Message
import socket
-import ssl
from smtplib import SMTP
+try:
+ from ssl import SSLError
+except ImportError:
+ # BBB Python 2.5
+ from socket import sslerror as SSLError
+
from zope.interface import implementer
from repoze.sendmail.interfaces import IMailer
from repoze.sendmail import encoding
have_ssl = hasattr(socket, 'ssl')
-@implementer(IMailer)
+
class SMTPMailer(object):
smtp = SMTP
@@ -78,6 +83,9 @@ def send(self, fromaddr, toaddrs, message):
connection.sendmail(fromaddr, toaddrs, message)
try:
connection.quit()
- except ssl.SSLError:
+ except SSLError:
#something weird happened while quiting
connection.close()
+
+# BBB Python 2.5 compat
+SMTPMailer = implementer(IMailer)(SMTPMailer)
View
28 repoze/sendmail/queue.py
@@ -135,7 +135,9 @@ def _send_message(self, filename):
age = None
mtime = os.stat(tmp_filename)[stat.ST_MTIME]
age = time.time() - mtime
- except OSError as e:
+ except OSError:
+ # BBB Python 2.5 compat
+ e = sys.exc_info()[1]
if e.errno == errno.ENOENT: # file does not exist
# the tmp file could not be stated because it
# doesn't exist, that's fine, keep going
@@ -160,7 +162,9 @@ def _send_message(self, filename):
return
# if we get here, the file existed, but was too
# old, so it was unlinked
- except OSError as e:
+ except OSError:
+ # BBB Python 2.5 compat
+ e = sys.exc_info()[1]
if e.errno == errno.ENOENT: # file does not exist
# it looks like someone else removed the tmp
# file, that's fine, we'll try to deliver the
@@ -174,7 +178,9 @@ def _send_message(self, filename):
# more processes to touch the file "simultaneously")
try:
os.utime(filename, None)
- except OSError as e:
+ except OSError:
+ # BBB Python 2.5 compat
+ e = sys.exc_info()[1]
if e.errno == errno.ENOENT: # file does not exist
# someone removed the message before we could
# touch it, no need to complain, we'll just keep
@@ -189,7 +195,9 @@ def _send_message(self, filename):
# also sending this message
try:
_os_link(filename, tmp_filename)
- except OSError as e:
+ except OSError:
+ # BBB Python 2.5 compat
+ e = sys.exc_info()[1]
if e.errno == errno.EEXIST: # file exists, *nix
# it looks like someone else is sending this
# message too; we'll try again later
@@ -212,7 +220,9 @@ def _send_message(self, filename):
fromaddr, toaddrs, message = self._parseMessage(open(filename))
try:
self.mailer.send(fromaddr, toaddrs, message)
- except smtplib.SMTPResponseException as e:
+ except smtplib.SMTPResponseException:
+ # BBB Python 2.5 compat
+ e = sys.exc_info()[1]
if 500 <= e.smtp_code <= 599:
# permanent error, ditch the message
self.log.error(
@@ -226,7 +236,9 @@ def _send_message(self, filename):
try:
os.remove(filename)
- except OSError as e:
+ except OSError:
+ # BBB Python 2.5 compat
+ e = sys.exc_info()[1]
if e.errno == errno.ENOENT: # file does not exist
# someone else unlinked the file; oh well
pass
@@ -236,7 +248,9 @@ def _send_message(self, filename):
try:
os.remove(tmp_filename)
- except OSError as e:
+ except OSError:
+ # BBB Python 2.5 compat
+ e = sys.exc_info()[1]
if e.errno == errno.ENOENT: # file does not exist
# someone else unlinked the file; oh well
pass
View
12 repoze/sendmail/tests/test_delivery.py
@@ -15,11 +15,13 @@
import unittest
from unittest import TestCase, TestSuite, makeSuite
-raw_header = str
+# BBB Python 2 & 3 compat
+raw_header = b = str
try:
raw_header = unicode
except NameError:
- pass # Python 2 & 3 compat
+ import codecs
+ def b(x): return codecs.latin_1_encode(x)[0]
import transaction
from zope.interface import implementer
@@ -28,7 +30,6 @@
from repoze.sendmail.interfaces import IMailer
-@implementer(IMailer)
class MailerStub(object):
def __init__(self, *args, **kw):
@@ -37,6 +38,9 @@ def __init__(self, *args, **kw):
def send(self, fromaddr, toaddrs, message):
self.sent_messages.append((fromaddr, toaddrs, message))
+# BBB Python 2.5 compat
+MailerStub = implementer(IMailer)(MailerStub)
+
class TestMailDataManager(TestCase):
@@ -207,7 +211,7 @@ def testNonASCIIAddrs(self):
from repoze.sendmail.delivery import QueuedMailDelivery
delivery = QueuedMailDelivery('/path/to/mailbox')
- non_ascii = b'LaPe\xc3\xb1a'.decode('utf-8')
+ non_ascii = b('LaPe\xc3\xb1a').decode('utf-8')
fromaddr = non_ascii+' <jim@example.com>'
toaddrs = (non_ascii+' <guido@recip.com>',)
message = Message()
View
57 repoze/sendmail/tests/test_encoding.py
@@ -19,6 +19,14 @@
from email.mime import multipart
from email.mime import application
+# BBB Python 2.5 & 3 compat
+b = str
+try:
+ unicode
+except NameError:
+ import codecs
+ def b(x): return codecs.latin_1_encode(x)[0]
+
try:
from urllib.parse import quote
except ImportError:
@@ -30,9 +38,9 @@ class TestEncoding(unittest.TestCase):
def setUp(self):
self.message = message.Message()
- self.latin_1_encoded = b'LaPe\xf1a'
+ self.latin_1_encoded = b('LaPe\xf1a')
self.latin_1 = self.latin_1_encoded.decode('latin_1')
- self.utf_8_encoded = b'mo \xe2\x82\xac'
+ self.utf_8_encoded = b('mo \xe2\x82\xac')
self.utf_8 = self.utf_8_encoded.decode('utf_8')
def encode(self, message=None):
@@ -45,7 +53,7 @@ def test_best_charset_ascii(self):
from repoze.sendmail import encoding
value = 'foo'
best, encoded = encoding.best_charset(value)
- self.assertEqual(encoded, b'foo')
+ self.assertEqual(encoded, b('foo'))
self.assertEqual(best, 'ascii')
def test_best_charset_latin_1(self):
@@ -74,10 +82,10 @@ def test_encoding_ascii_headers(self):
encoded = self.encode()
self.assertTrue(
- b'To: Chris McDonough <chrism@example.com>, "Chris Rossi,'
+ b('To: Chris McDonough <chrism@example.com>, "Chris Rossi,')
in encoded)
- self.assertTrue(b'From: '+from_.encode('ascii') in encoded)
- self.assertTrue(b'Subject: '+subject.encode('ascii') in encoded)
+ self.assertTrue(b('From: ')+from_.encode('ascii') in encoded)
+ self.assertTrue(b('Subject: ')+subject.encode('ascii') in encoded)
def test_encoding_latin_1_headers(self):
to = ', '.join([
@@ -91,12 +99,12 @@ def test_encoding_latin_1_headers(self):
encoded = self.encode()
- self.assertTrue(b'To: =?iso-8859-1?' in encoded)
- self.assertTrue(b'From: =?iso-8859-1?' in encoded)
- self.assertTrue(b'Subject: =?iso-8859-1?' in encoded)
- self.assertTrue(b'<chrism@example.com>' in encoded)
- self.assertTrue(b'<chrisr@example.com>' in encoded)
- self.assertTrue(b'<rpatterson@example.com>' in encoded)
+ self.assertTrue(b('To: =?iso-8859-1?') in encoded)
+ self.assertTrue(b('From: =?iso-8859-1?') in encoded)
+ self.assertTrue(b('Subject: =?iso-8859-1?') in encoded)
+ self.assertTrue(b('<chrism@example.com>') in encoded)
+ self.assertTrue(b('<chrisr@example.com>') in encoded)
+ self.assertTrue(b('<rpatterson@example.com>') in encoded)
def test_encoding_utf_8_headers(self):
to = ', '.join([
@@ -110,12 +118,12 @@ def test_encoding_utf_8_headers(self):
encoded = self.encode()
- self.assertTrue(b'To: =?utf' in encoded)
- self.assertTrue(b'From: =?utf' in encoded)
- self.assertTrue(b'Subject: =?utf' in encoded)
- self.assertTrue(b'<chrism@example.com>' in encoded)
- self.assertTrue(b'<chrisr@example.com>' in encoded)
- self.assertTrue(b'<rpatterson@example.com>' in encoded)
+ self.assertTrue(b('To: =?utf') in encoded)
+ self.assertTrue(b('From: =?utf') in encoded)
+ self.assertTrue(b('Subject: =?utf') in encoded)
+ self.assertTrue(b('<chrism@example.com>') in encoded)
+ self.assertTrue(b('<chrisr@example.com>') in encoded)
+ self.assertTrue(b('<rpatterson@example.com>') in encoded)
def test_encoding_ascii_header_parameters(self):
self.message['Content-Disposition'] = (
@@ -124,7 +132,8 @@ def test_encoding_ascii_header_parameters(self):
encoded = self.encode()
self.assertTrue(
- b'Content-Disposition: attachment; filename="foo.ppt"' in encoded)
+ b('Content-Disposition: attachment; filename="foo.ppt"')
+ in encoded)
def test_encoding_latin_1_header_parameters(self):
self.message['Content-Disposition'] = (
@@ -133,8 +142,8 @@ def test_encoding_latin_1_header_parameters(self):
encoded = self.encode()
self.assertTrue(
- b"Content-Disposition: attachment; filename*=" in encoded)
- self.assertTrue(b"latin_1''"+quote(
+ b("Content-Disposition: attachment; filename*=") in encoded)
+ self.assertTrue(b("latin_1''")+quote(
self.latin_1_encoded).encode('ascii') in encoded)
def test_encoding_utf_8_header_parameters(self):
@@ -144,8 +153,8 @@ def test_encoding_utf_8_header_parameters(self):
encoded = self.encode()
self.assertTrue(
- b"Content-Disposition: attachment; filename*=" in encoded)
- self.assertTrue(b"utf_8''"+quote(self.utf_8_encoded).encode('ascii')
+ b("Content-Disposition: attachment; filename*=") in encoded)
+ self.assertTrue(b("utf_8''")+quote(self.utf_8_encoded).encode('ascii')
in encoded)
def test_encoding_ascii_body(self):
@@ -173,7 +182,7 @@ def test_encoding_utf_8_body(self):
self.assertTrue(base64.encodestring(body.encode('utf_8')) in encoded)
def test_binary_body(self):
- body = b'I know what you did last PyCon'
+ body = b('I know what you did last PyCon')
self.message = multipart.MIMEMultipart()
self.message.attach(application.MIMEApplication(body))
View
9 repoze/sendmail/tests/test_mailer.py
@@ -15,9 +15,14 @@
from zope.interface.verify import verifyObject
from repoze.sendmail.mailer import SMTPMailer
import email
-import ssl
import unittest
+try:
+ from ssl import SSLError
+except ImportError:
+ # BBB Python 2.5
+ from socket import sslerror as SSLError
+
class TestSMTPMailer(unittest.TestCase):
@@ -50,7 +55,7 @@ def login(self, username, password):
def quit(self):
if self.fail_on_quit:
- raise ssl.SSLError("dang")
+ raise SSLError("dang")
self.quitted = True
self.close()
View
53 repoze/sendmail/tests/test_queue.py
@@ -1,6 +1,3 @@
-# BBB Python 2 vs 3 compat
-from __future__ import unicode_literals
-
import os.path
import shutil
import smtplib
@@ -8,6 +5,14 @@
import unittest
from unittest import TestCase, TestSuite, makeSuite
+# BBB Python 2.5 & 3 compat
+b = str
+try:
+ str = unicode
+except NameError:
+ import codecs
+ def b(x): return codecs.latin_1_encode(x)[0]
+
try:
from io import StringIO
StringIO # pyflakes
@@ -40,7 +45,6 @@ class BizzarreMailError(IOError):
pass
-@implementer(IMailer)
class BrokenMailerStub(object):
def __init__(self, *args, **kw):
@@ -49,8 +53,10 @@ def __init__(self, *args, **kw):
def send(self, fromaddr, toaddrs, message):
raise BizzarreMailError("bad things happened while sending mail")
+# BBB Python 2.5 compat
+BrokenMailerStub = implementer(IMailer)(BrokenMailerStub)
+
-@implementer(IMailer)
class SMTPResponseExceptionMailerStub(object):
def __init__(self, code):
@@ -59,6 +65,11 @@ def __init__(self, code):
def send(self, fromaddr, toaddrs, message):
raise smtplib.SMTPResponseException(self.code, 'Serious Error')
+# BBB Python 2.5 compat
+SMTPResponseExceptionMailerStub = implementer(IMailer)(
+ SMTPResponseExceptionMailerStub)
+
+
class TestQueueProcessor(TestCase):
def setUp(self):
@@ -76,7 +87,7 @@ def test_parseMessage(self):
msg = ('Header: value\n'
'\n'
'Body\n')
- f, t, m = self.qp._parseMessage(StringIO(hdr + msg))
+ f, t, m = self.qp._parseMessage(StringIO(str(hdr + msg)))
self.assertEquals(f, 'foo@example.com')
self.assertEquals(t, ('bar@example.com', 'baz@example.com'))
self.assertEquals(m, msg)
@@ -84,9 +95,9 @@ def test_parseMessage(self):
def test_delivery(self):
self.filename = os.path.join(self.dir, 'message')
temp = open(self.filename, "w+b")
- temp.write(b'X-Actually-From: foo@example.com\n'
- b'X-Actually-To: bar@example.com, baz@example.com\n'
- b'Header: value\n\nBody\n')
+ temp.write(b('X-Actually-From: foo@example.com\n')+
+ b('X-Actually-To: bar@example.com, baz@example.com\n')+
+ b('Header: value\n\nBody\n'))
temp.close()
self.qp.maildir.files.append(self.filename)
self.qp.send_messages()
@@ -105,9 +116,9 @@ def test_error_logging(self):
self.qp.mailer = BrokenMailerStub()
self.filename = os.path.join(self.dir, 'message')
temp = open(self.filename, "w+b")
- temp.write(b'X-Actually-From: foo@example.com\n'
- b'X-Actually-To: bar@example.com, baz@example.com\n'
- b'Header: value\n\nBody\n')
+ temp.write(b('X-Actually-From: foo@example.com\n')+
+ b('X-Actually-To: bar@example.com, baz@example.com\n')+
+ b('Header: value\n\nBody\n'))
temp.close()
self.qp.maildir.files.append(self.filename)
self.qp.send_messages()
@@ -122,9 +133,9 @@ def test_smtp_response_error_transient(self):
self.qp.mailer = SMTPResponseExceptionMailerStub(451)
self.filename = os.path.join(self.dir, 'message')
temp = open(self.filename, "w+b")
- temp.write(b'X-Actually-From: foo@example.com\n'
- b'X-Actually-To: bar@example.com, baz@example.com\n'
- b'Header: value\n\nBody\n')
+ temp.write(b('X-Actually-From: foo@example.com\n')+
+ b('X-Actually-To: bar@example.com, baz@example.com\n')+
+ b('Header: value\n\nBody\n'))
temp.close()
self.qp.maildir.files.append(self.filename)
self.qp.send_messages()
@@ -142,9 +153,9 @@ def test_smtp_response_error_permanent(self):
self.qp.mailer = SMTPResponseExceptionMailerStub(550)
self.filename = os.path.join(self.dir, 'message')
temp = open(self.filename, "w+b")
- temp.write(b'X-Actually-From: foo@example.com\n'
- b'X-Actually-To: bar@example.com, baz@example.com\n'
- b'Header: value\n\nBody\n')
+ temp.write(b('X-Actually-From: foo@example.com\n')+
+ b('X-Actually-To: bar@example.com, baz@example.com\n')+
+ b('Header: value\n\nBody\n'))
temp.close()
self.qp.maildir.files.append(self.filename)
self.qp.send_messages()
@@ -166,9 +177,9 @@ def test_concurrent_delivery(self):
self.filename = os.path.join(self.dir, 'message')
temp = open(self.filename, "w+b")
- temp.write(b'X-Actually-From: foo@example.com\n'
- b'X-Actually-To: bar@example.com, baz@example.com\n'
- b'Header: value\n\nBody\n')
+ temp.write(b('X-Actually-From: foo@example.com\n')+
+ b('X-Actually-To: bar@example.com, baz@example.com\n')+
+ b('Header: value\n\nBody\n'))
temp.close()
self.qp.maildir.files.append(self.filename)
View
8 setup.py
@@ -12,8 +12,14 @@
#
##############################################################################
+import sys
from setuptools import setup, find_packages
+transaction = 'transaction'
+if sys.version < '2.6':
+ # BBB Python 2.5 compat
+ transaction = 'transaction<1.2'
+
setup(name='repoze.sendmail',
version = '2.4dev',
url='http://www.repoze.org',
@@ -30,7 +36,7 @@
tests_require = [],
install_requires=['setuptools',
'zope.interface>=3.6.0',
- 'transaction',
+ transaction,
],
test_suite="repoze.sendmail",
include_package_data = True,
View
2  tox.ini
@@ -1,6 +1,6 @@
[tox]
envlist =
- py26,py27,py32,pypy,cover
+ py25,py26,py27,py32,pypy,cover
[testenv]
commands =
Please sign in to comment.
Something went wrong with that request. Please try again.