Skip to content

Commit

Permalink
refactor!: Drop support for Python 2.7, 3.3, 3.4, PyPy2 and Jython.
Browse files Browse the repository at this point in the history
  • Loading branch information
Stranger6667 committed Aug 29, 2020
1 parent db20b64 commit 415ece4
Show file tree
Hide file tree
Showing 57 changed files with 47 additions and 147 deletions.
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ Or you can look at the docs/ directory in the repository.
Python support
==============

Postmarker supports Python 2.7, 3.4, 3.5, 3.6, 3.7, PyPy, PyPy3 and Jython.
Postmarker supports Python 3.5, 3.6, 3.7 and PyPy3.

Thanks
======
Expand Down
5 changes: 5 additions & 0 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ Changelog
`Unreleased`_
-------------

Removed
~~~~~~~

- Support for Python 2.7, 3.3, 3.4, PyPy2 and Jython.

`0.14.1`_ - 2020-03-31
----------------------

Expand Down
2 changes: 1 addition & 1 deletion docs/django.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ For convenience, Postmarker provides a Django email backend. To use it you have
That's it!
For every supported Python version, the backend is tested on the latest Django release that supports given the Python version:

- Python 2.7, 3.4, 3.5, 3.6, PyPy - Django 1.10
- Python 3.5, 3.6 - Django 1.10


Example:
Expand Down
3 changes: 0 additions & 3 deletions postmarker/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1 @@
# coding: utf-8


__version__ = "0.14.1"
18 changes: 0 additions & 18 deletions postmarker/_compat.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,3 @@
# coding: utf-8


try:
from urllib.parse import urljoin
except ImportError: # Python 2.7
from urlparse import urljoin # noqa


try:
from unittest.mock import patch
except ImportError: # Python < 3.3
try:
from mock import patch # noqa
except ImportError:
patch = None


try:
from inspect import signature

Expand Down
10 changes: 5 additions & 5 deletions postmarker/core.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
# coding: utf-8
import sys
from urllib.parse import urljoin

import requests

from . import __version__
from ._compat import get_args, urljoin
from .exceptions import ClientError, SpamAssassinError
from .logging import get_logger
from .models.bounces import BounceManager
Expand All @@ -17,6 +16,7 @@
from .models.status import StatusManager
from .models.templates import TemplateManager
from .models.triggers import TriggersManager
from .utils import get_args

DEFAULT_API = "https://api.postmarkapp.com/"
STATUS_API = "https://status.postmarkapp.com/api/1.0/"
Expand All @@ -25,7 +25,7 @@
TEST_TOKEN = "POSTMARK_API_TEST"


class PostmarkClient(object):
class PostmarkClient:
"""Basic class for API clients. Provides basic functionality to make requests."""

_managers = (
Expand Down Expand Up @@ -73,7 +73,7 @@ def from_config(cls, config, prefix="postmark_", is_uppercase=False):
return cls(**kwargs)

def __repr__(self):
return "<%s: %s>" % (self.__class__.__name__, self.server_token)
return "<{}: {}>".format(self.__class__.__name__, self.server_token)

def _setup_managers(self):
"""Allows to access manager by model name.
Expand Down Expand Up @@ -144,4 +144,4 @@ def check_response(self, response):
raise ClientError(message, error_code=data["ErrorCode"])

def format_exception_message(self, data):
return "[%s] %s" % (data["ErrorCode"], data["Message"])
return "[{}] {}".format(data["ErrorCode"], data["Message"])
1 change: 0 additions & 1 deletion postmarker/django/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
# coding: utf-8
from .backend import EmailBackend, PostmarkEmailMessage, PostmarkEmailMixin, PostmarkEmailMultiAlternatives # noqa
from .signals import post_send, pre_send # noqa
9 changes: 3 additions & 6 deletions postmarker/django/backend.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
# coding: utf-8
from __future__ import absolute_import

from django.conf import settings
from django.core.exceptions import ImproperlyConfigured
from django.core.mail import EmailMessage, EmailMultiAlternatives
Expand All @@ -19,7 +16,7 @@ class EmailBackend(BaseEmailBackend):
"""A wrapper that manages sending emails via Postmark API."""

def __init__(self, token=None, fail_silently=False, **kwargs):
super(EmailBackend, self).__init__(fail_silently=fail_silently)
super().__init__(fail_silently=fail_silently)
self.client = None
if self.get_option("TEST_MODE"):
self.server_token = TEST_TOKEN
Expand Down Expand Up @@ -88,13 +85,13 @@ def prepare_message(self, message):
return instance


class PostmarkEmailMixin(object):
class PostmarkEmailMixin:
"""Provides an ability to set tags on Django email instances."""

def __init__(self, *args, **kwargs):
self.tag = kwargs.pop("tag", None)
self.metadata = kwargs.pop("metadata", None)
super(PostmarkEmailMixin, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)


class PostmarkEmailMessage(PostmarkEmailMixin, EmailMessage):
Expand Down
1 change: 0 additions & 1 deletion postmarker/django/signals.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# coding: utf-8
from django.dispatch import Signal

pre_send = Signal(providing_args=["messages"])
Expand Down
5 changes: 1 addition & 4 deletions postmarker/exceptions.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
# coding=utf-8


class PostmarkerException(Exception):
"""Base class for all exceptions in Postmarker."""

Expand All @@ -10,7 +7,7 @@ class ClientError(PostmarkerException):

def __init__(self, *args, **kwargs):
self.error_code = kwargs.pop("error_code")
super(ClientError, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)


class SpamAssassinError(PostmarkerException):
Expand Down
3 changes: 0 additions & 3 deletions postmarker/logging.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
# coding: utf-8
from __future__ import absolute_import

import logging

DEFAULT_LOGGING_LEVEL = logging.CRITICAL
Expand Down
1 change: 0 additions & 1 deletion postmarker/models/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +0,0 @@
# coding: utf-8
9 changes: 4 additions & 5 deletions postmarker/models/base.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
# coding: utf-8
from json import loads

from ..utils import sizes


class Model(object):
class Model:
"""Abstract data model for Postmark entities."""

_data = None
Expand All @@ -14,7 +13,7 @@ def __init__(self, manager=None, **kwargs):
self._update(kwargs)

def __str__(self):
return "%s: %s" % (self.__class__.__name__, self._data.get("ID"))
return "{}: {}".format(self.__class__.__name__, self._data.get("ID"))

def __repr__(self):
return "<%s>" % self
Expand All @@ -38,7 +37,7 @@ def as_dict(self):
return self._data.copy()


class ModelManager(object):
class ModelManager:
"""Proxies calls to main API client. Encapsulates logic of certain part of API - bounces, emails, etc."""

name = None
Expand Down Expand Up @@ -109,7 +108,7 @@ class SubModelManager(ModelManager):
_managers = ()

def __init__(self, *args, **kwargs):
super(SubModelManager, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)
self._setup_managers()

def _setup_managers(self):
Expand Down
1 change: 0 additions & 1 deletion postmarker/models/bounces.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# coding: utf-8
"""Bounces.
Information about bounces is available via the :py:class:`~postmarker.models.bounces.BounceManager`,
Expand Down
3 changes: 1 addition & 2 deletions postmarker/models/domains.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
# coding: utf-8
from .base import Model, ModelManager


class Domain(Model):
def __str__(self):
return "%s: %s (%s)" % (
return "{}: {} ({})".format(
self.__class__.__name__,
self._data.get("Name"),
self._data.get("ID"),
Expand Down
9 changes: 4 additions & 5 deletions postmarker/models/emails.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# coding: utf-8
"""Basic ways to send emails."""
import mimetypes
import os
Expand Down Expand Up @@ -117,7 +116,7 @@ def __init__(self, **kwargs):
kwargs["Headers"] = {}
if not kwargs.get("Attachments"):
kwargs["Attachments"] = []
super(BaseEmail, self).__init__(**kwargs)
super().__init__(**kwargs)

def __setitem__(self, key, value):
self.Headers[key] = value
Expand All @@ -130,7 +129,7 @@ def as_dict(self):
:return:
"""
data = super(BaseEmail, self).as_dict()
data = super().as_dict()
data["Headers"] = [{"Name": name, "Value": value} for name, value in data["Headers"].items()]
for field in ("To", "Cc", "Bcc"):
if field in data:
Expand Down Expand Up @@ -181,7 +180,7 @@ def prepare_header(value):
class Email(BaseEmail):
def __init__(self, **kwargs):
assert kwargs.get("TextBody") or kwargs.get("HtmlBody"), "Provide either email TextBody or HtmlBody or both"
super(Email, self).__init__(**kwargs)
super().__init__(**kwargs)

@classmethod
def from_mime(cls, message, manager):
Expand Down Expand Up @@ -231,7 +230,7 @@ class EmailBatch(Model):

def __init__(self, *emails, **kwargs):
self.emails = emails
super(EmailBatch, self).__init__(**kwargs)
super().__init__(**kwargs)

def __len__(self):
return len(self.emails)
Expand Down
7 changes: 3 additions & 4 deletions postmarker/models/messages.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# coding: utf-8
from base64 import b64decode
from email.mime.base import MIMEBase
from email.mime.multipart import MIMEMultipart
Expand Down Expand Up @@ -69,7 +68,7 @@ def get(self):
class OutboundMessage(BaseMessage):
def __str__(self):
recipients = ", ".join(self._data.get("Recipients"))
return "%s message to %s" % (self._data.get("Status"), recipients)
return "{} message to {}".format(self._data.get("Status"), recipients)

def get_dump(self):
return self._manager.get_dump(self.MessageID)
Expand Down Expand Up @@ -134,7 +133,7 @@ def get_dump(self, id):

class InboundMessage(BaseMessage):
def __str__(self):
return "%s message from %s" % (self._data.get("Status"), self._data.get("From"))
return "{} message from {}".format(self._data.get("Status"), self._data.get("From"))

def __getitem__(self, item):
for header in self._data["Headers"]:
Expand Down Expand Up @@ -175,7 +174,7 @@ def __str__(self):
return self.Name

def __repr__(self):
return "<%s: %s>" % (self.__class__.__name__, self)
return "<{}: {}>".format(self.__class__.__name__, self)

def __len__(self):
return self.ContentLength
Expand Down
1 change: 0 additions & 1 deletion postmarker/models/senders.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# coding: utf-8
import warnings

from .base import Model, ModelManager
Expand Down
3 changes: 1 addition & 2 deletions postmarker/models/server.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
# coding: utf-8
from .base import Model, ModelManager


class Server(Model):
def __str__(self):
return "%s: %s (%s)" % (
return "{}: {} ({})".format(
self.__class__.__name__,
self.Name,
self._data.get("ID"),
Expand Down
1 change: 0 additions & 1 deletion postmarker/models/stats.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# coding: utf-8
from .base import ModelManager


Expand Down
5 changes: 2 additions & 3 deletions postmarker/models/status.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
# coding: utf-8
from .base import Model, ModelManager


class Incident(Model):
def __str__(self):
return "%s: %s" % (self.__class__.__name__, self._data.get("id"))
return "{}: {}".format(self.__class__.__name__, self._data.get("id"))


class IncidentsManager(ModelManager):
Expand All @@ -31,7 +30,7 @@ class StatusManager(ModelManager):
name = "status"

def __init__(self, *args, **kwargs):
super(StatusManager, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)
self.incidents = IncidentsManager(self.client)

def call(self, *args, **kwargs):
Expand Down
3 changes: 1 addition & 2 deletions postmarker/models/templates.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
# coding: utf-8
from .base import Model, ModelManager


class Template(Model):
def __str__(self):
return "%s: %s (%s)" % (
return "{}: {} ({})".format(
self.__class__.__name__,
self._data.get("Name"),
self._data.get("TemplateId"),
Expand Down
1 change: 0 additions & 1 deletion postmarker/models/triggers.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# coding: utf-8
from .base import Model, ModelManager, SubModelManager


Expand Down
4 changes: 1 addition & 3 deletions postmarker/pytest.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
# coding: utf-8
from __future__ import absolute_import
from unittest.mock import patch

import pytest

from ._compat import patch
from .core import PostmarkClient, requests


Expand Down
3 changes: 1 addition & 2 deletions postmarker/tornado.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
# coding: utf-8
from .core import PostmarkClient

POSTMARK_SERVER_TOKEN = "postmark_server_token"


class PostmarkMixin(object):
class PostmarkMixin:
@property
def postmark_client(self):
self.require_setting(POSTMARK_SERVER_TOKEN, "Postmark client")
Expand Down
6 changes: 5 additions & 1 deletion postmarker/utils.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# coding: utf-8
from inspect import signature


def chunks(container, n):
Expand All @@ -20,3 +20,7 @@ def sizes(count, offset=0, max_chunk=500):
count = max(0, count - max_chunk)
yield chunk, offset
offset += chunk


def get_args(cls):
return list(signature(cls).parameters)
Loading

0 comments on commit 415ece4

Please sign in to comment.