Skip to content

Commit 1994f38

Browse files
committed
fix crawling tests under twisted pre 11.0.0
1 parent abf756f commit 1994f38

File tree

2 files changed

+43
-23
lines changed

2 files changed

+43
-23
lines changed

scrapy/core/downloader/webclient.py

+3
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,15 @@ def handleEndHeaders(self):
6060
self.factory.gotHeaders(self.headers)
6161

6262
def connectionLost(self, reason):
63+
self._connection_lost_reason = reason
6364
HTTPClient.connectionLost(self, reason)
6465
self.factory.noPage(reason)
6566

6667
def handleResponse(self, response):
6768
if self.factory.method.upper() == 'HEAD':
6869
self.factory.page('')
70+
elif self.length is not None and self.length > 0:
71+
self.factory.noPage(self._connection_lost_reason)
6972
else:
7073
self.factory.page(response)
7174
self.transport.loseConnection()

scrapy/tests/mockserver.py

+40-23
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,29 @@
22
from subprocess import Popen, PIPE
33
from twisted.web.server import Site, NOT_DONE_YET
44
from twisted.web.resource import Resource
5-
from twisted.internet import reactor
6-
from twisted.internet.task import deferLater
5+
from twisted.internet import reactor, defer
6+
from scrapy import twisted_version
7+
8+
9+
if twisted_version < (11, 0, 0):
10+
def deferLater(clock, delay, func, *args, **kw):
11+
def _cancel_method():
12+
_cancel_cb(None)
13+
d.errback(Exception())
14+
15+
def _cancel_cb(result):
16+
if cl.active():
17+
cl.cancel()
18+
return result
19+
20+
d = defer.Deferred()
21+
d.cancel = _cancel_method
22+
d.addCallback(lambda ignored: func(*args, **kw))
23+
d.addBoth(_cancel_cb)
24+
cl = clock.callLater(delay, d.callback, None)
25+
return d
26+
else:
27+
from twisted.internet.task import deferLater
728

829

930
def getarg(request, name, default=None, type=str):
@@ -13,7 +34,9 @@ def getarg(request, name, default=None, type=str):
1334
return default
1435

1536

16-
class DeferMixin(object):
37+
class LeafResource(Resource):
38+
39+
isLeaf = True
1740

1841
def deferRequest(self, request, delay, f, *a, **kw):
1942
def _cancelrequest(_):
@@ -26,9 +49,7 @@ def _cancelrequest(_):
2649
return d
2750

2851

29-
class Follow(DeferMixin, Resource):
30-
31-
isLeaf = True
52+
class Follow(LeafResource):
3253

3354
def render(self, request):
3455
total = getarg(request, "total", 100, type=int)
@@ -57,9 +78,7 @@ def renderRequest(self, request, nlist):
5778
request.finish()
5879

5980

60-
class Delay(DeferMixin, Resource):
61-
62-
isLeaf = True
81+
class Delay(LeafResource):
6382

6483
def render_GET(self, request):
6584
n = getarg(request, "n", 1, type=float)
@@ -75,24 +94,21 @@ def _delayedRender(self, request, n):
7594
request.finish()
7695

7796

78-
class Status(Resource):
79-
80-
isLeaf = True
97+
class Status(LeafResource):
8198

8299
def render_GET(self, request):
83100
n = getarg(request, "n", 200, type=int)
84101
request.setResponseCode(n)
85102
return ""
86103

87104

88-
class Raw(DeferMixin, Resource):
89-
90-
isLeaf = True
105+
class Raw(LeafResource):
91106

92107
def render_GET(self, request):
93108
request.startedWriting = 1
94109
self.deferRequest(request, 0, self._delayedRender, request)
95110
return NOT_DONE_YET
111+
render_POST = render_GET
96112

97113
def _delayedRender(self, request):
98114
raw = getarg(request, 'raw', 'HTTP 1.1 200 OK\n')
@@ -102,15 +118,12 @@ def _delayedRender(self, request):
102118
request.finish()
103119

104120

105-
class Partial(DeferMixin, Resource):
106-
107-
isLeaf = True
121+
class Partial(LeafResource):
108122

109123
def render_GET(self, request):
110124
request.setHeader("Content-Length", "1024")
111125
self.deferRequest(request, 0, self._delayedRender, request)
112126
return NOT_DONE_YET
113-
render_POST = render_GET
114127

115128
def _delayedRender(self, request):
116129
request.write("partial content\n")
@@ -122,10 +135,13 @@ class Drop(Partial):
122135
def _delayedRender(self, request):
123136
abort = getarg(request, "abort", 0, type=int)
124137
request.write("this connection will be dropped\n")
125-
if abort:
126-
request.channel.transport.abortConnection()
127-
else:
128-
request.channel.transport.loseConnection()
138+
tr = request.channel.transport
139+
try:
140+
if abort and hasattr(tr, 'abortConnection'):
141+
tr.abortConnection()
142+
else:
143+
tr.loseConnection()
144+
finally:
129145
request.finish()
130146

131147

@@ -165,6 +181,7 @@ def __exit__(self, exc_type, exc_value, traceback):
165181
root = Root()
166182
factory = Site(root)
167183
port = reactor.listenTCP(8998, factory)
184+
168185
def print_listening():
169186
h = port.getHost()
170187
print "Mock server running at http://%s:%d" % (h.host, h.port)

0 commit comments

Comments
 (0)