Commit 53c68c72 authored by Serge S. Koval's avatar Serge S. Koval

Python 3 fixes.

parent f6894398
......@@ -26,7 +26,7 @@ class User(db.Model):
email = db.Column(db.String(120), unique=True)
# Required for administrative interface
def __unicode__(self):
def __str__(self):
return self.username
......@@ -48,7 +48,7 @@ class Post(db.Model):
tags = db.relationship('Tag', secondary=post_tags_table)
def __unicode__(self):
def __str__(self):
return self.title
......@@ -56,7 +56,7 @@ class Tag(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.Unicode(64))
def __unicode__(self):
def __str__(self):
return self.name
......@@ -69,7 +69,7 @@ class UserInfo(db.Model):
user_id = db.Column(db.Integer(), db.ForeignKey(User.id))
user = db.relationship(User, backref='info')
def __unicode__(self):
def __str__(self):
return '%s - %s' % (self.key, self.value)
......@@ -79,7 +79,7 @@ class Tree(db.Model):
parent_id = db.Column(db.Integer, db.ForeignKey('tree.id'))
parent = db.relationship('Tree', remote_side=[id], backref='children')
def __unicode__(self):
def __str__(self):
return self.name
......
# -*- coding: utf-8 -*-
"""
flask.ext.admin._compat
~~~~~~~~~~~~~~~~~~~~~~~
Some py2/py3 compatibility support based on a stripped down
version of six so we don't have to depend on a specific version
of it.
:copyright: (c) 2013 by Armin Ronacher.
:license: BSD, see LICENSE for more details.
"""
import sys
PY2 = sys.version_info[0] == 2
if not PY2:
text_type = str
string_types = (str,)
integer_types = (int, )
iterkeys = lambda d: iter(d.keys())
itervalues = lambda d: iter(d.values())
iteritems = lambda d: iter(d.items())
def as_unicode(text):
return str(text)
from functools import reduce
else:
unicode_type = unicode
text_type = unicode
string_types = (str, unicode)
integer_types = (int, long)
iterkeys = lambda d: d.iterkeys()
itervalues = lambda d: d.itervalues()
iteritems = lambda d: d.iteritems()
def as_unicode(text):
return unicode(text)
reduce = __builtin__.reduce
def with_metaclass(meta, *bases):
# This requires a bit of explanation: the basic idea is to make a
# dummy metaclass for one level of class instantiation that replaces
# itself with the actual metaclass. Because of internal type checks
# we also need to make sure that we downgrade the custom metaclass
# for one level to something closer to type (that's why __call__ and
# __init__ comes back from type etc.).
#
# This has the advantage over six.with_metaclass in that it does not
# introduce dummy classes into the final MRO.
class metaclass(meta):
__call__ = type.__call__
__init__ = type.__init__
def __new__(cls, name, this_bases, d):
if this_bases is None:
return type.__new__(cls, name, (), d)
return meta(name, bases, d)
return metaclass('temporary_class', None, {})
from flask import request, url_for, redirect
from flask.ext.admin.tools import get_dict_attr
from flask.ext.admin import tools, _compat
def action(name, text, confirmation=None):
......@@ -53,7 +53,7 @@ class ActionsMixin(object):
self._actions_data = {}
for p in dir(self):
attr = get_dict_attr(self, p)
attr = tools.get_dict_attr(self, p)
if hasattr(attr, '_action'):
name, text, desc = attr._action
......@@ -85,12 +85,12 @@ class ActionsMixin(object):
name, text = act
if self.is_action_allowed(name):
text = unicode(text)
text = _compat.as_unicode(text)
actions.append((name, text))
confirmation = self._actions_data[name][2]
if confirmation:
actions_confirmation[name] = unicode(confirmation)
actions_confirmation[name] = _compat.text_type(confirmation)
return actions, actions_confirmation
......
from functools import wraps
from re import sub
import six
from flask import Blueprint, render_template, url_for, abort, g
from flask.ext.admin import babel
from flask.ext.admin import babel, _compat
from flask.ext.admin import helpers as h
......@@ -95,7 +94,7 @@ class BaseMeta(object):
pass
class BaseView(six.with_metaclass(AdminViewMeta, BaseMeta)):
class BaseView(_compat.with_metaclass(AdminViewMeta, BaseMeta)):
"""
Base administrative view.
......
......@@ -4,6 +4,7 @@ from flask import flash
from flask.ext.admin.babel import gettext, ngettext, lazy_gettext
from flask.ext.admin.model import BaseModelView
from flask.ext.admin import _compat
import mongoengine
from bson.objectid import ObjectId
......@@ -115,7 +116,7 @@ class ModelView(BaseModelView):
if model is None:
model = self.model
return sorted(model._fields.iteritems(), key=lambda n: n[1].creation_counter)
return sorted(_compat.iteritems(model._fields), key=lambda n: n[1].creation_counter)
def scaffold_pk(self):
# MongoEngine models have predefined 'id' as a key
......@@ -171,7 +172,7 @@ class ModelView(BaseModelView):
"""
if self.column_searchable_list:
for p in self.column_searchable_list:
if isinstance(p, basestring):
if isinstance(p, _compat.string_types):
p = self.model._fields.get(p)
if p is None:
......@@ -195,7 +196,7 @@ class ModelView(BaseModelView):
:param name:
Either field name or field instance
"""
if isinstance(name, basestring):
if isinstance(name, _compat.string_types):
attr = self.model._fields.get(name)
else:
attr = name
......@@ -206,7 +207,7 @@ class ModelView(BaseModelView):
# Find name
visible_name = None
if not isinstance(name, basestring):
if not isinstance(name, _compat.string_types):
visible_name = self.get_column_name(attr.name)
if not visible_name:
......
......@@ -5,7 +5,7 @@ from peewee import (DateTimeField, DateField, TimeField,
from wtfpeewee.orm import ModelConverter, model_form
from flask.ext.admin import form
from flask.ext.admin import form, _compat
from flask.ext.admin.model.form import InlineFormAdmin, InlineModelConverterBase
from flask.ext.admin.model.fields import InlineModelFormField, InlineFieldList
......@@ -164,6 +164,6 @@ class InlineModelConverter(InlineModelConverterBase):
def save_inline(form, model):
for _, f in form._fields.iteritems():
for _, f in _compat(form._fields):
if f.type == 'InlineModelFormList':
f.save_related(model)
......@@ -2,7 +2,7 @@ import logging
from flask import flash
from flask.ext.admin import form
from flask.ext.admin import form, _compat
from flask.ext.admin.babel import gettext, ngettext, lazy_gettext
from flask.ext.admin.model import BaseModelView
......@@ -173,7 +173,7 @@ class ModelView(BaseModelView):
def init_search(self):
if self.column_searchable_list:
for p in self.column_searchable_list:
if isinstance(p, basestring):
if isinstance(p, _compat.string_types):
p = getattr(self.model, p)
field_type = type(p)
......@@ -189,7 +189,7 @@ class ModelView(BaseModelView):
return bool(self._search_fields)
def scaffold_filters(self, name):
if isinstance(name, basestring):
if isinstance(name, _compat.string_types):
attr = getattr(self.model, name, None)
else:
attr = name
......@@ -202,7 +202,7 @@ class ModelView(BaseModelView):
visible_name = '%s / %s' % (self.get_column_name(attr.model_class.__name__),
self.get_column_name(attr.name))
else:
if not isinstance(name, basestring):
if not isinstance(name, _compat.string_types):
visible_name = self.get_column_name(attr.name)
else:
visible_name = self.get_column_name(name)
......@@ -253,7 +253,7 @@ class ModelView(BaseModelView):
return query
def _order_by(self, query, joins, sort_field, sort_desc):
if isinstance(sort_field, basestring):
if isinstance(sort_field, _compat.string_types):
field = getattr(self.model, sort_field)
query = query.order_by(field.desc() if sort_desc else field.asc())
elif isinstance(sort_field, Field):
......
......@@ -5,8 +5,8 @@ from bson import ObjectId
from bson.errors import InvalidId
from flask import flash
from jinja2 import contextfunction
from flask.ext.admin import _compat
from flask.ext.admin.babel import gettext, ngettext, lazy_gettext
from flask.ext.admin.model import BaseModelView
from flask.ext.admin.actions import action
......@@ -92,7 +92,7 @@ class ModelView(BaseModelView):
"""
if self.column_searchable_list:
for p in self.column_searchable_list:
if not isinstance(p, basestring):
if not isinstance(p, _compat.string_types):
raise ValueError('Expected string')
# TODO: Validation?
......
......@@ -8,6 +8,7 @@ from wtforms.fields import SelectFieldBase
from wtforms.validators import ValidationError
from .tools import get_primary_key
from flask.ext.admin import _compat
from flask.ext.admin.model.fields import InlineFieldList, InlineModelFormField
......@@ -63,14 +64,14 @@ class QuerySelectField(SelectFieldBase):
if get_pk is None:
if not has_identity_key:
raise Exception('The sqlalchemy identity_key function could not be imported.')
raise Exception(u'The sqlalchemy identity_key function could not be imported.')
self.get_pk = get_pk_from_identity
else:
self.get_pk = get_pk
if get_label is None:
self.get_label = lambda x: x
elif isinstance(get_label, basestring):
elif isinstance(get_label, _compat.string_types):
self.get_label = operator.attrgetter(get_label)
else:
self.get_label = get_label
......@@ -98,7 +99,7 @@ class QuerySelectField(SelectFieldBase):
if self._object_list is None:
query = self.query or self.query_factory()
get_pk = self.get_pk
self._object_list = list((unicode(get_pk(obj)), obj) for obj in query)
self._object_list = [(_compat.as_unicode(get_pk(obj)), obj) for obj in query]
return self._object_list
def iter_choices(self):
......@@ -177,7 +178,7 @@ class QuerySelectMultipleField(QuerySelectField):
obj_list = list(x[1] for x in self._get_object_list())
for v in self.data:
if v not in obj_list:
raise ValidationError(self.gettext('Not a valid choice'))
raise ValidationError(self.gettext(u'Not a valid choice'))
class InlineModelFormList(InlineFieldList):
......@@ -238,4 +239,4 @@ class InlineModelFormList(InlineFieldList):
def get_pk_from_identity(obj):
# TODO: Remove me
cls, key = identity_key(instance=obj)
return u':'.join(unicode(x) for x in key)
return u':'.join(_compat.as_unicode(x) for x in key)
......@@ -26,7 +26,8 @@ class Unique(object):
def __call__(self, form, field):
try:
obj = (self.db_session.query(self.model)
.filter(self.column == field.data).one())
.filter(self.column == field.data)
.one())
if not hasattr(form, '_obj') or not form._obj == obj:
if self.message is None:
......
......@@ -7,6 +7,7 @@ from sqlalchemy import or_, Column, func
from flask import flash
from flask.ext.admin import _compat
from flask.ext.admin.tools import ObsoleteAttr
from flask.ext.admin.babel import gettext, ngettext, lazy_gettext
from flask.ext.admin.model import BaseModelView
......@@ -348,7 +349,7 @@ class ModelView(BaseModelView):
return columns
def _get_columns_for_field(self, field):
if isinstance(field, basestring):
if isinstance(field, _compat.string_types):
attr = getattr(self.model, field, None)
if field is None:
......@@ -410,7 +411,7 @@ class ModelView(BaseModelView):
"""
join_tables = []
if isinstance(name, basestring):
if isinstance(name, _compat.string_types):
model = self.model
for attribute in name.split('.'):
......@@ -474,7 +475,7 @@ class ModelView(BaseModelView):
self.get_column_name(column.name)
)
else:
if not isinstance(name, basestring):
if not isinstance(name, _compat.string_types):
visible_name = self.get_column_name(name.property.key)
else:
visible_name = self.get_column_name(name)
......@@ -596,7 +597,7 @@ class ModelView(BaseModelView):
"""
# TODO: Preprocessing for joins
# Try to handle it as a string
if isinstance(sort_field, basestring):
if isinstance(sort_field, _compat.string_types):
# Create automatic join against a table if column name
# contains dot.
if '.' in sort_field:
......@@ -637,7 +638,7 @@ class ModelView(BaseModelView):
if order is not None:
field, direction = order
if isinstance(field, basestring):
if isinstance(field, _compat.string_types):
field = getattr(self.model, field)
return field, direction
......@@ -764,7 +765,7 @@ class ModelView(BaseModelView):
self.session.add(model)
self.on_model_change(form, model)
self.session.commit()
except Exception, ex:
except Exception as ex:
flash(gettext('Failed to create model. %(error)s', error=str(ex)), 'error')
logging.exception('Failed to create model')
self.session.rollback()
......@@ -787,7 +788,7 @@ class ModelView(BaseModelView):
form.populate_obj(model)
self.on_model_change(form, model)
self.session.commit()
except Exception, ex:
except Exception as ex:
flash(gettext('Failed to update model. %(error)s', error=str(ex)), 'error')
logging.exception('Failed to update model')
self.session.rollback()
......@@ -810,7 +811,7 @@ class ModelView(BaseModelView):
self.session.delete(model)
self.session.commit()
return True
except Exception, ex:
except Exception as ex:
flash(gettext('Failed to delete model. %(error)s', error=str(ex)), 'error')
logging.exception('Failed to delete model')
self.session.rollback()
......@@ -848,5 +849,5 @@ class ModelView(BaseModelView):
'%(count)s models were successfully deleted.',
count,
count=count))
except Exception, ex:
except Exception as ex:
flash(gettext('Failed to delete models. %(error)s', error=str(ex)), 'error')
......@@ -5,11 +5,15 @@ from wtforms import form, fields, widgets
from flask.globals import _request_ctx_stack
from flask.ext.admin.babel import gettext, ngettext
from flask.ext.admin import helpers as h
from flask.ext.admin import _compat
# TODO: Use flask.ext.wtf if possible
class BaseForm(form.Form):
pass
def __init__(self, formdata=None, obj=None, prefix=u'', **kwargs):
self._obj = obj
super(BaseForm, self).__init__(formdata=formdata, obj=obj, prefix=prefix, **kwargs)
class TimeField(fields.Field):
......@@ -88,7 +92,7 @@ class Select2Field(fields.SelectField):
"""
widget = Select2Widget()
def __init__(self, label=None, validators=None, coerce=unicode,
def __init__(self, label=None, validators=None, coerce=_compat.text_type,
choices=None, allow_blank=False, blank_text=None, **kwargs):
super(Select2Field, self).__init__(
label, validators, coerce, choices, **kwargs
......
......@@ -10,7 +10,7 @@ from flask.ext.admin.base import BaseView, expose
from flask.ext.admin.tools import rec_getattr, ObsoleteAttr
from flask.ext.admin.model import filters, typefmt
from flask.ext.admin.actions import ActionsMixin
from flask.ext.admin import get_form_data, validate_form_on_submit
from flask.ext.admin.helpers import get_form_data, validate_form_on_submit
class BaseModelView(BaseView, ActionsMixin):
......@@ -937,7 +937,7 @@ class BaseModelView(BaseView, ActionsMixin):
search, filters)
# Calculate number of pages
num_pages = count / self.page_size
num_pages = count // self.page_size
if count % self.page_size != 0:
num_pages += 1
......@@ -1014,8 +1014,7 @@ class BaseModelView(BaseView, ActionsMixin):
# Actions
actions=actions,
actions_confirmation=actions_confirmation
)
actions_confirmation=actions_confirmation)
@expose('/new/', methods=('GET', 'POST'))
def create_view(self):
......
......@@ -2,6 +2,7 @@ import itertools
from wtforms.fields import FieldList, FormField
from flask.ext.admin import _compat
from .widgets import InlineFieldListWidget, InlineFormWidget
......@@ -22,9 +23,9 @@ class InlineFieldList(FieldList):
def __call__(self, **kwargs):
return self.widget(self,
template=self.template,
check=self.display_row_controls,
**kwargs)
template=self.template,
check=self.display_row_controls,
**kwargs)
def display_row_controls(self, field):
return True
......@@ -82,7 +83,7 @@ class InlineModelFormField(FormField):
return getattr(self.form, self._pk).data
def populate_obj(self, obj, name):
for name, field in self.form._fields.iteritems():
for name, field in _compat.iteritems(self.form._fields):
if name != self._pk:
field.populate_obj(obj, name)
......
from flask.ext.admin import _compat
from flask.ext.admin.babel import lazy_gettext
......@@ -30,7 +31,7 @@ class BaseFilter(object):
Associated administrative view class.
"""
if self.options:
return [(v, unicode(n)) for v, n in self.options]
return [(v, _compat.as_unicode(n)) for v, n in self.options]
return None
......
import inspect
from flask.ext.admin.form import BaseForm
from flask.ext.admin import _compat
def converts(*args):
......@@ -37,7 +38,7 @@ class InlineFormAdmin(object):
if not hasattr(self, k):
setattr(self, k, None)
for k, v in kwargs.iteritems():
for k, v in _compat.iteritems(kwargs):
setattr(self, k, v)
def postprocess_form(self, form_class):
......
from jinja2 import Markup
from flask.ext.admin import _compat
def null_formatter(view, value):
......@@ -38,7 +39,7 @@ def list_formatter(view, values):
:param values:
Value to check
"""
return u', '.join(unicode(v) for v in values)
return u', '.join(_compat.as_unicode(v) for v in values)
BASE_FORMATTERS = {
......
......@@ -22,7 +22,7 @@
this.addInlineField = function(id, el, template) {
var $el = $(el);
var $template = $(template);
var $template = $($(template).html());
// Figure out new field ID
var lastField = $el.children('.fa-inline-field').last();
......@@ -30,7 +30,7 @@
var prefix = id + '-0';
if (lastField.length > 0) {
var parts = $(lastField[0]).attr('id').split('-');
idx = parseInt(parts[parts.length - 1]) + 1;
idx = parseInt(parts[parts.length - 1], 10) + 1;
prefix = id + '-' + idx;
}
......
{% macro render_template(template, render) -%}
<div class="fa-inline-field">
<div class="fa-inline-field-control">
<a href="javascript:void(0)" class="fa-remove-field"><i class="icon-remove"></i></a>
</div>
{{ render(template) }}
</div>
{%- endmacro %}
{% macro render_inline_fields(field, template, render, check=None) %}
<div class="well">
<div id="{{ field.id }}-fields">
......@@ -23,6 +14,14 @@
</div>
{% endfor %}
</div>
<a href="javascript:void(0)" class="btn" onclick="faForm.addInlineField('{{ field.id }}', '#{{ field.id }}-fields', {{ render_template(template, render)|tojson }});">{{ _gettext('Add') }} {{ field.label.text }}</a>
<div id="{{ field.id }}-template" class="hide">
<div class="fa-inline-field">
<div class="fa-inline-field-control">
<a href="javascript:void(0)" class="fa-remove-field"><i class="icon-remove"></i></a>
</div>
{{ render(template) }}
</div>
</div>
<a id="{{ field.id }}-button" href="javascript:void(0)" class="btn" onclick="faForm.addInlineField('{{ field.id }}', '#{{ field.id }}-fields', '#{{ field.id }}-template');">{{ _gettext('Add') }} {{ field.label.text }}</a>
</div>
{% endmacro %}
......@@ -4,6 +4,7 @@ import peewee
from wtforms import fields
from flask.ext.admin import _compat
from flask.ext.admin.contrib.peeweemodel import ModelView
from . import setup
......@@ -13,7 +14,7 @@ class CustomModelView(ModelView):
def __init__(self, model,
name=None, category=None, endpoint=None, url=None,
**kwargs):
for k, v in kwargs.iteritems():
for k, v in _compat.iteritems(kwargs):
setattr(self, k, v)
super(CustomModelView, self).__init__(model,
......
from nose.tools import eq_, ok_, raises
from wtforms import fields
from flask.ext.admin import _compat
from flask.ext.admin.contrib.sqlamodel import ModelView
from . import setup
......@@ -10,7 +12,7 @@ class CustomModelView(ModelView):
def __init__(self, model, session,
name=None, category=None, endpoint=None, url=None,
**kwargs):
for k, v in kwargs.iteritems():
for k, v in _compat.iteritems(kwargs):
setattr(self, k, v)
super(CustomModelView, self).__init__(model, session,
......
......@@ -4,7 +4,7 @@ from flask import Flask
from wtforms import fields
from flask.ext.admin import Admin, form
from flask.ext.admin import Admin, form, _compat
from flask.ext.admin.model import base, filters
......@@ -35,7 +35,7 @@ class MockModelView(base.BaseModelView):
def __init__(self, model, name=None, category=None, endpoint=None, url=None,
**kwargs):
# Allow to set any attributes from parameters
for k, v in kwargs.iteritems():
for k, v in _compat.iteritems(kwargs):
setattr(self, k, v)
super(MockModelView, self).__init__(model, name, category, endpoint, url)
......
......@@ -2,6 +2,9 @@ import sys
import warnings
import traceback
# Python 3 compatibility
from ._compat import reduce
def import_module(name, required=True):
"""
......
......@@ -42,7 +42,6 @@ setup(
zip_safe=False,
platforms='any',
install_requires=[
'six>=1.2',
'Flask>=0.7'
],
tests_require=[
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment