Permalink
Browse files

Unification of release information, setup script, and setup configura…

…tion and now correct use of internal exceptions upon message failure.
  • Loading branch information...
amcgregor committed Aug 19, 2011
1 parent c9b5763 commit b7dd6ef55a800d6b35d215341a40f4ce246b0b2a
View
@@ -1,2 +1,6 @@
*.egg-info
*.pyc
+.coverage
+build/
+dist/
+examples/local.py
View
@@ -197,9 +197,6 @@ def __get__(self, instance, owner):
if value is None:
return self.cls() if self.can else None
- if not isinstance(value, self.cls):
- return self.cls(value)
-
return value
def __set__(self, instance, value):
View
@@ -70,7 +70,10 @@ class TransportFailedException(TransportException):
class MessageFailedException(TransportException):
"""The transport has failed to deliver the message due to a problem with
the message itself, and no attempt should be made to retry delivery of
- this message. The transport may still be re-used, however."""
+ this message. The transport may still be re-used, however.
+
+ The reason for the failure should be the first argument.
+ """
pass
@@ -2,7 +2,7 @@
from functools import partial
-from marrow.mailer.exc import TransportFailedException, TransportExhaustedException
+from marrow.mailer.exc import TransportFailedException, TransportExhaustedException, MessageFailedException, DeliveryFailedException
from marrow.mailer.manager.util import TransportPool
try:
@@ -25,6 +25,10 @@ def worker(pool, message):
try:
result = transport.deliver(message)
+ except MessageFailedException:
+ e = sys.exc_info()[1]
+ raise DeliveryFailedException(message, e.args[0] if e.args else "No reason given.")
+
except TransportFailedException:
# The transport has suffered an internal error or has otherwise
# requested to not be recycled. Delivery should be attempted
@@ -1,6 +1,6 @@
# encoding: utf-8
-from marrow.mailer.exc import TransportExhaustedException, TransportFailedException
+from marrow.mailer.exc import TransportExhaustedException, TransportFailedException, DeliveryFailedException, MessageFailedException
from marrow.mailer.manager.util import TransportPool
@@ -42,6 +42,10 @@ def deliver(self, message):
try:
result = transport.deliver(message)
+ except MessageFailedException:
+ e = sys.exc_info()[1]
+ raise DeliveryFailedException(message, e.args[0] if e.args else "No reason given.")
+
except TransportFailedException:
# The transport has suffered an internal error or has otherwise
# requested to not be recycled. Delivery should be attempted
View
@@ -10,4 +10,4 @@
version_info = namedtuple('version_info', ('major', 'minor', 'micro', 'releaselevel', 'serial'))(4, 0, 0, 'beta', 3)
-version = ".".join([str(i) for i in version_info[:3]]) + (version_info.releaselevel[0] + str(version_info.serial)) if version_info.releaselevel != 'final' else ''
+version = ".".join([str(i) for i in version_info[:3]]) + ((version_info.releaselevel[0] + str(version_info.serial)) if version_info.releaselevel != 'final' else '')
@@ -4,7 +4,7 @@
from datetime import datetime
-from marrow.mailer.exc import TransportException, DeliveryFailedException
+from marrow.mailer.exc import TransportException, MessageFailedException
__all__ = ['IMAPTransport']
@@ -46,7 +46,7 @@ def deliver(self, message):
)
if result[0] != b'OK':
- raise DeliveryFailedException(message, "\n".join(result[1]))
+ raise MessageFailedException("\n".join(result[1]))
def shutdown(self):
self.connection.logout()
@@ -2,7 +2,7 @@
import os
-from marrow.mailer.exc import DeliveryFailedException
+from marrow.mailer.exc import MessageFailedException
__all__ = ['SendmailTransport']
@@ -22,12 +22,13 @@ def startup(self):
def __call__(self, message):
# TODO: Utilize -F full_name (sender full name), -f sender (envelope sender), -V envid (envelope ID), and space-separated BCC recipients
+ # TODO: Record the output of STDOUT and STDERR to capture errors.
proc = os.popen('%s -t -i' % (self.executable, ), 'w')
proc.write(bytes(message))
status = proc.close()
if status != 0:
- raise DeliveryFailedException("Sendmail delivery failed with status code %d." % (status, ), status)
+ raise MessageFailedException("Status code %d." % (status, ))
def shutdown(self):
pass
@@ -126,14 +126,14 @@ def send_with_smtp(self, message):
# The envelope sender was refused. This is bad.
e = sys.exc_info()[1]
log.error("%s REFUSED %s %s", message.id, e.__class__.__name__, e)
- raise MessageFailedException(e)
+ raise MessageFailedException(str(e))
except SMTPRecipientsRefused:
# All recipients were refused. Log which recipients.
# This allows you to automatically parse your logs for bad e-mail addresses.
e = sys.exc_info()[1]
log.warning("%s REFUSED %s %s", message.id, e.__class__.__name__, e)
- raise MessageFailedException(e)
+ raise MessageFailedException(str(e))
except SMTPServerDisconnected:
if message.retries >= 0:
View
@@ -1,8 +1,11 @@
[nosetests]
-with-coverage = 1
+quiet = true
+with-coverage = true
cover-package = marrow.mailer
-cover-erase = 1
-;cover-inclusive = 1
+cover-inclusive = true
+where = tests
+detailed-errors = true
+with-achievements = true
[aliases]
-;test = nosetests
+test = nosetests
View
136 setup.py
@@ -1,79 +1,87 @@
#!/usr/bin/env python
# encoding: utf-8
-import sys
import os
+import sys
from setuptools import setup, find_packages
if sys.version_info < (2, 6):
raise SystemExit("Python 2.6 or later is required.")
-exec(open(os.path.join("marrow", "mailer", "release.py")).read())
+exec(open(os.path.join("marrow", "mailer", "release.py")))
+
setup(
- name="marrow.mailer",
- version=version,
-
- description="""
-A highly efficient and modular mail delivery framework for
-Python 2.6+ and 3.1+, formerly called TurboMail.""",
- author="Alice Bevan-McGregor",
- author_email="alice+marrow@gothcandy.com",
- url="https://github.com/marrow/marrow.mailer",
- download_url="http://pypi.python.org/pypi/marrow.mailer",
- license="MIT",
- keywords="",
-
- install_requires=["marrow.util", "marrow.interface"],
-
- test_suite="nose.collector",
- tests_require=["nose", "coverage"],
-
- classifiers=[
- "Development Status :: 4 - Beta",
- "Environment :: Console",
- "Intended Audience :: Developers",
- "License :: OSI Approved :: MIT License",
- "Operating System :: OS Independent",
- "Programming Language :: Python",
- "Programming Language :: Python :: 2.6",
- "Programming Language :: Python :: 2.7",
- "Programming Language :: Python :: 3",
- "Programming Language :: Python :: 3.1",
- "Programming Language :: Python :: 3.2",
- "Topic :: Software Development :: Libraries :: Python Modules"
- ],
-
- packages=find_packages(exclude=["examples", "tests"]),
- zip_safe=True,
- include_package_data=True,
- package_data={
- "": ["README.textile", "LICENSE", "distribute_setup.py"]
- },
-
- namespace_packages=["marrow"],
- entry_points = {
- 'marrow.mailer.manager': [
- "immediate = marrow.mailer.manager.immediate:ImmediateManager",
- "futures = marrow.mailer.manager.futures:FuturesManager",
- "dynamic = marrow.mailer.manager.dynamic:DynamicManager",
- "transactional = marrow.mailer.manager.transactional:TransactionalDynamicManager"
+ name = "marrow.mailer",
+ version = version,
+
+ description = "A highly efficient and modular mail delivery framework for Python 2.6+ and 3.1+, formerly called TurboMail.",
+ long_description = """\
+For full documentation, see the README.textile file present in the package,
+or view it online on the GitHub project page:
+
+https://github.com/marrow/marrow.mailer""",
+
+ author = "Alice Bevan-McGregor",
+ author_email = "alice+marrow@gothcandy.com",
+ url = "https://github.com/marrow/marrow.wsgi.objects",
+ license = "MIT",
+
+ install_requires = [
+ 'marrow.util < 2.0',
+ 'marrow.interface < 2.0'
+ ],
+
+ test_suite = 'nose.collector',
+ tests_require = [
+ 'nose',
+ 'coverage'
+ ],
+
+ classifiers=[
+ "Development Status :: 4 - Beta",
+ "Environment :: Console",
+ "Intended Audience :: Developers",
+ "License :: OSI Approved :: MIT License",
+ "Operating System :: OS Independent",
+ "Programming Language :: Python",
+ "Programming Language :: Python :: 2.6",
+ "Programming Language :: Python :: 2.7",
+ "Programming Language :: Python :: 3",
+ "Programming Language :: Python :: 3.1",
+ "Programming Language :: Python :: 3.2",
+ "Topic :: Software Development :: Libraries :: Python Modules"
],
- 'marrow.mailer.transport': [
- "amazon = marrow.mailer.transport.ses:AmazonTransport",
- "mock = marrow.mailer.transport.mock:MockTransport",
- "smtp = marrow.mailer.transport.smtp:SMTPTransport",
- "mbox = marrow.mailer.transport.mbox:MailboxTransport",
- "mailbox = marrow.mailer.transport.mbox:MailboxTransport",
- "maildir = marrow.mailer.transport.maildir:MaildirTransport",
- "sendmail = marrow.mailer.transport.sendmail:SendmailTransport",
- "imap = marrow.mailer.transport.imap:IMAPTransport",
- "appengine = marrow.mailer.transport.gae:AppEngineTransport",
- "logging = marrow.mailer.transport.log:LoggingTransport",
- "sms = marrow.mailer.transport.sms:SMSTransport",
- ]
- }
-)
+
+ packages = find_packages(exclude=['examples', 'tests']),
+ zip_safe = True,
+ include_package_data = True,
+ package_data = {'': ['README.textile', 'LICENSE']},
+
+ namespace_packages = ['marrow'],
+
+ entry_points = {
+ 'marrow.mailer.manager': [
+ 'immediate = marrow.mailer.manager.immediate:ImmediateManager',
+ 'futures = marrow.mailer.manager.futures:FuturesManager',
+ 'dynamic = marrow.mailer.manager.dynamic:DynamicManager',
+ 'transactional = marrow.mailer.manager.transactional:TransactionalDynamicManager'
+ ],
+ 'marrow.mailer.transport': [
+ 'amazon = marrow.mailer.transport.ses:AmazonTransport',
+ 'mock = marrow.mailer.transport.mock:MockTransport',
+ 'smtp = marrow.mailer.transport.smtp:SMTPTransport',
+ 'mbox = marrow.mailer.transport.mbox:MailboxTransport',
+ 'mailbox = marrow.mailer.transport.mbox:MailboxTransport',
+ 'maildir = marrow.mailer.transport.maildir:MaildirTransport',
+ 'sendmail = marrow.mailer.transport.sendmail:SendmailTransport',
+ 'imap = marrow.mailer.transport.imap:IMAPTransport',
+ 'appengine = marrow.mailer.transport.gae:AppEngineTransport',
+ 'logging = marrow.mailer.transport.log:LoggingTransport',
+ 'sms = marrow.mailer.transport.sms:SMSTransport',
+ ]
+ }
+ )
View
@@ -158,6 +158,8 @@ def tearDown(self):
def test_assignment(self):
eq_([], self.addresses)
+ self.addresses = ['me@example.com']
+ eq_(['me@example.com'], self.addresses)
def test_assign_single_address(self):
address = 'user@example.com'

0 comments on commit b7dd6ef

Please sign in to comment.