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.urls import resolve
from django.utils import six
from django.utils.translation import ugettext_lazy as _
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,
# get_form() will populate the form with all available fields.
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.
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 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

View File

@ -8,8 +8,8 @@ from django.contrib.contenttypes.models import ContentType
from django.db import models
from django.db.models.fields.related import ReverseOneToOneDescriptor, ForwardManyToOneDescriptor
from django.db.utils import DEFAULT_DB_ALIAS
from django.utils import six
from polymorphic.compat import with_metaclass
from .base import PolymorphicModelBase
from .managers import PolymorphicManager
from .query_translate import translate_polymorphic_Q_object
@ -26,7 +26,7 @@ class PolymorphicTypeInvalid(RuntimeError):
pass
class PolymorphicModel(six.with_metaclass(PolymorphicModelBase, models.Model)):
class PolymorphicModel(with_metaclass(PolymorphicModelBase, models.Model)):
"""
Abstract base class that provides polymorphic behaviour
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.db.models import FieldDoesNotExist
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_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."""
field_names = [
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
]
return super(PolymorphicQuerySet, self).order_by(*field_names)
@ -267,7 +267,7 @@ class PolymorphicQuerySet(QuerySet):
for a in args:
test___lookup(a)
for a in six.itervalues(kwargs):
for a in kwargs.values():
patch_lookup(a)
def annotate(self, *args, **kwargs):
@ -430,12 +430,12 @@ class PolymorphicQuerySet(QuerySet):
real_object = transmogrify(real_class, real_object)
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)
setattr(real_object, anno_field_name, attr)
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)
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)
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:
real_object.polymorphic_annotate_names = annotate_names
# set polymorphic_extra_select_names in all objects (currently just used for debugging/printing)
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:
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.fields.related import ForeignObjectRel, RelatedField
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
# functionality to filters and Q objects.
# 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):
"""
@ -129,7 +130,7 @@ def translate_polymorphic_field_path(queryset_model, field_path):
into modela__modelb__modelc__field3.
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))
classname, sep, pure_field_path = field_path.partition('___')

View File

@ -2,8 +2,9 @@
import re
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_.*')
@ -41,7 +42,7 @@ class ShowFieldBase(object):
out += content.__class__.__name__
elif issubclass(field_type, models.ManyToManyField):
out += '%d' % content.count()
elif isinstance(content, six.integer_types):
elif isinstance(content, compat.integer_types):
out += str(content)
elif content is None:
out += 'None'

View File

@ -1,5 +1,5 @@
from django.template import Library, Node, TemplateSyntaxError
from django.utils import six
from polymorphic import compat
register = Library()
@ -32,7 +32,7 @@ class BreadcrumbScope(Node):
# Instead, have an assignment tag that inserts that in the template.
base_opts = self.base_opts.resolve(context)
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 = {
'app_label': base_opts.app_label, # What this is all about
'opts': base_opts,

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
import django
import uuid
from django.contrib.contenttypes.models import ContentType
@ -201,6 +201,7 @@ class MROBase3(models.Model):
class MRODerived(MROBase2, MROBase3):
if django.VERSION < (3, 0):
class Meta:
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.models import Case, Count, Q, When
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.models import PolymorphicTypeInvalid, PolymorphicTypeUndefined
from polymorphic.tests.models import (
@ -566,7 +565,7 @@ class PolymorphicTests(TransactionTestCase):
select={"topic": "tests_modelextraexternal.topic"},
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[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">')