Merge pull request #143 from CyrilRoelandteNovance/clean_py3

Python 3 support
This commit is contained in:
CyrilRoelandteNovance
2014-02-03 09:59:02 -08:00
4 changed files with 67 additions and 56 deletions

View File

@@ -166,6 +166,10 @@ class HTTPrettyRequest(BaseHTTPRequestHandler, BaseClass):
# Now 2 convenient attributes for the HTTPretty API:
# `querystring` holds a dictionary with the parsed query string
try:
self.path = self.path.encode('iso-8859-1')
except UnicodeDecodeError:
pass
self.path = decode_utf8(self.path)
qstring = self.path.split("?", 1)[-1]
@@ -187,7 +191,7 @@ class HTTPrettyRequest(BaseHTTPRequestHandler, BaseClass):
parsed = parse_qs(expanded)
result = {}
for k in parsed:
result[k] = map(decode_utf8, parsed[k])
result[k] = list(map(decode_utf8, parsed[k]))
return result
@@ -204,6 +208,7 @@ class HTTPrettyRequest(BaseHTTPRequestHandler, BaseClass):
content_type = self.headers.get('content-type', '')
do_parse = PARSING_FUNCTIONS.get(content_type, FALLBACK_FUNCTION)
body = decode_utf8(body)
try:
return do_parse(body)
except:
@@ -343,8 +348,8 @@ class fakesock(object):
self._sent_data.append(data)
try:
requestline, _ = data.split('\r\n', 1)
method, path, version = parse_requestline(requestline)
requestline, _ = data.split(b'\r\n', 1)
method, path, version = parse_requestline(decode_utf8(requestline))
is_parsing_headers = True
except ValueError:
is_parsing_headers = False
@@ -358,10 +363,10 @@ class fakesock(object):
if not is_parsing_headers:
if len(self._sent_data) > 1:
headers = utf8(last_requestline(self._sent_data))
meta = dict(self._entry.request.headers)
meta = self._entry.request.headers
body = utf8(self._sent_data[-1])
if meta.get('transfer-encoding', '') == 'chunked':
if not body.isdigit() and body != '\r\n' and body != '0\r\n\r\n':
if not body.isdigit() and body != b'\r\n' and body != b'0\r\n\r\n':
self._entry.request.body += body
else:
self._entry.request.body += body
@@ -372,7 +377,7 @@ class fakesock(object):
# path might come with
s = urlsplit(path)
POTENTIAL_HTTP_PORTS.add(int(s.port or 80))
headers, body = map(utf8, data.split('\r\n\r\n', 1))
headers, body = list(map(utf8, data.split(b'\r\n\r\n', 1)))
request = httpretty.historify_request(headers, body)
@@ -393,7 +398,7 @@ class fakesock(object):
def debug(self, func, *a, **kw):
if self.is_http:
frame = inspect.stack()[0][0]
lines = map(utf8, traceback.format_stack(frame))
lines = list(map(utf8, traceback.format_stack(frame)))
message = [
"HTTPretty intercepted and unexpected socket method call.",
@@ -807,12 +812,12 @@ class httpretty(HttpBaseClass):
'uri': uri,
'method': request.method,
'headers': dict(request.headers),
'body': request.body,
'body': decode_utf8(request.body),
'querystring': request.querystring
},
'response': {
'status': response.status,
'body': response.data,
'body': decode_utf8(response.data),
'headers': dict(response.headers)
}
})

View File

@@ -27,6 +27,7 @@ from __future__ import unicode_literals
import re
from .compat import BaseClass
from .utils import decode_utf8
STATUSES = {
@@ -109,14 +110,14 @@ STATUSES = {
class HttpBaseClass(BaseClass):
GET = b'GET'
PUT = b'PUT'
POST = b'POST'
DELETE = b'DELETE'
HEAD = b'HEAD'
PATCH = b'PATCH'
OPTIONS = b'OPTIONS'
CONNECT = b'CONNECT'
GET = 'GET'
PUT = 'PUT'
POST = 'POST'
DELETE = 'DELETE'
HEAD = 'HEAD'
PATCH = 'PATCH'
OPTIONS = 'OPTIONS'
CONNECT = 'CONNECT'
METHODS = (GET, PUT, POST, DELETE, HEAD, PATCH, OPTIONS, CONNECT)
@@ -133,8 +134,8 @@ def parse_requestline(s):
...
ValueError: Not a Request-Line
"""
methods = b'|'.join(HttpBaseClass.METHODS)
m = re.match(br'(' + methods + b')\s+(.*)\s+HTTP/(1.[0|1])', s, re.I)
methods = '|'.join(HttpBaseClass.METHODS)
m = re.match(r'(' + methods + ')\s+(.*)\s+HTTP/(1.[0|1])', s, re.I)
if m:
return m.group(1).upper(), m.group(2), m.group(3)
else:
@@ -147,7 +148,7 @@ def last_requestline(sent_data):
"""
for line in reversed(sent_data):
try:
parse_requestline(line)
parse_requestline(decode_utf8(line))
except ValueError:
pass
else:

View File

@@ -32,10 +32,12 @@ import re
import json
import requests
from sure import within, microseconds, expect
from tornado import version as tornado_version
from httpretty import HTTPretty, httprettified
from httpretty.compat import text_type
from httpretty.core import decode_utf8
from base import FIXTURE_FILE, use_tornado_server
from .base import FIXTURE_FILE, use_tornado_server
from tornado import version as tornado_version
try:
@@ -573,7 +575,7 @@ def test_httpretty_should_allow_registering_regexes_with_streaming_responses():
os.environ['DEBUG'] = 'true'
def my_callback(request, url, headers):
request.body.should.equal('hithere')
request.body.should.equal(b'hithere')
return 200, headers, "Received"
HTTPretty.register_uri(
@@ -590,7 +592,7 @@ def test_httpretty_should_allow_registering_regexes_with_streaming_responses():
'https://api.yipit.com/v1/deal;brand=gap?first_name=chuck&last_name=norris',
data=gen(),
)
expect(response.content).to.equal("Received")
expect(response.content).to.equal(b"Received")
expect(HTTPretty.last_request.method).to.equal('POST')
expect(HTTPretty.last_request.path).to.equal('/v1/deal;brand=gap?first_name=chuck&last_name=norris')
@@ -697,7 +699,7 @@ def test_recording_calls():
]
})
response['response'].should.have.key("status").being.equal(200)
response['response'].should.have.key("body").being.an(unicode)
response['response'].should.have.key("body").being.an(text_type)
response['response'].should.have.key("headers").being.a(dict)
response['response']["headers"].should.have.key("server").being.equal("TornadoServer/" + tornado_version)

View File

@@ -8,6 +8,7 @@ from datetime import datetime
from mock import Mock, patch, call
from sure import expect
from httpretty.compat import StringIO
from httpretty.core import HTTPrettyRequest, FakeSSLSocket, fakesock, httpretty
@@ -23,11 +24,11 @@ def test_request_stubs_internals():
# Given a valid HTTP request header string
headers = "\r\n".join([
'POST /somewhere/?name=foo&age=bar HTTP/1.1',
'Accept-Encoding: identity',
'Host: github.com',
'Content-Type: application/json',
'Connection: close',
'User-Agent: Python-urllib/2.7',
'accept-encoding: identity',
'host: github.com',
'content-type: application/json',
'connection: close',
'user-agent: Python-urllib/2.7',
])
# When I create a HTTPrettyRequest with an empty body
@@ -43,10 +44,12 @@ def test_request_stubs_internals():
})
# And the `rfile` should be a StringIO
request.should.have.property('rfile').being.a('StringIO.StringIO')
type_as_str = StringIO.__module__ + '.' + StringIO.__name__
request.should.have.property('rfile').being.a(type_as_str)
# And the `wfile` should be a StringIO
request.should.have.property('wfile').being.a('StringIO.StringIO')
request.should.have.property('wfile').being.a(type_as_str)
# And the `method` should be available
request.should.have.property('method').being.equal('POST')
@@ -301,16 +304,16 @@ def test_fakesock_socket_real_sendall(old_socket):
# Background: the real socket will stop returning bytes after the
# first call
real_socket = old_socket.return_value
real_socket.recv.side_effect = ['response from server', ""]
real_socket.recv.side_effect = [b'response from server', b""]
# Given a fake socket
socket = fakesock.socket()
# When I call real_sendall with data, some args and kwargs
socket.real_sendall("SOMEDATA", 'some extra args...', foo='bar')
socket.real_sendall(b"SOMEDATA", b'some extra args...', foo=b'bar')
# Then it should have called sendall in the real socket
real_socket.sendall.assert_called_once_with("SOMEDATA", 'some extra args...', foo='bar')
real_socket.sendall.assert_called_once_with(b"SOMEDATA", b'some extra args...', foo=b'bar')
# And the timeout was set to 0
real_socket.settimeout.assert_called_once_with(0)
@@ -322,7 +325,7 @@ def test_fakesock_socket_real_sendall(old_socket):
])
# And the buffer should contain the data from the server
socket.fd.getvalue().should.equal("response from server")
socket.fd.getvalue().should.equal(b"response from server")
# And connect was never called
real_socket.connect.called.should.be.false
@@ -336,17 +339,17 @@ def test_fakesock_socket_real_sendall_continue_eagain(socket, old_socket):
# Background: the real socket will stop returning bytes after the
# first call
real_socket = old_socket.return_value
real_socket.recv.side_effect = [SocketErrorStub(errno.EAGAIN), 'after error', ""]
real_socket.recv.side_effect = [SocketErrorStub(errno.EAGAIN), b'after error', b""]
# Given a fake socket
socket = fakesock.socket()
# When I call real_sendall with data, some args and kwargs
socket.real_sendall("SOMEDATA", 'some extra args...', foo='bar')
socket.real_sendall(b"SOMEDATA", b'some extra args...', foo=b'bar')
# Then it should have called sendall in the real socket
real_socket.sendall.assert_called_once_with("SOMEDATA", 'some extra args...', foo='bar')
real_socket.sendall.assert_called_once_with(b"SOMEDATA", b'some extra args...', foo=b'bar')
# And the timeout was set to 0
real_socket.settimeout.assert_called_once_with(0)
@@ -358,7 +361,7 @@ def test_fakesock_socket_real_sendall_continue_eagain(socket, old_socket):
])
# And the buffer should contain the data from the server
socket.fd.getvalue().should.equal("after error")
socket.fd.getvalue().should.equal(b"after error")
# And connect was never called
real_socket.connect.called.should.be.false
@@ -372,16 +375,16 @@ def test_fakesock_socket_real_sendall_socket_error(socket, old_socket):
# Background: the real socket will stop returning bytes after the
# first call
real_socket = old_socket.return_value
real_socket.recv.side_effect = [SocketErrorStub(42), 'after error', ""]
real_socket.recv.side_effect = [SocketErrorStub(42), b'after error', ""]
# Given a fake socket
socket = fakesock.socket()
# When I call real_sendall with data, some args and kwargs
socket.real_sendall("SOMEDATA", 'some extra args...', foo='bar')
socket.real_sendall(b"SOMEDATA", b'some extra args...', foo=b'bar')
# Then it should have called sendall in the real socket
real_socket.sendall.assert_called_once_with("SOMEDATA", 'some extra args...', foo='bar')
real_socket.sendall.assert_called_once_with(b"SOMEDATA", b'some extra args...', foo=b'bar')
# And the timeout was set to 0
real_socket.settimeout.assert_called_once_with(0)
@@ -390,7 +393,7 @@ def test_fakesock_socket_real_sendall_socket_error(socket, old_socket):
real_socket.recv.assert_called_once_with(16)
# And the buffer should contain the data from the server
socket.fd.getvalue().should.equal("")
socket.fd.getvalue().should.equal(b"")
# And connect was never called
real_socket.connect.called.should.be.false
@@ -403,7 +406,7 @@ def test_fakesock_socket_real_sendall_when_http(POTENTIAL_HTTP_PORTS, old_socket
# Background: the real socket will stop returning bytes after the
# first call
real_socket = old_socket.return_value
real_socket.recv.side_effect = ['response from foobar :)', ""]
real_socket.recv.side_effect = [b'response from foobar :)', b""]
# And the potential http port is 4000
POTENTIAL_HTTP_PORTS.__contains__.side_effect = lambda other: int(other) == 4000
@@ -415,7 +418,7 @@ def test_fakesock_socket_real_sendall_when_http(POTENTIAL_HTTP_PORTS, old_socket
socket.connect(('foobar.com', 4000))
# And send some data
socket.real_sendall("SOMEDATA")
socket.real_sendall(b"SOMEDATA")
# Then connect should have been called
real_socket.connect.assert_called_once_with(('foobar.com', 4000))
@@ -430,7 +433,7 @@ def test_fakesock_socket_real_sendall_when_http(POTENTIAL_HTTP_PORTS, old_socket
])
# And the buffer should contain the data from the server
socket.fd.getvalue().should.equal("response from foobar :)")
socket.fd.getvalue().should.equal(b"response from foobar :)")
@patch('httpretty.core.old_socket')
@@ -456,7 +459,7 @@ def test_fakesock_socket_sendall_with_valid_requestline(POTENTIAL_HTTP_PORTS, ht
socket.connect(('foo.com', 80))
# When I try to send data
socket.sendall("GET /foobar HTTP/1.1\r\nContent-Type: application/json\r\n\r\n")
socket.sendall(b"GET /foobar HTTP/1.1\r\nContent-Type: application/json\r\n\r\n")
@patch('httpretty.core.old_socket')
@@ -482,7 +485,7 @@ def test_fakesock_socket_sendall_with_valid_requestline(POTENTIAL_HTTP_PORTS, ht
socket.connect(('foo.com', 80))
# When I try to send data
socket.sendall("GET /foobar HTTP/1.1\r\nContent-Type: application/json\r\n\r\n")
socket.sendall(b"GET /foobar HTTP/1.1\r\nContent-Type: application/json\r\n\r\n")
@patch('httpretty.core.old_socket')
@@ -493,7 +496,7 @@ def test_fakesock_socket_sendall_with_body_data_no_entry(POTENTIAL_HTTP_PORTS, o
# Using a subclass of socket that mocks out real_sendall
class MySocket(fakesock.socket):
def real_sendall(self, data):
data.should.equal('BLABLABLABLA')
data.should.equal(b'BLABLABLABLA')
return 'cool'
# Given an instance of that socket
@@ -504,7 +507,7 @@ def test_fakesock_socket_sendall_with_body_data_no_entry(POTENTIAL_HTTP_PORTS, o
socket.connect(('foo.com', 80))
# When I try to send data
result = socket.sendall("BLABLABLABLA")
result = socket.sendall(b"BLABLABLABLA")
# Then the result should be the return value from real_sendall
result.should.equal('cool')
@@ -522,7 +525,7 @@ def test_fakesock_socket_sendall_with_body_data_with_entry(POTENTIAL_HTTP_PORTS,
# Using a mocked entry
entry = Mock()
entry.request.headers = {}
entry.request.body = ''
entry.request.body = b''
# Given an instance of that socket
socket = MySocket()
@@ -533,10 +536,10 @@ def test_fakesock_socket_sendall_with_body_data_with_entry(POTENTIAL_HTTP_PORTS,
socket.connect(('foo.com', 80))
# When I try to send data
socket.sendall("BLABLABLABLA")
socket.sendall(b"BLABLABLABLA")
# Then the entry should have that body
entry.request.body.should.equal('BLABLABLABLA')
entry.request.body.should.equal(b'BLABLABLABLA')
@patch('httpretty.core.old_socket')
@@ -553,7 +556,7 @@ def test_fakesock_socket_sendall_with_body_data_with_chunked_entry(POTENTIAL_HTT
entry.request.headers = {
'transfer-encoding': 'chunked',
}
entry.request.body = ''
entry.request.body = b''
# Given an instance of that socket
socket = MySocket()
@@ -563,7 +566,7 @@ def test_fakesock_socket_sendall_with_body_data_with_chunked_entry(POTENTIAL_HTT
socket.connect(('foo.com', 80))
# When I try to send data
socket.sendall("BLABLABLABLA")
socket.sendall(b"BLABLABLABLA")
# Then the entry should have that body
httpretty.last_request.body.should.equal('BLABLABLABLA')
httpretty.last_request.body.should.equal(b'BLABLABLABLA')