From d11d45aad969be313b9e046d0d42b179a3fb6906 Mon Sep 17 00:00:00 2001 From: Aymeric Augustin Date: Fri, 20 Jul 2012 21:20:42 +0200 Subject: [PATCH] [py3] Used six.with_metaclass wherever necessary. --- django/contrib/admin/options.py | 4 ++-- django/db/models/base.py | 18 ++++++++++++++---- django/forms/forms.py | 4 ++-- django/forms/models.py | 6 ++++-- django/forms/widgets.py | 4 ++-- 5 files changed, 24 insertions(+), 12 deletions(-) diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py index 40f6e2842c..c13a6bc5cc 100644 --- a/django/contrib/admin/options.py +++ b/django/contrib/admin/options.py @@ -24,6 +24,7 @@ from django.utils.decorators import method_decorator from django.utils.datastructures import SortedDict from django.utils.html import escape, escapejs from django.utils.safestring import mark_safe +from django.utils import six from django.utils.text import capfirst, get_text_list from django.utils.translation import ugettext as _ from django.utils.translation import ungettext @@ -57,9 +58,8 @@ FORMFIELD_FOR_DBFIELD_DEFAULTS = { csrf_protect_m = method_decorator(csrf_protect) -class BaseModelAdmin(object): +class BaseModelAdmin(six.with_metaclass(forms.MediaDefiningClass)): """Functionality common to both ModelAdmin and InlineAdmin.""" - __metaclass__ = forms.MediaDefiningClass raw_id_fields = () fields = None diff --git a/django/db/models/base.py b/django/db/models/base.py index 79af1cb34c..04ae4bc96d 100644 --- a/django/db/models/base.py +++ b/django/db/models/base.py @@ -24,6 +24,7 @@ from django.db.models.loading import register_models, get_model from django.utils.translation import ugettext_lazy as _ from django.utils.functional import curry from django.utils.encoding import smart_str, force_unicode +from django.utils import six from django.utils.text import get_text_list, capfirst @@ -275,8 +276,8 @@ class ModelState(object): # This impacts validation only; it has no effect on the actual save. self.adding = True -class Model(object): - __metaclass__ = ModelBase + +class ModelWithoutMeta(object): _deferred = False def __init__(self, *args, **kwargs): @@ -369,7 +370,7 @@ class Model(object): pass if kwargs: raise TypeError("'%s' is an invalid keyword argument for this function" % kwargs.keys()[0]) - super(Model, self).__init__() + super(ModelWithoutMeta, self).__init__() signals.post_init.send(sender=self.__class__, instance=self) def __repr__(self): @@ -401,7 +402,7 @@ class Model(object): only module-level classes can be pickled by the default path. """ if not self._deferred: - return super(Model, self).__reduce__() + return super(ModelWithoutMeta, self).__reduce__() data = self.__dict__ defers = [] for field in self._meta.fields: @@ -876,6 +877,15 @@ class Model(object): raise ValidationError(errors) +# For unknown reasons, six.with_metaclass doesn't work correctly for Model. +# Fallback to exec'ing the appropriate syntax for each Python version. + +if six.PY3: + six.exec_("class Model(ModelWithoutMeta, metaclass=ModelBase): pass") +else: + six.exec_("class Model(ModelWithoutMeta): __metaclass__ = ModelBase") + + ############################################ # HELPER FUNCTIONS (CURRIED MODEL METHODS) # ############################################ diff --git a/django/forms/forms.py b/django/forms/forms.py index 7942275609..0af71918d8 100644 --- a/django/forms/forms.py +++ b/django/forms/forms.py @@ -14,6 +14,7 @@ from django.utils.datastructures import SortedDict from django.utils.html import conditional_escape, format_html from django.utils.encoding import StrAndUnicode, smart_unicode, force_unicode from django.utils.safestring import mark_safe +from django.utils import six __all__ = ('BaseForm', 'Form') @@ -380,14 +381,13 @@ class BaseForm(StrAndUnicode): """ return [field for field in self if not field.is_hidden] -class Form(BaseForm): +class Form(six.with_metaclass(DeclarativeFieldsMetaclass, BaseForm)): "A collection of Fields, plus their associated data." # This is a separate class from BaseForm in order to abstract the way # self.fields is specified. This class (Form) is the one that does the # fancy metaclass stuff purely for the semantic sugar -- it allows one # to define a form using declarative syntax. # BaseForm itself has no way of designating self.fields. - __metaclass__ = DeclarativeFieldsMetaclass class BoundField(StrAndUnicode): "A Field plus data" diff --git a/django/forms/models.py b/django/forms/models.py index 26f869155b..1ef308d93a 100644 --- a/django/forms/models.py +++ b/django/forms/models.py @@ -15,6 +15,7 @@ from django.forms.widgets import (SelectMultiple, HiddenInput, MultipleHiddenInput, media_property) from django.utils.encoding import smart_unicode, force_unicode from django.utils.datastructures import SortedDict +from django.utils import six from django.utils.text import get_text_list, capfirst from django.utils.translation import ugettext_lazy as _, ugettext @@ -365,8 +366,8 @@ class BaseModelForm(BaseForm): save.alters_data = True -class ModelForm(BaseModelForm): - __metaclass__ = ModelFormMetaclass +class ModelForm(six.with_metaclass(ModelFormMetaclass, BaseModelForm)): + pass def modelform_factory(model, form=ModelForm, fields=None, exclude=None, formfield_callback=None, widgets=None): @@ -401,6 +402,7 @@ def modelform_factory(model, form=ModelForm, fields=None, exclude=None, form_metaclass = ModelFormMetaclass + # TODO: this doesn't work under Python 3. if issubclass(form, BaseModelForm) and hasattr(form, '__metaclass__'): form_metaclass = form.__metaclass__ diff --git a/django/forms/widgets.py b/django/forms/widgets.py index 04a838093c..20fa9e973a 100644 --- a/django/forms/widgets.py +++ b/django/forms/widgets.py @@ -17,6 +17,7 @@ from django.utils.translation import ugettext, ugettext_lazy from django.utils.encoding import StrAndUnicode, force_unicode from django.utils.safestring import mark_safe from django.utils import datetime_safe, formats +from django.utils import six __all__ = ( 'Media', 'MediaDefiningClass', 'Widget', 'TextInput', 'PasswordInput', @@ -153,8 +154,7 @@ class SubWidget(StrAndUnicode): args.append(self.choices) return self.parent_widget.render(*args) -class Widget(object): - __metaclass__ = MediaDefiningClass +class Widget(six.with_metaclass(MediaDefiningClass)): is_hidden = False # Determines whether this corresponds to an . needs_multipart_form = False # Determines does this widget need multipart form is_localized = False