Port new code to Python 3 as well, fix six.with_metaclass() issues
Many thanks to @atheiste for the big porting steps!fix_request_path_info
parent
cbf52a61af
commit
4d7d33ed0d
|
|
@ -2,6 +2,7 @@ language: python
|
||||||
python:
|
python:
|
||||||
- "2.6"
|
- "2.6"
|
||||||
- "2.7"
|
- "2.7"
|
||||||
|
- "3.3"
|
||||||
env:
|
env:
|
||||||
- DJANGO=django==1.4.5
|
- DJANGO=django==1.4.5
|
||||||
- DJANGO=django==1.5
|
- DJANGO=django==1.5
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,13 @@ class PolymorphicModelBase(ModelBase):
|
||||||
def __new__(self, model_name, bases, attrs):
|
def __new__(self, model_name, bases, attrs):
|
||||||
#print; print '###', model_name, '- bases:', bases
|
#print; print '###', model_name, '- bases:', bases
|
||||||
|
|
||||||
|
# Workaround compatibility issue with six.with_metaclass() and custom Django model metaclasses:
|
||||||
|
# Let Django fully ignore the class which is inserted in between.
|
||||||
|
if not attrs and model_name == 'NewBase':
|
||||||
|
attrs['__module__'] = 'django.utils.six'
|
||||||
|
attrs['Meta'] = type('Meta', (), {'abstract': True})
|
||||||
|
return super(PolymorphicModelBase, self).__new__(self, model_name, bases, attrs)
|
||||||
|
|
||||||
# create new model
|
# create new model
|
||||||
new_class = self.call_superclass_new_method(model_name, bases, attrs)
|
new_class = self.call_superclass_new_method(model_name, bases, attrs)
|
||||||
|
|
||||||
|
|
@ -145,7 +152,7 @@ class PolymorphicModelBase(ModelBase):
|
||||||
# The ordering in the base.__dict__ may randomly change depending on which method is added.
|
# The ordering in the base.__dict__ may randomly change depending on which method is added.
|
||||||
# Make sure base_objects is on top, and 'objects' and '_default_manager' follow afterwards.
|
# Make sure base_objects is on top, and 'objects' and '_default_manager' follow afterwards.
|
||||||
# This makes sure that the _base_manager is also assigned properly.
|
# This makes sure that the _base_manager is also assigned properly.
|
||||||
add_managers = sorted(add_managers, key=lambda item: item[2].creation_counter, reverse=True)
|
add_managers = sorted(add_managers, key=lambda item: (item[1].startswith('_'), item[1]))
|
||||||
return add_managers
|
return add_managers
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
|
@ -178,9 +185,8 @@ class PolymorphicModelBase(ModelBase):
|
||||||
# which is directly in the python path. To work around this we temporarily set
|
# which is directly in the python path. To work around this we temporarily set
|
||||||
# app_label here for PolymorphicModel.
|
# app_label here for PolymorphicModel.
|
||||||
meta = attrs.get('Meta', None)
|
meta = attrs.get('Meta', None)
|
||||||
model_module_name = attrs['__module__']
|
|
||||||
do_app_label_workaround = (meta
|
do_app_label_workaround = (meta
|
||||||
and model_module_name == 'polymorphic'
|
and attrs['__module__'] == 'polymorphic'
|
||||||
and model_name == 'PolymorphicModel'
|
and model_name == 'PolymorphicModel'
|
||||||
and getattr(meta, 'app_label', None) is None)
|
and getattr(meta, 'app_label', None) is None)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ def translate_polymorphic_filter_definitions_in_kwargs(queryset_model, kwargs):
|
||||||
Returns: a list of non-keyword-arguments (Q objects) to be added to the filter() query.
|
Returns: a list of non-keyword-arguments (Q objects) to be added to the filter() query.
|
||||||
"""
|
"""
|
||||||
additional_args = []
|
additional_args = []
|
||||||
for field_path, val in kwargs.items():
|
for field_path, val in kwargs.copy().items(): # Python 3 needs copy
|
||||||
|
|
||||||
new_expr = _translate_polymorphic_filter_definition(queryset_model, field_path, val)
|
new_expr = _translate_polymorphic_filter_definition(queryset_model, field_path, val)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
""" Test Cases
|
""" Test Cases
|
||||||
Please see README.rst or DOCS.rst or http://chrisglass.github.com/django_polymorphic/
|
Please see README.rst or DOCS.rst or http://chrisglass.github.com/django_polymorphic/
|
||||||
"""
|
"""
|
||||||
|
from __future__ import print_function
|
||||||
import uuid
|
import uuid
|
||||||
import re
|
import re
|
||||||
from django.db.models.query import QuerySet
|
from django.db.models.query import QuerySet
|
||||||
|
|
@ -10,6 +11,7 @@ from django.test import TestCase
|
||||||
from django.db.models import Q,Count
|
from django.db.models import Q,Count
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
|
from django.utils import six
|
||||||
|
|
||||||
from polymorphic import PolymorphicModel, PolymorphicManager, PolymorphicQuerySet
|
from polymorphic import PolymorphicModel, PolymorphicManager, PolymorphicQuerySet
|
||||||
from polymorphic import ShowFieldContent, ShowFieldType, ShowFieldTypeAndContent
|
from polymorphic import ShowFieldContent, ShowFieldType, ShowFieldTypeAndContent
|
||||||
|
|
@ -253,10 +255,10 @@ class PolymorphicTests(TestCase):
|
||||||
o2 = DiamondXY.objects.get()
|
o2 = DiamondXY.objects.get()
|
||||||
|
|
||||||
if o2.field_b != 'b':
|
if o2.field_b != 'b':
|
||||||
print
|
print('')
|
||||||
print '# known django model inheritance diamond problem detected'
|
print('# known django model inheritance diamond problem detected')
|
||||||
print 'DiamondXY fields 1: field_b "{0}", field_x "{1}", field_y "{2}"'.format(o1.field_b, o1.field_x, o1.field_y)
|
print('DiamondXY fields 1: field_b "{0}", field_x "{1}", field_y "{2}"'.format(o1.field_b, o1.field_x, o1.field_y))
|
||||||
print 'DiamondXY fields 2: field_b "{0}", field_x "{1}", field_y "{2}"'.format(o2.field_b, o2.field_x, o2.field_y)
|
print('DiamondXY fields 2: field_b "{0}", field_x "{1}", field_y "{2}"'.format(o2.field_b, o2.field_x, o2.field_y))
|
||||||
|
|
||||||
|
|
||||||
def test_annotate_aggregate_order(self):
|
def test_annotate_aggregate_order(self):
|
||||||
|
|
@ -363,16 +365,16 @@ class PolymorphicTests(TestCase):
|
||||||
<UUIDResearchProject: uuid_primary_key (UUIDField/pk), topic (CharField) "Swallow Aerodynamics", supervisor (CharField) "Dr. Winter"> ]"""
|
<UUIDResearchProject: uuid_primary_key (UUIDField/pk), topic (CharField) "Swallow Aerodynamics", supervisor (CharField) "Dr. Winter"> ]"""
|
||||||
self.assertEqual(res, res_exp)
|
self.assertEqual(res, res_exp)
|
||||||
#if (a.pk!= uuid.UUID or c.pk!= uuid.UUID):
|
#if (a.pk!= uuid.UUID or c.pk!= uuid.UUID):
|
||||||
# print
|
# print()
|
||||||
# print '# known inconstency with custom primary key field detected (django problem?)'
|
# print('# known inconstency with custom primary key field detected (django problem?)')
|
||||||
|
|
||||||
a = UUIDPlainA.objects.create(field1='A1')
|
a = UUIDPlainA.objects.create(field1='A1')
|
||||||
b = UUIDPlainB.objects.create(field1='B1', field2='B2')
|
b = UUIDPlainB.objects.create(field1='B1', field2='B2')
|
||||||
c = UUIDPlainC.objects.create(field1='C1', field2='C2', field3='C3')
|
c = UUIDPlainC.objects.create(field1='C1', field2='C2', field3='C3')
|
||||||
qs = UUIDPlainA.objects.all()
|
qs = UUIDPlainA.objects.all()
|
||||||
if a.pk!= uuid.UUID or c.pk!= uuid.UUID:
|
if a.pk!= uuid.UUID or c.pk!= uuid.UUID:
|
||||||
print
|
print('')
|
||||||
print '# known type inconstency with custom primary key field detected (django problem?)'
|
print('# known type inconstency with custom primary key field detected (django problem?)')
|
||||||
|
|
||||||
|
|
||||||
def create_model2abcd(self):
|
def create_model2abcd(self):
|
||||||
|
|
@ -531,9 +533,14 @@ class PolymorphicTests(TestCase):
|
||||||
ModelExtraExternal.objects.create(topic='extra2')
|
ModelExtraExternal.objects.create(topic='extra2')
|
||||||
ModelExtraExternal.objects.create(topic='extra3')
|
ModelExtraExternal.objects.create(topic='extra3')
|
||||||
objects = ModelExtraA.objects.extra(tables=["polymorphic_modelextraexternal"], select={"topic":"polymorphic_modelextraexternal.topic"}, where=["polymorphic_modelextraa.id = polymorphic_modelextraexternal.id"])
|
objects = ModelExtraA.objects.extra(tables=["polymorphic_modelextraexternal"], select={"topic":"polymorphic_modelextraexternal.topic"}, where=["polymorphic_modelextraa.id = polymorphic_modelextraexternal.id"])
|
||||||
self.assertEqual(repr(objects[0]), '<ModelExtraA: id 1, field1 (CharField) "A1" - Extra: topic (unicode) "extra1">')
|
if six.PY3:
|
||||||
self.assertEqual(repr(objects[1]), '<ModelExtraB: id 2, field1 (CharField) "B1", field2 (CharField) "B2" - Extra: topic (unicode) "extra2">')
|
self.assertEqual(repr(objects[0]), '<ModelExtraA: id 1, field1 (CharField) "A1" - Extra: topic (str) "extra1">')
|
||||||
self.assertEqual(repr(objects[2]), '<ModelExtraC: id 3, field1 (CharField) "C1", field2 (CharField) "C2", field3 (CharField) "C3" - Extra: topic (unicode) "extra3">')
|
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">')
|
||||||
|
else:
|
||||||
|
self.assertEqual(repr(objects[0]), '<ModelExtraA: id 1, field1 (CharField) "A1" - Extra: topic (unicode) "extra1">')
|
||||||
|
self.assertEqual(repr(objects[1]), '<ModelExtraB: id 2, field1 (CharField) "B1", field2 (CharField) "B2" - Extra: topic (unicode) "extra2">')
|
||||||
|
self.assertEqual(repr(objects[2]), '<ModelExtraC: id 3, field1 (CharField) "C1", field2 (CharField) "C2", field3 (CharField) "C3" - Extra: topic (unicode) "extra3">')
|
||||||
self.assertEqual(len(objects), 3)
|
self.assertEqual(len(objects), 3)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ import uuid
|
||||||
|
|
||||||
from django import forms
|
from django import forms
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.utils.encoding import smart_unicode
|
from django.utils.encoding import smart_text
|
||||||
from django.utils import six
|
from django.utils import six
|
||||||
|
|
||||||
class UUIDVersionError(Exception):
|
class UUIDVersionError(Exception):
|
||||||
|
|
@ -98,7 +98,7 @@ class UUIDField(six.with_metaclass(models.SubfieldBase, models.CharField)):
|
||||||
if isinstance(value, uuid.UUID):
|
if isinstance(value, uuid.UUID):
|
||||||
return value
|
return value
|
||||||
# attempt to parse a UUID
|
# attempt to parse a UUID
|
||||||
return uuid.UUID(smart_unicode(value))
|
return uuid.UUID(smart_text(value))
|
||||||
|
|
||||||
#
|
#
|
||||||
# If I do the following (returning a String instead of a UUID
|
# If I do the following (returning a String instead of a UUID
|
||||||
|
|
@ -108,7 +108,7 @@ class UUIDField(six.with_metaclass(models.SubfieldBase, models.CharField)):
|
||||||
#if not value:
|
#if not value:
|
||||||
# return None
|
# return None
|
||||||
#if isinstance(value, uuid.UUID):
|
#if isinstance(value, uuid.UUID):
|
||||||
# return smart_unicode(value)
|
# return smart_text(value)
|
||||||
#else:
|
#else:
|
||||||
# return value
|
# return value
|
||||||
|
|
||||||
|
|
@ -126,7 +126,7 @@ class UUIDField(six.with_metaclass(models.SubfieldBase, models.CharField)):
|
||||||
def get_db_prep_value(self, value, connection, prepared):
|
def get_db_prep_value(self, value, connection, prepared):
|
||||||
"""Casts uuid.UUID values into the format expected by the back end for use in queries"""
|
"""Casts uuid.UUID values into the format expected by the back end for use in queries"""
|
||||||
if isinstance(value, uuid.UUID):
|
if isinstance(value, uuid.UUID):
|
||||||
return smart_unicode(value)
|
return smart_text(value)
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def value_to_string(self, obj):
|
def value_to_string(self, obj):
|
||||||
|
|
@ -134,7 +134,7 @@ class UUIDField(six.with_metaclass(models.SubfieldBase, models.CharField)):
|
||||||
if val is None:
|
if val is None:
|
||||||
data = ''
|
data = ''
|
||||||
else:
|
else:
|
||||||
data = smart_unicode(val)
|
data = smart_text(val)
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def formfield(self, **kwargs):
|
def formfield(self, **kwargs):
|
||||||
|
|
|
||||||
6
tox.ini
6
tox.ini
|
|
@ -1,5 +1,6 @@
|
||||||
[tox]
|
[tox]
|
||||||
envlist=
|
envlist=
|
||||||
|
py33-django15,
|
||||||
py26-django15,
|
py26-django15,
|
||||||
py27-django15,
|
py27-django15,
|
||||||
py26-django14,
|
py26-django14,
|
||||||
|
|
@ -31,3 +32,8 @@ basepython=python2.7
|
||||||
deps=
|
deps=
|
||||||
django==1.4.5
|
django==1.4.5
|
||||||
|
|
||||||
|
[testenv:py33-django15]
|
||||||
|
basepython=python3.3
|
||||||
|
deps=
|
||||||
|
django==1.5
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue