diff --git a/model_utils/__init__.py b/model_utils/__init__.py index f297da6..54f1b02 100644 --- a/model_utils/__init__.py +++ b/model_utils/__init__.py @@ -1,4 +1,4 @@ -from .choices import Choices -from .tracker import FieldTracker, ModelTracker +from .choices import Choices # noqa:F401 +from .tracker import FieldTracker, ModelTracker # noqa:F401 __version__ = '3.1.2' diff --git a/model_utils/choices.py b/model_utils/choices.py index d48ba90..681e44b 100644 --- a/model_utils/choices.py +++ b/model_utils/choices.py @@ -57,7 +57,6 @@ class Choices(object): self._process(choices) - def _store(self, triple, triple_collector, double_collector): self._identifier_map[triple[1]] = triple[0] self._display_map[triple[0]] = triple[2] @@ -65,7 +64,6 @@ class Choices(object): triple_collector.append(triple) double_collector.append((triple[0], triple[2])) - def _process(self, choices, triple_collector=None, double_collector=None): if triple_collector is None: triple_collector = self._triples @@ -94,30 +92,25 @@ class Choices(object): raise ValueError( "Choices can't take a list of length %s, only 2 or 3" % len(choice) - ) + ) else: store((choice, choice, choice)) - def __len__(self): return len(self._doubles) - def __iter__(self): return iter(self._doubles) - def __getattr__(self, attname): try: return self._identifier_map[attname] except KeyError: raise AttributeError(attname) - def __getitem__(self, key): return self._display_map[key] - def __add__(self, other): if isinstance(other, self.__class__): other = other._triples @@ -125,29 +118,24 @@ class Choices(object): other = list(other) return Choices(*(self._triples + other)) - def __radd__(self, other): # radd is never called for matching types, so we don't check here other = list(other) return Choices(*(other + self._triples)) - def __eq__(self, other): if isinstance(other, self.__class__): return self._triples == other._triples return False - def __repr__(self): return '%s(%s)' % ( self.__class__.__name__, ', '.join(("%s" % repr(i) for i in self._triples)) - ) - + ) def __contains__(self, item): return item in self._db_values - def __deepcopy__(self, memo): return self.__class__(*copy.deepcopy(self._triples, memo)) diff --git a/model_utils/fields.py b/model_utils/fields.py index f308706..d9d9b85 100644 --- a/model_utils/fields.py +++ b/model_utils/fields.py @@ -141,6 +141,7 @@ SPLIT_DEFAULT_PARAGRAPHS = getattr(settings, 'SPLIT_DEFAULT_PARAGRAPHS', 2) _excerpt_field_name = lambda name: '_%s_excerpt' % name + def get_excerpt(content): excerpt = [] default_excerpt = [] @@ -156,6 +157,7 @@ def get_excerpt(content): return '\n'.join(default_excerpt) + @python_2_unicode_compatible class SplitText(object): def __init__(self, instance, field_name, excerpt_field_name): @@ -166,11 +168,13 @@ class SplitText(object): self.excerpt_field_name = excerpt_field_name # content is read/write - def _get_content(self): + @property + def content(self): return self.instance.__dict__[self.field_name] - def _set_content(self, val): + + @content.setter + def content(self, val): setattr(self.instance, self.field_name, val) - content = property(_get_content, _set_content) # excerpt is a read only property def _get_excerpt(self): @@ -185,6 +189,7 @@ class SplitText(object): def __str__(self): return self.content + class SplitDescriptor(object): def __init__(self, field): self.field = field @@ -205,6 +210,7 @@ class SplitDescriptor(object): else: obj.__dict__[self.field.name] = value + class SplitField(models.TextField): def __init__(self, *args, **kwargs): # for South FakeORM compatibility: the frozen version of a diff --git a/model_utils/managers.py b/model_utils/managers.py index 98a2a54..b760ffd 100644 --- a/model_utils/managers.py +++ b/model_utils/managers.py @@ -76,7 +76,7 @@ class InheritanceQuerySetMixin(object): raise ValueError( '%r is not in the discovered subclasses, tried: %s' % ( subclass, ', '.join(calculated_subclasses)) - ) + ) subclasses = verified_subclasses # workaround https://code.djangoproject.com/ticket/16855 @@ -159,7 +159,7 @@ class InheritanceQuerySetMixin(object): if isinstance(rel.field, OneToOneField) and issubclass(rel.field.model, model) and model is not rel.field.model - ] + ] subclasses = [] if levels: diff --git a/model_utils/tracker.py b/model_utils/tracker.py index 582ae06..8ce10dc 100644 --- a/model_utils/tracker.py +++ b/model_utils/tracker.py @@ -235,6 +235,7 @@ class FieldTracker(object): def patch_save(self, instance): original_save = instance.save + def save(**kwargs): ret = original_save(**kwargs) update_fields = kwargs.get('update_fields') @@ -251,6 +252,7 @@ class FieldTracker(object): fields=fields ) return ret + instance.save = save def __get__(self, instance, owner): diff --git a/tests/models.py b/tests/models.py index 7c9bb56..80f3a3f 100644 --- a/tests/models.py +++ b/tests/models.py @@ -38,9 +38,6 @@ class InheritanceManagerTestParent(models.Model): on_delete=models.CASCADE) objects = InheritanceManager() - def __unicode__(self): - return unicode(self.pk) - def __str__(self): return "%s(%s)" % ( self.__class__.__name__[len('InheritanceManagerTest'):], diff --git a/tests/test_choices.py b/tests/test_choices.py index a503405..29dbb36 100644 --- a/tests/test_choices.py +++ b/tests/test_choices.py @@ -79,7 +79,7 @@ class LabelChoicesTests(ChoicesTests): ('DRAFT', 'is draft'), ('PUBLISHED', 'is published'), ('DELETED', 'DELETED')) - ) + ) def test_indexing(self): self.assertEqual(self.STATUS['PUBLISHED'], 'is published') diff --git a/tests/test_fields/test_field_tracker.py b/tests/test_fields/test_field_tracker.py index 93b9efa..43f12f5 100644 --- a/tests/test_fields/test_field_tracker.py +++ b/tests/test_fields/test_field_tracker.py @@ -1,7 +1,5 @@ from __future__ import unicode_literals -from unittest import skipUnless - import django from django.core.exceptions import FieldError from django.test import TestCase @@ -75,7 +73,7 @@ class FieldTrackerTests(FieldTrackerTestCase, FieldTrackerCommonTests): self.assertChanged(name=None, number=None) self.instance.name = '' self.assertChanged(name=None, number=None) - self.instance.mutable = [1,2,3] + self.instance.mutable = [1, 2, 3] self.assertChanged(name=None, number=None, mutable=None) def test_pre_save_has_changed(self): @@ -84,7 +82,7 @@ class FieldTrackerTests(FieldTrackerTestCase, FieldTrackerCommonTests): self.assertHasChanged(name=True, number=False, mutable=False) self.instance.number = 7 self.assertHasChanged(name=True, number=True) - self.instance.mutable = [1,2,3] + self.instance.mutable = [1, 2, 3] self.assertHasChanged(name=True, number=True, mutable=True) def test_first_save(self): @@ -94,22 +92,22 @@ class FieldTrackerTests(FieldTrackerTestCase, FieldTrackerCommonTests): self.assertChanged(name=None) self.instance.name = 'retro' self.instance.number = 4 - self.instance.mutable = [1,2,3] + self.instance.mutable = [1, 2, 3] self.assertHasChanged(name=True, number=True, mutable=True) self.assertPrevious(name=None, number=None, mutable=None) - self.assertCurrent(name='retro', number=4, id=None, mutable=[1,2,3]) + self.assertCurrent(name='retro', number=4, id=None, mutable=[1, 2, 3]) self.assertChanged(name=None, number=None, mutable=None) self.instance.save(update_fields=[]) self.assertHasChanged(name=True, number=True, mutable=True) self.assertPrevious(name=None, number=None, mutable=None) - self.assertCurrent(name='retro', number=4, id=None, mutable=[1,2,3]) + self.assertCurrent(name='retro', number=4, id=None, mutable=[1, 2, 3]) self.assertChanged(name=None, number=None, mutable=None) with self.assertRaises(ValueError): self.instance.save(update_fields=['number']) def test_post_save_has_changed(self): - self.update_instance(name='retro', number=4, mutable=[1,2,3]) + self.update_instance(name='retro', number=4, mutable=[1, 2, 3]) self.assertHasChanged(name=False, number=False, mutable=False) self.instance.name = 'new age' self.assertHasChanged(name=True, number=False) @@ -121,14 +119,14 @@ class FieldTrackerTests(FieldTrackerTestCase, FieldTrackerCommonTests): self.assertHasChanged(name=False, number=True, mutable=True) def test_post_save_previous(self): - self.update_instance(name='retro', number=4, mutable=[1,2,3]) + self.update_instance(name='retro', number=4, mutable=[1, 2, 3]) self.instance.name = 'new age' - self.assertPrevious(name='retro', number=4, mutable=[1,2,3]) + self.assertPrevious(name='retro', number=4, mutable=[1, 2, 3]) self.instance.mutable[1] = 4 - self.assertPrevious(name='retro', number=4, mutable=[1,2,3]) + self.assertPrevious(name='retro', number=4, mutable=[1, 2, 3]) def test_post_save_changed(self): - self.update_instance(name='retro', number=4, mutable=[1,2,3]) + self.update_instance(name='retro', number=4, mutable=[1, 2, 3]) self.assertChanged() self.instance.name = 'new age' self.assertChanged(name='retro') @@ -137,8 +135,8 @@ class FieldTrackerTests(FieldTrackerTestCase, FieldTrackerCommonTests): self.instance.name = 'retro' self.assertChanged(number=4) self.instance.mutable[1] = 4 - self.assertChanged(number=4, mutable=[1,2,3]) - self.instance.mutable = [1,2,3] + self.assertChanged(number=4, mutable=[1, 2, 3]) + self.instance.mutable = [1, 2, 3] self.assertChanged(number=4) def test_current(self): @@ -147,29 +145,29 @@ class FieldTrackerTests(FieldTrackerTestCase, FieldTrackerCommonTests): self.assertCurrent(id=None, name='new age', number=None, mutable=None) self.instance.number = 8 self.assertCurrent(id=None, name='new age', number=8, mutable=None) - self.instance.mutable = [1,2,3] - self.assertCurrent(id=None, name='new age', number=8, mutable=[1,2,3]) + self.instance.mutable = [1, 2, 3] + self.assertCurrent(id=None, name='new age', number=8, mutable=[1, 2, 3]) self.instance.mutable[1] = 4 - self.assertCurrent(id=None, name='new age', number=8, mutable=[1,4,3]) + self.assertCurrent(id=None, name='new age', number=8, mutable=[1, 4, 3]) self.instance.save() - self.assertCurrent(id=self.instance.id, name='new age', number=8, mutable=[1,4,3]) + self.assertCurrent(id=self.instance.id, name='new age', number=8, mutable=[1, 4, 3]) def test_update_fields(self): - self.update_instance(name='retro', number=4, mutable=[1,2,3]) + self.update_instance(name='retro', number=4, mutable=[1, 2, 3]) self.assertChanged() self.instance.name = 'new age' self.instance.number = 8 - self.instance.mutable = [4,5,6] - self.assertChanged(name='retro', number=4, mutable=[1,2,3]) + self.instance.mutable = [4, 5, 6] + self.assertChanged(name='retro', number=4, mutable=[1, 2, 3]) self.instance.save(update_fields=[]) - self.assertChanged(name='retro', number=4, mutable=[1,2,3]) + self.assertChanged(name='retro', number=4, mutable=[1, 2, 3]) self.instance.save(update_fields=['name']) in_db = self.tracked_class.objects.get(id=self.instance.id) self.assertEqual(in_db.name, self.instance.name) self.assertNotEqual(in_db.number, self.instance.number) - self.assertChanged(number=4, mutable=[1,2,3]) + self.assertChanged(number=4, mutable=[1, 2, 3]) self.instance.save(update_fields=['number']) - self.assertChanged(mutable=[1,2,3]) + self.assertChanged(mutable=[1, 2, 3]) self.instance.save(update_fields=['mutable']) self.assertChanged() in_db = self.tracked_class.objects.get(id=self.instance.id) @@ -241,7 +239,6 @@ class FieldTrackerTests(FieldTrackerTestCase, FieldTrackerCommonTests): self.assertFalse(item.tracker.has_changed('number')) - class FieldTrackerMultipleInstancesTests(TestCase): def test_with_deferred_fields_access_multiple(self): @@ -650,7 +647,7 @@ class ModelTrackerTests(FieldTrackerTests): self.assertChanged() self.instance.name = '' self.assertChanged() - self.instance.mutable = [1,2,3] + self.instance.mutable = [1, 2, 3] self.assertChanged() def test_first_save(self): @@ -660,16 +657,16 @@ class ModelTrackerTests(FieldTrackerTests): self.assertChanged() self.instance.name = 'retro' self.instance.number = 4 - self.instance.mutable = [1,2,3] + self.instance.mutable = [1, 2, 3] self.assertHasChanged(name=True, number=True, mutable=True) self.assertPrevious(name=None, number=None, mutable=None) - self.assertCurrent(name='retro', number=4, id=None, mutable=[1,2,3]) + self.assertCurrent(name='retro', number=4, id=None, mutable=[1, 2, 3]) self.assertChanged() self.instance.save(update_fields=[]) self.assertHasChanged(name=True, number=True, mutable=True) self.assertPrevious(name=None, number=None, mutable=None) - self.assertCurrent(name='retro', number=4, id=None, mutable=[1,2,3]) + self.assertCurrent(name='retro', number=4, id=None, mutable=[1, 2, 3]) self.assertChanged() with self.assertRaises(ValueError): self.instance.save(update_fields=['number']) diff --git a/tests/test_fields/test_status_field.py b/tests/test_fields/test_status_field.py index 5f077da..dc0f223 100644 --- a/tests/test_fields/test_status_field.py +++ b/tests/test_fields/test_status_field.py @@ -6,7 +6,7 @@ from model_utils.fields import StatusField from tests.models import ( Article, StatusFieldDefaultFilled, StatusFieldDefaultNotFilled, StatusFieldChoicesName, - ) +) class StatusFieldTests(TestCase): diff --git a/tests/test_managers/test_inheritance_manager.py b/tests/test_managers/test_inheritance_manager.py index 39c694e..7cde8d3 100644 --- a/tests/test_managers/test_inheritance_manager.py +++ b/tests/test_managers/test_inheritance_manager.py @@ -6,11 +6,12 @@ import django from django.db import models from django.test import TestCase -from tests.models import (InheritanceManagerTestRelated, InheritanceManagerTestGrandChild1, - InheritanceManagerTestGrandChild1_2, InheritanceManagerTestParent, - InheritanceManagerTestChild1, - InheritanceManagerTestChild2, TimeFrame, InheritanceManagerTestChild3 - ) +from tests.models import ( + InheritanceManagerTestRelated, InheritanceManagerTestGrandChild1, + InheritanceManagerTestGrandChild1_2, InheritanceManagerTestParent, + InheritanceManagerTestChild1, + InheritanceManagerTestChild2, TimeFrame, InheritanceManagerTestChild3 +) class InheritanceManagerTests(TestCase): @@ -177,27 +178,26 @@ class InheritanceManagerTests(TestCase): # No argument to select_subclasses objs_1 = list( - self.get_manager(). - select_subclasses(). - values_list('id') + self.get_manager() + .select_subclasses() + .values_list('id') ) # String argument to select_subclasses objs_2 = list( - self.get_manager(). - select_subclasses( + self.get_manager() + .select_subclasses( "inheritancemanagertestchild2" - ). - values_list('id') + ) + .values_list('id') ) # String argument to select_subclasses objs_3 = list( - self.get_manager(). - select_subclasses( + self.get_manager() + .select_subclasses( InheritanceManagerTestChild2 - ). - values_list('id') + ).values_list('id') ) assert all(( diff --git a/tests/test_models/test_deferred_fields.py b/tests/test_models/test_deferred_fields.py index 05ba336..ea8e3bd 100644 --- a/tests/test_models/test_deferred_fields.py +++ b/tests/test_models/test_deferred_fields.py @@ -24,7 +24,7 @@ class CustomDescriptorTests(TestCase): self.assertEqual(instance.custom_field, '2') self.assertEqual(instance.__dict__['custom_field'], 2) instance.save() - intance = ModelWithCustomDescriptor.objects.get(pk=instance.pk) + instance = ModelWithCustomDescriptor.objects.get(pk=instance.pk) self.assertEqual(instance.custom_field, '2') self.assertEqual(instance.__dict__['custom_field'], 2) diff --git a/tests/test_models/test_status_model.py b/tests/test_models/test_status_model.py index f660936..6950dbf 100644 --- a/tests/test_models/test_status_model.py +++ b/tests/test_models/test_status_model.py @@ -18,7 +18,7 @@ class StatusModelTests(TestCase): c1 = self.model.objects.create() self.assertTrue(c1.status_changed, datetime(2016, 1, 1)) - c2 = self.model.objects.create() + self.model.objects.create() self.assertEqual(self.model.active.count(), 2) self.assertEqual(self.model.deleted.count(), 0) diff --git a/tox.ini b/tox.ini index 861074c..71caa88 100644 --- a/tox.ini +++ b/tox.ini @@ -4,6 +4,7 @@ envlist = py34-django{18,19,110,111,200} py35-django{18,19,110,111,200,trunk} py36-django{111,200,trunk} + flake8 [testenv] deps = @@ -19,10 +20,25 @@ deps = ignore_outcome = djangotrunk: True passenv = - CI - TRAVIS - TRAVIS_* + CI + TRAVIS + TRAVIS_* commands = pip install -e . py.test {posargs} + +[testenv:flake8] +basepython = + python3.6 +deps = + flake8 +commands = + flake8 model_utils tests + +[flake8] +ignore = + E731 ; do not assign a lambda expression, use a def + W503 ; line break before binary operator + E402 ; module level import not at top of file + E501 ; line too long