mirror of
https://github.com/scrapy/scrapy.git
synced 2025-02-24 20:23:44 +00:00
added Request.replace method, improved tests for replace/copy method in Request/Response classes
--HG-- extra : convert_revision : svn%3Ab85faa78-f9eb-468e-a121-7cced6da292c%40745
This commit is contained in:
parent
314bbabb30
commit
0c9f7257a2
@ -17,9 +17,8 @@ from scrapy.utils.defer import chain_deferred
|
|||||||
|
|
||||||
class Request(object):
|
class Request(object):
|
||||||
|
|
||||||
def __init__(self, url, callback=None, method='GET',
|
def __init__(self, url, callback=None, method='GET', headers=None, body=None,
|
||||||
body=None, headers=None, cookies=None, meta=None,
|
cookies=None, meta=None, url_encoding='utf-8', dont_filter=None):
|
||||||
url_encoding='utf-8', dont_filter=None):
|
|
||||||
|
|
||||||
self.encoding = url_encoding # this one has to be set first
|
self.encoding = url_encoding # this one has to be set first
|
||||||
self.set_url(url)
|
self.set_url(url)
|
||||||
@ -69,14 +68,14 @@ class Request(object):
|
|||||||
'method': self.method,
|
'method': self.method,
|
||||||
'url': self.url,
|
'url': self.url,
|
||||||
'headers': self.headers,
|
'headers': self.headers,
|
||||||
'cookies': self.cookies,
|
|
||||||
'body': self.body,
|
'body': self.body,
|
||||||
|
'cookies': self.cookies,
|
||||||
'meta': self.meta,
|
'meta': self.meta,
|
||||||
}
|
}
|
||||||
return "%s(%s)" % (self.__class__.__name__, repr(d))
|
return "%s(%s)" % (self.__class__.__name__, repr(d))
|
||||||
|
|
||||||
def copy(self):
|
def copy(self):
|
||||||
"""Return a new request cloned from this one"""
|
"""Return a copy a of this Request"""
|
||||||
new = copy.copy(self)
|
new = copy.copy(self)
|
||||||
new.cache = {}
|
new.cache = {}
|
||||||
for att in self.__dict__:
|
for att in self.__dict__:
|
||||||
@ -86,6 +85,17 @@ class Request(object):
|
|||||||
new.deferred = defer.Deferred()
|
new.deferred = defer.Deferred()
|
||||||
return new
|
return new
|
||||||
|
|
||||||
|
def replace(self, url=None, method=None, headers=None, body=None, cookies=None, meta=None):
|
||||||
|
"""Create a new Request with the same attributes except for those
|
||||||
|
given new values.
|
||||||
|
"""
|
||||||
|
return self.__class__(url=url or self.url,
|
||||||
|
method=method or self.method,
|
||||||
|
headers=headers or copy.deepcopy(self.headers),
|
||||||
|
body=body or self.body,
|
||||||
|
cookies=cookies or self.cookies,
|
||||||
|
meta=meta or self.meta)
|
||||||
|
|
||||||
def httprepr(self):
|
def httprepr(self):
|
||||||
""" Return raw HTTP request representation (as string). This is
|
""" Return raw HTTP request representation (as string). This is
|
||||||
provided only for reference since it's not the actual stream of bytes
|
provided only for reference since it's not the actual stream of bytes
|
||||||
|
@ -51,24 +51,21 @@ class Response(object):
|
|||||||
return "<%d %s>" % (self.status, self.url)
|
return "<%d %s>" % (self.status, self.url)
|
||||||
|
|
||||||
def copy(self):
|
def copy(self):
|
||||||
"""Create a new Response based on the current one"""
|
"""Return a copy of this Response"""
|
||||||
return self.replace()
|
return self.replace()
|
||||||
|
|
||||||
def replace(self, url=None, status=None, headers=None, body=None):
|
def replace(self, url=None, status=None, headers=None, body=None, meta=None):
|
||||||
"""Create a new Response with the same attributes except for those
|
"""Create a new Response with the same attributes except for those
|
||||||
given new values.
|
given new values.
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
>>> newresp = oldresp.replace(body="New body")
|
|
||||||
"""
|
"""
|
||||||
new = self.__class__(url=url or self.url,
|
new = self.__class__(url=url or self.url,
|
||||||
status=status or self.status,
|
status=status or self.status,
|
||||||
headers=headers or copy.deepcopy(self.headers),
|
headers=headers or copy.deepcopy(self.headers),
|
||||||
body=body)
|
meta=meta or self.meta)
|
||||||
if body is None:
|
if body is None:
|
||||||
new.body = copy.deepcopy(self.body)
|
new.body = copy.deepcopy(self.body)
|
||||||
new.meta = self.meta.copy()
|
else:
|
||||||
|
new.body = _ResponseBody(body, self.headers_encoding())
|
||||||
return new
|
return new
|
||||||
|
|
||||||
def httprepr(self):
|
def httprepr(self):
|
||||||
@ -184,3 +181,6 @@ class _ResponseBody(object):
|
|||||||
def __len__(self):
|
def __len__(self):
|
||||||
return len(self._content)
|
return len(self._content)
|
||||||
|
|
||||||
|
def __eq__(self, other):
|
||||||
|
return self._content == other._content and self.declared_encoding == other.declared_encoding
|
||||||
|
|
||||||
|
@ -105,7 +105,10 @@ class RequestTest(unittest.TestCase):
|
|||||||
def test_copy(self):
|
def test_copy(self):
|
||||||
"""Test Request copy"""
|
"""Test Request copy"""
|
||||||
|
|
||||||
r1 = Request("http://www.example.com")
|
def somecallback():
|
||||||
|
pass
|
||||||
|
|
||||||
|
r1 = Request("http://www.example.com", callback=somecallback)
|
||||||
r1.meta['foo'] = 'bar'
|
r1.meta['foo'] = 'bar'
|
||||||
r1.cache['lala'] = 'lolo'
|
r1.cache['lala'] = 'lolo'
|
||||||
r2 = r1.copy()
|
r2 = r1.copy()
|
||||||
@ -113,10 +116,18 @@ class RequestTest(unittest.TestCase):
|
|||||||
assert r1.cache
|
assert r1.cache
|
||||||
assert not r2.cache
|
assert not r2.cache
|
||||||
|
|
||||||
|
assert r1.deferred is not r2.deferred
|
||||||
|
|
||||||
# make sure meta dict is shallow copied
|
# make sure meta dict is shallow copied
|
||||||
assert r1.meta is not r2.meta, "meta must be a shallow copy, not identical"
|
assert r1.meta is not r2.meta, "meta must be a shallow copy, not identical"
|
||||||
self.assertEqual(r1.meta, r2.meta)
|
self.assertEqual(r1.meta, r2.meta)
|
||||||
|
|
||||||
|
# make sure headers attribute is shallow copied
|
||||||
|
assert r1.headers is not r2.headers, "headers must be a shallow copy, not identical"
|
||||||
|
self.assertEqual(r1.headers, r2.headers)
|
||||||
|
|
||||||
|
# Request.body can be identical since it's an immutable object (str)
|
||||||
|
|
||||||
def test_copy_inherited_classes(self):
|
def test_copy_inherited_classes(self):
|
||||||
"""Test Request children copies preserve their class"""
|
"""Test Request children copies preserve their class"""
|
||||||
|
|
||||||
@ -128,6 +139,16 @@ class RequestTest(unittest.TestCase):
|
|||||||
|
|
||||||
assert type(r2) is CustomRequest
|
assert type(r2) is CustomRequest
|
||||||
|
|
||||||
|
def test_replace(self):
|
||||||
|
"""Test Request.replace() method"""
|
||||||
|
hdrs = Headers({"key": "value"})
|
||||||
|
r1 = Request("http://www.example.com")
|
||||||
|
r2 = r1.replace(method="POST", body="New body", headers=hdrs)
|
||||||
|
self.assertEqual(r1.url, r2.url)
|
||||||
|
self.assertEqual((r1.method, r2.method), ("GET", "POST"))
|
||||||
|
self.assertEqual((r1.body, r2.body), (None, "New body"))
|
||||||
|
self.assertEqual((r1.headers, r2.headers), ({}, hdrs))
|
||||||
|
|
||||||
def test_httprepr(self):
|
def test_httprepr(self):
|
||||||
r1 = Request("http://www.example.com")
|
r1 = Request("http://www.example.com")
|
||||||
self.assertEqual(r1.httprepr(), 'GET http://www.example.com HTTP/1.1\r\nHost: www.example.com\r\n\r\n')
|
self.assertEqual(r1.httprepr(), 'GET http://www.example.com HTTP/1.1\r\nHost: www.example.com\r\n\r\n')
|
||||||
|
@ -36,7 +36,7 @@ class ResponseTest(unittest.TestCase):
|
|||||||
def test_copy(self):
|
def test_copy(self):
|
||||||
"""Test Response copy"""
|
"""Test Response copy"""
|
||||||
|
|
||||||
r1 = Response("http://www.example.com")
|
r1 = Response("http://www.example.com", body="Some body")
|
||||||
r1.meta['foo'] = 'bar'
|
r1.meta['foo'] = 'bar'
|
||||||
r1.cache['lala'] = 'lolo'
|
r1.cache['lala'] = 'lolo'
|
||||||
r2 = r1.copy()
|
r2 = r1.copy()
|
||||||
@ -48,6 +48,14 @@ class ResponseTest(unittest.TestCase):
|
|||||||
assert r1.meta is not r2.meta, "meta must be a shallow copy, not identical"
|
assert r1.meta is not r2.meta, "meta must be a shallow copy, not identical"
|
||||||
self.assertEqual(r1.meta, r2.meta)
|
self.assertEqual(r1.meta, r2.meta)
|
||||||
|
|
||||||
|
# make sure headers attribute is shallow copied
|
||||||
|
assert r1.headers is not r2.headers, "headers must be a shallow copy, not identical"
|
||||||
|
self.assertEqual(r1.headers, r2.headers)
|
||||||
|
|
||||||
|
# make sure body is shallow copied
|
||||||
|
assert r1.body is not r2.body, "body must be a shallow copy, not identical"
|
||||||
|
self.assertEqual(r1.body, r2.body)
|
||||||
|
|
||||||
def test_copy_inherited_classes(self):
|
def test_copy_inherited_classes(self):
|
||||||
"""Test Response children copies preserve their class"""
|
"""Test Response children copies preserve their class"""
|
||||||
|
|
||||||
@ -59,6 +67,18 @@ class ResponseTest(unittest.TestCase):
|
|||||||
|
|
||||||
assert type(r2) is CustomResponse
|
assert type(r2) is CustomResponse
|
||||||
|
|
||||||
|
def test_replace(self):
|
||||||
|
"""Test Response.replace() method"""
|
||||||
|
hdrs = Headers({"key": "value"})
|
||||||
|
r1 = Response("http://www.example.com")
|
||||||
|
r2 = r1.replace(status=301, body="New body", headers=hdrs)
|
||||||
|
assert r1.body is None
|
||||||
|
assert isinstance(r2.body, _ResponseBody)
|
||||||
|
self.assertEqual(r1.url, r2.url)
|
||||||
|
self.assertEqual((r1.status, r2.status), (200, 301))
|
||||||
|
self.assertEqual((r1.body, r2.body.to_string()), (None, "New body"))
|
||||||
|
self.assertEqual((r1.headers, r2.headers), ({}, hdrs))
|
||||||
|
|
||||||
def test_httprepr(self):
|
def test_httprepr(self):
|
||||||
r1 = Response("http://www.example.com")
|
r1 = Response("http://www.example.com")
|
||||||
self.assertEqual(r1.httprepr(), 'HTTP/1.1 200 OK\r\n\r\n')
|
self.assertEqual(r1.httprepr(), 'HTTP/1.1 200 OK\r\n\r\n')
|
||||||
|
Loading…
x
Reference in New Issue
Block a user