Refs #46 -- Add Py3 support.

This commit is contained in:
Rémy HUBSCHER 2014-02-16 19:04:47 +01:00
parent 6232fcb736
commit 1ea2790ba9
11 changed files with 34 additions and 21 deletions

View file

@ -1,6 +1,7 @@
language: python
env:
- TOXENV=py27
- TOXENV=py33
- TOXENV=flake8
- TOXENV=sphinx
- TOXENV=readme

View file

@ -1,4 +1,4 @@
from StringIO import StringIO
from six import StringIO
from django.core.files.base import ContentFile
@ -10,7 +10,7 @@ from django_downloadview import StringIteratorIO
class TextDownloadView(VirtualDownloadView):
def get_file(self):
"""Return :class:`django.core.files.base.ContentFile` object."""
return ContentFile(u"Hello world!\n", name='hello-world.txt')
return ContentFile(b"Hello world!\n", name='hello-world.txt')
class StringIODownloadView(VirtualDownloadView):

View file

@ -1,3 +1,4 @@
from six import iteritems
from django_downloadview.apache.response import XSendfileResponse
@ -21,7 +22,7 @@ class XSendfileValidator(object):
"""
self.assert_x_sendfile_response(test_case, response)
for key, value in assertions.iteritems():
for key, value in iteritems(assertions):
assert_func = getattr(self, 'assert_%s' % key)
assert_func(test_case, response, value)

View file

@ -2,7 +2,7 @@
"""File wrappers for use as exchange data between views and responses."""
from __future__ import absolute_import
from io import BytesIO
from urlparse import urlparse
from six.moves.urllib.parse import urlparse
from django.core.files.base import File
from django.utils.encoding import force_bytes

View file

@ -1,3 +1,4 @@
from six import iteritems
from django_downloadview.nginx.response import XAccelRedirectResponse
@ -35,7 +36,7 @@ class XAccelRedirectValidator(object):
"""
self.assert_x_accel_redirect_response(test_case, response)
for key, value in assertions.iteritems():
for key, value in iteritems(assertions):
assert_func = getattr(self, 'assert_%s' % key)
assert_func(test_case, response, value)

View file

@ -4,7 +4,8 @@ import os
import mimetypes
import re
import unicodedata
import urllib
import six
from six.moves import urllib
from django.conf import settings
from django.http import HttpResponse, StreamingHttpResponse
@ -14,28 +15,31 @@ from django.utils.encoding import force_str
def encode_basename_ascii(value):
"""Return US-ASCII encoded ``value`` for use in Content-Disposition header.
>>> encode_basename_ascii(unicode('éà', 'utf-8'))
>>> encode_basename_ascii('éà') # doctest: +IGNORE_UNICODE
u'ea'
Spaces are converted to underscores.
>>> encode_basename_ascii(' ')
>>> encode_basename_ascii(' ') # doctest: +IGNORE_UNICODE
u'_'
Text with non US-ASCII characters is expected to be unicode.
>>> encode_basename_ascii('éà') # doctest: +ELLIPSIS
>>> from six import b
>>> encode_basename_ascii(b('éà')) # doctest: +ELLIPSIS
Traceback (most recent call last):
...
UnicodeDecodeError: \'ascii\' codec can\'t decode byte ...
UnicodeDecodeError: ...
Of course, ASCII values are not modified.
>>> encode_basename_ascii('ea')
>>> encode_basename_ascii('ea') # doctest: +IGNORE_UNICODE
u'ea'
"""
ascii_basename = unicode(value)
if isinstance(value, six.binary_type):
value = value.decode('utf-8')
ascii_basename = six.text_type(value)
ascii_basename = unicodedata.normalize('NFKD', ascii_basename)
ascii_basename = ascii_basename.encode('ascii', 'ignore')
ascii_basename = ascii_basename.decode('ascii')
@ -49,11 +53,11 @@ def encode_basename_utf8(value):
>>> encode_basename_utf8(u' .txt')
'%20.txt'
>>> encode_basename_utf8(unicode('éà', 'utf-8'))
>>> encode_basename_utf8(u'éà')
'%C3%A9%C3%A0'
"""
return urllib.quote(force_str(value))
return urllib.parse.quote(force_str(value))
def content_disposition(filename):
@ -70,7 +74,7 @@ def content_disposition(filename):
If filename contains non US-ASCII characters, the returned value contains
UTF-8 encoded filename and US-ASCII fallback.
>>> content_disposition(unicode('é.txt', 'utf-8'))
>>> content_disposition(u'é.txt')
"attachment; filename=e.txt; filename*=UTF-8''%C3%A9.txt"
"""

View file

@ -1,5 +1,6 @@
"""Testing utilities."""
import shutil
from six import iteritems
import tempfile
from django.conf import settings
@ -101,7 +102,7 @@ class DownloadResponseValidator(object):
"""
self.assert_download_response(test_case, response)
for key, value in assertions.iteritems():
for key, value in iteritems(assertions):
assert_func = getattr(self, 'assert_%s' % key)
assert_func(test_case, response, value)
@ -138,7 +139,9 @@ class DownloadResponseValidator(object):
test_case.assertTrue(response['Content-Type'].startswith(value))
def assert_content(self, test_case, response, value):
test_case.assertEqual(''.join(response.streaming_content), value)
test_case.assertEqual(
''.join([s.decode('utf-8') for s in response.streaming_content]),
value)
def assert_attachment(self, test_case, response, value):
test_case.assertEqual('attachment;' in response['Content-Disposition'],

View file

@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
"""Test suite around :mod:`django_downloadview.api` and deprecation plan."""
import unittest
from six.moves import reload_module as reload
import warnings
from django.core.exceptions import ImproperlyConfigured

View file

@ -26,7 +26,7 @@ def url_basename(url, content_type):
If URL contains extension, it is kept as-is.
>>> url_basename(u'/path/to/somefile.rst', 'text/plain')
>>> url_basename(u'/path/to/somefile.rst', 'text/plain') # doctest: +IGNORE_UNICODE
u'somefile.rst'
"""
@ -43,5 +43,5 @@ def import_member(import_string):
"""
module_name, factory_name = str(import_string).rsplit('.', 1)
module = __import__(module_name, globals(), locals(), [factory_name], -1)
module = __import__(module_name, globals(), locals(), [factory_name], 0)
return getattr(module, factory_name)

View file

@ -35,7 +35,7 @@ KEYWORDS = ['file',
'mod_xsendfile',
'offload']
PACKAGES = [NAME.replace('-', '_')]
REQUIREMENTS = ['setuptools', 'Django>=1.5', 'requests']
REQUIREMENTS = ['setuptools', 'Django>=1.5', 'requests', 'six']
if IS_PYTHON2:
REQUIREMENTS.append('mock')
ENTRY_POINTS = {}

View file

@ -1,11 +1,12 @@
[tox]
envlist = py27,flake8,sphinx,readme
envlist = py27,py33,flake8,sphinx,readme
[testenv]
deps =
nose
rednose
coverage
doctest-ignore-unicode
commands =
pip install -e ./
pip install -e demo/
@ -28,6 +29,7 @@ deps =
nose
rednose
Sphinx
doctest-ignore-unicode
commands =
make --directory=docs clean html doctest
whitelist_externals =