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:
Pablo Hoffman 2009-02-28 02:39:28 +00:00
parent bfe5a554c2
commit d16169e9ab
8 changed files with 24 additions and 35 deletions

View File

@ -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()

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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"""

View File

@ -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')

View File

@ -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), [])

View File

@ -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()