Drop support for Django 1.3, Python 2.6 and 3.2.

* Shrink the Travis test matrix
* Remove a lot of backported test code
* Update requirements in setup.py
* Update docs

Closes #79
This commit is contained in:
medmunds
2015-05-14 11:39:57 -07:00
parent 99ac099081
commit da260de1a0
10 changed files with 25 additions and 131 deletions

View File

@@ -1,19 +1,10 @@
language: python language: python
matrix: matrix:
include: include:
# Django 1.3: Python 2.6--2.7 # Django 1.4: Python 2.6--2.7 (but we don't support 2.6)
- python: "2.6"
env: DJANGO=django==1.3
- python: "2.7"
env: DJANGO=django==1.3
# Django 1.4: Python 2.6--2.7
- python: "2.6"
env: DJANGO=django==1.4
- python: "2.7" - python: "2.7"
env: DJANGO=django==1.4 env: DJANGO=django==1.4
# Django 1.5: Python 2.7, pypy # Django 1.5: Python 2.7, pypy
# (As of Django 1.5, Python 2.6 no longer "highly recommended",
# and Python 3.2+ support was only "experimental", so skip those.)
- python: "2.7" - python: "2.7"
env: DJANGO=django==1.5 env: DJANGO=django==1.5
- python: "pypy" - python: "pypy"
@@ -21,8 +12,6 @@ matrix:
# Django 1.6: Python 2.7--3.3, pypy # Django 1.6: Python 2.7--3.3, pypy
- python: "2.7" - python: "2.7"
env: DJANGO=django==1.6 env: DJANGO=django==1.6
- python: "3.2"
env: DJANGO=django==1.6
- python: "3.3" - python: "3.3"
env: DJANGO=django==1.6 env: DJANGO=django==1.6
- python: "pypy" - python: "pypy"
@@ -30,8 +19,6 @@ matrix:
# Django 1.7: Python 2.7--3.4, pypy # Django 1.7: Python 2.7--3.4, pypy
- python: "2.7" - python: "2.7"
env: DJANGO=django==1.7 env: DJANGO=django==1.7
- python: "3.2"
env: DJANGO=django==1.7
- python: "3.3" - python: "3.3"
env: DJANGO=django==1.7 env: DJANGO=django==1.7
- python: "3.4" - python: "3.4"

View File

@@ -29,7 +29,7 @@ package. It includes:
* Optional support for Mandrill inbound email and other webhook notifications, * Optional support for Mandrill inbound email and other webhook notifications,
via Django signals via Django signals
Djrill is released under the BSD license. It is tested against Django 1.3--1.8 Djrill is released under the BSD license. It is tested against Django 1.4--1.8
(including Python 3 with Django 1.6+, and PyPy support with Django 1.5+). (including Python 3 with Django 1.6+, and PyPy support with Django 1.5+).
Djrill uses `semantic versioning <http://semver.org/>`_. Djrill uses `semantic versioning <http://semver.org/>`_.

View File

@@ -4,13 +4,12 @@ import requests
import six import six
from django.test import TestCase from django.test import TestCase
from django.test.utils import override_settings
from .utils import BackportedAssertions, override_settings
@override_settings(MANDRILL_API_KEY="FAKE_API_KEY_FOR_TESTING", @override_settings(MANDRILL_API_KEY="FAKE_API_KEY_FOR_TESTING",
EMAIL_BACKEND="djrill.mail.backends.djrill.DjrillBackend") EMAIL_BACKEND="djrill.mail.backends.djrill.DjrillBackend")
class DjrillBackendMockAPITestCase(TestCase, BackportedAssertions): class DjrillBackendMockAPITestCase(TestCase):
"""TestCase that uses Djrill EmailBackend with a mocked Mandrill API""" """TestCase that uses Djrill EmailBackend with a mocked Mandrill API"""
class MockResponse(requests.Response): class MockResponse(requests.Response):

View File

@@ -1,26 +1,22 @@
from __future__ import unicode_literals from __future__ import unicode_literals
import os import os
import unittest
from django.core import mail from django.core import mail
from django.test import TestCase from django.test import TestCase
from django.test.utils import override_settings
from djrill import MandrillAPIError from djrill import MandrillAPIError
from djrill.tests.utils import BackportedAssertions, override_settings
try:
from unittest import skipUnless
except ImportError:
from django.utils.unittest import skipUnless
MANDRILL_TEST_API_KEY = os.getenv('MANDRILL_TEST_API_KEY') MANDRILL_TEST_API_KEY = os.getenv('MANDRILL_TEST_API_KEY')
@skipUnless(MANDRILL_TEST_API_KEY, @unittest.skipUnless(MANDRILL_TEST_API_KEY,
"Set MANDRILL_TEST_API_KEY environment variable to run integration tests") "Set MANDRILL_TEST_API_KEY environment variable to run integration tests")
@override_settings(MANDRILL_API_KEY=MANDRILL_TEST_API_KEY, @override_settings(MANDRILL_API_KEY=MANDRILL_TEST_API_KEY,
EMAIL_BACKEND="djrill.mail.backends.djrill.DjrillBackend") EMAIL_BACKEND="djrill.mail.backends.djrill.DjrillBackend")
class DjrillIntegrationTests(TestCase, BackportedAssertions): class DjrillIntegrationTests(TestCase):
"""Mandrill API integration tests """Mandrill API integration tests
These tests run against the **live** Mandrill API, using the These tests run against the **live** Mandrill API, using the

View File

@@ -10,20 +10,16 @@ from email.mime.image import MIMEImage
import json import json
import os import os
import six import six
import unittest
try:
from unittest import SkipTest
except ImportError:
from django.utils.unittest import SkipTest
from django.core import mail from django.core import mail
from django.core.exceptions import ImproperlyConfigured from django.core.exceptions import ImproperlyConfigured
from django.core.mail import make_msgid from django.core.mail import make_msgid
from django.test import TestCase from django.test import TestCase
from django.test.utils import override_settings
from djrill import MandrillAPIError, NotSupportedByMandrillError from djrill import MandrillAPIError, NotSupportedByMandrillError
from .mock_backend import DjrillBackendMockAPITestCase from djrill.tests.mock_backend import DjrillBackendMockAPITestCase
from .utils import override_settings
def decode_att(att): def decode_att(att):
@@ -158,7 +154,7 @@ class DjrillBackendTests(DjrillBackendMockAPITestCase):
headers={'X-Other': 'Keep'}) headers={'X-Other': 'Keep'})
except TypeError: except TypeError:
# Pre-Django 1.8 # Pre-Django 1.8
raise SkipTest("Django version doesn't support EmailMessage(reply_to)") raise unittest.SkipTest("Django version doesn't support EmailMessage(reply_to)")
email.send() email.send()
self.assert_mandrill_called("/messages/send.json") self.assert_mandrill_called("/messages/send.json")
data = self.get_api_call_data() data = self.get_api_call_data()

View File

@@ -1,7 +1,7 @@
from django.core import mail from django.core import mail
from django.test.utils import override_settings
from .mock_backend import DjrillBackendMockAPITestCase from djrill.tests.mock_backend import DjrillBackendMockAPITestCase
from .utils import override_settings
class DjrillMandrillSubaccountTests(DjrillBackendMockAPITestCase): class DjrillMandrillSubaccountTests(DjrillBackendMockAPITestCase):

View File

@@ -6,10 +6,10 @@ import json
from django.conf import settings from django.conf import settings
from django.core.exceptions import ImproperlyConfigured from django.core.exceptions import ImproperlyConfigured
from django.test import TestCase from django.test import TestCase
from django.test.utils import override_settings
from ..compat import b from djrill.compat import b
from ..signals import webhook_event from djrill.signals import webhook_event
from .utils import override_settings
class DjrillWebhookSecretMixinTests(TestCase): class DjrillWebhookSecretMixinTests(TestCase):

View File

@@ -1,94 +1,5 @@
import re
import six
import sys import sys
__all__ = (
'BackportedAssertions',
'override_settings',
'reset_warning_registry',
)
try:
from django.test.utils import override_settings
except ImportError:
# Back-port override_settings from Django 1.4
# https://github.com/django/django/blob/stable/1.4.x/django/test/utils.py
from django.conf import settings, UserSettingsHolder
from django.utils.functional import wraps
class override_settings(object):
"""
Acts as either a decorator, or a context manager. If it's a decorator it
takes a function and returns a wrapped function. If it's a contextmanager
it's used with the ``with`` statement. In either event entering/exiting
are called before and after, respectively, the function/block is executed.
"""
def __init__(self, **kwargs):
self.options = kwargs
self.wrapped = settings._wrapped
def __enter__(self):
self.enable()
def __exit__(self, exc_type, exc_value, traceback):
self.disable()
def __call__(self, test_func):
from django.test import TransactionTestCase
if isinstance(test_func, type) and issubclass(test_func, TransactionTestCase):
original_pre_setup = test_func._pre_setup
original_post_teardown = test_func._post_teardown
def _pre_setup(innerself):
self.enable()
original_pre_setup(innerself)
def _post_teardown(innerself):
original_post_teardown(innerself)
self.disable()
test_func._pre_setup = _pre_setup
test_func._post_teardown = _post_teardown
return test_func
else:
@wraps(test_func)
def inner(*args, **kwargs):
with self:
return test_func(*args, **kwargs)
return inner
def enable(self):
override = UserSettingsHolder(settings._wrapped)
for key, new_value in self.options.items():
setattr(override, key, new_value)
settings._wrapped = override
# No setting_changed signal in Django 1.3
# for key, new_value in self.options.items():
# setting_changed.send(sender=settings._wrapped.__class__,
# setting=key, value=new_value)
def disable(self):
settings._wrapped = self.wrapped
# No setting_changed signal in Django 1.3
# for key in self.options:
# new_value = getattr(settings, key, None)
# setting_changed.send(sender=settings._wrapped.__class__,
# setting=key, value=new_value)
class BackportedAssertions(object):
"""Handful of useful TestCase assertions backported to Python 2.6/Django 1.3"""
# Backport from Python 2.7/3.1
def assertIn(self, member, container, msg=None):
"""Just like self.assertTrue(a in b), but with a nicer default message."""
if member not in container:
self.fail(msg or '%r not found in %r' % (member, container))
# Backport from Django 1.4
def assertRaisesMessage(self, expected_exception, expected_message,
callable_obj=None, *args, **kwargs):
return six.assertRaisesRegex(self, expected_exception, re.escape(expected_message),
callable_obj, *args, **kwargs)
# Backport from Django 1.8 (django.test.utils) # Backport from Django 1.8 (django.test.utils)
# with fix suggested by https://code.djangoproject.com/ticket/21049 # with fix suggested by https://code.djangoproject.com/ticket/21049

View File

@@ -21,6 +21,13 @@ in debug mode.)
Breaking Changes in Djrill 2.0 Breaking Changes in Djrill 2.0
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Dropped support for Django 1.3, Python 2.6, and Python 3.2
Although Djrill may still work with these older configurations,
we no longer test against them. Djrill now requires Django 1.4
or later and Python 2.7, 3.3, or 3.4.
If you require earlier support, Djrill 1.4 remains available.
Removed DjrillAdminSite Removed DjrillAdminSite
Earlier versions of Djrill included a custom Django admin site. Earlier versions of Djrill included a custom Django admin site.
The equivalent functionality is available in Mandrill's dashboard. The equivalent functionality is available in Mandrill's dashboard.

View File

@@ -29,7 +29,7 @@ setup(
license="BSD License", license="BSD License",
packages=["djrill"], packages=["djrill"],
zip_safe=False, zip_safe=False,
install_requires=["requests>=1.0.0", "django>=1.3"], install_requires=["requests>=1.0.0", "django>=1.4"],
include_package_data=True, include_package_data=True,
test_suite="runtests.runtests", test_suite="runtests.runtests",
tests_require=["mock", "six"], tests_require=["mock", "six"],
@@ -37,10 +37,8 @@ setup(
"Programming Language :: Python", "Programming Language :: Python",
"Programming Language :: Python :: Implementation :: PyPy", "Programming Language :: Python :: Implementation :: PyPy",
"Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: CPython",
"Programming Language :: Python :: 2.6",
"Programming Language :: Python :: 2.7", "Programming Language :: Python :: 2.7",
"Programming Language :: Python :: 3", "Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.2",
"Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.3",
"Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.4",
"License :: OSI Approved :: BSD License", "License :: OSI Approved :: BSD License",