Skip to content
This repository has been archived by the owner on Nov 17, 2022. It is now read-only.

Commit

Permalink
Merge 4b28463 into ad7487f
Browse files Browse the repository at this point in the history
  • Loading branch information
jwhitlock committed Mar 29, 2019
2 parents ad7487f + 4b28463 commit af2da13
Show file tree
Hide file tree
Showing 13 changed files with 77 additions and 77 deletions.
31 changes: 11 additions & 20 deletions .travis.yml
Expand Up @@ -7,30 +7,21 @@ matrix:
env: TOXENV=docs
- python: "2.7"
env: TOXENV=flake8
- python: "2.7"
env: TOXENV=py27-1.8
- python: "3.5"
env: TOXENV=py35-1.8
- python: "2.7"
env: TOXENV=py27-1.9
- python: "3.5"
env: TOXENV=py35-1.9
- python: "2.7"
env: TOXENV=py27-1.10
- python: "3.5"
env: TOXENV=py35-1.10
- python: "2.7"
env: TOXENV=py27-1.11
- python: "3.4"
env: TOXENV=py34-1.11
- python: "3.5"
env: TOXENV=py35-2.1
- python: "3.6"
env: TOXENV=py36-1.11
- python: "3.6"
env: TOXENV=py36-2.0
- python: "3.6"
env: TOXENV=py36-master
env: TOXENV=py36-2.2
dist: xenial # For SQLite 3.8.3 or later
- python: "3.7"
env: TOXENV=py37-master
dist: xenial # For Python 3.7
allow_failures:
- env: TOXENV=py36-master
- env: TOXENV=py37-master
install:
- pip install coveralls tox
- pip install tox
script:
- tox
after_success: coveralls
2 changes: 1 addition & 1 deletion Makefile
Expand Up @@ -70,4 +70,4 @@ test-release: clean sdist
twine upload --repository test dist/*
python -m webbrowser -n https://testpypi.python.org/pypi/django-tidings

.PHONY: help clean coverage coveragehtml develop lint qa qa-all release sdist test test-all test-release
.PHONY: help clean coverage coveragehtml develop docs lint qa qa-all release sdist test test-all test-release
6 changes: 3 additions & 3 deletions docs/requirements.txt
@@ -1,5 +1,5 @@
-r ../tests/requirements.txt

Sphinx==1.6.7
sphinx-rtd-theme==0.2.4
Django<2.1
Sphinx==1.8.5
sphinx-rtd-theme==0.4.3
Django<2.2
2 changes: 1 addition & 1 deletion requirements.dev.txt
@@ -1,6 +1,6 @@
# Testing and development requirements
-r tests/requirements.txt
Django<2.1
Django<2.2
check-manifest
coverage
flake8
Expand Down
6 changes: 3 additions & 3 deletions setup.py
Expand Up @@ -49,11 +49,10 @@ def long_description():
classifiers=[
'Environment :: Web Environment',
'Framework :: Django',
'Framework :: Django :: 1.8',
'Framework :: Django :: 1.9',
'Framework :: Django :: 1.10',
'Framework :: Django :: 1.11',
'Framework :: Django :: 2.0',
'Framework :: Django :: 2.1',
'Framework :: Django :: 2.2',
'Intended Audience :: Developers',
'License :: OSI Approved :: BSD License',
'Natural Language :: English',
Expand All @@ -65,6 +64,7 @@ def long_description():
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
'Topic :: Communications :: Email',
'Topic :: Software Development :: Libraries :: Python Modules'],
)
2 changes: 1 addition & 1 deletion tests/base.py
Expand Up @@ -2,8 +2,8 @@
from string import ascii_letters

from django.contrib.auth import get_user_model
from django.utils.six.moves import range

from tidings.compat import range
from tidings.models import Watch, WatchFilter


Expand Down
24 changes: 14 additions & 10 deletions tests/test_events.py
Expand Up @@ -4,8 +4,8 @@
from django.core import mail
from django.core.mail import EmailMessage
from django.test import TestCase, override_settings
from django.utils.six.moves import range

from tidings.compat import range
from tidings.events import Event, _unique_by_email, EventUnion, InstanceEvent
from tidings.models import Watch, EmailUser

Expand Down Expand Up @@ -42,6 +42,16 @@ class FilteredContentTypeEvent(ContentTypeEvent):
filters = set(['color', 'flavor'])


fire_simple_event_called = False


class FireSimpleEvent(SimpleEvent):
def _mails(self, users_and_watches):
global fire_simple_event_called
fire_simple_event_called = True
return []


class UsersWatchingTests(TestCase):
"""Unit tests for Event._users_watching_by_filter()"""

Expand Down Expand Up @@ -262,19 +272,13 @@ def _users_watching(self):

def test_fire(self):
"""Assert firing the union gets the mails from the first event."""

class FireSimpleEvent(SimpleEvent):
called = False

def _mails(self, users_and_watches):
self.called = True
return []

global fire_simple_event_called
watch(event_type=TYPE, email='he@llo.com').save()
simple_event = FireSimpleEvent()
fire_simple_event_called = False
another_event = AnotherEvent()
EventUnion(simple_event, another_event).fire()
self.assertTrue(simple_event.called)
self.assertTrue(fire_simple_event_called)

def test_watch_lists(self):
"""Ensure the Union returns every watch a user has."""
Expand Down
2 changes: 1 addition & 1 deletion tests/test_utils.py
@@ -1,7 +1,7 @@
from django.core.exceptions import ImproperlyConfigured
from django.test import override_settings, TestCase
from django.utils.six.moves import range, reduce

from tidings.compat import range, reduce
from tidings.utils import collate, import_from_setting


Expand Down
37 changes: 22 additions & 15 deletions tidings/compat.py
@@ -1,21 +1,28 @@
"""Compatibility functions for tidings."""

# The standard Django reverse function
# This is the default value if TIDINGS_REVERSE is not set
# Python 2/3 compatibility for Django 1.11
try:
# Django 1.10 and later
from django.urls import reverse
# Django 2.2 and earlier include six, but it is only
# needed for Python 2.7 under Django 1.11.
from django.utils.six import (iteritems, iterkeys, string_types, next,
text_type)
from django.utils.six.moves import range, reduce
except ImportError:
# Django 1.9 and earlier
from django.core.urlresolvers import reverse
assert reverse
# Django 3.0 drops the six library, but only runs under Python 3
# Copy Python 3 variants from https://github.com/benjaminp/six

from functools import reduce
assert reduce # Make flake8 happier

def is_authenticated(user):
"""Is a user instance authenticated?"""
if callable(user.is_authenticated):
# Django 1.9 and earlier
return user.is_authenticated()
else:
# Django 1.10 and later
return user.is_authenticated
def iteritems(d, **kw):
return iter(d.items(**kw))

def iterkeys(d, **kw):
return iter(d.keys(**kw))

string_types = str,
text_type = str

# Asign built-ins to importable variables
next = next
range = range
10 changes: 4 additions & 6 deletions tidings/events.py
Expand Up @@ -7,12 +7,10 @@
from django.contrib.contenttypes.models import ContentType
from django.core import mail
from django.db.models import Q
from django.utils.six import iteritems, iterkeys, string_types
from django.utils.six.moves import range

from celery.task import task

from .compat import is_authenticated
from .compat import iteritems, iterkeys, string_types, range
from .models import Watch, WatchFilter, EmailUser, multi_raw
from .utils import collate, hash_to_unsigned

Expand Down Expand Up @@ -70,8 +68,8 @@ def ensure_user_has_email(user, cluster_email):
watches)
favorite_user, watches = u, []
cluster_email = row_email
elif ((not favorite_user.email or not is_authenticated(u)) and
u.email and is_authenticated(u)):
elif ((not favorite_user.email or not u.is_authenticated) and
u.email and u.is_authenticated):
favorite_user = u
watches.extend(w)
if favorite_user is not None:
Expand Down Expand Up @@ -310,7 +308,7 @@ def _watches_belonging_to_user(cls, user_or_email, object_id=None,

if isinstance(user_or_email, string_types):
user_condition = Q(email=user_or_email)
elif is_authenticated(user_or_email):
elif user_or_email.is_authenticated:
user_condition = Q(user=user_or_email)
else:
return Watch.objects.none()
Expand Down
6 changes: 2 additions & 4 deletions tidings/models.py
Expand Up @@ -5,8 +5,8 @@
from django.contrib.contenttypes.models import ContentType
from django.contrib.sites.models import Site
from django.db import models, connections, router
from django.utils.six import next, text_type

from .compat import next, text_type
from .utils import import_from_setting, reverse


Expand Down Expand Up @@ -130,9 +130,7 @@ class EmailUser(AnonymousUser):
"""An anonymous user identified only by email address.
This is based on Django's AnonymousUser, so you can use the
``is_authenticated`` property (Django 1.10 or later) or
``is_authenticated`` method (Django 1.9 or earlier) to tell that
this is an anonymous user.
``is_authenticated`` property to tell that this is an anonymous user.
"""
def __init__(self, email=''):
self.email = email
Expand Down
4 changes: 2 additions & 2 deletions tidings/utils.py
Expand Up @@ -4,10 +4,10 @@
from django.core.exceptions import ImproperlyConfigured
from django.core.mail import EmailMessage
from django.template import Context, loader
from django.urls import reverse as django_reverse
from django.utils.module_loading import import_string
from django.utils.six import next, string_types

from .compat import reverse as django_reverse
from .compat import next, string_types


def collate(*iterables, **kwargs):
Expand Down
22 changes: 12 additions & 10 deletions tox.ini
Expand Up @@ -4,28 +4,30 @@ skip_missing_interpreters = true
envlist =
docs,
flake8,
py{27,34,35}-1.8
py{27,34,35,36}-{1.9,1.10,1.11}
py{35,36}-{2.0,master}
py{27,34,35,36}-1.11
py{35,36,37}-{2.0,2.1,2.2,master}

[testenv]
passenv = TRAVIS TRAVIS_*
basepython =
py27: python2.7
py34: python3.4
py35: python3.5
py36: python3.6
py37: python3.7
usedevelop = true
pip_pre = true
commands = make coverage
commands =
make coverage
coveralls
deps =
coverage
1.8: Django>=1.8,<1.9
1.9: Django>=1.9,<1.10
1.10: Django>=1.10,<1.11
coveralls
1.11: Django>=1.11,<2.0
2.0: Django>=2.0,<2.1
2.1: Django>=2.1,<2.2
2.2: Django>=2.2a1,<2.3
master: https://github.com/django/django/archive/master.tar.gz
{1.8,1.9,1.10,1.11,2.0}: -r{toxinidir}/tests/requirements.txt
{1.11,2.0,2.1,2.2}: -r{toxinidir}/tests/requirements.txt
master: -r{toxinidir}/tests/requirements-latest.txt
whitelist_externals = make

Expand All @@ -38,5 +40,5 @@ commands = make docs
basepython = python2.7
deps =
flake8
Django<1.9
Django<2.2
commands = make lint

0 comments on commit af2da13

Please sign in to comment.