py3k support

This commit is contained in:
Steve Pulec 2013-02-13 23:10:07 -05:00
parent 751557dd46
commit 5dd66a0536
12 changed files with 113 additions and 52 deletions

2
MANIFEST.in Normal file
View File

@ -0,0 +1,2 @@
include requirements.pip

View File

@ -11,15 +11,17 @@ check_dependencies:
python -c "import $$dependency" 2>/dev/null || (echo "You must install $$dependency in order to run httpretty's tests" && exit 3) ; \
done
unit: clean
test: unit functional doctests
unit:
@echo "Running unit tests ..."
@nosetests -s --verbosity=2 --with-coverage --cover-erase --cover-inclusive tests/unit --cover-package=httpretty
functional: clean
functional:
@echo "Running functional tests ..."
@nosetests -s --verbosity=2 --with-coverage --cover-erase --cover-inclusive tests/functional --cover-package=httpretty
doctests: clean
doctests:
@echo "Running documentation tests tests ..."
@steadymark README.md

View File

@ -31,14 +31,40 @@ import functools
import itertools
import warnings
import logging
import sys
import traceback
PY3 = sys.version_info[0] == 3
if PY3:
text_type = str
binary_type = bytes
import io
StringIO = io.StringIO
class Compat_Repr(object):
def __repr__(self):
return self.__unicode__()
else:
text_type = unicode
binary_type = str
import StringIO
StringIO = StringIO.StringIO
class Compat_Repr(object):
def __repr__(self):
return self.__unicode__().encode('utf-8')
from datetime import datetime
from datetime import timedelta
from StringIO import StringIO
from urlparse import urlsplit
try:
from urllib.parse import urlsplit
except ImportError:
from urlparse import urlsplit
from BaseHTTPServer import BaseHTTPRequestHandler
try:
from http.server import BaseHTTPRequestHandler
except ImportError:
from BaseHTTPServer import BaseHTTPRequestHandler
old_socket = socket.socket
old_create_connection = socket.create_connection
@ -59,7 +85,8 @@ except ImportError:
try:
import ssl
old_ssl_wrap_socket = ssl.wrap_socket
old_sslwrap_simple = ssl.sslwrap_simple
if not PY3:
old_sslwrap_simple = ssl.sslwrap_simple
old_sslsocket = ssl.SSLSocket
except ImportError:
ssl = None
@ -70,10 +97,10 @@ class HTTPrettyError(Exception):
def utf8(s):
if isinstance(s, unicode):
if isinstance(s, text_type):
s = s.encode('utf-8')
return str(s)
return binary_type(s)
def parse_requestline(s):
@ -97,7 +124,7 @@ def parse_requestline(s):
raise ValueError('Not a Request-Line')
class HTTPrettyRequest(BaseHTTPRequestHandler, object):
class HTTPrettyRequest(BaseHTTPRequestHandler, Compat_Repr, object):
def __init__(self, headers, body=''):
self.body = utf8(body)
self.raw_headers = utf8(headers)
@ -107,7 +134,7 @@ class HTTPrettyRequest(BaseHTTPRequestHandler, object):
self.parse_request()
self.method = self.command
def __repr__(self):
def __unicode__(self):
return 'HTTPrettyRequest(headers={0}, body="{1}")'.format(
self.headers,
self.body,
@ -229,6 +256,7 @@ class fakesock(object):
hostnames = [i.hostname for i in HTTPretty._entries.keys()]
self.fd.seek(0)
try:
print("data", data)
requestline, _ = data.split('\r\n', 1)
method, path, version = parse_requestline(requestline)
is_parsing_headers = True
@ -244,7 +272,7 @@ class fakesock(object):
try:
return HTTPretty.historify_request(headers, body, False)
except Exception, e:
except Exception as e:
logging.error(traceback.format_exc(e))
return self._true_sendall(data, *args, **kw)
@ -390,7 +418,7 @@ STATUSES = {
}
class Entry(object):
class Entry(Compat_Repr, object):
def __init__(self, method, uri, body,
adding_headers=None,
forcing_headers=None,
@ -443,7 +471,7 @@ class Entry(object):
)
)
def __repr__(self):
def __unicode__(self):
return r'<Entry %s %s getting %d>' % (
self.method, self.uri, self.status)
@ -511,7 +539,7 @@ class Entry(object):
fk.seek(0)
class URIInfo(object):
class URIInfo(Compat_Repr, object):
def __init__(self,
username='',
password='',
@ -564,16 +592,13 @@ class URIInfo(object):
'path',
)
fmt = ", ".join(['%s="%s"' % (k, getattr(self, k, '')) for k in attrs])
return ur'<httpretty.URIInfo(%s)>' % fmt
def __repr__(self):
return unicode(self)
return r'<httpretty.URIInfo(%s)>' % fmt
def __hash__(self):
return hash(unicode(self))
return hash(text_type(self))
def __eq__(self, other):
return unicode(self) == unicode(other)
return text_type(self) == text_type(other)
@classmethod
def from_uri(cls, uri, entry):
@ -589,7 +614,7 @@ class URIInfo(object):
entry)
class HTTPretty(object):
class HTTPretty(Compat_Repr, object):
u"""The URI registration class"""
_entries = {}
latest_requests = []
@ -646,7 +671,7 @@ class HTTPretty(object):
cls._entries[info] = entries_for_this_uri
def __repr__(self):
def __unicode__(self):
return u'<HTTPretty with %d URI entries>' % len(self._entries)
@classmethod
@ -688,12 +713,14 @@ class HTTPretty(object):
if ssl:
ssl.wrap_socket = old_ssl_wrap_socket
ssl.sslwrap_simple = old_sslwrap_simple
ssl.SSLSocket = old_sslsocket
ssl.__dict__['wrap_socket'] = old_ssl_wrap_socket
ssl.__dict__['sslwrap_simple'] = old_sslwrap_simple
ssl.__dict__['SSLSocket'] = old_sslsocket
if not PY3:
ssl.sslwrap_simple = old_sslwrap_simple
ssl.__dict__['sslwrap_simple'] = old_sslwrap_simple
@classmethod
def enable(cls):
socket.socket = fakesock.socket
@ -722,13 +749,15 @@ class HTTPretty(object):
if ssl:
ssl.wrap_socket = fake_wrap_socket
ssl.sslwrap_simple = fake_wrap_socket
ssl.SSLSocket = FakeSSLSocket
ssl.__dict__['wrap_socket'] = fake_wrap_socket
ssl.__dict__['sslwrap_simple'] = fake_wrap_socket
ssl.__dict__['SSLSocket'] = FakeSSLSocket
if not PY3:
ssl.sslwrap_simple = fake_wrap_socket
ssl.__dict__['sslwrap_simple'] = fake_wrap_socket
def httprettified(test):
"A decorator tests that use HTTPretty"

View File

@ -1,7 +1,5 @@
bolacha==0.6.0
couleur==0.4.1
distribute==0.6.31
coverage==3.5.3
distribute==0.6.30
httplib2==0.7.6
ipdb==0.7
ipython==0.13.1

View File

@ -42,11 +42,20 @@ def get_packages():
return packages
def test_packages():
test_reqs = os.path.join(os.getcwd(), 'requirements.pip')
tests_require = [
line.strip() for line in open(test_reqs).readlines()
if not line.startswith("#")
]
setup(name='httpretty',
version=version,
description='HTTP client mock for Python',
author=u'Gabriel Falcao',
author_email='gabriel@nacaolivre.org',
url='http://github.com/gabrielfalcao/httpretty',
packages=get_packages()
packages=get_packages(),
tests_require=test_packages()
)

View File

@ -24,6 +24,8 @@
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
from __future__ import unicode_literals
import urllib2
from testserver import Server
from sure import expect, that_with_context

View File

@ -24,6 +24,7 @@
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
from __future__ import unicode_literals
import httplib2
from sure import expect, within, microseconds

View File

@ -24,6 +24,7 @@
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
from __future__ import unicode_literals
import requests
from sure import within, microseconds, expect
@ -224,7 +225,7 @@ def test_httpretty_ignores_querystrings_from_registered_uri(now):
u"HTTPretty should ignore querystrings from the registered uri (requests library)"
HTTPretty.register_uri(HTTPretty.GET, "http://yipit.com/?id=123",
body="Find the best daily deals")
body=b"Find the best daily deals")
response = requests.get('http://yipit.com/', params={'id': 123})
expect(response.text).to.equal('Find the best daily deals')
@ -257,9 +258,9 @@ def test_streaming_responses(now):
#XXX this obviously isn't a fully functional twitter streaming client!
twitter_response_lines = [
'{"text":"If \\"for the boobs\\" requests to follow me one more time I\'m calling the police. http://t.co/a0mDEAD8"}\r\n',
'\r\n',
'{"text":"RT @onedirection: Thanks for all your #FollowMe1D requests Directioners! We\u2019ll be following 10 people throughout the day starting NOW. G ..."}\r\n'
b'{"text":"If \\"for the boobs\\" requests to follow me one more time I\'m calling the police. http://t.co/a0mDEAD8"}\r\n',
b'\r\n',
b'{"text":"RT @onedirection: Thanks for all your #FollowMe1D requests Directioners! We\u2019ll be following 10 people throughout the day starting NOW. G ..."}\r\n'
]
TWITTER_STREAMING_URL = "https://stream.twitter.com/1/statuses/filter.json"

View File

@ -24,7 +24,15 @@
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
import urllib2
from __future__ import unicode_literals
try:
from urllib.request import urlopen
import urllib as urllib2
except ImportError:
import urllib2
urlopen = urllib2.urlopen
from sure import *
from httpretty import HTTPretty, httprettified
@ -37,7 +45,7 @@ def test_httpretty_should_mock_a_simple_get_with_urllib2_read():
HTTPretty.register_uri(HTTPretty.GET, "http://yipit.com/",
body="Find the best daily deals")
fd = urllib2.urlopen('http://yipit.com')
fd = urlopen('http://yipit.com')
got = fd.read()
fd.close()
@ -53,7 +61,7 @@ def test_httpretty_should_mock_headers_urllib2(now):
body="this is supposed to be the response",
status=201)
request = urllib2.urlopen('http://github.com')
request = urlopen('http://github.com')
headers = dict(request.headers)
request.close()
@ -82,7 +90,7 @@ def test_httpretty_should_allow_adding_and_overwritting_urllib2(now):
'Content-Type': 'application/json',
})
request = urllib2.urlopen('http://github.com')
request = urlopen('http://github.com')
headers = dict(request.headers)
request.close()
@ -108,7 +116,7 @@ def test_httpretty_should_allow_forcing_headers_urllib2():
'Content-Type': 'application/xml',
})
request = urllib2.urlopen('http://github.com')
request = urlopen('http://github.com')
headers = dict(request.headers)
request.close()
@ -129,7 +137,7 @@ def test_httpretty_should_allow_adding_and_overwritting_by_kwargs_u2(now):
content_length='111111',
content_type='application/json')
request = urllib2.urlopen('http://github.com')
request = urlopen('http://github.com')
headers = dict(request.headers)
request.close()
@ -157,20 +165,20 @@ def test_httpretty_should_support_a_list_of_successive_responses_urllib2(now):
HTTPretty.Response(body='second and last response', status=202),
])
request1 = urllib2.urlopen('https://api.yahoo.com/test')
request1 = urlopen('https://api.yahoo.com/test')
body1 = request1.read()
request1.close()
expect(request1.code).to.equal(201)
expect(body1).to.equal('first response')
request2 = urllib2.urlopen('https://api.yahoo.com/test')
request2 = urlopen('https://api.yahoo.com/test')
body2 = request2.read()
request2.close()
expect(request2.code).to.equal(202)
expect(body2).to.equal('second and last response')
request3 = urllib2.urlopen('https://api.yahoo.com/test')
request3 = urlopen('https://api.yahoo.com/test')
body3 = request3.read()
request3.close()
expect(request3.code).to.equal(202)
@ -192,7 +200,7 @@ def test_can_inspect_last_request(now):
'content-type': 'text/json',
},
)
fd = urllib2.urlopen(request)
fd = urlopen(request)
got = fd.read()
fd.close()
@ -221,7 +229,7 @@ def test_can_inspect_last_request_with_ssl(now):
'content-type': 'text/json',
},
)
fd = urllib2.urlopen(request)
fd = urlopen(request)
got = fd.read()
fd.close()
@ -243,7 +251,7 @@ def test_httpretty_ignores_querystrings_from_registered_uri():
HTTPretty.register_uri(HTTPretty.GET, "http://yipit.com/?id=123",
body="Find the best daily deals")
fd = urllib2.urlopen('http://yipit.com/?id=123')
fd = urlopen('http://yipit.com/?id=123')
got = fd.read()
fd.close()

View File

@ -24,9 +24,17 @@
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
from __future__ import unicode_literals
import os
import sys
from StringIO import StringIO
try:
import io
StringIO = io.StringIO
except ImportError:
import StringIO
StringIO = StringIO.StringIO
from tornado.web import Application
from tornado.web import RequestHandler
from tornado.httpserver import HTTPServer

View File

@ -24,6 +24,7 @@
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
from __future__ import unicode_literals
from sure import expect
from httpretty import HTTPretty, HTTPrettyError, STATUSES

View File

@ -1,7 +1,7 @@
[tox]
envlist = py26, py27
envlist = py26, py27, py33
[testenv]
commands =
pip install --use-mirrors -q -r requirements.pip
make
python setup.py test
make test