Check that spidercls arguments in scrapy.crawler classes are not spider objects

This commit is contained in:
Adrián Chaves 2019-02-01 13:50:01 +01:00
parent 65d631329a
commit 03e61b9908
3 changed files with 27 additions and 1 deletions

View File

@ -7,6 +7,7 @@ import sys
from twisted.internet import reactor, defer
from zope.interface.verify import verifyClass, DoesNotImplement
from scrapy import Spider
from scrapy.core.engine import ExecutionEngine
from scrapy.resolver import CachingThreadedResolver
from scrapy.interfaces import ISpiderLoader
@ -27,6 +28,10 @@ logger = logging.getLogger(__name__)
class Crawler(object):
def __init__(self, spidercls, settings=None):
if isinstance(spidercls, Spider):
raise ValueError(
'The spidercls argument must be a class, not an object')
if isinstance(settings, dict) or settings is None:
settings = Settings(settings)
@ -168,6 +173,10 @@ class CrawlerRunner(object):
:param dict kwargs: keyword arguments to initialize the spider
"""
if isinstance(crawler_or_spidercls, Spider):
raise ValueError(
'The crawler_or_spidercls argument cannot be a spider object, '
'it must be a spider class (or a Crawler object)')
crawler = self.create_crawler(crawler_or_spidercls)
return self._crawl(crawler, *args, **kwargs)
@ -195,6 +204,10 @@ class CrawlerRunner(object):
a spider with this name in a Scrapy project (using spider loader),
then creates a Crawler instance for it.
"""
if isinstance(crawler_or_spidercls, Spider):
raise ValueError(
'The crawler_or_spidercls argument cannot be a spider object, '
'it must be a spider class (or a Crawler object)')
if isinstance(crawler_or_spidercls, Crawler):
return crawler_or_spidercls
return self._create_crawler(crawler_or_spidercls)

View File

@ -4,6 +4,7 @@ import warnings
from twisted.internet import defer
from twisted.trial import unittest
from pytest import raises
import scrapy
from scrapy.crawler import Crawler, CrawlerRunner, CrawlerProcess
@ -66,6 +67,10 @@ class CrawlerTestCase(BaseCrawlerTest):
crawler = Crawler(DefaultSpider)
self.assertOptionIsDefault(crawler.settings, 'RETRY_ENABLED')
def test_crawler_rejects_spider_objects(self):
with raises(ValueError):
Crawler(DefaultSpider())
class SpiderSettingsTestCase(unittest.TestCase):
def test_spider_custom_settings(self):
@ -177,6 +182,14 @@ class CrawlerRunnerTestCase(BaseCrawlerTest):
self.assertEqual(len(w), 1)
self.assertIn('Please use SPIDER_LOADER_CLASS', str(w[0].message))
def test_crawl_rejects_spider_objects(self):
with raises(ValueError):
CrawlerRunner().crawl(DefaultSpider())
def test_create_crawler_rejects_spider_objects(self):
with raises(ValueError):
CrawlerRunner().create_crawler(DefaultSpider())
class CrawlerProcessTest(BaseCrawlerTest):
def test_crawler_process_accepts_dict(self):

View File

@ -25,7 +25,7 @@ class TestHttpProxyMiddleware(TestCase):
def test_not_enabled(self):
settings = Settings({'HTTPPROXY_ENABLED': False})
crawler = Crawler(spider, settings)
crawler = Crawler(Spider, settings)
self.assertRaises(NotConfigured, partial(HttpProxyMiddleware.from_crawler, crawler))
def test_no_environment_proxies(self):