Fix compatibility with Django 3.0 alpha

Removed django.utils.six dependency, copied the parts we still need for
Python 2 compatibility.
fix_request_path_info
Diederik van der Boor 2019-07-12 17:38:49 +02:00
parent 7a315f7c17
commit 8fb8f47fb0
No known key found for this signature in database
GPG Key ID: 4FA014E0305E73C1
10 changed files with 71 additions and 26 deletions

View File

@ -5,7 +5,6 @@ import inspect
from django.contrib import admin from django.contrib import admin
from django.urls import resolve from django.urls import resolve
from django.utils import six
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from polymorphic.utils import get_base_polymorphic_model from polymorphic.utils import get_base_polymorphic_model
@ -216,7 +215,7 @@ class PolymorphicChildModelAdmin(admin.ModelAdmin):
# By not declaring the fields/form in the base class, # By not declaring the fields/form in the base class,
# get_form() will populate the form with all available fields. # get_form() will populate the form with all available fields.
form = self.get_form(request, obj, exclude=exclude) form = self.get_form(request, obj, exclude=exclude)
subclass_fields = list(six.iterkeys(form.base_fields)) + list(self.get_readonly_fields(request, obj)) subclass_fields = list(form.base_fields.keys()) + list(self.get_readonly_fields(request, obj))
# Find which fields are not part of the common fields. # Find which fields are not part of the common fields.
for fieldset in self.get_base_fieldsets(request, obj): for fieldset in self.get_base_fieldsets(request, obj):

View File

@ -0,0 +1,44 @@
"""Compatibility with Python 2 (taken from 'django.utils.six')"""
import sys
PY2 = sys.version_info[0] == 2
PY3 = sys.version_info[0] == 3
if PY3:
string_types = str,
integer_types = int,
class_types = type,
text_type = str
binary_type = bytes
MAXSIZE = sys.maxsize
else:
string_types = basestring,
integer_types = (int, long)
def with_metaclass(meta, *bases):
class metaclass(type):
def __new__(cls, name, this_bases, d):
return meta(name, bases, d)
return type.__new__(metaclass, 'temporary_class', (), {})
def python_2_unicode_compatible(klass):
"""
A decorator that defines __unicode__ and __str__ methods under Python 2.
Under Python 3 it does nothing.
To support Python 2 and 3 with a single code base, define a __str__ method
returning text and apply this decorator to the class.
"""
if PY2:
if '__str__' not in klass.__dict__:
raise ValueError("@python_2_unicode_compatible cannot be applied "
"to %s because it doesn't define __str__()." %
klass.__name__)
klass.__unicode__ = klass.__str__
klass.__str__ = lambda self: self.__unicode__().encode('utf-8')
return klass

View File

@ -5,7 +5,7 @@ The manager class for use in the models.
from __future__ import unicode_literals from __future__ import unicode_literals
from django.db import models from django.db import models
from django.utils.six import python_2_unicode_compatible from polymorphic.compat import python_2_unicode_compatible
from polymorphic.query import PolymorphicQuerySet from polymorphic.query import PolymorphicQuerySet

View File

@ -8,8 +8,8 @@ from django.contrib.contenttypes.models import ContentType
from django.db import models from django.db import models
from django.db.models.fields.related import ReverseOneToOneDescriptor, ForwardManyToOneDescriptor from django.db.models.fields.related import ReverseOneToOneDescriptor, ForwardManyToOneDescriptor
from django.db.utils import DEFAULT_DB_ALIAS from django.db.utils import DEFAULT_DB_ALIAS
from django.utils import six
from polymorphic.compat import with_metaclass
from .base import PolymorphicModelBase from .base import PolymorphicModelBase
from .managers import PolymorphicManager from .managers import PolymorphicManager
from .query_translate import translate_polymorphic_Q_object from .query_translate import translate_polymorphic_Q_object
@ -26,7 +26,7 @@ class PolymorphicTypeInvalid(RuntimeError):
pass pass
class PolymorphicModel(six.with_metaclass(PolymorphicModelBase, models.Model)): class PolymorphicModel(with_metaclass(PolymorphicModelBase, models.Model)):
""" """
Abstract base class that provides polymorphic behaviour Abstract base class that provides polymorphic behaviour
for any model directly or indirectly derived from it. for any model directly or indirectly derived from it.

View File

@ -10,8 +10,8 @@ from collections import defaultdict
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from django.db.models import FieldDoesNotExist from django.db.models import FieldDoesNotExist
from django.db.models.query import ModelIterable, Q, QuerySet from django.db.models.query import ModelIterable, Q, QuerySet
from django.utils import six
from . import compat
from .query_translate import translate_polymorphic_filter_definitions_in_kwargs, translate_polymorphic_filter_definitions_in_args from .query_translate import translate_polymorphic_filter_definitions_in_kwargs, translate_polymorphic_filter_definitions_in_args
from .query_translate import translate_polymorphic_field_path, translate_polymorphic_Q_object from .query_translate import translate_polymorphic_field_path, translate_polymorphic_Q_object
@ -162,7 +162,7 @@ class PolymorphicQuerySet(QuerySet):
"""translate the field paths in the args, then call vanilla order_by.""" """translate the field paths in the args, then call vanilla order_by."""
field_names = [ field_names = [
translate_polymorphic_field_path(self.model, a) translate_polymorphic_field_path(self.model, a)
if isinstance(a, six.string_types) else a # allow expressions to pass unchanged if isinstance(a, compat.string_types) else a # allow expressions to pass unchanged
for a in field_names for a in field_names
] ]
return super(PolymorphicQuerySet, self).order_by(*field_names) return super(PolymorphicQuerySet, self).order_by(*field_names)
@ -267,7 +267,7 @@ class PolymorphicQuerySet(QuerySet):
for a in args: for a in args:
test___lookup(a) test___lookup(a)
for a in six.itervalues(kwargs): for a in kwargs.values():
patch_lookup(a) patch_lookup(a)
def annotate(self, *args, **kwargs): def annotate(self, *args, **kwargs):
@ -430,12 +430,12 @@ class PolymorphicQuerySet(QuerySet):
real_object = transmogrify(real_class, real_object) real_object = transmogrify(real_class, real_object)
if self.query.annotations: if self.query.annotations:
for anno_field_name in six.iterkeys(self.query.annotations): for anno_field_name in self.query.annotations.keys():
attr = getattr(base_object, anno_field_name) attr = getattr(base_object, anno_field_name)
setattr(real_object, anno_field_name, attr) setattr(real_object, anno_field_name, attr)
if self.query.extra_select: if self.query.extra_select:
for select_field_name in six.iterkeys(self.query.extra_select): for select_field_name in self.query.extra_select.keys():
attr = getattr(base_object, select_field_name) attr = getattr(base_object, select_field_name)
setattr(real_object, select_field_name, attr) setattr(real_object, select_field_name, attr)
@ -445,13 +445,13 @@ class PolymorphicQuerySet(QuerySet):
# set polymorphic_annotate_names in all objects (currently just used for debugging/printing) # set polymorphic_annotate_names in all objects (currently just used for debugging/printing)
if self.query.annotations: if self.query.annotations:
annotate_names = list(six.iterkeys(self.query.annotations)) # get annotate field list annotate_names = list(self.query.annotations.keys()) # get annotate field list
for real_object in resultlist: for real_object in resultlist:
real_object.polymorphic_annotate_names = annotate_names real_object.polymorphic_annotate_names = annotate_names
# set polymorphic_extra_select_names in all objects (currently just used for debugging/printing) # set polymorphic_extra_select_names in all objects (currently just used for debugging/printing)
if self.query.extra_select: if self.query.extra_select:
extra_select_names = list(six.iterkeys(self.query.extra_select)) # get extra select field list extra_select_names = list(self.query.extra_select.keys()) # get extra select field list
for real_object in resultlist: for real_object in resultlist:
real_object.polymorphic_extra_select_names = extra_select_names real_object.polymorphic_extra_select_names = extra_select_names

View File

@ -14,7 +14,6 @@ from django.db import models
from django.db.models import Q from django.db.models import Q
from django.db.models.fields.related import ForeignObjectRel, RelatedField from django.db.models.fields.related import ForeignObjectRel, RelatedField
from django.db.utils import DEFAULT_DB_ALIAS from django.db.utils import DEFAULT_DB_ALIAS
from django.utils import six
################################################################################### ###################################################################################
@ -24,6 +23,8 @@ from django.utils import six
# They form a kind of small framework for easily adding more # They form a kind of small framework for easily adding more
# functionality to filters and Q objects. # functionality to filters and Q objects.
# Probably a more general queryset enhancement class could be made out of them. # Probably a more general queryset enhancement class could be made out of them.
from polymorphic import compat
def translate_polymorphic_filter_definitions_in_kwargs(queryset_model, kwargs, using=DEFAULT_DB_ALIAS): def translate_polymorphic_filter_definitions_in_kwargs(queryset_model, kwargs, using=DEFAULT_DB_ALIAS):
""" """
@ -129,7 +130,7 @@ def translate_polymorphic_field_path(queryset_model, field_path):
into modela__modelb__modelc__field3. into modela__modelb__modelc__field3.
Returns: translated path (unchanged, if no translation needed) Returns: translated path (unchanged, if no translation needed)
""" """
if not isinstance(field_path, six.string_types): if not isinstance(field_path, compat.string_types):
raise ValueError("Expected field name as string: {0}".format(field_path)) raise ValueError("Expected field name as string: {0}".format(field_path))
classname, sep, pure_field_path = field_path.partition('___') classname, sep, pure_field_path = field_path.partition('___')

View File

@ -2,8 +2,9 @@
import re import re
from django.db import models from django.db import models
from django.utils import six
from django.utils.six import python_2_unicode_compatible from . import compat
from .compat import python_2_unicode_compatible
RE_DEFERRED = re.compile('_Deferred_.*') RE_DEFERRED = re.compile('_Deferred_.*')
@ -41,7 +42,7 @@ class ShowFieldBase(object):
out += content.__class__.__name__ out += content.__class__.__name__
elif issubclass(field_type, models.ManyToManyField): elif issubclass(field_type, models.ManyToManyField):
out += '%d' % content.count() out += '%d' % content.count()
elif isinstance(content, six.integer_types): elif isinstance(content, compat.integer_types):
out += str(content) out += str(content)
elif content is None: elif content is None:
out += 'None' out += 'None'

View File

@ -1,5 +1,5 @@
from django.template import Library, Node, TemplateSyntaxError from django.template import Library, Node, TemplateSyntaxError
from django.utils import six from polymorphic import compat
register = Library() register = Library()
@ -32,7 +32,7 @@ class BreadcrumbScope(Node):
# Instead, have an assignment tag that inserts that in the template. # Instead, have an assignment tag that inserts that in the template.
base_opts = self.base_opts.resolve(context) base_opts = self.base_opts.resolve(context)
new_vars = {} new_vars = {}
if base_opts and not isinstance(base_opts, six.string_types): if base_opts and not isinstance(base_opts, compat.string_types):
new_vars = { new_vars = {
'app_label': base_opts.app_label, # What this is all about 'app_label': base_opts.app_label, # What this is all about
'opts': base_opts, 'opts': base_opts,

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import django
import uuid import uuid
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
@ -201,6 +201,7 @@ class MROBase3(models.Model):
class MRODerived(MROBase2, MROBase3): class MRODerived(MROBase2, MROBase3):
if django.VERSION < (3, 0):
class Meta: class Meta:
manager_inheritance_from_future = True manager_inheritance_from_future = True

View File

@ -5,9 +5,8 @@ from django.contrib.contenttypes.models import ContentType
from django.db import models from django.db import models
from django.db.models import Case, Count, Q, When from django.db.models import Case, Count, Q, When
from django.test import TransactionTestCase from django.test import TransactionTestCase
from django.utils import six
from polymorphic import query_translate from polymorphic import compat, query_translate
from polymorphic.managers import PolymorphicManager from polymorphic.managers import PolymorphicManager
from polymorphic.models import PolymorphicTypeInvalid, PolymorphicTypeUndefined from polymorphic.models import PolymorphicTypeInvalid, PolymorphicTypeUndefined
from polymorphic.tests.models import ( from polymorphic.tests.models import (
@ -566,7 +565,7 @@ class PolymorphicTests(TransactionTestCase):
select={"topic": "tests_modelextraexternal.topic"}, select={"topic": "tests_modelextraexternal.topic"},
where=["tests_modelextraa.id = tests_modelextraexternal.id"], where=["tests_modelextraa.id = tests_modelextraexternal.id"],
) )
if six.PY3: if compat.PY3:
self.assertEqual(repr(objects[0]), '<ModelExtraA: id 1, field1 (CharField) "A1" - Extra: topic (str) "extra1">') self.assertEqual(repr(objects[0]), '<ModelExtraA: id 1, field1 (CharField) "A1" - Extra: topic (str) "extra1">')
self.assertEqual(repr(objects[1]), '<ModelExtraB: id 2, field1 (CharField) "B1", field2 (CharField) "B2" - Extra: topic (str) "extra2">') self.assertEqual(repr(objects[1]), '<ModelExtraB: id 2, field1 (CharField) "B1", field2 (CharField) "B2" - Extra: topic (str) "extra2">')
self.assertEqual(repr(objects[2]), '<ModelExtraC: id 3, field1 (CharField) "C1", field2 (CharField) "C2", field3 (CharField) "C3" - Extra: topic (str) "extra3">') self.assertEqual(repr(objects[2]), '<ModelExtraC: id 3, field1 (CharField) "C1", field2 (CharField) "C2", field3 (CharField) "C3" - Extra: topic (str) "extra3">')