mirror of
https://github.com/Hopiu/django-model-utils.git
synced 2026-03-16 20:00:23 +00:00
Modernize Python syntax, add Python 3.8 (#398)
* Modernize Python syntax, add Python 3.8 * Update Python version & dist in TravisCI * Add postgresql as addon * Switch to psycopg2-binary * Drop django.utils.six
This commit is contained in:
parent
aa94194dbc
commit
ffa1a85dc7
32 changed files with 85 additions and 133 deletions
12
.travis.yml
12
.travis.yml
|
|
@ -1,19 +1,23 @@
|
|||
sudo: True
|
||||
dist: xenial
|
||||
version: ~> 1.0
|
||||
dist: bionic
|
||||
os: linux
|
||||
language: python
|
||||
cache: pip
|
||||
python:
|
||||
- 3.7
|
||||
- 3.6
|
||||
- 3.7
|
||||
- 3.8
|
||||
install: pip install tox-travis codecov
|
||||
# positional args ({posargs}) to pass into tox.ini
|
||||
script: tox -- --cov --cov-append
|
||||
addons:
|
||||
postgresql: '10'
|
||||
services:
|
||||
- postgresql
|
||||
after_success: codecov
|
||||
deploy:
|
||||
provider: pypi
|
||||
user: jazzband
|
||||
username: jazzband
|
||||
server: https://jazzband.co/projects/django-model-utils/upload
|
||||
distributions: sdist bdist_wheel
|
||||
password:
|
||||
|
|
|
|||
17
docs/conf.py
17
docs/conf.py
|
|
@ -1,4 +1,3 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# django-model-utils documentation build configuration file, created by
|
||||
# sphinx-quickstart on Wed Jul 31 22:27:07 2013.
|
||||
|
|
@ -40,8 +39,8 @@ source_suffix = '.rst'
|
|||
master_doc = 'index'
|
||||
|
||||
# General information about the project.
|
||||
project = u'django-model-utils'
|
||||
copyright = u'2015, Carl Meyer'
|
||||
project = 'django-model-utils'
|
||||
copyright = '2015, Carl Meyer'
|
||||
|
||||
parent_dir = os.path.dirname(os.path.dirname(__file__))
|
||||
|
||||
|
|
@ -194,8 +193,8 @@ latex_elements = {
|
|||
# Grouping the document tree into LaTeX files. List of tuples
|
||||
# (source start file, target name, title, author, documentclass [howto/manual]).
|
||||
latex_documents = [
|
||||
('index', 'django-model-utils.tex', u'django-model-utils Documentation',
|
||||
u'Carl Meyer', 'manual'),
|
||||
('index', 'django-model-utils.tex', 'django-model-utils Documentation',
|
||||
'Carl Meyer', 'manual'),
|
||||
]
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top of
|
||||
|
|
@ -224,8 +223,8 @@ latex_documents = [
|
|||
# One entry per manual page. List of tuples
|
||||
# (source start file, name, description, authors, manual section).
|
||||
man_pages = [
|
||||
('index', 'django-model-utils', u'django-model-utils Documentation',
|
||||
[u'Carl Meyer'], 1)
|
||||
('index', 'django-model-utils', 'django-model-utils Documentation',
|
||||
['Carl Meyer'], 1)
|
||||
]
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
|
|
@ -238,8 +237,8 @@ man_pages = [
|
|||
# (source start file, target name, title, author,
|
||||
# dir menu entry, description, category)
|
||||
texinfo_documents = [
|
||||
('index', 'django-model-utils', u'django-model-utils Documentation',
|
||||
u'Carl Meyer', 'django-model-utils', 'One line description of project.',
|
||||
('index', 'django-model-utils', 'django-model-utils Documentation',
|
||||
'Carl Meyer', 'django-model-utils', 'One line description of project.',
|
||||
'Miscellaneous'),
|
||||
]
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
import copy
|
||||
|
||||
|
||||
|
|
@ -132,9 +130,9 @@ class Choices:
|
|||
return False
|
||||
|
||||
def __repr__(self):
|
||||
return '%s(%s)' % (
|
||||
return '{}({})'.format(
|
||||
self.__class__.__name__,
|
||||
', '.join(("%s" % repr(i) for i in self._triples))
|
||||
', '.join("%s" % repr(i) for i in self._triples)
|
||||
)
|
||||
|
||||
def __contains__(self, item):
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
import django
|
||||
import uuid
|
||||
from django.db import models
|
||||
|
|
@ -22,7 +20,7 @@ class AutoCreatedField(models.DateTimeField):
|
|||
def __init__(self, *args, **kwargs):
|
||||
kwargs.setdefault('editable', False)
|
||||
kwargs.setdefault('default', now)
|
||||
super(AutoCreatedField, self).__init__(*args, **kwargs)
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
|
||||
class AutoLastModifiedField(AutoCreatedField):
|
||||
|
|
@ -73,7 +71,7 @@ class StatusField(models.CharField):
|
|||
kwargs.setdefault('max_length', 100)
|
||||
self.check_for_status = not kwargs.pop('no_check_for_status', False)
|
||||
self.choices_name = kwargs.pop('choices_name', DEFAULT_CHOICES_NAME)
|
||||
super(StatusField, self).__init__(*args, **kwargs)
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
def prepare_class(self, sender, **kwargs):
|
||||
if not sender._meta.abstract and self.check_for_status:
|
||||
|
|
@ -90,10 +88,10 @@ 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')]
|
||||
super(StatusField, self).contribute_to_class(cls, name)
|
||||
super().contribute_to_class(cls, name)
|
||||
|
||||
def deconstruct(self):
|
||||
name, path, args, kwargs = super(StatusField, self).deconstruct()
|
||||
name, path, args, kwargs = super().deconstruct()
|
||||
kwargs['no_check_for_status'] = True
|
||||
return name, path, args, kwargs
|
||||
|
||||
|
|
@ -117,12 +115,12 @@ class MonitorField(models.DateTimeField):
|
|||
if when is not None:
|
||||
when = set(when)
|
||||
self.when = when
|
||||
super(MonitorField, self).__init__(*args, **kwargs)
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
def contribute_to_class(self, cls, name):
|
||||
self.monitor_attname = '_monitor_%s' % name
|
||||
models.signals.post_init.connect(self._save_initial, sender=cls)
|
||||
super(MonitorField, self).contribute_to_class(cls, name)
|
||||
super().contribute_to_class(cls, name)
|
||||
|
||||
def get_monitored_value(self, instance):
|
||||
return getattr(instance, self.monitor)
|
||||
|
|
@ -141,10 +139,10 @@ class MonitorField(models.DateTimeField):
|
|||
if self.when is None or current in self.when:
|
||||
setattr(model_instance, self.attname, value)
|
||||
self._save_initial(model_instance.__class__, model_instance)
|
||||
return super(MonitorField, self).pre_save(model_instance, add)
|
||||
return super().pre_save(model_instance, add)
|
||||
|
||||
def deconstruct(self):
|
||||
name, path, args, kwargs = super(MonitorField, self).deconstruct()
|
||||
name, path, args, kwargs = super().deconstruct()
|
||||
kwargs['monitor'] = self.monitor
|
||||
if self.when is not None:
|
||||
kwargs['when'] = self.when
|
||||
|
|
@ -236,17 +234,17 @@ class SplitField(models.TextField):
|
|||
# _excerpt field itself is frozen as well. See introspection
|
||||
# rules below.
|
||||
self.add_excerpt_field = not kwargs.pop('no_excerpt_field', False)
|
||||
super(SplitField, self).__init__(*args, **kwargs)
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
def contribute_to_class(self, cls, name):
|
||||
if self.add_excerpt_field and not cls._meta.abstract:
|
||||
excerpt_field = models.TextField(editable=False)
|
||||
cls.add_to_class(_excerpt_field_name(name), excerpt_field)
|
||||
super(SplitField, self).contribute_to_class(cls, name)
|
||||
super().contribute_to_class(cls, name)
|
||||
setattr(cls, self.name, SplitDescriptor(self))
|
||||
|
||||
def pre_save(self, model_instance, add):
|
||||
value = super(SplitField, self).pre_save(model_instance, add)
|
||||
value = super().pre_save(model_instance, add)
|
||||
excerpt = get_excerpt(value.content)
|
||||
setattr(model_instance, _excerpt_field_name(self.attname), excerpt)
|
||||
return value.content
|
||||
|
|
@ -262,7 +260,7 @@ class SplitField(models.TextField):
|
|||
return value
|
||||
|
||||
def deconstruct(self):
|
||||
name, path, args, kwargs = super(SplitField, self).deconstruct()
|
||||
name, path, args, kwargs = super().deconstruct()
|
||||
kwargs['no_excerpt_field'] = True
|
||||
return name, path, args, kwargs
|
||||
|
||||
|
|
@ -310,4 +308,4 @@ class UUIDField(models.UUIDField):
|
|||
kwargs.setdefault('primary_key', primary_key)
|
||||
kwargs.setdefault('editable', editable)
|
||||
kwargs.setdefault('default', default)
|
||||
super(UUIDField, self).__init__(*args, **kwargs)
|
||||
super().__init__(*args, **kwargs)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
from __future__ import unicode_literals
|
||||
import django
|
||||
from django.db import models
|
||||
from django.db.models.fields.related import OneToOneField, OneToOneRel
|
||||
|
|
@ -7,7 +6,6 @@ from django.db.models.query import ModelIterable
|
|||
from django.core.exceptions import ObjectDoesNotExist
|
||||
|
||||
from django.db.models.constants import LOOKUP_SEP
|
||||
from django.utils.six import string_types
|
||||
|
||||
from django.db import connection
|
||||
from django.db.models.sql.datastructures import Join
|
||||
|
|
@ -40,13 +38,12 @@ class InheritanceIterable(ModelIterable):
|
|||
|
||||
yield sub_obj
|
||||
else:
|
||||
for obj in iter:
|
||||
yield obj
|
||||
yield from iter
|
||||
|
||||
|
||||
class InheritanceQuerySetMixin:
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(InheritanceQuerySetMixin, self).__init__(*args, **kwargs)
|
||||
super().__init__(*args, **kwargs)
|
||||
self._iterable_class = InheritanceIterable
|
||||
|
||||
def select_subclasses(self, *subclasses):
|
||||
|
|
@ -65,7 +62,7 @@ class InheritanceQuerySetMixin:
|
|||
if subclass is self.model:
|
||||
continue
|
||||
|
||||
if not isinstance(subclass, string_types):
|
||||
if not isinstance(subclass, (str,)):
|
||||
subclass = self._get_ancestors_path(
|
||||
subclass, levels=levels)
|
||||
|
||||
|
|
@ -73,7 +70,7 @@ class InheritanceQuerySetMixin:
|
|||
verified_subclasses.append(subclass)
|
||||
else:
|
||||
raise ValueError(
|
||||
'%r is not in the discovered subclasses, tried: %s' % (
|
||||
'{!r} is not in the discovered subclasses, tried: {}'.format(
|
||||
subclass, ', '.join(calculated_subclasses))
|
||||
)
|
||||
subclasses = verified_subclasses
|
||||
|
|
@ -93,11 +90,11 @@ class InheritanceQuerySetMixin:
|
|||
if hasattr(self, name):
|
||||
kwargs[name] = getattr(self, name)
|
||||
|
||||
return super(InheritanceQuerySetMixin, self)._chain(**kwargs)
|
||||
return super()._chain(**kwargs)
|
||||
|
||||
def _clone(self, klass=None, setup=False, **kwargs):
|
||||
if django.VERSION >= (2, 0):
|
||||
qs = super(InheritanceQuerySetMixin, self)._clone()
|
||||
qs = super()._clone()
|
||||
for name in ['subclasses', '_annotated']:
|
||||
if hasattr(self, name):
|
||||
setattr(qs, name, getattr(self, name))
|
||||
|
|
@ -107,10 +104,10 @@ class InheritanceQuerySetMixin:
|
|||
if hasattr(self, name):
|
||||
kwargs[name] = getattr(self, name)
|
||||
|
||||
return super(InheritanceQuerySetMixin, self)._clone(**kwargs)
|
||||
return super()._clone(**kwargs)
|
||||
|
||||
def annotate(self, *args, **kwargs):
|
||||
qset = super(InheritanceQuerySetMixin, self).annotate(*args, **kwargs)
|
||||
qset = super().annotate(*args, **kwargs)
|
||||
qset._annotated = [a.default_alias for a in args] + list(kwargs.keys())
|
||||
return qset
|
||||
|
||||
|
|
@ -152,7 +149,7 @@ class InheritanceQuerySetMixin:
|
|||
"""
|
||||
if not issubclass(model, self.model):
|
||||
raise ValueError(
|
||||
"%r is not a subclass of %r" % (model, self.model))
|
||||
"{!r} is not a subclass of {!r}".format(model, self.model))
|
||||
|
||||
ancestry = []
|
||||
# should be a OneToOneField or None
|
||||
|
|
@ -208,7 +205,7 @@ class InheritanceQuerySet(InheritanceQuerySetMixin, QuerySet):
|
|||
where_queries = []
|
||||
for model in models:
|
||||
where_queries.append('(' + ' AND '.join([
|
||||
'"%s"."%s" IS NOT NULL' % (
|
||||
'"{}"."{}" IS NOT NULL'.format(
|
||||
model._meta.db_table,
|
||||
field.attname, # Should this be something else?
|
||||
) for field in model._meta.parents.values()
|
||||
|
|
@ -244,14 +241,14 @@ class QueryManagerMixin:
|
|||
else:
|
||||
self._q = models.Q(**kwargs)
|
||||
self._order_by = None
|
||||
super(QueryManagerMixin, self).__init__()
|
||||
super().__init__()
|
||||
|
||||
def order_by(self, *args):
|
||||
self._order_by = args
|
||||
return self
|
||||
|
||||
def get_queryset(self):
|
||||
qs = super(QueryManagerMixin, self).get_queryset().filter(self._q)
|
||||
qs = super().get_queryset().filter(self._q)
|
||||
if self._order_by is not None:
|
||||
return qs.order_by(*self._order_by)
|
||||
return qs
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
from django.db import models, transaction, router
|
||||
from django.db.models.signals import post_save, pre_save
|
||||
|
|
@ -136,7 +134,7 @@ class SoftDeletableModel(models.Model):
|
|||
self.is_removed = True
|
||||
self.save(using=using)
|
||||
else:
|
||||
return super(SoftDeletableModel, self).delete(using=using, *args, **kwargs)
|
||||
return super().delete(using=using, *args, **kwargs)
|
||||
|
||||
|
||||
class UUIDModel(models.Model):
|
||||
|
|
@ -170,7 +168,7 @@ class SaveSignalHandlingModel(models.Model):
|
|||
|
||||
self.signals_to_disable = signals_to_disable or []
|
||||
|
||||
super(SaveSignalHandlingModel, self).save(*args, **kwargs)
|
||||
super().save(*args, **kwargs)
|
||||
|
||||
def save_base(self, raw=False, force_insert=False,
|
||||
force_update=False, using=None, update_fields=None):
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
from copy import deepcopy
|
||||
|
||||
import django
|
||||
|
|
@ -20,7 +18,7 @@ class DescriptorMixin:
|
|||
if field_name in instance._deferred_fields:
|
||||
instance._deferred_fields.remove(field_name)
|
||||
was_deferred = True
|
||||
value = super(DescriptorMixin, self).__get__(instance, owner)
|
||||
value = super().__get__(instance, owner)
|
||||
if was_deferred:
|
||||
self.tracker_instance.saved_data[field_name] = deepcopy(value)
|
||||
return value
|
||||
|
|
@ -125,7 +123,7 @@ class FieldInstanceTracker:
|
|||
else:
|
||||
fields = self.fields
|
||||
|
||||
return dict((f, self.get_field_value(f)) for f in fields)
|
||||
return {f: self.get_field_value(f) for f in fields}
|
||||
|
||||
def has_changed(self, field):
|
||||
"""Returns ``True`` if field has changed from currently saved value"""
|
||||
|
|
@ -159,11 +157,11 @@ class FieldInstanceTracker:
|
|||
|
||||
def changed(self):
|
||||
"""Returns dict of fields that changed since save (with old values)"""
|
||||
return dict(
|
||||
(field, self.previous(field))
|
||||
return {
|
||||
field: self.previous(field)
|
||||
for field in self.fields
|
||||
if self.has_changed(field)
|
||||
)
|
||||
}
|
||||
|
||||
def init_deferred_fields(self):
|
||||
self.instance._deferred_fields = set()
|
||||
|
|
@ -199,10 +197,10 @@ class FieldTracker:
|
|||
|
||||
def get_field_map(self, cls):
|
||||
"""Returns dict mapping fields names to model attribute names"""
|
||||
field_map = dict((field, field) for field in self.fields)
|
||||
all_fields = dict((f.name, f.attname) for f in cls._meta.fields)
|
||||
field_map.update(**dict((k, v) for (k, v) in all_fields.items()
|
||||
if k in field_map))
|
||||
field_map = {field: field for field in self.fields}
|
||||
all_fields = {f.name: f.attname for f in cls._meta.fields}
|
||||
field_map.update(**{k: v for (k, v) in all_fields.items()
|
||||
if k in field_map})
|
||||
return field_map
|
||||
|
||||
def contribute_to_class(self, cls, name):
|
||||
|
|
@ -280,11 +278,11 @@ class ModelInstanceTracker(FieldInstanceTracker):
|
|||
return {}
|
||||
saved = self.saved_data.items()
|
||||
current = self.current()
|
||||
return dict((k, v) for k, v in saved if v != current[k])
|
||||
return {k: v for k, v in saved if v != current[k]}
|
||||
|
||||
|
||||
class ModelTracker(FieldTracker):
|
||||
tracker_class = ModelInstanceTracker
|
||||
|
||||
def get_field_map(self, cls):
|
||||
return dict((field, field) for field in self.fields)
|
||||
return {field: field for field in self.fields}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
pytest==4.5.0
|
||||
pytest-django==3.4.7
|
||||
psycopg2==2.7.6.1
|
||||
psycopg2-binary==2.8.4
|
||||
pytest-cov==2.7.1
|
||||
|
|
|
|||
5
setup.py
5
setup.py
|
|
@ -42,11 +42,12 @@ setup(
|
|||
'Operating System :: OS Independent',
|
||||
'Programming Language :: Python',
|
||||
'Programming Language :: Python :: 3',
|
||||
'Programming Language :: Python :: 3.7',
|
||||
'Programming Language :: Python :: 3.6',
|
||||
'Programming Language :: Python :: 3.7',
|
||||
'Programming Language :: Python :: 3.8',
|
||||
'Framework :: Django',
|
||||
'Framework :: Django :: 2.1',
|
||||
'Framework :: Django :: 1.11',
|
||||
'Framework :: Django :: 2.1',
|
||||
'Framework :: Django :: 2.2',
|
||||
],
|
||||
zip_safe=False,
|
||||
|
|
|
|||
|
|
@ -1,13 +1,12 @@
|
|||
import django
|
||||
from django.db import models
|
||||
from django.utils.six import with_metaclass, string_types
|
||||
|
||||
|
||||
def mutable_from_db(value):
|
||||
if value == '':
|
||||
return None
|
||||
try:
|
||||
if isinstance(value, string_types):
|
||||
if isinstance(value, (str,)):
|
||||
return [int(i) for i in value.split(',')]
|
||||
except ValueError:
|
||||
pass
|
||||
|
|
@ -18,7 +17,7 @@ def mutable_to_db(value):
|
|||
if value is None:
|
||||
return ''
|
||||
if isinstance(value, list):
|
||||
value = ','.join((str(i) for i in value))
|
||||
value = ','.join(str(i) for i in value)
|
||||
return str(value)
|
||||
|
||||
|
||||
|
|
@ -30,5 +29,5 @@ class MutableField(models.TextField):
|
|||
return mutable_from_db(value)
|
||||
|
||||
def get_db_prep_save(self, value, connection):
|
||||
value = super(MutableField, self).get_db_prep_save(value, connection)
|
||||
value = super().get_db_prep_save(value, connection)
|
||||
return mutable_to_db(value)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
from __future__ import unicode_literals, absolute_import
|
||||
|
||||
from model_utils.managers import SoftDeletableQuerySet, SoftDeletableManager
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
from __future__ import unicode_literals, absolute_import
|
||||
|
||||
import django
|
||||
from django.db import models
|
||||
from django.db.models.query_utils import DeferredAttribute
|
||||
|
|
@ -48,7 +46,7 @@ class InheritanceManagerTestParent(models.Model):
|
|||
objects = InheritanceManager()
|
||||
|
||||
def __str__(self):
|
||||
return "%s(%s)" % (
|
||||
return "{}({})".format(
|
||||
self.__class__.__name__[len('InheritanceManagerTest'):],
|
||||
self.pk,
|
||||
)
|
||||
|
|
@ -246,7 +244,7 @@ class Tracked(models.Model):
|
|||
|
||||
def save(self, *args, **kwargs):
|
||||
""" No-op save() to ensure that FieldTracker.patch_save() works. """
|
||||
super(Tracked, self).save(*args, **kwargs)
|
||||
super().save(*args, **kwargs)
|
||||
|
||||
|
||||
class TrackedFK(models.Model):
|
||||
|
|
@ -399,7 +397,7 @@ class StringyDescriptor:
|
|||
|
||||
class CustomDescriptorField(models.IntegerField):
|
||||
def contribute_to_class(self, cls, name, **kwargs):
|
||||
super(CustomDescriptorField, self).contribute_to_class(cls, name, **kwargs)
|
||||
super().contribute_to_class(cls, name, **kwargs)
|
||||
setattr(cls, name, StringyDescriptor(name))
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
from django.test import TestCase
|
||||
|
||||
from model_utils import Choices
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
from __future__ import unicode_literals
|
||||
from unittest import skip
|
||||
import django
|
||||
from django.core.exceptions import FieldError
|
||||
|
|
@ -414,7 +413,7 @@ class FieldTrackedModelMultiTests(FieldTrackerTestCase,
|
|||
def test_pre_save_previous(self):
|
||||
for tracker in self.trackers:
|
||||
self.tracker = tracker
|
||||
super(FieldTrackedModelMultiTests, self).test_pre_save_previous()
|
||||
super().test_pre_save_previous()
|
||||
|
||||
def test_post_save_has_changed(self):
|
||||
self.update_instance(name='retro', number=4)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
from datetime import datetime
|
||||
|
||||
from freezegun import freeze_time
|
||||
|
|
|
|||
|
|
@ -1,6 +1,3 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
from django.utils.six import text_type
|
||||
from django.test import TestCase
|
||||
|
||||
from tests.models import Article, SplitFieldAbstractParent
|
||||
|
|
@ -15,7 +12,7 @@ class SplitFieldTests(TestCase):
|
|||
title='example post', body=self.full_text)
|
||||
|
||||
def test_unicode_content(self):
|
||||
self.assertEqual(text_type(self.post.body), self.full_text)
|
||||
self.assertEqual(str(self.post.body), self.full_text)
|
||||
|
||||
def test_excerpt(self):
|
||||
self.assertEqual(self.post.body.excerpt, self.excerpt)
|
||||
|
|
@ -40,13 +37,13 @@ class SplitFieldTests(TestCase):
|
|||
new_text = 'different\n\n<!-- split -->\n\nother'
|
||||
self.post.body = new_text
|
||||
self.post.save()
|
||||
self.assertEqual(text_type(self.post.body), new_text)
|
||||
self.assertEqual(str(self.post.body), new_text)
|
||||
|
||||
def test_assign_to_content(self):
|
||||
new_text = 'different\n\n<!-- split -->\n\nother'
|
||||
self.post.body.content = new_text
|
||||
self.post.save()
|
||||
self.assertEqual(text_type(self.post.body), new_text)
|
||||
self.assertEqual(str(self.post.body), new_text)
|
||||
|
||||
def test_assign_to_excerpt(self):
|
||||
with self.assertRaises(AttributeError):
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
from django.test import TestCase
|
||||
|
||||
from model_utils.fields import StatusField
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
import uuid
|
||||
|
||||
from django.core.exceptions import ValidationError
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
from unittest import skipIf
|
||||
|
||||
import django
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
from unittest import skipUnless
|
||||
|
||||
import django
|
||||
|
|
@ -27,16 +25,16 @@ class InheritanceManagerTests(TestCase):
|
|||
return InheritanceManagerTestParent.objects
|
||||
|
||||
def test_normal(self):
|
||||
children = set([
|
||||
children = {
|
||||
InheritanceManagerTestParent(pk=self.child1.pk),
|
||||
InheritanceManagerTestParent(pk=self.child2.pk),
|
||||
InheritanceManagerTestParent(pk=self.grandchild1.pk),
|
||||
InheritanceManagerTestParent(pk=self.grandchild1_2.pk),
|
||||
])
|
||||
}
|
||||
self.assertEqual(set(self.get_manager().all()), children)
|
||||
|
||||
def test_select_all_subclasses(self):
|
||||
children = set([self.child1, self.child2])
|
||||
children = {self.child1, self.child2}
|
||||
children.add(self.grandchild1)
|
||||
children.add(self.grandchild1_2)
|
||||
self.assertEqual(
|
||||
|
|
@ -53,12 +51,12 @@ class InheritanceManagerTests(TestCase):
|
|||
self.get_manager().select_subclasses('user')
|
||||
|
||||
def test_select_specific_subclasses(self):
|
||||
children = set([
|
||||
children = {
|
||||
self.child1,
|
||||
InheritanceManagerTestParent(pk=self.child2.pk),
|
||||
InheritanceManagerTestChild1(pk=self.grandchild1.pk),
|
||||
InheritanceManagerTestChild1(pk=self.grandchild1_2.pk),
|
||||
])
|
||||
}
|
||||
self.assertEqual(
|
||||
set(
|
||||
self.get_manager().select_subclasses(
|
||||
|
|
@ -68,12 +66,12 @@ class InheritanceManagerTests(TestCase):
|
|||
)
|
||||
|
||||
def test_select_specific_grandchildren(self):
|
||||
children = set([
|
||||
children = {
|
||||
InheritanceManagerTestParent(pk=self.child1.pk),
|
||||
InheritanceManagerTestParent(pk=self.child2.pk),
|
||||
self.grandchild1,
|
||||
InheritanceManagerTestParent(pk=self.grandchild1_2.pk),
|
||||
])
|
||||
}
|
||||
self.assertEqual(
|
||||
set(
|
||||
self.get_manager().select_subclasses(
|
||||
|
|
@ -84,12 +82,12 @@ class InheritanceManagerTests(TestCase):
|
|||
)
|
||||
|
||||
def test_children_and_grandchildren(self):
|
||||
children = set([
|
||||
children = {
|
||||
self.child1,
|
||||
InheritanceManagerTestParent(pk=self.child2.pk),
|
||||
self.grandchild1,
|
||||
InheritanceManagerTestChild1(pk=self.grandchild1_2.pk),
|
||||
])
|
||||
}
|
||||
self.assertEqual(
|
||||
set(
|
||||
self.get_manager().select_subclasses(
|
||||
|
|
@ -463,14 +461,14 @@ class InheritanceManagerUsingModelsTests(TestCase):
|
|||
|
||||
results = InheritanceManagerTestParent.objects.instance_of(InheritanceManagerTestChild3, InheritanceManagerTestGrandChild1).select_subclasses()
|
||||
|
||||
self.assertEqual(set([child3, grandchild1]), set(results))
|
||||
self.assertEqual({child3, grandchild1}, set(results))
|
||||
|
||||
def test_select_subclasses_interaction_with_instance_of(self):
|
||||
child3 = InheritanceManagerTestChild3.objects.create()
|
||||
|
||||
results = InheritanceManagerTestParent.objects.select_subclasses(InheritanceManagerTestChild1).instance_of(InheritanceManagerTestChild3)
|
||||
|
||||
self.assertEqual(set([child3]), set(results))
|
||||
self.assertEqual({child3}, set(results))
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
from django.test import TestCase
|
||||
|
||||
from tests.models import JoinItemForeignKey, BoxJoinModel
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
from django.test import TestCase
|
||||
|
||||
from tests.models import Post
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
from django.test import TestCase
|
||||
|
||||
from tests.models import CustomSoftDelete
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
from django.test import TestCase
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
from django.core.management import call_command
|
||||
from django.test import TestCase
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
import django
|
||||
from django.test import TestCase
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
from django.test import TestCase
|
||||
|
||||
from tests.models import SaveSignalHandlingTestModel
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
from django.db.utils import ConnectionDoesNotExist
|
||||
from django.test import TestCase
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
from django.db import models
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
from freezegun import freeze_time
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
from django.test import TestCase
|
||||
|
||||
from tests.models import CustomUUIDModel, CustomNotPrimaryUUIDModel
|
||||
|
|
|
|||
7
tox.ini
7
tox.ini
|
|
@ -2,13 +2,14 @@
|
|||
envlist =
|
||||
py37-django{202,201}
|
||||
py36-django{111,202,201,trunk}
|
||||
py38-django{202,201,trunk}
|
||||
flake8
|
||||
|
||||
[testenv]
|
||||
deps =
|
||||
django111: Django>=1.11,<1.12
|
||||
django202: Django>=2.2,<3.0
|
||||
django201: Django>=2.1,<2.2
|
||||
django111: Django==1.11.*
|
||||
django202: Django==2.2.*
|
||||
django201: Django==2.1.*
|
||||
djangotrunk: https://github.com/django/django/archive/master.tar.gz
|
||||
freezegun == 0.3.8
|
||||
-rrequirements-test.txt
|
||||
|
|
|
|||
Loading…
Reference in a new issue