summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVictor Stinner <victor.stinner@gmail.com>2015-04-22 00:26:01 +0200
committerVictor Stinner <victor.stinner@gmail.com>2015-04-22 00:26:01 +0200
commit565341b5faeacc912900bb244afc956cbf4a0a2a (patch)
tree395c204608f0e80f06db33ffea35bc7f28901075
parent82f13b6240a5a0e92f68291d90bef7e75d82a3ee (diff)
downloadpaste-565341b5faeacc912900bb244afc956cbf4a0a2a.tar.gz
Fix fileapp on Python 3
* Don't compare None with int * Add __next__() method (alias to next()). * HTTP body must be bytes * Don't use string.letters but an hardcoded string to not depend on the locale.
-rw-r--r--paste/fileapp.py12
-rw-r--r--tests/test_fileapp.py51
2 files changed, 37 insertions, 26 deletions
diff --git a/paste/fileapp.py b/paste/fileapp.py
index 3825386..e18281a 100644
--- a/paste/fileapp.py
+++ b/paste/fileapp.py
@@ -122,7 +122,7 @@ class DataApp(object):
for head in list_headers(entity=True):
head.delete(headers)
start_response('304 Not Modified', headers)
- return ['']
+ return [b'']
except HTTPBadRequest as exce:
return exce.wsgi_application(environ, start_response)
@@ -133,12 +133,13 @@ class DataApp(object):
if not client_etags:
try:
client_clock = IF_MODIFIED_SINCE.parse(environ)
- if client_clock >= int(self.last_modified):
+ if (client_clock is not None
+ and client_clock >= int(self.last_modified)):
# horribly inefficient, n^2 performance, yuck!
for head in list_headers(entity=True):
head.delete(headers)
start_response('304 Not Modified', headers)
- return [''] # empty body
+ return [b''] # empty body
except HTTPBadRequest as exce:
return exce.wsgi_application(environ, start_response)
@@ -224,11 +225,11 @@ class FileApp(DataApp):
if isinstance(retval, list):
# cached content, exception, or not-modified
if is_head:
- return ['']
+ return [b'']
return retval
(lower, content_length) = retval
if is_head:
- return ['']
+ return [b'']
file.seek(lower)
file_wrapper = environ.get('wsgi.file_wrapper', None)
if file_wrapper:
@@ -256,6 +257,7 @@ class _FileIter(object):
if not data:
raise StopIteration
return data
+ __next__ = next
def close(self):
self.file.close()
diff --git a/tests/test_fileapp.py b/tests/test_fileapp.py
index d5b2a95..3bf2bb9 100644
--- a/tests/test_fileapp.py
+++ b/tests/test_fileapp.py
@@ -9,22 +9,27 @@ try:
except ImportError:
# Python 2
from rfc822 import parsedate_tz, mktime_tz
+import six
from paste.fileapp import *
from paste.fixture import *
+# NOTE(haypo): don't use string.letters because the order of lower and upper
+# case letters changes when locale.setlocale() is called for the first time
+LETTERS = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
+
def test_data():
- harness = TestApp(DataApp('mycontent'))
+ harness = TestApp(DataApp(b'mycontent'))
res = harness.get("/")
assert 'application/octet-stream' == res.header('content-type')
assert '9' == res.header('content-length')
assert "<Response 200 OK 'mycontent'>" == repr(res)
- harness.app.set_content("bingles")
+ harness.app.set_content(b"bingles")
assert "<Response 200 OK 'bingles'>" == repr(harness.get("/"))
def test_cache():
def build(*args,**kwargs):
- app = DataApp("SomeContent")
+ app = DataApp(b"SomeContent")
app.cache_control(*args,**kwargs)
return TestApp(app).get("/")
res = build()
@@ -48,7 +53,7 @@ def test_cache():
def test_disposition():
def build(*args,**kwargs):
- app = DataApp("SomeContent")
+ app = DataApp(b"SomeContent")
app.content_disposition(*args,**kwargs)
return TestApp(app).get("/")
res = build()
@@ -73,7 +78,7 @@ def test_disposition():
assert False, "should be an exception"
def test_modified():
- harness = TestApp(DataApp('mycontent'))
+ harness = TestApp(DataApp(b'mycontent'))
res = harness.get("/")
assert "<Response 200 OK 'mycontent'>" == repr(res)
last_modified = res.header('last-modified')
@@ -84,19 +89,20 @@ def test_modified():
assert "<Response 304 Not Modified ''>" == repr(res)
res = harness.get("/",status=400,
headers={'if-modified-since': 'garbage'})
- assert 400 == res.status and "ill-formed timestamp" in res.body
+ assert 400 == res.status and b"ill-formed timestamp" in res.body
res = harness.get("/",status=400,
headers={'if-modified-since':
'Thu, 22 Dec 2030 01:01:01 GMT'})
- assert 400 == res.status and "check your system clock" in res.body
+ assert 400 == res.status and b"check your system clock" in res.body
def test_file():
import random, string, os
tempfile = "test_fileapp.%s.txt" % (random.random())
- content = string.letters * 20
- file = open(tempfile,"w")
- file.write(content)
- file.close()
+ content = LETTERS * 20
+ if six.PY3:
+ content = content.encode('utf8')
+ with open(tempfile, "wb") as fp:
+ fp.write(content)
try:
from paste import fileapp
app = fileapp.FileApp(tempfile)
@@ -113,7 +119,7 @@ def test_file():
res = TestApp(app).get("/",headers={'Cache-Control': 'max-age=0'})
assert len(content)+10 == int(res.header('content-length'))
assert 'text/plain' == res.header('content-type')
- assert content + "0123456789" == res.body
+ assert content + b"0123456789" == res.body
assert app.content # we are still cached
file = open(tempfile,"a+")
file.write("X" * fileapp.CACHE_SIZE) # exceed the cashe size
@@ -123,7 +129,7 @@ def test_file():
newsize = fileapp.CACHE_SIZE + len(content)+12
assert newsize == int(res.header('content-length'))
assert newsize == len(res.body)
- assert res.body.startswith(content) and res.body.endswith('XYZ')
+ assert res.body.startswith(content) and res.body.endswith(b'XYZ')
assert not app.content # we are no longer cached
finally:
import os
@@ -147,7 +153,7 @@ def test_dir():
assert TestApp(app).get(path, status=403).status == 403, ValueError(path)
for path in ['/~', '/foo', '/dir', '/dir/']:
assert TestApp(app).get(path, status=404).status == 404, ValueError(path)
- assert TestApp(app).get('/file').body == 'abcd'
+ assert TestApp(app).get('/file').body == b'abcd'
finally:
os.remove(tmpfile)
os.rmdir(tmpsubdir)
@@ -171,14 +177,16 @@ def _excercize_range(build,content):
assert res.body == content[:10]
assert res.header('content-length') == '10'
res = build("bytes=%d-" % (len(content)-1), status=206)
- assert res.body == 'Z'
+ assert res.body == b'Z'
assert res.header('content-length') == '1'
res = build("bytes=%d-%d" % (3,17), status=206)
assert res.body == content[3:18]
assert res.header('content-length') == '15'
def test_range():
- content = string.letters * 5
+ content = LETTERS * 5
+ if six.PY3:
+ content = content.encode('utf8')
def build(range, status=200):
app = DataApp(content)
return TestApp(app).get("/",headers={'Range': range}, status=status)
@@ -189,18 +197,19 @@ def test_file_range():
from paste import fileapp
import random, string, os
tempfile = "test_fileapp.%s.txt" % (random.random())
- content = string.letters * (1+(fileapp.CACHE_SIZE / len(string.letters)))
+ content = LETTERS * (1+(fileapp.CACHE_SIZE // len(LETTERS)))
+ if six.PY3:
+ content = content.encode('utf8')
assert len(content) > fileapp.CACHE_SIZE
- file = open(tempfile,"w")
- file.write(content)
- file.close()
+ with open(tempfile, "wb") as fp:
+ fp.write(content)
try:
def build(range, status=200):
app = fileapp.FileApp(tempfile)
return TestApp(app).get("/",headers={'Range': range},
status=status)
_excercize_range(build,content)
- for size in (13,len(string.letters),len(string.letters)-1):
+ for size in (13,len(LETTERS), len(LETTERS)-1):
fileapp.BLOCK_SIZE = size
_excercize_range(build,content)
finally: