mirror of https://github.com/scrapy/scrapy.git
replaced UsageError exception by more standard (and explicit) ones such as TypeError and ValueError
--HG-- extra : convert_revision : svn%3Ab85faa78-f9eb-468e-a121-7cced6da292c%40936
This commit is contained in:
parent
bfe5a554c2
commit
d16169e9ab
|
|
@ -5,19 +5,16 @@ useful in some Scrapy implementations
|
|||
|
||||
import hashlib
|
||||
|
||||
from pydispatch import dispatcher
|
||||
from pprint import PrettyPrinter
|
||||
|
||||
from scrapy.item import ScrapedItem, ItemDelta
|
||||
from scrapy.item.adaptors import AdaptorPipe
|
||||
from scrapy.spider import spiders
|
||||
from scrapy.core import signals
|
||||
from scrapy.core.exceptions import UsageError, DropItem
|
||||
from scrapy.core.exceptions import DropItem
|
||||
from scrapy.utils.python import unique
|
||||
|
||||
class ValidationError(DropItem):
|
||||
"""Indicates a data validation error"""
|
||||
def __init__(self,problem,value=None):
|
||||
def __init__(self, problem, value=None):
|
||||
self.problem = problem
|
||||
self.value = value
|
||||
|
||||
|
|
@ -141,7 +138,7 @@ class RobustScrapedItem(ScrapedItem):
|
|||
return ret
|
||||
|
||||
if not values:
|
||||
raise UsageError("You must specify at least one value when setting an attribute")
|
||||
raise ValueError("You must specify at least one value when setting an attribute")
|
||||
if attrname not in self.ATTRIBUTES:
|
||||
raise AttributeError('Attribute "%s" is not a valid attribute name. You must add it to %s.ATTRIBUTES' % (attrname, self.__class__.__name__))
|
||||
|
||||
|
|
@ -215,7 +212,7 @@ class RobustScrapedItem(ScrapedItem):
|
|||
if getattr(self, '_version', None):
|
||||
return self._version
|
||||
hash_ = hashlib.sha1()
|
||||
hash_.update("".join(["".join([n, str(v)]) for n,v in sorted(self.__dict__.iteritems())]))
|
||||
hash_.update("".join(["".join([n, str(v)]) for n, v in sorted(self.__dict__.iteritems())]))
|
||||
return hash_.hexdigest()
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ from scrapy.item import ScrapedItem
|
|||
from scrapy.http import Request
|
||||
from scrapy.utils.iterators import xmliter, csviter
|
||||
from scrapy.xpath.selector import XmlXPathSelector, HtmlXPathSelector
|
||||
from scrapy.core.exceptions import UsageError, NotConfigured, NotSupported
|
||||
from scrapy.core.exceptions import NotConfigured, NotSupported
|
||||
|
||||
class XMLFeedSpider(BaseSpider):
|
||||
"""
|
||||
|
|
@ -55,7 +55,7 @@ class XMLFeedSpider(BaseSpider):
|
|||
if isinstance(ret, (ScrapedItem, Request)):
|
||||
ret = [ret]
|
||||
if not isinstance(ret, (list, tuple)):
|
||||
raise UsageError('You cannot return an "%s" object from a spider' % type(ret).__name__)
|
||||
raise TypeError('You cannot return an "%s" object from a spider' % type(ret).__name__)
|
||||
for result_item in self.process_results(response, ret):
|
||||
yield result_item
|
||||
|
||||
|
|
@ -107,7 +107,7 @@ class CSVFeedSpider(BaseSpider):
|
|||
if isinstance(ret, (ScrapedItem, Request)):
|
||||
ret = [ret]
|
||||
if not isinstance(ret, (list, tuple)):
|
||||
raise UsageError('You cannot return an "%s" object from a spider' % type(ret).__name__)
|
||||
raise TypeError('You cannot return an "%s" object from a spider' % type(ret).__name__)
|
||||
for result_item in self.process_results(response, ret):
|
||||
yield result_item
|
||||
|
||||
|
|
|
|||
|
|
@ -3,10 +3,9 @@ Download handlers for different schemes
|
|||
"""
|
||||
from __future__ import with_statement
|
||||
|
||||
import os
|
||||
import urlparse
|
||||
|
||||
from twisted.internet import defer, reactor
|
||||
from twisted.internet import reactor
|
||||
from twisted.web import error as web_error
|
||||
|
||||
try:
|
||||
|
|
@ -16,8 +15,8 @@ except ImportError:
|
|||
|
||||
from scrapy import optional_features
|
||||
from scrapy.core import signals
|
||||
from scrapy.http import Request, Response, Headers
|
||||
from scrapy.core.exceptions import UsageError, HttpException, NotSupported
|
||||
from scrapy.http import Headers
|
||||
from scrapy.core.exceptions import HttpException, NotSupported
|
||||
from scrapy.utils.defer import defer_succeed
|
||||
from scrapy.conf import settings
|
||||
|
||||
|
|
|
|||
|
|
@ -7,10 +7,6 @@ new exceptions here without documenting them there.
|
|||
|
||||
# Internal
|
||||
|
||||
class UsageError(Exception):
|
||||
"""Incorrect usage of the core API"""
|
||||
pass
|
||||
|
||||
class NotConfigured(Exception):
|
||||
"""Indicates a missing configuration situation"""
|
||||
pass
|
||||
|
|
|
|||
|
|
@ -8,20 +8,19 @@ from twisted.plugin import IPlugin
|
|||
|
||||
from scrapy import log
|
||||
from scrapy.http import Request
|
||||
from scrapy.core.exceptions import UsageError
|
||||
|
||||
def _valid_domain_name(obj):
|
||||
"""Check the domain name specified is valid"""
|
||||
if not obj.domain_name:
|
||||
raise UsageError("A site domain name is required")
|
||||
raise ValueError("A site domain name is required")
|
||||
|
||||
def _valid_download_delay(obj):
|
||||
"""Check the download delay is valid, if specified"""
|
||||
delay = getattr(obj, 'download_delay', 0)
|
||||
if not type(delay) in (int, long, float):
|
||||
raise UsageError("download_delay must be numeric")
|
||||
raise ValueError("download_delay must be numeric")
|
||||
if float(delay) < 0.0:
|
||||
raise UsageError("download_delay must be positive")
|
||||
raise ValueError("download_delay must be positive")
|
||||
|
||||
class ISpider(Interface, IPlugin) :
|
||||
"""Interface to be implemented by site-specific web spiders"""
|
||||
|
|
|
|||
|
|
@ -2,9 +2,8 @@
|
|||
import unittest
|
||||
|
||||
from scrapy.contrib.item import RobustScrapedItem
|
||||
from scrapy.item.adaptors import AdaptorPipe, AdaptorFunc
|
||||
from scrapy.item.adaptors import AdaptorPipe
|
||||
from scrapy.contrib_exp import adaptors
|
||||
from scrapy.core.exceptions import UsageError
|
||||
|
||||
class MyItem(RobustScrapedItem):
|
||||
ATTRIBUTES = {
|
||||
|
|
@ -20,7 +19,7 @@ class RobustScrapedItemTestCase(unittest.TestCase):
|
|||
self.item = MyItem()
|
||||
|
||||
def test_attribute_basic(self):
|
||||
self.assertRaises(UsageError, self.item.attribute, 'foo')
|
||||
self.assertRaises(ValueError, self.item.attribute, 'foo')
|
||||
self.assertRaises(AttributeError, self.item.attribute, 'foo', 'something')
|
||||
|
||||
self.item.attribute('name', 'John')
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ import unittest
|
|||
from cStringIO import StringIO
|
||||
|
||||
from scrapy.utils.misc import hash_values, items_to_csv, load_object, to_list
|
||||
from scrapy.core.exceptions import UsageError
|
||||
from scrapy.item import ScrapedItem
|
||||
|
||||
class UtilsMiscTestCase(unittest.TestCase):
|
||||
|
|
@ -10,7 +9,7 @@ class UtilsMiscTestCase(unittest.TestCase):
|
|||
self.assertEqual(hash_values('some', 'values', 'to', 'hash'),
|
||||
'f37f5dc65beaaea35af05e16e26d439fd150c576')
|
||||
|
||||
self.assertRaises(UsageError, hash_values, 'some', None, 'value')
|
||||
self.assertRaises(ValueError, hash_values, 'some', None, 'value')
|
||||
|
||||
def test_items_to_csv(self):
|
||||
item_1 = ScrapedItem()
|
||||
|
|
@ -59,6 +58,8 @@ class UtilsMiscTestCase(unittest.TestCase):
|
|||
def test_load_object(self):
|
||||
obj = load_object('scrapy.utils.misc.load_object')
|
||||
assert obj is load_object
|
||||
self.assertRaises(ImportError, load_object, 'nomodule999.mod.function')
|
||||
self.assertRaises(NameError, load_object, 'scrapy.utils.misc.load_object999')
|
||||
|
||||
def test_to_list(self):
|
||||
self.assertEqual(to_list(None), [])
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ import csv
|
|||
|
||||
from twisted.internet import defer
|
||||
|
||||
from scrapy.core.exceptions import UsageError
|
||||
from scrapy.utils.python import flatten, unicode_to_str
|
||||
from scrapy.utils.markup import remove_entities
|
||||
from scrapy.utils.defer import defer_succeed
|
||||
|
|
@ -78,18 +77,18 @@ def load_object(path):
|
|||
try:
|
||||
dot = path.rindex('.')
|
||||
except ValueError:
|
||||
raise UsageError, '%s isn\'t a module' % path
|
||||
raise ValueError, "Error loading object '%s': not a full path" % path
|
||||
|
||||
module, name = path[:dot], path[dot+1:]
|
||||
try:
|
||||
mod = __import__(module, {}, {}, [''])
|
||||
except ImportError, e:
|
||||
raise UsageError, 'Error importing %s: "%s"' % (module, e)
|
||||
raise ImportError, "Error loading object '%s': %s" % (path, e)
|
||||
|
||||
try:
|
||||
obj = getattr(mod, name)
|
||||
except AttributeError:
|
||||
raise UsageError, 'module "%s" does not define any object named "%s"' % (module, name)
|
||||
raise NameError, "Module '%s' doesn't define any object named '%s'" % (module, name)
|
||||
|
||||
return obj
|
||||
load_class = load_object # backwards compatibility, but isnt going to be available for too long.
|
||||
|
|
@ -117,7 +116,7 @@ def extract_regex(regex, text, encoding):
|
|||
return [remove_entities(unicode(s, encoding), keep=['lt', 'amp']) for s in strings]
|
||||
|
||||
def hash_values(*values):
|
||||
"""Hash a series of values.
|
||||
"""Hash a series of non-None values.
|
||||
|
||||
For example:
|
||||
>>> hash_values('some', 'values', 'to', 'hash')
|
||||
|
|
@ -126,9 +125,8 @@ def hash_values(*values):
|
|||
hash = hashlib.sha1()
|
||||
for value in values:
|
||||
if value is None:
|
||||
message = "hash_values was passed None at argument index %d. This is a bug in the calling code" \
|
||||
% list(values).index(None)
|
||||
raise UsageError(message)
|
||||
message = "hash_values was passed None at argument index %d" % list(values).index(None)
|
||||
raise ValueError(message)
|
||||
hash.update(value)
|
||||
return hash.hexdigest()
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue