Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade python>=3.9 #470

Merged
merged 1 commit into from
Jun 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 7 additions & 13 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@ name: Test

on:
push:
branches: [ master ]
pull_request:
branches: [ master ]

permissions:
contents: read
Expand All @@ -16,15 +14,12 @@ jobs:
name: Python${{ matrix.python-version }}/Django${{ matrix.django-version }}
strategy:
matrix:
python-version: ["3.8", "3.10"]
django-version: ["3.2", "4.0", "4.1", "4.2"]
# exclude:
# - python-version: 3.7
# django-version: 4.0
# - python-version: 3.7
# django-version: 4.1
# - python-version: 3.8
# django-version: 4.2
python-version: ["3.9", "3.10", "3.11", "3.12"]
django-version: ["4.2", "5.0"]
exclude:
- python-version: "3.9"
django-version: "5.0"


steps:
- uses: actions/checkout@v3
Expand All @@ -37,8 +32,7 @@ jobs:
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install pytz
pip install "Django==${{ matrix.django-version }}.*"
pip install "Django~=${{ matrix.django-version }}.0"

- name: Run Test
run: |
Expand Down
6 changes: 1 addition & 5 deletions post_office/__init__.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
import django
from ast import literal_eval
from os.path import dirname, join

with open(join(dirname(__file__), 'version.txt'), 'r') as fh:
with open(join(dirname(__file__), "version.txt")) as fh:
VERSION = literal_eval(fh.read())

from .backends import EmailBackend

if django.VERSION < (3, 2): # pragma: no cover
default_app_config = 'post_office.apps.PostOfficeConfig'
3 changes: 1 addition & 2 deletions post_office/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,12 @@
from django.utils.translation import gettext_lazy as _

from .fields import CommaSeparatedEmailField
from .mail import send
from .models import STATUS, Attachment, Email, EmailTemplate, Log
from .sanitizer import clean_html


def get_message_preview(instance):
return ('{0}...'.format(instance.message[:25]) if len(instance.message) > 25
return (f'{instance.message[:25]}...' if len(instance.message) > 25
else instance.message)


Expand Down
1 change: 0 additions & 1 deletion post_office/backends.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
from email.mime.base import MIMEBase
from django.core.files.base import ContentFile
from django.core.mail.backends.base import BaseEmailBackend
import quopri
from .settings import get_default_priority

class EmailBackend(BaseEmailBackend):
Expand Down
2 changes: 1 addition & 1 deletion post_office/lockfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def __init__(self, lock_filename, timeout=None, force=False):
def get_lock_pid(self):
try:
return int(open(self.lock_filename).read())
except IOError:
except OSError:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason why this is changed?

Copy link
Contributor Author

@Mogost Mogost Jun 13, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In Python 3.3+, this exception is simple alias. OSError is actually thrown

# If we can't read symbolic link, there are two possibilities:
# 1. The symbolic link is dead (point to non existing file)
# 2. Symbolic link is not there
Expand Down
4 changes: 1 addition & 3 deletions post_office/mail.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import sys

from django.conf import settings
from django.core.exceptions import ValidationError
Expand All @@ -7,8 +6,7 @@
from django.template import Context, Template
from django.utils import timezone
from email.utils import make_msgid
from multiprocessing import Pool, TimeoutError
from multiprocessing.context import TimeoutError as ContextTimeoutError
from multiprocessing import Pool
from multiprocessing.dummy import Pool as ThreadPool

from .connections import connections
Expand Down
2 changes: 1 addition & 1 deletion post_office/migrations/0002_add_i18n_and_backend_alias.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,6 @@ class Migration(migrations.Migration):
),
migrations.AlterUniqueTogether(
name='emailtemplate',
unique_together=set([('language', 'default_template')]),
unique_together={('language', 'default_template')},
),
]
2 changes: 1 addition & 1 deletion post_office/migrations/0005_auto_20170515_0013.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ class Migration(migrations.Migration):
operations = [
migrations.AlterUniqueTogether(
name='emailtemplate',
unique_together=set([('name', 'language', 'default_template')]),
unique_together={('name', 'language', 'default_template')},
),
]
2 changes: 1 addition & 1 deletion post_office/migrations/0010_message_id.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ def forwards(apps, schema_editor):
if email.status in [STATUS.queued, STATUS.requeued]:
# create a unique Message-ID for all emails which have not been send yet
randint1, randint2 = random.getrandbits(64), random.getrandbits(16)
email.message_id = '<{}.{}.{}@{}>'.format(email.id, randint1, randint2, msg_id_fqdn)
email.message_id = f'<{email.id}.{randint1}.{randint2}@{msg_id_fqdn}>'
email.save()


Expand Down
2 changes: 1 addition & 1 deletion post_office/template/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,5 @@ def render_to_string(template_name, context=None, request=None, using=None):
template = get_template(template_name, using=using)
try:
return template.render(context, request), template.template._attached_images
except Exception as a:
except Exception:
return template.render(context, request)
6 changes: 3 additions & 3 deletions post_office/templatetags/post_office.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def inline_image(context, file):
try:
absfilename = finders.find(file)
if absfilename is None:
raise FileNotFoundError("No such file: {}".format(file))
raise FileNotFoundError(f"No such file: {file}")
except Exception:
if settings.DEBUG:
raise
Expand All @@ -33,6 +33,6 @@ def inline_image(context, file):
image = MIMEImage(raw_data)
md5sum = hashlib.md5(raw_data).hexdigest()
image.add_header('Content-Disposition', 'inline', filename=md5sum)
image.add_header('Content-ID', '<{}>'.format(md5sum))
image.add_header('Content-ID', f'<{md5sum}>')
context.template._attached_images.append(image)
return 'cid:{}'.format(md5sum)
return f'cid:{md5sum}'
4 changes: 2 additions & 2 deletions post_office/tests/test_html_email.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from post_office.models import Email, EmailTemplate, STATUS
from post_office.template import render_to_string
from post_office.template.backends.post_office import PostOfficeTemplates
from post_office.mail import create, send, send_queued
from post_office.mail import send, send_queued


class HTMLMailTest(TestCase):
Expand Down Expand Up @@ -165,7 +165,7 @@ def test_email_change_view(self):
try:
import bleach
self.assertContains(response, "<h3>Testing image attachments</h3>")
self.assertContains(response, '<img src="{}" width="200"'.format(email_image_url))
self.assertContains(response, f'<img src="{email_image_url}" width="200"')
except ImportError:
self.assertContains(response, "Testing image attachments")

Expand Down
9 changes: 5 additions & 4 deletions post_office/tests/test_mail.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
import time
from datetime import timedelta
from multiprocessing.context import TimeoutError
from unittest.mock import MagicMock, patch
from unittest.mock import patch
from zoneinfo import ZoneInfo

import pytz
from django.conf import settings
from django.core import mail
from django.core.exceptions import ValidationError
Expand Down Expand Up @@ -412,6 +412,7 @@ def test_send_bulk_with_faulty_template(self):
email = Email.objects.get(id=email.id)
self.assertEqual(email.status, STATUS.sent)

@override_settings(USE_TZ=False)
def test_retry_failed(self):
self.assertEqual(get_retry_timedelta(), timezone.timedelta(minutes=15))
self.assertEqual(get_max_retries(), 2)
Expand Down Expand Up @@ -460,12 +461,12 @@ def test_retry_failed(self):

@override_settings(USE_TZ=True)
def test_expired(self):
tzinfo = pytz.timezone('Asia/Jakarta')
tzinfo = ZoneInfo('Asia/Jakarta')
email = create('[email protected]', recipients=['[email protected]'], subject='subject', message='message',
expires_at=timezone.datetime(2020, 5, 18, 9, 0, 1, tzinfo=tzinfo))
self.assertEqual(email.expires_at, timezone.datetime(2020, 5, 18, 9, 0, 1, tzinfo=tzinfo))
msg = email.prepare_email_message()
self.assertEqual(msg.extra_headers['Expires'], 'Mon, 18 May 09:00:01 +0707')
self.assertEqual(msg.extra_headers['Expires'], 'Mon, 18 May 09:00:01 +0700')

# check that email is not sent after its expire_at date
with patch('django.utils.timezone.now', side_effect=lambda: timezone.datetime(2020, 5, 18, 9, 0, 2, tzinfo=tzinfo)):
Expand Down
1 change: 0 additions & 1 deletion post_office/tests/test_models.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import django
import json
import os

Expand Down
10 changes: 5 additions & 5 deletions post_office/tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ def test_create_attachments(self):
self.assertTrue(attachments[0].pk)
self.assertEqual(attachments[0].file.read(), b'content')
self.assertTrue(attachments[0].name.startswith('attachment_file'))
self.assertEquals(attachments[0].mimetype, '')
self.assertEqual(attachments[0].mimetype, '')

def test_create_attachments_with_mimetype(self):
attachments = create_attachments({
Expand All @@ -161,9 +161,9 @@ def test_create_attachments_with_mimetype(self):
self.assertEqual(len(attachments), 2)
self.assertIsInstance(attachments[0], Attachment)
self.assertTrue(attachments[0].pk)
self.assertEquals(attachments[0].file.read(), b'content')
self.assertEqual(attachments[0].file.read(), b'content')
self.assertTrue(attachments[0].name.startswith('attachment_file'))
self.assertEquals(attachments[0].mimetype, 'text/plain')
self.assertEqual(attachments[0].mimetype, 'text/plain')

def test_create_attachments_open_file(self):
attachments = create_attachments({
Expand All @@ -174,8 +174,8 @@ def test_create_attachments_open_file(self):
self.assertIsInstance(attachments[0], Attachment)
self.assertTrue(attachments[0].pk)
self.assertTrue(attachments[0].file.read())
self.assertEquals(attachments[0].name, 'attachment_file.py')
self.assertEquals(attachments[0].mimetype, '')
self.assertEqual(attachments[0].name, 'attachment_file.py')
self.assertEqual(attachments[0].mimetype, '')

def test_parse_priority(self):
self.assertEqual(parse_priority('now'), PRIORITY.now)
Expand Down
12 changes: 7 additions & 5 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def run_tests(self):
sys.exit(errno)


with open(join(dirname(__file__), 'post_office/version.txt'), 'r') as fh:
with open(join(dirname(__file__), 'post_office/version.txt')) as fh:
VERSION = '.'.join(map(str, literal_eval(fh.read())))

TESTS_REQUIRE = ['tox >= 2.3']
Expand All @@ -47,25 +47,27 @@ def run_tests(self):
zip_safe=False,
include_package_data=True,
package_data={'': ['README.rst']},
python_requires='>=3.9',
install_requires=[
'bleach[css]',
'django>=3.2',
'pytz',
'django>=4.2',
],
classifiers=[
'Development Status :: 5 - Production/Stable',
'Environment :: Web Environment',
'Framework :: Django',
'Framework :: Django :: 4.2',
'Framework :: Django :: 5.0',
'Intended Audience :: Developers',
'License :: OSI Approved :: MIT License',
'Operating System :: OS Independent',
'Programming Language :: Python',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3 :: Only',
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.8',
'Programming Language :: Python :: 3.9',
'Programming Language :: Python :: 3.10',
'Programming Language :: Python :: 3.11',
'Programming Language :: Python :: 3.12',
'Topic :: Communications :: Email',
'Topic :: Internet :: WWW/HTTP',
'Topic :: Software Development :: Libraries :: Python Modules',
Expand Down
Loading