From 665fc04b7e4a237d53e73c8cfe59fb0847cbd656 Mon Sep 17 00:00:00 2001 From: jarekwg Date: Wed, 28 Oct 2015 23:47:33 +1100 Subject: [PATCH 01/12] Must use the 'Now' database function in django>=1.9 --- model_utils/models.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/model_utils/models.py b/model_utils/models.py index f343dfb..142b77c 100644 --- a/model_utils/models.py +++ b/model_utils/models.py @@ -1,10 +1,15 @@ from __future__ import unicode_literals +import django from django.db import models from django.utils.translation import ugettext_lazy as _ from django.db.models.fields import FieldDoesNotExist from django.core.exceptions import ImproperlyConfigured -from django.utils.timezone import now +if django.VERSION >= (1, 9, 0): + from django.db.models.functions import Now + now = Now() +else: + from django.utils.timezone import now from model_utils.managers import QueryManager from model_utils.fields import AutoCreatedField, AutoLastModifiedField, \ From 7a33e14f4b31f031cff2419aa00a9f9473a74aa8 Mon Sep 17 00:00:00 2001 From: jarekwg Date: Thu, 29 Oct 2015 00:02:46 +1100 Subject: [PATCH 02/12] Get StatusFields working --- model_utils/fields.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/model_utils/fields.py b/model_utils/fields.py index 74c44b2..805c707 100644 --- a/model_utils/fields.py +++ b/model_utils/fields.py @@ -1,5 +1,6 @@ from __future__ import unicode_literals +import django from django.db import models from django.conf import settings from django.utils.encoding import python_2_unicode_compatible @@ -59,6 +60,8 @@ class StatusField(models.CharField): "To use StatusField, the model '%s' must have a %s choices class attribute." \ % (sender.__name__, self.choices_name) self._choices = getattr(sender, self.choices_name) + if django.VERSION >= (1, 9, 0): + self.choices = self._choices if not self.has_default(): self.default = tuple(getattr(sender, self.choices_name))[0][0] # set first as default @@ -68,6 +71,8 @@ class StatusField(models.CharField): # the STATUS class attr being available), but we need to set some dummy # choices now so the super method will add the get_FOO_display method self._choices = [(0, 'dummy')] + if django.VERSION >= (1, 9, 0): + self.choices = self._choices super(StatusField, self).contribute_to_class(cls, name) def deconstruct(self): From 2824ec2e4875ab6530caa440034959d51d5b9830 Mon Sep 17 00:00:00 2001 From: jarekwg Date: Thu, 29 Oct 2015 00:10:28 +1100 Subject: [PATCH 03/12] Remove PassThroughManager As of Django 1.7, QuerySet.as_manager() achieves the same result. --- model_utils/managers.py | 88 ---------------------------- model_utils/tests/models.py | 72 +---------------------- model_utils/tests/tests.py | 112 +----------------------------------- 3 files changed, 2 insertions(+), 270 deletions(-) diff --git a/model_utils/managers.py b/model_utils/managers.py index b6496ba..8e95318 100644 --- a/model_utils/managers.py +++ b/model_utils/managers.py @@ -224,91 +224,3 @@ class QueryManagerMixin(object): class QueryManager(QueryManagerMixin, models.Manager): pass - - -class PassThroughManagerMixin(object): - """ - A mixin that enables you to call custom QuerySet methods from your manager. - """ - - # pickling causes recursion errors - _deny_methods = ['__getstate__', '__setstate__', '__getinitargs__', - '__getnewargs__', '__copy__', '__deepcopy__', '_db', - '__slots__'] - - def __init__(self, queryset_cls=None): - self._queryset_cls = queryset_cls - super(PassThroughManagerMixin, self).__init__() - - def __getattr__(self, name): - if name in self._deny_methods: - raise AttributeError(name) - if django.VERSION < (1, 6, 0): - return getattr(self.get_query_set(), name) - return getattr(self.get_queryset(), name) - - def __dir__(self): - """ - Allow introspection via dir() and ipythonesque tab-discovery. - - We do dir(type(self)) because to do dir(self) would be a recursion - error. - We call dir(self.get_query_set()) because it is possible that the - queryset returned by get_query_set() is interesting, even if - self._queryset_cls is None. - """ - my_values = frozenset(dir(type(self))) - my_values |= frozenset(dir(self.get_query_set())) - return list(my_values) - - def get_queryset(self): - try: - qs = super(PassThroughManagerMixin, self).get_queryset() - except AttributeError: - qs = super(PassThroughManagerMixin, self).get_query_set() - if self._queryset_cls is not None: - qs = qs._clone(klass=self._queryset_cls) - return qs - - get_query_set = get_queryset - - @classmethod - def for_queryset_class(cls, queryset_cls): - return create_pass_through_manager_for_queryset_class( - cls, queryset_cls) - - -class PassThroughManager(PassThroughManagerMixin, models.Manager): - """ - Inherit from this Manager to enable you to call any methods from your - custom QuerySet class from your manager. Simply define your QuerySet - class, and return an instance of it from your manager's `get_queryset` - method. - - Alternately, if you don't need any extra methods on your manager that - aren't on your QuerySet, then just pass your QuerySet class to the - ``for_queryset_class`` class method. - - class PostQuerySet(QuerySet): - def enabled(self): - return self.filter(disabled=False) - - class Post(models.Model): - objects = PassThroughManager.for_queryset_class(PostQuerySet)() - - """ - pass - - -def create_pass_through_manager_for_queryset_class(base, queryset_cls): - class _PassThroughManager(base): - def __init__(self, *args, **kwargs): - return super(_PassThroughManager, self).__init__(*args, **kwargs) - - def get_queryset(self): - qs = super(_PassThroughManager, self).get_queryset() - return qs._clone(klass=queryset_cls) - - get_query_set = get_queryset - - return _PassThroughManager diff --git a/model_utils/tests/models.py b/model_utils/tests/models.py index ea46d0f..b1903ed 100644 --- a/model_utils/tests/models.py +++ b/model_utils/tests/models.py @@ -6,7 +6,7 @@ from django.utils.translation import ugettext_lazy as _ from model_utils.models import TimeStampedModel, StatusModel, TimeFramedModel from model_utils.tracker import FieldTracker, ModelTracker -from model_utils.managers import QueryManager, InheritanceManager, PassThroughManager +from model_utils.managers import QueryManager, InheritanceManager from model_utils.fields import SplitField, MonitorField, StatusField from model_utils.tests.fields import MutableField from model_utils import Choices @@ -201,76 +201,6 @@ class FeaturedManager(models.Manager): get_query_set = get_queryset -class DudeQuerySet(models.query.QuerySet): - def abiding(self): - return self.filter(abides=True) - - def rug_positive(self): - return self.filter(has_rug=True) - - def rug_negative(self): - return self.filter(has_rug=False) - - def by_name(self, name): - return self.filter(name__iexact=name) - - - -class AbidingManager(PassThroughManager): - def get_queryset(self): - return DudeQuerySet(self.model).abiding() - - get_query_set = get_queryset - - def get_stats(self): - return { - "abiding_count": self.count(), - "rug_count": self.rug_positive().count(), - } - - - -class Dude(models.Model): - abides = models.BooleanField(default=True) - name = models.CharField(max_length=20) - has_rug = models.BooleanField(default=False) - - objects = PassThroughManager(DudeQuerySet) - abiders = AbidingManager() - - -class Car(models.Model): - name = models.CharField(max_length=20) - owner = models.ForeignKey(Dude, related_name='cars_owned') - - objects = PassThroughManager(DudeQuerySet) - - -class SpotManager(PassThroughManager): - def get_queryset(self): - return super(SpotManager, self).get_queryset().filter(secret=False) - - get_query_set = get_queryset - - -class SpotQuerySet(models.query.QuerySet): - def closed(self): - return self.filter(closed=True) - - def secured(self): - return self.filter(secure=True) - - -class Spot(models.Model): - name = models.CharField(max_length=20) - secure = models.BooleanField(default=True) - closed = models.BooleanField(default=False) - secret = models.BooleanField(default=False) - owner = models.ForeignKey(Dude, related_name='spots_owned') - - objects = SpotManager.for_queryset_class(SpotQuerySet)() - - class Tracked(models.Model): name = models.CharField(max_length=20) number = models.IntegerField() diff --git a/model_utils/tests/tests.py b/model_utils/tests/tests.py index bbacfd1..aa25512 100644 --- a/model_utils/tests/tests.py +++ b/model_utils/tests/tests.py @@ -1,7 +1,6 @@ from __future__ import unicode_literals from datetime import datetime, timedelta -import pickle try: from unittest import skipUnless except ImportError: # Python 2.6 @@ -25,7 +24,7 @@ from model_utils.tests.models import ( InheritanceManagerTestParent, InheritanceManagerTestChild1, InheritanceManagerTestChild2, TimeStamp, Post, Article, Status, StatusPlainTuple, TimeFrame, Monitored, MonitorWhen, MonitorWhenEmpty, StatusManagerAdded, - TimeFrameManagerAdded, Dude, SplitFieldAbstractParent, Car, Spot, + TimeFrameManagerAdded, SplitFieldAbstractParent, ModelTracked, ModelTrackedFK, ModelTrackedNotDefault, ModelTrackedMultiple, InheritedModelTracked, Tracked, TrackedFK, TrackedNotDefault, TrackedNonFieldAttr, TrackedMultiple, InheritedTracked, StatusFieldDefaultFilled, StatusFieldDefaultNotFilled, @@ -1206,115 +1205,6 @@ class SouthFreezingTests(TestCase): self.assertEqual(kwargs['no_check_for_status'], 'True') - -class PassThroughManagerTests(TestCase): - def setUp(self): - Dude.objects.create(name='The Dude', abides=True, has_rug=False) - Dude.objects.create(name='His Dudeness', abides=False, has_rug=True) - Dude.objects.create(name='Duder', abides=False, has_rug=False) - Dude.objects.create(name='El Duderino', abides=True, has_rug=True) - - - def test_chaining(self): - self.assertEqual(Dude.objects.by_name('Duder').count(), 1) - self.assertEqual(Dude.objects.all().by_name('Duder').count(), 1) - self.assertEqual(Dude.abiders.rug_positive().count(), 1) - self.assertEqual(Dude.abiders.all().rug_positive().count(), 1) - - - def test_manager_only_methods(self): - stats = Dude.abiders.get_stats() - self.assertEqual(stats['rug_count'], 1) - with self.assertRaises(AttributeError): - Dude.abiders.all().get_stats() - - - def test_queryset_pickling(self): - qs = Dude.objects.all() - saltyqs = pickle.dumps(qs) - unqs = pickle.loads(saltyqs) - self.assertEqual(unqs.by_name('The Dude').count(), 1) - - - def test_queryset_not_available_on_related_manager(self): - dude = Dude.objects.by_name('Duder').get() - Car.objects.create(name='Ford', owner=dude) - self.assertFalse(hasattr(dude.cars_owned, 'by_name')) - - - def test_using_dir(self): - # make sure introspecing via dir() doesn't actually cause queries, - # just as a sanity check. - with self.assertNumQueries(0): - querysets_to_dir = ( - Dude.objects, - Dude.objects.by_name('Duder'), - Dude.objects.all().by_name('Duder'), - Dude.abiders, - Dude.abiders.rug_positive(), - Dude.abiders.all().rug_positive() - ) - for qs in querysets_to_dir: - self.assertTrue('by_name' in dir(qs)) - self.assertTrue('abiding' in dir(qs)) - self.assertTrue('rug_positive' in dir(qs)) - self.assertTrue('rug_negative' in dir(qs)) - # some standard qs methods - self.assertTrue('count' in dir(qs)) - self.assertTrue('order_by' in dir(qs)) - self.assertTrue('select_related' in dir(qs)) - # make sure it's been de-duplicated - self.assertEqual(1, dir(qs).count('distinct')) - - # manager only method. - self.assertTrue('get_stats' in dir(Dude.abiders)) - # manager only method shouldn't appear on the non AbidingManager - self.assertFalse('get_stats' in dir(Dude.objects)) - # standard manager methods - self.assertTrue('get_query_set' in dir(Dude.abiders)) - self.assertTrue('contribute_to_class' in dir(Dude.abiders)) - - - -class CreatePassThroughManagerTests(TestCase): - def setUp(self): - self.dude = Dude.objects.create(name='El Duderino') - self.other_dude = Dude.objects.create(name='Das Dude') - - def test_reverse_manager(self): - Spot.objects.create( - name='The Crib', owner=self.dude, closed=True, secure=True, - secret=False) - self.assertEqual(self.dude.spots_owned.closed().count(), 1) - Spot.objects.create( - name='The Crux', owner=self.other_dude, closed=True, secure=True, - secret=False - ) - self.assertEqual(self.dude.spots_owned.closed().all().count(), 1) - self.assertEqual(self.dude.spots_owned.closed().count(), 1) - - def test_related_queryset_pickling(self): - Spot.objects.create( - name='The Crib', owner=self.dude, closed=True, secure=True, - secret=False) - qs = self.dude.spots_owned.closed() - pickled_qs = pickle.dumps(qs) - unpickled_qs = pickle.loads(pickled_qs) - self.assertEqual(unpickled_qs.secured().count(), 1) - - def test_related_queryset_superclass_method(self): - Spot.objects.create( - name='The Crib', owner=self.dude, closed=True, secure=True, - secret=False) - Spot.objects.create( - name='The Secret Crib', owner=self.dude, closed=False, secure=True, - secret=True) - self.assertEqual(self.dude.spots_owned.count(), 1) - - def test_related_manager_create(self): - self.dude.spots_owned.create(name='The Crib', closed=True, secure=True) - - class FieldTrackerTestCase(TestCase): tracker = None From bbad2b7b47f1dbec2972e16207d8a94c8175a196 Mon Sep 17 00:00:00 2001 From: jarekwg Date: Thu, 29 Oct 2015 02:00:49 +1100 Subject: [PATCH 04/12] Hide _clone params in kwargs to match django 1.9 signature --- model_utils/managers.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/model_utils/managers.py b/model_utils/managers.py index 8e95318..2247d8a 100644 --- a/model_utils/managers.py +++ b/model_utils/managers.py @@ -53,12 +53,11 @@ class InheritanceQuerySetMixin(object): new_qs.subclasses = subclasses return new_qs - def _clone(self, klass=None, setup=False, **kwargs): + def _clone(self, **kwargs): for name in ['subclasses', '_annotated']: if hasattr(self, name): kwargs[name] = getattr(self, name) - return super(InheritanceQuerySetMixin, self)._clone( - klass, setup, **kwargs) + return super(InheritanceQuerySetMixin, self)._clone(**kwargs) def annotate(self, *args, **kwargs): qset = super(InheritanceQuerySetMixin, self).annotate(*args, **kwargs) From 201aa3bf30568a500ab8ea915d63148b05589c66 Mon Sep 17 00:00:00 2001 From: jarekwg Date: Thu, 29 Oct 2015 08:12:02 +1100 Subject: [PATCH 05/12] Half-assed use of User model raises exceptions in 1.9b1 --- model_utils/tests/tests.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/model_utils/tests/tests.py b/model_utils/tests/tests.py index aa25512..8c86682 100644 --- a/model_utils/tests/tests.py +++ b/model_utils/tests/tests.py @@ -2,9 +2,9 @@ from __future__ import unicode_literals from datetime import datetime, timedelta try: - from unittest import skipUnless + from unittest import skipIf, skipUnless except ImportError: # Python 2.6 - from django.utils.unittest import skipUnless + from django.utils.unittest import skipIf, skipUnless import django from django.db import models @@ -867,6 +867,8 @@ class InheritanceManagerUsingModelsTests(TestCase): ]) + @skipIf( + django.VERSION == (1, 9, 0, 'beta', 1), "Something shonky in 1.9b1 when using Auth like this") def test_select_subclass_invalid_related_model(self): """ Confirming that giving a stupid model doesn't work. From 01514db83c09379a8a9e327de5380f4efb2f13fc Mon Sep 17 00:00:00 2001 From: jarekwg Date: Thu, 29 Oct 2015 08:12:35 +1100 Subject: [PATCH 06/12] Update MutableField for 1.9 --- model_utils/tests/fields.py | 49 +++++++++++++++++++++++++------------ model_utils/tests/models.py | 4 +-- 2 files changed, 35 insertions(+), 18 deletions(-) diff --git a/model_utils/tests/fields.py b/model_utils/tests/fields.py index 3f1503a..7c29aa4 100644 --- a/model_utils/tests/fields.py +++ b/model_utils/tests/fields.py @@ -1,26 +1,43 @@ +import django from django.db import models from django.utils.six import with_metaclass, string_types -class MutableField(with_metaclass(models.SubfieldBase, models.TextField)): +def mutable_from_db(value): + if value == '': + return None + try: + if isinstance(value, string_types): + return [int(i) for i in value.split(',')] + except ValueError: + pass + return value - def to_python(self, value): - if value == '': - return None - try: - if isinstance(value, string_types): - return [int(i) for i in value.split(',')] - except ValueError: - pass +def mutable_to_db(value): + if value is None: + return '' + if isinstance(value, list): + value = ','.join((str(i) for i in value)) + return str(value) - return value - def get_db_prep_save(self, value, connection): - if value is None: - return '' +if django.VERSION >= (1, 9, 0): + class MutableField(models.TextField): + def to_python(self, value): + return mutable_from_db(value) - if isinstance(value, list): - value = ','.join((str(i) for i in value)) + def from_db_value(self, value, expression, connection, context): + return mutable_from_db(value) - return super(MutableField, self).get_db_prep_save(value, connection) + def get_db_prep_save(self, value, connection): + value = super(MutableField, self).get_db_prep_save(value, connection) + return mutable_to_db(value) +else: + class MutableField(with_metaclass(models.SubfieldBase, models.TextField)): + def to_python(self, value): + return mutable_from_db(value) + + def get_db_prep_save(self, value, connection): + value = mutable_to_db(value) + return super(MutableField, self).get_db_prep_save(value, connection) diff --git a/model_utils/tests/models.py b/model_utils/tests/models.py index b1903ed..6b82541 100644 --- a/model_utils/tests/models.py +++ b/model_utils/tests/models.py @@ -204,7 +204,7 @@ class FeaturedManager(models.Manager): class Tracked(models.Model): name = models.CharField(max_length=20) number = models.IntegerField() - mutable = MutableField() + mutable = MutableField(default=None) tracker = FieldTracker() @@ -249,7 +249,7 @@ class InheritedTracked(Tracked): class ModelTracked(models.Model): name = models.CharField(max_length=20) number = models.IntegerField() - mutable = MutableField() + mutable = MutableField(default=None) tracker = ModelTracker() From c82ce585b3fa93bfa62dc24311322c4e852340e1 Mon Sep 17 00:00:00 2001 From: jarekwg Date: Thu, 29 Oct 2015 08:26:36 +1100 Subject: [PATCH 07/12] Make tests run against django1.9 --- .travis.yml | 4 ++++ setup.py | 1 + tox.ini | 9 +++++---- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index b24d579..cba3063 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,19 +12,23 @@ env: - TOXENV=py27-django16 - TOXENV=py27-django17 - TOXENV=py27-django18 + - TOXENV=py27-django19 - TOXENV=py27-django_trunk - TOXENV=py32-django15 - TOXENV=py32-django16 - TOXENV=py32-django17 - TOXENV=py32-django18 + - TOXENV=py32-django19 - TOXENV=py32-django_trunk - TOXENV=py33-django15 - TOXENV=py33-django16 - TOXENV=py33-django17 - TOXENV=py33-django18 + - TOXENV=py33-django19 - TOXENV=py33-django_trunk - TOXENV=py34-django17 - TOXENV=py34-django18 + - TOXENV=py34-django19 - TOXENV=py34-django_trunk install: diff --git a/setup.py b/setup.py index a1b49b6..feb5ffc 100644 --- a/setup.py +++ b/setup.py @@ -35,6 +35,7 @@ setup( 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3.2', 'Programming Language :: Python :: 3.3', + 'Programming Language :: Python :: 3.4', 'Framework :: Django', ], zip_safe=False, diff --git a/tox.ini b/tox.ini index 5255cf5..ce8310c 100644 --- a/tox.ini +++ b/tox.ini @@ -2,8 +2,8 @@ envlist = py26-django{14,15,16}, py27-django14, py27-django15_nosouth, - py{27,32,33}-django{15,16,17,18,_trunk}, - py34-django{17,18,_trunk}, + py{27,32,33}-django{15,16,17,18,19_trunk}, + py34-django{17,18,19_trunk}, [testenv] basepython = @@ -18,8 +18,9 @@ deps = django14: Django==1.4.18 django15{,_nosouth}: Django==1.5.12 django16: Django==1.6.10 - django17: Django==1.7.3 - django18: Django==1.8a1 + django17: Django==1.7.7 + django18: Django==1.8.5 + django19: Django==1.9b1 django_trunk: https://github.com/django/django/tarball/master django{14,15,16}: South==1.0.2 From 9204fe0ed2cacc7cbe05d6595b920d49cde40b4b Mon Sep 17 00:00:00 2001 From: jarekwg Date: Thu, 29 Oct 2015 08:45:53 +1100 Subject: [PATCH 08/12] Missing commas --- tox.ini | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tox.ini b/tox.ini index ce8310c..0c4e8b5 100644 --- a/tox.ini +++ b/tox.ini @@ -2,8 +2,8 @@ envlist = py26-django{14,15,16}, py27-django14, py27-django15_nosouth, - py{27,32,33}-django{15,16,17,18,19_trunk}, - py34-django{17,18,19_trunk}, + py{27,32,33}-django{15,16,17,18,19,_trunk}, + py34-django{17,18,19,_trunk}, [testenv] basepython = From c2019fd3706f7c9b689dfe3cf5086e6c9a972be8 Mon Sep 17 00:00:00 2001 From: jarekwg Date: Thu, 29 Oct 2015 09:29:49 +1100 Subject: [PATCH 09/12] Add py35 tests; remove py32&33 tests against django19 --- .travis.yml | 5 +++-- setup.py | 1 + tox.ini | 4 +++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index cba3063..f4b9c89 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,18 +18,19 @@ env: - TOXENV=py32-django16 - TOXENV=py32-django17 - TOXENV=py32-django18 - - TOXENV=py32-django19 - TOXENV=py32-django_trunk - TOXENV=py33-django15 - TOXENV=py33-django16 - TOXENV=py33-django17 - TOXENV=py33-django18 - - TOXENV=py33-django19 - TOXENV=py33-django_trunk - TOXENV=py34-django17 - TOXENV=py34-django18 - TOXENV=py34-django19 - TOXENV=py34-django_trunk + - TOXENV=py35-django18 + - TOXENV=py35-django19 + - TOXENV=py35-django_trunk install: - pip install --upgrade pip setuptools tox virtualenv coveralls diff --git a/setup.py b/setup.py index feb5ffc..5137408 100644 --- a/setup.py +++ b/setup.py @@ -36,6 +36,7 @@ setup( 'Programming Language :: Python :: 3.2', 'Programming Language :: Python :: 3.3', 'Programming Language :: Python :: 3.4', + 'Programming Language :: Python :: 3.5', 'Framework :: Django', ], zip_safe=False, diff --git a/tox.ini b/tox.ini index 0c4e8b5..ae7287f 100644 --- a/tox.ini +++ b/tox.ini @@ -2,8 +2,9 @@ envlist = py26-django{14,15,16}, py27-django14, py27-django15_nosouth, - py{27,32,33}-django{15,16,17,18,19,_trunk}, + py{27,32,33}-django{15,16,17,18,_trunk}, py34-django{17,18,19,_trunk}, + py35-django{18,19,_trunk}, [testenv] basepython = @@ -12,6 +13,7 @@ basepython = py32: python3.2 py33: python3.3 py34: python3.4 + py35: python3.5 deps = coverage == 3.6 From 1d473ec6a94a0a55f467274d93c5b5603733521d Mon Sep 17 00:00:00 2001 From: jarekwg Date: Thu, 29 Oct 2015 09:33:45 +1100 Subject: [PATCH 10/12] Test InheritanceManager fail against a different model --- model_utils/tests/tests.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/model_utils/tests/tests.py b/model_utils/tests/tests.py index 8c86682..a5f484b 100644 --- a/model_utils/tests/tests.py +++ b/model_utils/tests/tests.py @@ -4,7 +4,7 @@ from datetime import datetime, timedelta try: from unittest import skipIf, skipUnless except ImportError: # Python 2.6 - from django.utils.unittest import skipIf, skipUnless + from django.utils.unittest import skipUnless import django from django.db import models @@ -867,17 +867,14 @@ class InheritanceManagerUsingModelsTests(TestCase): ]) - @skipIf( - django.VERSION == (1, 9, 0, 'beta', 1), "Something shonky in 1.9b1 when using Auth like this") def test_select_subclass_invalid_related_model(self): """ Confirming that giving a stupid model doesn't work. """ - from django.contrib.auth.models import User regex = '^.+? is not a subclass of .+$' with self.assertRaisesRegexp(ValueError, regex): InheritanceManagerTestParent.objects.select_subclasses( - User).order_by('pk') + TimeFrame).order_by('pk') From 81eba92e61cea3162b11d27777ab85fa5a68c82f Mon Sep 17 00:00:00 2001 From: jarekwg Date: Thu, 29 Oct 2015 09:37:21 +1100 Subject: [PATCH 11/12] flakes --- model_utils/models.py | 1 - model_utils/tests/tests.py | 10 ++++------ 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/model_utils/models.py b/model_utils/models.py index 142b77c..3db4073 100644 --- a/model_utils/models.py +++ b/model_utils/models.py @@ -3,7 +3,6 @@ from __future__ import unicode_literals import django from django.db import models from django.utils.translation import ugettext_lazy as _ -from django.db.models.fields import FieldDoesNotExist from django.core.exceptions import ImproperlyConfigured if django.VERSION >= (1, 9, 0): from django.db.models.functions import Now diff --git a/model_utils/tests/tests.py b/model_utils/tests/tests.py index a5f484b..dd40506 100644 --- a/model_utils/tests/tests.py +++ b/model_utils/tests/tests.py @@ -2,7 +2,7 @@ from __future__ import unicode_literals from datetime import datetime, timedelta try: - from unittest import skipIf, skipUnless + from unittest import skipUnless except ImportError: # Python 2.6 from django.utils.unittest import skipUnless @@ -1391,15 +1391,13 @@ class FieldTrackerTests(FieldTrackerTestCase, FieldTrackerCommonTests): class FieldTrackerMultipleInstancesTests(TestCase): def test_with_deferred_fields_access_multiple(self): - instances = [ - Tracked.objects.create(pk=1, name='foo', number=1), - Tracked.objects.create(pk=2, name='bar', number=2) - ] + Tracked.objects.create(pk=1, name='foo', number=1) + Tracked.objects.create(pk=2, name='bar', number=2) queryset = Tracked.objects.only('id') for instance in queryset: - name = instance.name + instance.name class FieldTrackedModelCustomTests(FieldTrackerTestCase, From dcd288cb09ebc2d973c0a5428418acd8b98e3427 Mon Sep 17 00:00:00 2001 From: jarekwg Date: Thu, 29 Oct 2015 09:42:16 +1100 Subject: [PATCH 12/12] Jumped the gun with py35 tests.. https://github.com/travis-ci/travis-ci/issues/4794 --- .travis.yml | 3 --- setup.py | 1 - tox.ini | 2 -- 3 files changed, 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index f4b9c89..b23f12e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -28,9 +28,6 @@ env: - TOXENV=py34-django18 - TOXENV=py34-django19 - TOXENV=py34-django_trunk - - TOXENV=py35-django18 - - TOXENV=py35-django19 - - TOXENV=py35-django_trunk install: - pip install --upgrade pip setuptools tox virtualenv coveralls diff --git a/setup.py b/setup.py index 5137408..feb5ffc 100644 --- a/setup.py +++ b/setup.py @@ -36,7 +36,6 @@ setup( 'Programming Language :: Python :: 3.2', 'Programming Language :: Python :: 3.3', 'Programming Language :: Python :: 3.4', - 'Programming Language :: Python :: 3.5', 'Framework :: Django', ], zip_safe=False, diff --git a/tox.ini b/tox.ini index ae7287f..00eea15 100644 --- a/tox.ini +++ b/tox.ini @@ -4,7 +4,6 @@ envlist = py27-django14, py27-django15_nosouth, py{27,32,33}-django{15,16,17,18,_trunk}, py34-django{17,18,19,_trunk}, - py35-django{18,19,_trunk}, [testenv] basepython = @@ -13,7 +12,6 @@ basepython = py32: python3.2 py33: python3.3 py34: python3.4 - py35: python3.5 deps = coverage == 3.6