Various compat changes for Python 3
This commit is contained in:
parent
3b5b360a4b
commit
7113cc701a
|
@ -4,8 +4,9 @@ from django.db.models.fields import FieldDoesNotExist
|
|||
from django.utils.datastructures import SortedDict
|
||||
from django.utils.safestring import SafeData
|
||||
from django_tables2.templatetags.django_tables2 import title
|
||||
from django_tables2.utils import A, AttributeDict, OrderBy, OrderByTuple
|
||||
from itertools import ifilter, islice
|
||||
from django_tables2.utils import (A, AttributeDict, basestring, OrderBy,
|
||||
OrderByTuple)
|
||||
from itertools import islice
|
||||
import warnings
|
||||
|
||||
|
||||
|
@ -573,7 +574,7 @@ class BoundColumns(object):
|
|||
conjunction with e.g. ``{{ forloop.last }}`` (the last column might not
|
||||
be the actual last that is rendered).
|
||||
"""
|
||||
return ifilter(lambda x: x.orderable, self.iterall())
|
||||
return (x for x in self.iterall() if x.orderable)
|
||||
|
||||
def itersortable(self):
|
||||
warnings.warn('`itersortable` is deprecated, use `iterorderable` instead.',
|
||||
|
@ -595,7 +596,7 @@ class BoundColumns(object):
|
|||
|
||||
This is geared towards table rendering.
|
||||
"""
|
||||
return ifilter(lambda x: x.visible, self.iterall())
|
||||
return (x for x in self.iterall() if x.visible)
|
||||
|
||||
def visible(self):
|
||||
return list(self.itervisible())
|
||||
|
|
|
@ -3,7 +3,7 @@ from __future__ import absolute_import, unicode_literals
|
|||
from django.db import models
|
||||
from django.utils.html import escape
|
||||
from django.utils.safestring import mark_safe
|
||||
from django_tables2.utils import AttributeDict
|
||||
from django_tables2.utils import AttributeDict, basestring
|
||||
from .base import Column, library
|
||||
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
# coding: utf-8
|
||||
from __future__ import unicode_literals
|
||||
from django.core.paginator import EmptyPage, PageNotAnInteger
|
||||
|
||||
|
||||
|
@ -42,7 +43,7 @@ class RequestConfig(object):
|
|||
kwargs = {}
|
||||
# extract some options from the request
|
||||
for arg in ("page", "per_page"):
|
||||
name = getattr(table, u"prefixed_%s_field" % arg)
|
||||
name = getattr(table, "prefixed_%s_field" % arg)
|
||||
try:
|
||||
kwargs[arg] = int(self.request.GET[name])
|
||||
except (ValueError, KeyError):
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# coding: utf-8
|
||||
from django.db import models
|
||||
from django.db.models.fields import FieldDoesNotExist
|
||||
from .utils import A, getargspec
|
||||
from .utils import A, basestring, getargspec
|
||||
|
||||
|
||||
class BoundRow(object):
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
# coding: utf-8
|
||||
from __future__ import unicode_literals
|
||||
import copy
|
||||
from django.core.paginator import Paginator
|
||||
from django.db.models.fields import FieldDoesNotExist
|
||||
|
@ -7,8 +8,8 @@ from django.template import RequestContext
|
|||
from django.template.loader import get_template
|
||||
import warnings
|
||||
from .config import RequestConfig
|
||||
from .utils import (Accessor, AttributeDict, cached_property, build_request,
|
||||
OrderBy, OrderByTuple, segment, Sequence)
|
||||
from .utils import (Accessor, AttributeDict, basestring, build_request,
|
||||
cached_property, OrderBy, OrderByTuple, segment, Sequence)
|
||||
from .rows import BoundRows
|
||||
from . import columns
|
||||
|
||||
|
@ -223,7 +224,7 @@ class TableOptions(object):
|
|||
def __init__(self, options=None):
|
||||
super(TableOptions, self).__init__()
|
||||
self.attrs = AttributeDict(getattr(options, "attrs", {}))
|
||||
self.default = getattr(options, "default", u"—")
|
||||
self.default = getattr(options, "default", "—")
|
||||
self.empty_text = getattr(options, "empty_text", None)
|
||||
self.fields = getattr(options, "fields", ())
|
||||
self.exclude = getattr(options, "exclude", ())
|
||||
|
@ -547,15 +548,15 @@ class Table(object):
|
|||
|
||||
@property
|
||||
def prefixed_order_by_field(self):
|
||||
return u"%s%s" % (self.prefix, self.order_by_field)
|
||||
return "%s%s" % (self.prefix, self.order_by_field)
|
||||
|
||||
@property
|
||||
def prefixed_page_field(self):
|
||||
return u"%s%s" % (self.prefix, self.page_field)
|
||||
return "%s%s" % (self.prefix, self.page_field)
|
||||
|
||||
@property
|
||||
def prefixed_per_page_field(self):
|
||||
return u"%s%s" % (self.prefix, self.per_page_field)
|
||||
return "%s%s" % (self.prefix, self.per_page_field)
|
||||
|
||||
@property
|
||||
def sequence(self):
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# coding: utf-8
|
||||
from __future__ import absolute_import
|
||||
from __future__ import absolute_import, unicode_literals
|
||||
from django import template
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
from django.template import TemplateSyntaxError, Variable, Node
|
||||
|
@ -11,8 +11,12 @@ from django.utils.html import escape
|
|||
from django.utils.safestring import mark_safe
|
||||
import django_tables2 as tables
|
||||
from django_tables2.config import RequestConfig
|
||||
from django_tables2.utils import basestring
|
||||
import re
|
||||
import StringIO
|
||||
try:
|
||||
from io import StringIO
|
||||
except ImportError:
|
||||
from StringIO import StringIO
|
||||
import tokenize
|
||||
|
||||
|
||||
|
@ -85,7 +89,7 @@ def set_url_param(parser, token):
|
|||
key, value = i.split('=', 1)
|
||||
key = key.strip()
|
||||
value = value.strip()
|
||||
key_line_iter = StringIO.StringIO(key).readline
|
||||
key_line_iter = StringIO(key).readline
|
||||
keys = list(tokenize.generate_tokens(key_line_iter))
|
||||
if keys[0][0] == tokenize.NAME:
|
||||
# workaround bug #5270
|
||||
|
@ -241,7 +245,7 @@ def render_table(parser, token):
|
|||
try:
|
||||
tag, table = bits.pop(0), parser.compile_filter(bits.pop(0))
|
||||
except ValueError:
|
||||
raise TemplateSyntaxError(u"'%s' must be given a table or queryset."
|
||||
raise TemplateSyntaxError("'%s' must be given a table or queryset."
|
||||
% bits[0])
|
||||
template = parser.compile_filter(bits.pop(0)) if bits else None
|
||||
return RenderTableNode(table, template)
|
||||
|
|
|
@ -5,12 +5,23 @@ from django.utils.functional import curry
|
|||
from django.utils.html import escape
|
||||
from django.utils.safestring import mark_safe
|
||||
from django.test.client import FakePayload
|
||||
from itertools import chain, ifilter
|
||||
from itertools import chain
|
||||
import inspect
|
||||
from StringIO import StringIO
|
||||
try:
|
||||
from io import StringIO
|
||||
except ImportError:
|
||||
# Python 2 fallback
|
||||
from StringIO import StringIO
|
||||
import warnings
|
||||
|
||||
|
||||
try:
|
||||
basestring
|
||||
except NameError:
|
||||
# Python 3 compatibility
|
||||
basestring = str
|
||||
|
||||
|
||||
class Sequence(list):
|
||||
"""
|
||||
Represents a column sequence, e.g. ``("first_name", "...", "last_name")``
|
||||
|
@ -429,7 +440,8 @@ class cached_property(object): # pylint: disable=C0103
|
|||
return res
|
||||
|
||||
|
||||
funcs = ifilter(curry(hasattr, inspect), ('getfullargspec', 'getargspec'))
|
||||
funcs = (name for name in ('getfullargspec', 'getargspec')
|
||||
if hasattr(inspect, name))
|
||||
getargspec = getattr(inspect, next(funcs))
|
||||
del funcs
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
# coding: utf-8
|
||||
from __future__ import unicode_literals
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
from django.views.generic.list import ListView
|
||||
from .config import RequestConfig
|
||||
|
@ -50,8 +51,8 @@ class SingleTableMixin(object):
|
|||
"""
|
||||
if self.table_class:
|
||||
return self.table_class
|
||||
raise ImproperlyConfigured(u"A table class was not specified. Define "
|
||||
u"%(cls)s.table_class"
|
||||
raise ImproperlyConfigured("A table class was not specified. Define "
|
||||
"%(cls)s.table_class"
|
||||
% {"cls": type(self).__name__})
|
||||
|
||||
def get_context_table_name(self, table):
|
||||
|
@ -68,8 +69,8 @@ class SingleTableMixin(object):
|
|||
return self.table_data
|
||||
elif hasattr(self, "get_queryset"):
|
||||
return self.get_queryset()
|
||||
raise ImproperlyConfigured(u"Table data was not specified. Define "
|
||||
u"%(cls)s.table_data"
|
||||
raise ImproperlyConfigured("Table data was not specified. Define "
|
||||
"%(cls)s.table_data"
|
||||
% {"cls": type(self).__name__})
|
||||
|
||||
def get_table_pagination(self):
|
||||
|
|
2
setup.py
2
setup.py
|
@ -4,7 +4,7 @@ from setuptools import setup, find_packages
|
|||
|
||||
|
||||
with open('django_tables2/__init__.py', 'rb') as f:
|
||||
version = re.search('__version__ = "(.+?)"', f.read()).group(1)
|
||||
version = re.search('__version__ = "(.+?)"', f.read().decode('utf-8')).group(1)
|
||||
|
||||
|
||||
setup(
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
# coding: utf-8
|
||||
from __future__ import unicode_literals
|
||||
from django.db import models
|
||||
from django.utils.safestring import mark_safe
|
||||
from django.utils.translation import ugettext_lazy
|
||||
from django.utils.translation import ugettext
|
||||
import os
|
||||
|
||||
|
||||
class Person(models.Model):
|
||||
|
@ -34,7 +36,7 @@ class Person(models.Model):
|
|||
|
||||
@property
|
||||
def name(self):
|
||||
return u"%s %s" % (self.first_name, self.last_name)
|
||||
return "%s %s" % (self.first_name, self.last_name)
|
||||
|
||||
|
||||
class Occupation(models.Model):
|
||||
|
@ -55,11 +57,11 @@ class Region(models.Model):
|
|||
|
||||
# -- haystack -----------------------------------------------------------------
|
||||
|
||||
if 'SKIP_HAYSTACK' not in os.environ:
|
||||
from haystack import site
|
||||
from haystack.indexes import CharField, SearchIndex
|
||||
|
||||
from haystack import site
|
||||
from haystack.indexes import CharField, SearchIndex
|
||||
class PersonIndex(SearchIndex):
|
||||
first_name = CharField(document=True)
|
||||
|
||||
class PersonIndex(SearchIndex):
|
||||
first_name = CharField(document=True)
|
||||
|
||||
site.register(Person, PersonIndex)
|
||||
site.register(Person, PersonIndex)
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
from django.conf import global_settings
|
||||
import os
|
||||
|
||||
|
||||
DATABASES = {
|
||||
|
@ -11,7 +12,6 @@ DATABASES = {
|
|||
INSTALLED_APPS = [
|
||||
'tests.app',
|
||||
'django_tables2',
|
||||
'haystack',
|
||||
]
|
||||
|
||||
ROOT_URLCONF = 'tests.app.urls'
|
||||
|
@ -22,9 +22,13 @@ TEMPLATE_CONTEXT_PROCESSORS = [
|
|||
'django.core.context_processors.request'
|
||||
] + list(global_settings.TEMPLATE_CONTEXT_PROCESSORS)
|
||||
|
||||
HAYSTACK_SEARCH_ENGINE = 'simple',
|
||||
HAYSTACK_SITECONF = 'tests.app.models'
|
||||
|
||||
TIME_ZONE = "Australia/Brisbane"
|
||||
|
||||
USE_TZ = True
|
||||
|
||||
if 'SKIP_HAYSTACK' not in os.environ:
|
||||
INSTALLED_APPS += [
|
||||
'haystack',
|
||||
]
|
||||
HAYSTACK_SEARCH_ENGINE = 'simple',
|
||||
HAYSTACK_SITECONF = 'tests.app.models'
|
||||
|
|
|
@ -451,11 +451,11 @@ def unicode():
|
|||
# test unicode values + headings
|
||||
class UnicodeTable(tables.Table):
|
||||
first_name = tables.LinkColumn('person', args=[A('pk')])
|
||||
last_name = tables.LinkColumn('person', args=[A('pk')], verbose_name=u'äÚ¨´ˆÁ˜¨ˆ˜˘Ú…Ò˚ˆπ∆ˆ´')
|
||||
last_name = tables.LinkColumn('person', args=[A('pk')], verbose_name='äÚ¨´ˆÁ˜¨ˆ˜˘Ú…Ò˚ˆπ∆ˆ´')
|
||||
|
||||
dataset = [
|
||||
{'pk': 1, 'first_name': u'Brädley', 'last_name': u'∆yers'},
|
||||
{'pk': 2, 'first_name': u'Chr…s', 'last_name': u'DÒble'},
|
||||
{'pk': 1, 'first_name': 'Brädley', 'last_name': '∆yers'},
|
||||
{'pk': 2, 'first_name': 'Chr…s', 'last_name': 'DÒble'},
|
||||
]
|
||||
|
||||
table = UnicodeTable(dataset)
|
||||
|
@ -463,10 +463,10 @@ def unicode():
|
|||
template = Template('{% load django_tables2 %}{% render_table table %}')
|
||||
html = template.render(Context({'request': request, 'table': table}))
|
||||
|
||||
assert u'Brädley' in html
|
||||
assert u'∆yers' in html
|
||||
assert u'Chr…s' in html
|
||||
assert u'DÒble' in html
|
||||
assert 'Brädley' in html
|
||||
assert '∆yers' in html
|
||||
assert 'Chr…s' in html
|
||||
assert 'DÒble' in html
|
||||
|
||||
|
||||
@linkcolumn.test
|
||||
|
|
|
@ -6,7 +6,7 @@ import copy
|
|||
from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator
|
||||
import django_tables2 as tables
|
||||
from django_tables2.tables import DeclarativeColumnsMetaclass
|
||||
from haystack.query import SearchQuerySet
|
||||
import os
|
||||
|
||||
|
||||
core = Tests()
|
||||
|
@ -150,8 +150,11 @@ def should_support_tuple_data_source():
|
|||
|
||||
assert len(table.rows) == 2
|
||||
|
||||
@core.test
|
||||
|
||||
@core.test_if('SKIP_HAYSTACK' not in os.environ)
|
||||
def should_support_haystack_data_source():
|
||||
from haystack.query import SearchQuerySet
|
||||
|
||||
class PersonTable(tables.Table):
|
||||
first_name = tables.Column()
|
||||
|
||||
|
@ -254,7 +257,7 @@ def ordering_different_types():
|
|||
]
|
||||
|
||||
table = OrderedTable(data)
|
||||
assert u"—" == table.rows[0]['alpha']
|
||||
assert "—" == table.rows[0]['alpha']
|
||||
|
||||
table = OrderedTable(data, order_by='i')
|
||||
assert 1 == table.rows[0]['i']
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
# coding: utf-8
|
||||
from __future__ import unicode_literals
|
||||
from attest import assert_hook, raises, Tests # pylint: disable=W0611
|
||||
from contextlib import contextmanager
|
||||
from django_attest import queries, settings, TestContext
|
||||
|
@ -9,7 +10,10 @@ from django.core.exceptions import ImproperlyConfigured
|
|||
from django.template import Template, RequestContext, Context
|
||||
from django.utils.translation import ugettext_lazy
|
||||
from django.utils.safestring import mark_safe
|
||||
from urlparse import parse_qs
|
||||
try:
|
||||
from urlparse import parse_qs
|
||||
except ImportError:
|
||||
from urllib.parse import parse_qs
|
||||
import lxml.etree
|
||||
import lxml.html
|
||||
from .app.models import Person, Region
|
||||
|
@ -99,8 +103,8 @@ def custom_rendering():
|
|||
# row values
|
||||
template = Template('{% for row in countries.rows %}{% for value in row %}'
|
||||
'{{ value }} {% endfor %}{% endfor %}')
|
||||
result = (u'Germany Berlin 83 49 France — 64 33 Netherlands Amsterdam '
|
||||
u'— 31 Austria — 8 43 ')
|
||||
result = ('Germany Berlin 83 49 France — 64 33 Netherlands Amsterdam '
|
||||
'— 31 Austria — 8 43 ')
|
||||
assert result == template.render(context)
|
||||
|
||||
|
||||
|
@ -179,7 +183,7 @@ def render_table_supports_queryset():
|
|||
td = [[unicode(td.text) for td in tr.findall('td')] for tr in root.findall('.//tbody/tr')]
|
||||
db = []
|
||||
for region in Region.objects.all():
|
||||
db.append([unicode(region.id), region.name, u"—"])
|
||||
db.append([unicode(region.id), region.name, "—"])
|
||||
assert td == db
|
||||
|
||||
|
||||
|
@ -323,7 +327,7 @@ def localization_check():
|
|||
expected_reults = {
|
||||
None : '1234.5',
|
||||
False: '1234.5',
|
||||
True : u'1{0}234,5'.format(u' ') # non-breaking space
|
||||
True : '1{0}234,5'.format(' ') # non-breaking space
|
||||
}
|
||||
|
||||
# no localization
|
||||
|
@ -339,16 +343,16 @@ def localization_check():
|
|||
# with default polish locales and enabled thousand separator
|
||||
# 1234.5 is formatted as "1 234,5" with nbsp
|
||||
html = get_cond_localized_table(True)(simple_test_data).as_html()
|
||||
assert u'<td class="name">{0}</td>'.format(expected_reults[True]) in html
|
||||
assert '<td class="name">{0}</td>'.format(expected_reults[True]) in html
|
||||
|
||||
# with localize = False there should be no formatting
|
||||
html = get_cond_localized_table(False)(simple_test_data).as_html()
|
||||
assert u'<td class="name">{0}</td>'.format(expected_reults[False]) in html
|
||||
assert '<td class="name">{0}</td>'.format(expected_reults[False]) in html
|
||||
|
||||
# with localize = None and USE_L10N = True
|
||||
# there should be the same formatting as with localize = True
|
||||
html = get_cond_localized_table(None)(simple_test_data).as_html()
|
||||
assert u'<td class="name">{0}</td>'.format(expected_reults[True]) in html
|
||||
assert '<td class="name">{0}</td>'.format(expected_reults[True]) in html
|
||||
|
||||
|
||||
@templates.test
|
||||
|
@ -393,7 +397,7 @@ def localization_check_in_meta():
|
|||
expected_reults = {
|
||||
None : '1234.5',
|
||||
False: '1234.5',
|
||||
True : u'1{0}234,5'.format(u' ') # non-breaking space
|
||||
True : '1{0}234,5'.format(' ') # non-breaking space
|
||||
}
|
||||
|
||||
# No localize
|
||||
|
@ -405,11 +409,11 @@ def localization_check_in_meta():
|
|||
# the same as in localization_check.
|
||||
# with localization and polish locale we get formatted output
|
||||
html = TableNoLocalize(simple_test_data).as_html()
|
||||
assert u'<td class="name">{0}</td>'.format(expected_reults[True]) in html
|
||||
assert '<td class="name">{0}</td>'.format(expected_reults[True]) in html
|
||||
|
||||
# localize
|
||||
html = TableLocalize(simple_test_data).as_html()
|
||||
assert u'<td class="name">{0}</td>'.format(expected_reults[True]) in html
|
||||
assert '<td class="name">{0}</td>'.format(expected_reults[True]) in html
|
||||
|
||||
# unlocalize
|
||||
html = TableUnlocalize(simple_test_data).as_html()
|
||||
|
|
Loading…
Reference in New Issue