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
Diederik van der Boor 2013-04-08 01:04:00 +02:00
parent cbf52a61af
commit 4d7d33ed0d
6 changed files with 40 additions and 20 deletions

View File

@ -2,6 +2,7 @@ language: python
python:
- "2.6"
- "2.7"
- "3.3"
env:
- DJANGO=django==1.4.5
- DJANGO=django==1.5

View File

@ -54,6 +54,13 @@ class PolymorphicModelBase(ModelBase):
def __new__(self, model_name, bases, attrs):
#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
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.
# 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.
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
@classmethod
@ -178,9 +185,8 @@ class PolymorphicModelBase(ModelBase):
# which is directly in the python path. To work around this we temporarily set
# app_label here for PolymorphicModel.
meta = attrs.get('Meta', None)
model_module_name = attrs['__module__']
do_app_label_workaround = (meta
and model_module_name == 'polymorphic'
and attrs['__module__'] == 'polymorphic'
and model_name == 'PolymorphicModel'
and getattr(meta, 'app_label', None) is None)

View File

@ -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.
"""
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)

View File

@ -2,6 +2,7 @@
""" Test Cases
Please see README.rst or DOCS.rst or http://chrisglass.github.com/django_polymorphic/
"""
from __future__ import print_function
import uuid
import re
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 import models
from django.contrib.contenttypes.models import ContentType
from django.utils import six
from polymorphic import PolymorphicModel, PolymorphicManager, PolymorphicQuerySet
from polymorphic import ShowFieldContent, ShowFieldType, ShowFieldTypeAndContent
@ -253,10 +255,10 @@ class PolymorphicTests(TestCase):
o2 = DiamondXY.objects.get()
if o2.field_b != 'b':
print
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 2: field_b "{0}", field_x "{1}", field_y "{2}"'.format(o2.field_b, o2.field_x, o2.field_y)
print('')
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 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):
@ -363,16 +365,16 @@ class PolymorphicTests(TestCase):
<UUIDResearchProject: uuid_primary_key (UUIDField/pk), topic (CharField) "Swallow Aerodynamics", supervisor (CharField) "Dr. Winter"> ]"""
self.assertEqual(res, res_exp)
#if (a.pk!= uuid.UUID or c.pk!= uuid.UUID):
# print
# print '# known inconstency with custom primary key field detected (django problem?)'
# print()
# print('# known inconstency with custom primary key field detected (django problem?)')
a = UUIDPlainA.objects.create(field1='A1')
b = UUIDPlainB.objects.create(field1='B1', field2='B2')
c = UUIDPlainC.objects.create(field1='C1', field2='C2', field3='C3')
qs = UUIDPlainA.objects.all()
if a.pk!= uuid.UUID or c.pk!= uuid.UUID:
print
print '# known type inconstency with custom primary key field detected (django problem?)'
print('')
print('# known type inconstency with custom primary key field detected (django problem?)')
def create_model2abcd(self):
@ -531,9 +533,14 @@ class PolymorphicTests(TestCase):
ModelExtraExternal.objects.create(topic='extra2')
ModelExtraExternal.objects.create(topic='extra3')
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">')
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">')
if six.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">')
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)

View File

@ -6,7 +6,7 @@ import uuid
from django import forms
from django.db import models
from django.utils.encoding import smart_unicode
from django.utils.encoding import smart_text
from django.utils import six
class UUIDVersionError(Exception):
@ -98,7 +98,7 @@ class UUIDField(six.with_metaclass(models.SubfieldBase, models.CharField)):
if isinstance(value, uuid.UUID):
return value
# 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
@ -108,7 +108,7 @@ class UUIDField(six.with_metaclass(models.SubfieldBase, models.CharField)):
#if not value:
# return None
#if isinstance(value, uuid.UUID):
# return smart_unicode(value)
# return smart_text(value)
#else:
# return value
@ -126,7 +126,7 @@ class UUIDField(six.with_metaclass(models.SubfieldBase, models.CharField)):
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"""
if isinstance(value, uuid.UUID):
return smart_unicode(value)
return smart_text(value)
return value
def value_to_string(self, obj):
@ -134,7 +134,7 @@ class UUIDField(six.with_metaclass(models.SubfieldBase, models.CharField)):
if val is None:
data = ''
else:
data = smart_unicode(val)
data = smart_text(val)
return data
def formfield(self, **kwargs):

View File

@ -1,5 +1,6 @@
[tox]
envlist=
py33-django15,
py26-django15,
py27-django15,
py26-django14,
@ -31,3 +32,8 @@ basepython=python2.7
deps=
django==1.4.5
[testenv:py33-django15]
basepython=python3.3
deps=
django==1.5